" D_STR_PROTOCOL " | " +
+ "") +
+ F(""
+ "" D_STR_PROTOCOL " | ") +
htmlSelectClimateProtocol(KEY_PROTOCOL,
climate[chan]->next.protocol) +
- " | "
- "" D_STR_MODEL " | " +
+ F(" | "
+ "" D_STR_MODEL " | ") +
htmlSelectModel(KEY_MODEL, climate[chan]->next.model) +
- " | "
- "" D_STR_POWER " | " +
+ F(" | "
+ "" D_STR_POWER " | ") +
htmlSelectBool(KEY_POWER, climate[chan]->next.power) +
- " | "
- "" D_STR_MODE " | " +
+ F(" | "
+ "" D_STR_MODE " | ") +
htmlSelectMode(KEY_MODE, climate[chan]->next.mode) +
- " | "
+ F(""
"" D_STR_TEMP " | "
""
+ "step='0.5' value='") + String(climate[chan]->next.degrees, 1) +
+ F("'>"
" | "
- "" D_STR_FAN " | " +
+ " | " D_STR_FAN " | ") +
htmlSelectFanspeed(KEY_FANSPEED, climate[chan]->next.fanspeed) +
- " | "
- "" D_STR_SWINGV " | " +
+ F(" | "
+ "" D_STR_SWINGV " | ") +
htmlSelectSwingv(KEY_SWINGV, climate[chan]->next.swingv) +
- " | "
- "" D_STR_SWINGH " | " +
+ F(" | "
+ "" D_STR_SWINGH " | ") +
htmlSelectSwingh(KEY_SWINGH, climate[chan]->next.swingh) +
- " | "
- "" D_STR_QUIET " | " +
+ F(" | "
+ "" D_STR_QUIET " | ") +
htmlSelectBool(KEY_QUIET, climate[chan]->next.quiet) +
- " | "
- "" D_STR_TURBO " | " +
+ F(" | "
+ "" D_STR_TURBO " | ") +
htmlSelectBool(KEY_TURBO, climate[chan]->next.turbo) +
- " | "
- "" D_STR_ECONO " | " +
+ F(" | "
+ "" D_STR_ECONO " | ") +
htmlSelectBool(KEY_ECONO, climate[chan]->next.econo) +
- " | "
- "" D_STR_LIGHT " | " +
+ F(" | "
+ "" D_STR_LIGHT " | ") +
htmlSelectBool(KEY_LIGHT, climate[chan]->next.light) +
- " | "
- "" D_STR_FILTER " | " +
+ F(" | "
+ "" D_STR_FILTER " | ") +
htmlSelectBool(KEY_FILTER, climate[chan]->next.filter) +
- " | "
- "" D_STR_CLEAN " | " +
+ F(" | "
+ "" D_STR_CLEAN " | ") +
htmlSelectBool(KEY_CLEAN, climate[chan]->next.clean) +
- " | "
- "" D_STR_BEEP " | " +
+ F(" | "
+ "" D_STR_BEEP " | ") +
htmlSelectBool(KEY_BEEP, climate[chan]->next.beep) +
- " | "
- "Force resend | " +
+ F(" | "
+ "Force resend | ") +
htmlSelectBool(KEY_RESEND, false) +
- " | "
+ F(""
" "
""
- "";
+ "");
}
html += htmlEnd();
server.send(200, "text/html", html);
@@ -1232,124 +1240,127 @@ void handleInfo(void) {
String html = htmlHeader(F("IR MQTT server info"));
html += htmlMenu();
html +=
- "General"
- "Hostname: " + String(Hostname) + " "
- "IP address: " + WiFi.localIP().toString() + " "
- "MAC address: " + WiFi.macAddress() + " "
- "Booted: " + timeSince(1) + " " +
- "Version: " _MY_VERSION_ " "
+ F(" General"
+ "Hostname: ") + String(Hostname) + F(" "
+ "IP address: ") + WiFi.localIP().toString() + F(" "
+ "MAC address: ") + WiFi.macAddress() + F(" "
+ "Booted: ") + timeSince(1) + F(" ") +
+ F("Version: " _MY_VERSION_ " "
"Built: " __DATE__
" " __TIME__ " "
- "Period Offset: " + String(offset) + "us "
+ "Period Offset: ") + String(offset) + F("us "
"IR Lib Version: " _IRREMOTEESP8266_VERSION_ " "
#if defined(ESP8266)
- "ESP8266 Core Version: " + ESP.getCoreVersion() + " "
- "Free Sketch Space: " + String(maxSketchSpace() >> 10) + "k "
+ "ESP8266 Core Version: ") + ESP.getCoreVersion() + F(" "
+ "Free Sketch Space: ") + String(maxSketchSpace() >> 10) + F("k "
#endif // ESP8266
#if defined(ESP32)
- "ESP32 SDK Version: " + ESP.getSdkVersion() + " "
+ "ESP32 SDK Version: ") + ESP.getSdkVersion() + F(" "
#endif // ESP32
- "Cpu Freq: " + String(ESP.getCpuFreqMHz()) + "MHz "
- "Sanity Check: " + String((_sanity == 0) ? "Ok" : "FAILED") + " "
- "IR Send GPIO(s): " + listOfTxGpios() + " "
+ "Cpu Freq: ") + String(ESP.getCpuFreqMHz()) + F("MHz "
+ "Sanity Check: ") + String((_sanity == 0) ? F("Ok") : F("FAILED")) +
+ F(" "
+ "IR Send GPIO(s): ") + listOfTxGpios() + F(" ")
+ irutils::addBoolToString(kInvertTxOutput,
- "Inverting GPIO output", false) + " "
- "Total send requests: " + String(sendReqCounter) + " "
- "Last message sent: " + String(lastSendSucceeded ? "Ok" : "FAILED") +
- " (" + timeSince(lastSendTime) + ") "
+ F("Inverting GPIO output"), false) + F(" "
+ "Total send requests: ") + String(sendReqCounter) + F(" "
+ "Last message sent: ") + String(lastSendSucceeded ? F("Ok") : F("FAILED")) +
+ F(" (") + timeSince(lastSendTime) + F(") "
#if IR_RX
- "IR Recv GPIO: " + gpioToString(rx_gpio) +
+ "IR Recv GPIO: ") + gpioToString(rx_gpio) + F(
#if IR_RX_PULLUP
" (pullup)"
#endif // IR_RX_PULLUP
" "
- "Total IR Received: " + String(irRecvCounter) + " "
- "Last IR Received: " + lastIrReceived +
- " (" + timeSince(lastIrReceivedTime) + ") "
+ "Total IR Received: ") + String(irRecvCounter) + F(" "
+ "Last IR Received: ") + lastIrReceived +
+ F(" (") + timeSince(lastIrReceivedTime) + F(") "
#endif // IR_RX
- "Duplicate " D_STR_WIFI " networks: " +
- String(HIDE_DUPLICATE_NETWORKS ? "Hide" : "Show") + " "
+ "Duplicate " D_STR_WIFI " networks: ") +
+ String(HIDE_DUPLICATE_NETWORKS ? F("Hide") : F("Show")) + F(" "
"Min " D_STR_WIFI " signal required: "
#ifdef MIN_SIGNAL_STRENGTH
- + String(static_cast(MIN_SIGNAL_STRENGTH)) +
+ ) + // NOLINT(whitespace/parens)
+ String(static_cast(MIN_SIGNAL_STRENGTH)) + F(
#else // MIN_SIGNAL_STRENGTH
"8"
#endif // MIN_SIGNAL_STRENGTH
"% "
"Serial debugging: "
#if DEBUG
- + String(isSerialGpioUsedByIr() ? D_STR_OFF : D_STR_ON) +
+ ) + // NOLINT(whitespace/parens)
+ String(isSerialGpioUsedByIr() ? D_STR_OFF : D_STR_ON) + F(
#else // DEBUG
D_STR_OFF
#endif // DEBUG
" "
#if REPORT_VCC
- "Vcc: ";
+ "Vcc: ");
html += vccToString();
- html += "V "
+ html += F("V "
#endif // REPORT_VCC
" "
#if MQTT_ENABLE
"MQTT Information"
- "Server: " + String(MqttServer) + ":" + String(MqttPort) + " (" +
+ " Server: ") + String(MqttServer) + ":" + String(MqttPort) + F(" (") +
(mqtt_client.connected() ? "Connected " + timeSince(lastDisconnectedTime)
: "Disconnected " + timeSince(lastConnectedTime)) +
- ") "
- "Disconnections: " + String(mqttDisconnectCounter - 1) + " "
- "Buffer Size: " + String(mqtt_client.getBufferSize()) + " bytes "
- "Client id: " + MqttClientId + " "
- "Command topic(s): " + listOfCommandTopics() + " "
- "Acknowledgements topic: " + MqttAck + " "
+ F(") "
+ "Disconnections: ") + String(mqttDisconnectCounter - 1) + F(" "
+ "Buffer Size: ") + String(mqtt_client.getBufferSize()) + F(" bytes "
+ "Client id: ") + MqttClientId + F(" "
+ "Command topic(s): ") + listOfCommandTopics() + F(" "
+ "Acknowledgements topic: ") + MqttAck + F(" "
#if IR_RX
- "IR Received topic: " + MqttRecv + " "
+ "IR Received topic: ") + MqttRecv + F(" "
#endif // IR_RX
- "Log topic: " + MqttLog + " "
- "LWT topic: " + MqttLwt + " "
- "QoS: " + String(QOS) + " "
+ "Log topic: ") + MqttLog + F(" "
+ "LWT topic: ") + MqttLwt + F(" "
+ "QoS: ") + String(QOS) + F(" "
// lastMqttCmd* is unescaped untrusted input.
// Avoid any possible HTML/XSS when displaying it.
- "Last MQTT command seen: (topic) '" +
+ "Last MQTT command seen: (topic) '") +
irutils::htmlEscape(lastMqttCmdTopic) +
- "' (payload) '" + irutils::htmlEscape(lastMqttCmd) + "' (" +
- timeSince(lastMqttCmdTime) + ") "
- "Total published: " + String(mqttSentCounter) + " "
- "Total received: " + String(mqttRecvCounter) + " "
+ F("' (payload) '") + irutils::htmlEscape(lastMqttCmd) + F("' (") +
+ timeSince(lastMqttCmdTime) + F(") "
+ "Total published: ") + String(mqttSentCounter) + F(" "
+ "Total received: ") + String(mqttRecvCounter) + F(" "
" "
#endif // MQTT_ENABLE
"Climate Information"
""
- "IR Send GPIO: " + String(txGpioTable[0]) + " "
- "Last update source: " + lastClimateSource + " "
- "Total sent: " + String(irClimateCounter) + " "
- "Last send: " + String(hasClimateBeenSent ?
+ "IR Send GPIO: ") + String(txGpioTable[0]) + F(" "
+ "Last update source: ") + lastClimateSource + F(" "
+ "Total sent: ") + String(irClimateCounter) + F(" "
+ "Last send: ") + String(hasClimateBeenSent ?
(String(lastClimateSucceeded ? "Ok" : "FAILED") +
" (" + timeElapsed(lastClimateIr.elapsed()) + ")") :
- "Never") + " "
+ "Never") + F(" "
#if MQTT_ENABLE
- "State listen period: " + msToString(kStatListenPeriodMs) + " "
- "State broadcast period: " + msToString(kBroadcastPeriodMs) + " "
- "Last state broadcast: " + (hasBroadcastBeenSent ?
+ "State listen period: ") + msToString(kStatListenPeriodMs) + F(" "
+ "State broadcast period: ") + msToString(kBroadcastPeriodMs) + F(" "
+ "Last state broadcast: ") + (hasBroadcastBeenSent ?
timeElapsed(lastBroadcast.elapsed()) :
- String("Never")) + " "
+ String(F("Never"))) + F(" "
#if MQTT_DISCOVERY_ENABLE
- "Last discovery sent: " + (lockMqttBroadcast ?
- String("Locked") :
+ "Last discovery sent: ") + (lockMqttBroadcast ?
+ String(F("Locked")) :
(hasDiscoveryBeenSent ?
timeElapsed(lastDiscovery.elapsed()) :
- String("Never"))) +
- " "
- "Discovery topic: " + MqttDiscovery + " " +
+ String(F("Never")))) +
+ F(" "
+ "Discovery topic: ") + MqttDiscovery + F(" ") + F(
#endif // MQTT_DISCOVERY_ENABLE
- "Command topics: " + MqttClimate + channel_re + '/' + MQTT_CLIMATE_CMND +
- '/' + kClimateTopics +
- "State topics: " + MqttClimate + channel_re + '/' + MQTT_CLIMATE_STAT +
- '/' + kClimateTopics +
+ "Command topics: ") + MqttClimate + channel_re +
+ F("/" MQTT_CLIMATE_CMND "/") + FPSTR(kClimateTopics) +
+ F("State topics: ") + MqttClimate + channel_re +
+ F("/" MQTT_CLIMATE_STAT "/") + FPSTR(kClimateTopics) + F(
#endif // MQTT_ENABLE
" "
// Page footer
"
"
"(Note: Page will refresh every 60 " D_STR_SECONDS ".)"
- " ";
+ "");
html += addJsReloadUrl(kUrlInfo, 60, false);
html += htmlEnd();
server.send(200, "text/html", html);
@@ -1384,14 +1395,14 @@ bool clearMqttSavedStates(const String topic_base) {
for (size_t i = 0; i < sizeof(kMqttTopics) / sizeof(char*); i++) {
// Sending a retained "" message to the topic should clear previous values
// in theory.
- String topic = topic_base + channelStr + '/' + F(MQTT_CLIMATE_STAT) +
- '/' + String(kMqttTopics[i]);
+ String topic = topic_base + channelStr + F("/" MQTT_CLIMATE_STAT "/") +
+ String(kMqttTopics[i]);
success &= mqtt_client.publish(topic.c_str(), "", true);
}
channelStr = '_' + String(channel);
}
- String logmesg = "Removing all possible settings saved in MQTT for '" +
- topic_base + "' ";
+ String logmesg = F("Removing all possible settings saved in MQTT for '") +
+ topic_base + F("' ");
logmesg += success ? F("succeeded") : F("failed");
mqttLog(logmesg.c_str());
return success;
@@ -1410,13 +1421,13 @@ void handleClearMqtt(void) {
htmlHeader(F("Clearing saved info from MQTT"),
F("Removing all saved settings for this device from "
"MQTT.")) +
- "Device restarting. Try connecting in a few " D_STR_SECONDS ". " +
+ F("Device restarting. Try connecting in a few " D_STR_SECONDS ". ") +
addJsReloadUrl(kUrlRoot, 10, true) +
htmlEnd());
// Do the clearing.
- mqttLog("Clearing all saved settings from MQTT.");
+ mqttLog(PSTR("Clearing all saved settings from MQTT."));
clearMqttSavedStates(MqttClimate);
- doRestart("Rebooting...");
+ doRestart(PSTR("Rebooting..."));
}
#endif // MQTT_ENABLE && MQTT_CLEAR_ENABLE
@@ -1438,10 +1449,10 @@ void handleReset(void) {
// Do the reset.
#if MQTT_ENABLE
#if MQTT_CLEAR_ENABLE
- mqttLog("Clearing all saved climate settings from MQTT.");
+ mqttLog(PSTR("Clearing all saved climate settings from MQTT."));
clearMqttSavedStates(MqttClimate);
#endif // MQTT_CLEAR_ENABLE
- mqttLog("Wiping all saved config settings.");
+ mqttLog(PSTR("Wiping all saved config settings."));
#endif // MQTT_ENABLE
if (mountSpiffs()) {
debug("Removing JSON config file");
@@ -1451,7 +1462,7 @@ void handleReset(void) {
delay(1000);
debug("Reseting wifiManager's settings.");
wifiManager.resetSettings();
- doRestart("Rebooting...");
+ doRestart(PSTR("Rebooting..."));
}
// Reboot web page
@@ -1465,7 +1476,7 @@ void handleReboot() {
#endif
server.send(200, "text/html",
htmlHeader(F("Device restarting.")) +
- "Try connecting in a few " D_STR_SECONDS ". " +
+ F("Try connecting in a few " D_STR_SECONDS ". ") +
addJsReloadUrl(kUrlRoot, kRebootTime, true) +
htmlEnd());
doRestart("Reboot requested");
@@ -1484,7 +1495,7 @@ bool parseStringAndSendAirCon(IRsend *irsend, const decode_type_t irType,
uint8_t state[kStateSizeMax] = {0}; // All array elements are set to 0.
uint16_t stateSize = 0;
- if (str.startsWith("0x") || str.startsWith("0X"))
+ if (str.startsWith(PSTR("0x")) || str.startsWith(PSTR("0X")))
strOffset = 2;
// Calculate how many hexadecimal characters there are.
uint16_t inputLength = str.length() - strOffset;
@@ -1643,8 +1654,9 @@ uint16_t * newCodeArray(const uint16_t size) {
// Check we malloc'ed successfully.
if (result == NULL) // malloc failed, so give up.
doRestart(
- "FATAL: Can't allocate memory for an array for a new message! "
- "Forcing a reboot!", true); // Send to serial only as we are in low mem
+ PSTR("FATAL: Can't allocate memory for an array for a new message! "
+ "Forcing a reboot!"),
+ true); // Send to serial only as we are in low mem
return result;
}
@@ -1666,7 +1678,7 @@ bool parseStringAndSendGC(IRsend *irsend, const String str) {
String tmp_str;
// Remove the leading "1:1,1," if present.
- if (str.startsWith("1:1,1,"))
+ if (str.startsWith(PSTR("1:1,1,")))
tmp_str = str.substring(6);
else
tmp_str = str;
@@ -2097,7 +2109,7 @@ void setup(void) {
if (isSerialGpioUsedByIr()) Serial.end();
#endif // DEBUG
- channel_re.reserve(kNrOfIrTxGpios * 3);
+ channel_re.reserve(kNrOfIrTxGpios * 3 + 3 + 1);
// Initialise all the IR transmitters.
for (uint8_t i = 0; i < kNrOfIrTxGpios; i++) {
if (txGpioTable[i] == kGpioUnused) {
@@ -2195,7 +2207,7 @@ void setup(void) {
if (strlen(HttpPassword)) { // Allow if password is set.
server.on("/update", HTTP_POST, [](){
#if MQTT_ENABLE
- mqttLog("Attempting firmware update & reboot");
+ mqttLog(PSTR("Attempting firmware update & reboot"));
delay(1000);
#endif // MQTT_ENABLE
server.send(200, "text/html",
@@ -2287,7 +2299,7 @@ void unsubscribing(const String topic_name) {
void mqttLog(const char* str) {
debug(str);
- mqtt_client.publish(MqttLog.c_str(), str);
+ mqtt_client.publish(MqttLog.c_str(), String(str).c_str());
mqttSentCounter++;
}
@@ -2313,7 +2325,7 @@ bool reconnect(void) {
}
if (connected) {
// Once connected, publish an announcement...
- mqttLog("(Re)Connected.");
+ mqttLog(PSTR("(Re)Connected."));
// Update Last Will & Testament to say we are back online.
mqtt_client.publish(MqttLwt.c_str(), kLwtOnline, true);
@@ -2364,12 +2376,13 @@ void handleSendMqttDiscovery(void) {
server.send(200, "text/html",
htmlHeader(F("Sending MQTT Discovery message")) +
htmlMenu() +
- "The Home Assistant MQTT Discovery message is being sent to topic: " +
- MqttDiscovery + ". It will show up in Home Assistant in a few seconds."
+ F(" The Home Assistant MQTT Discovery message is being sent to topic: ")
+ + MqttDiscovery +
+ F(". It will show up in Home Assistant in a few seconds."
" "
"Warning!"
"Home Assistant's config for this device is reset each time this is "
- " is sent. " +
+ " is sent.") +
addJsReloadUrl(kUrlRoot, kRebootTime, true) +
htmlEnd());
sendMQTTDiscovery(MqttDiscovery.c_str());
@@ -2416,8 +2429,8 @@ void receivingMQTT(String const topic_name, String const callback_str) {
// Or is for a specific ac/climate channel. e.g. "*/ac_[1-9]"
debug(("Checking for channel number in " + topic_name).c_str());
for (uint16_t i = 0; i < kNrOfIrTxGpios; i++) {
- if (topic_name.endsWith("_" + String(i)) ||
- (i > 0 && topic_name.startsWith(MqttClimate + "_" + String(i)))) {
+ if (topic_name.endsWith('_' + String(i)) ||
+ (i > 0 && topic_name.startsWith(MqttClimate + '_' + String(i)))) {
channel = i;
break;
}
@@ -2425,8 +2438,8 @@ void receivingMQTT(String const topic_name, String const callback_str) {
debug(("Channel = " + String(channel)).c_str());
// Is it a climate topic?
if (topic_name.startsWith(MqttClimate)) {
- String alt_cmnd_topic = MqttClimate + "_" + String(channel) + '/' +
- MQTT_CLIMATE_CMND + '/';
+ String alt_cmnd_topic = MqttClimate + '_' + String(channel) +
+ F("/" MQTT_CLIMATE_CMND "/");
// Also accept climate commands on the '*_0' channel.
String cmnd_topic = topic_name.startsWith(alt_cmnd_topic) ? alt_cmnd_topic
: MqttClimateCmnd;
@@ -2440,7 +2453,7 @@ void receivingMQTT(String const topic_name, String const callback_str) {
if (topic_name.equals(cmnd_topic + KEY_RESEND) &&
callback_str.equalsIgnoreCase(KEY_RESEND)) {
force_resend = true;
- mqttLog("Climate resend requested.");
+ mqttLog(PSTR("Climate resend requested."));
}
if (sendClimate(stat_topic, true, false, force_resend, true,
climate[channel]) && !force_resend)
@@ -2548,10 +2561,15 @@ void mqttCallback(char* topic, byte* payload, unsigned int length) {
void sendMQTTDiscovery(const char *topic) {
if (mqtt_client.publish(
topic, String(
- "{"
- "\"~\":\"" + MqttClimate + "\","
- "\"name\":\"" + MqttHAName + "\","
+ F("{"
+ "\"~\":\"") + MqttClimate + F("\","
+ "\"name\":\"") + MqttHAName + F("\","
+#if (!MQTT_CLIMATE_HA_MODE)
+ // Typically we don't need or use the power command topic if we are using
+ // our Home Assistant Climate compatiblity mode. It causes odd behaviour
+ // if both are used.
"\"pow_cmd_t\":\"~/" MQTT_CLIMATE_CMND "/" KEY_POWER "\","
+#endif // !MQTT_CLIMATE_HA_MODE
"\"mode_cmd_t\":\"~/" MQTT_CLIMATE_CMND "/" KEY_MODE "\","
"\"mode_stat_t\":\"~/" MQTT_CLIMATE_STAT "/" KEY_MODE "\","
// I don't know why, but the modes need to be lower case to work with
@@ -2571,22 +2589,22 @@ void sendMQTTDiscovery(const char *topic) {
"\"swing_modes\":[\"" D_STR_OFF "\",\"" D_STR_AUTO "\",\"" D_STR_HIGHEST
"\",\"" D_STR_HIGH "\",\"" D_STR_MIDDLE "\",\""
D_STR_LOW "\",\"" D_STR_LOWEST "\"],"
- "\"uniq_id\":\"" + MqttUniqueId + "\","
+ "\"uniq_id\":\"") + MqttUniqueId + F("\","
"\"device\":{"
- "\"identifiers\":[\"" + MqttUniqueId + "\"],"
- "\"connections\":[[\"mac\",\"" + WiFi.macAddress() + "\"]],"
+ "\"identifiers\":[\"") + MqttUniqueId + F("\"],"
+ "\"connections\":[[\"mac\",\"") + WiFi.macAddress() + F("\"]],"
"\"manufacturer\":\"IRremoteESP8266\","
"\"model\":\"IRMQTTServer\","
- "\"name\":\"" + Hostname + "\","
+ "\"name\":\"") + Hostname + F("\","
"\"sw_version\":\"" _MY_VERSION_ "\""
"}"
- "}").c_str(), true)) {
- mqttLog("MQTT climate discovery successful sent.");
+ "}")).c_str(), true)) {
+ mqttLog(PSTR("MQTT climate discovery successful sent."));
hasDiscoveryBeenSent = true;
lastDiscovery.reset();
mqttSentCounter++;
} else {
- mqttLog("MQTT climate discovery FAILED to send.");
+ mqttLog(PSTR("MQTT climate discovery FAILED to send."));
}
}
#endif // MQTT_DISCOVERY_ENABLE
@@ -2616,11 +2634,12 @@ void loop(void) {
lastReconnectAttempt = 0;
wasConnected = true;
if (boot) {
- mqttLog("IRMQTTServer " _MY_VERSION_ " just booted");
+ mqttLog(PSTR("IRMQTTServer " _MY_VERSION_ " just booted"));
boot = false;
} else {
mqttLog(String(
- "IRMQTTServer just (re)connected to MQTT. Lost connection about "
+ F("IRMQTTServer just (re)connected to MQTT. "
+ "Lost connection about ")
+ timeSince(lastConnectedTime)).c_str());
}
lastConnectedTime = now;
@@ -2628,7 +2647,7 @@ void loop(void) {
if (lockMqttBroadcast) {
// Attempt to fetch back any Climate state stored in MQTT retained
// messages on the MQTT broker.
- mqttLog("Started listening for previous state.");
+ mqttLog(PSTR("Started listening for previous state."));
for (uint16_t i = 0; i < kNrOfIrTxGpios; i++)
subscribing(genStatTopic(i) + '+');
statListenTime.reset();
@@ -2648,10 +2667,10 @@ void loop(void) {
sendClimate(stat_topic, true, false, false,
MQTT_CLIMATE_IR_SEND_ON_RESTART, climate[i]);
lastClimateSource = F("MQTT (via retain)");
- mqttLog("The state was recovered from MQTT broker.");
+ mqttLog(PSTR("The state was recovered from MQTT broker."));
}
}
- mqttLog("Finished listening for previous state.");
+ mqttLog(PSTR("Finished listening for previous state."));
lockMqttBroadcast = false; // Release the lock so we can broadcast again.
}
// Periodically send all of the climate state via MQTT.
@@ -2671,17 +2690,17 @@ void loop(void) {
resultToHexidecimal(&capture);
#if REPORT_RAW_UNKNOWNS
if (capture.decode_type == UNKNOWN) {
- lastIrReceived += ";";
+ lastIrReceived += ';';
for (uint16_t i = 1; i < capture.rawlen; i++) {
uint32_t usecs;
for (usecs = capture.rawbuf[i] * kRawTick; usecs > UINT16_MAX;
usecs -= UINT16_MAX) {
lastIrReceived += uint64ToString(UINT16_MAX);
- lastIrReceived += ",0,";
+ lastIrReceived += F(",0,");
}
lastIrReceived += uint64ToString(usecs, 10);
if (i < capture.rawlen - 1)
- lastIrReceived += ",";
+ lastIrReceived += ',';
}
}
#endif // REPORT_RAW_UNKNOWNS
@@ -2875,10 +2894,10 @@ void sendJsonState(const stdAc::state_t state, const String topic,
json[KEY_PROTOCOL] = typeToString(state.protocol);
json[KEY_MODEL] = state.model;
json[KEY_POWER] = IRac::boolToString(state.power);
- json[KEY_MODE] = IRac::opmodeToString(state.mode);
+ json[KEY_MODE] = IRac::opmodeToString(state.mode, ha_mode);
// Home Assistant wants mode to be off if power is also off & vice-versa.
if (ha_mode && (state.mode == stdAc::opmode_t::kOff || !state.power)) {
- json[KEY_MODE] = IRac::opmodeToString(stdAc::opmode_t::kOff);
+ json[KEY_MODE] = IRac::opmodeToString(stdAc::opmode_t::kOff, ha_mode);
json[KEY_POWER] = IRac::boolToString(false);
}
json[KEY_CELSIUS] = IRac::boolToString(state.celsius);
@@ -2965,45 +2984,45 @@ void updateClimate(stdAc::state_t *state, const String str,
*state = jsonToState(*state, payload.c_str());
else
#endif // MQTT_CLIMATE_JSON
- if (str.equals(prefix + KEY_PROTOCOL)) {
+ if (str.equals(prefix + F(KEY_PROTOCOL))) {
state->protocol = strToDecodeType(payload.c_str());
- } else if (str.equals(prefix + KEY_MODEL)) {
+ } else if (str.equals(prefix + F(KEY_MODEL))) {
state->model = IRac::strToModel(payload.c_str());
- } else if (str.equals(prefix + KEY_POWER)) {
+ } else if (str.equals(prefix + F(KEY_POWER))) {
state->power = IRac::strToBool(payload.c_str());
#if MQTT_CLIMATE_HA_MODE
if (!state->power) state->mode = stdAc::opmode_t::kOff;
#endif // MQTT_CLIMATE_HA_MODE
- } else if (str.equals(prefix + KEY_MODE)) {
+ } else if (str.equals(prefix + F(KEY_MODE))) {
state->mode = IRac::strToOpmode(payload.c_str());
#if MQTT_CLIMATE_HA_MODE
state->power = (state->mode != stdAc::opmode_t::kOff);
#endif // MQTT_CLIMATE_HA_MODE
- } else if (str.equals(prefix + KEY_TEMP)) {
+ } else if (str.equals(prefix + F(KEY_TEMP))) {
state->degrees = payload.toFloat();
- } else if (str.equals(prefix + KEY_FANSPEED)) {
+ } else if (str.equals(prefix + F(KEY_FANSPEED))) {
state->fanspeed = IRac::strToFanspeed(payload.c_str());
- } else if (str.equals(prefix + KEY_SWINGV)) {
+ } else if (str.equals(prefix + F(KEY_SWINGV))) {
state->swingv = IRac::strToSwingV(payload.c_str());
- } else if (str.equals(prefix + KEY_SWINGH)) {
+ } else if (str.equals(prefix + F(KEY_SWINGH))) {
state->swingh = IRac::strToSwingH(payload.c_str());
- } else if (str.equals(prefix + KEY_QUIET)) {
+ } else if (str.equals(prefix + F(KEY_QUIET))) {
state->quiet = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_TURBO)) {
+ } else if (str.equals(prefix + F(KEY_TURBO))) {
state->turbo = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_ECONO)) {
+ } else if (str.equals(prefix + F(KEY_ECONO))) {
state->econo = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_LIGHT)) {
+ } else if (str.equals(prefix + F(KEY_LIGHT))) {
state->light = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_BEEP)) {
+ } else if (str.equals(prefix + F(KEY_BEEP))) {
state->beep = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_FILTER)) {
+ } else if (str.equals(prefix + F(KEY_FILTER))) {
state->filter = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_CLEAN)) {
+ } else if (str.equals(prefix + F(KEY_CLEAN))) {
state->clean = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_CELSIUS)) {
+ } else if (str.equals(prefix + F(KEY_CELSIUS))) {
state->celsius = IRac::strToBool(payload.c_str());
- } else if (str.equals(prefix + KEY_SLEEP)) {
+ } else if (str.equals(prefix + F(KEY_SLEEP))) {
state->sleep = payload.toInt();
}
}
@@ -3024,7 +3043,11 @@ bool sendClimate(const String topic_prefix, const bool retain,
diff = true;
success &= sendInt(topic_prefix + KEY_MODEL, next.model, retain);
}
+#ifdef MQTT_CLIMATE_HA_MODE
+ String mode_str = IRac::opmodeToString(next.mode, MQTT_CLIMATE_HA_MODE);
+#else // MQTT_CLIMATE_HA_MODE
String mode_str = IRac::opmodeToString(next.mode);
+#endif // MQTT_CLIMATE_HA_MODE
// I don't know why, but the modes need to be lower case to work with
// Home Assistant & Google Home.
mode_str.toLowerCase();
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini
index 0063a1133..b56304f66 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV2/platformio.ini
@@ -52,6 +52,12 @@ build_flags = -D_IR_LOCALE_=it-IT ; Italian
[env:pt-BR]
build_flags = -D_IR_LOCALE_=pt-BR ; Portuguese (Brazilian)
+[env:ru-RU]
+build_flags = -D_IR_LOCALE_=ru-RU ; Russian
+
+[env:sv-SE]
+build_flags = -D_IR_LOCALE_=sv-SE ; Swedish
+
[env:zh-CN]
build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV3/platformio.ini b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV3/platformio.ini
index 95a90ac86..e5df92876 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV3/platformio.ini
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/IRrecvDumpV3/platformio.ini
@@ -49,5 +49,14 @@ build_flags = -D_IR_LOCALE_=fr-FR ; French
[env:it-IT]
build_flags = -D_IR_LOCALE_=it-IT ; Italian
+[env:pt-BR]
+build_flags = -D_IR_LOCALE_=pt-BR ; Portuguese (Brazilian)
+
+[env:ru-RU]
+build_flags = -D_IR_LOCALE_=ru-RU ; Russian
+
+[env:sv-SE]
+build_flags = -D_IR_LOCALE_=sv-SE ; Swedish
+
[env:zh-CN]
build_flags = -D_IR_LOCALE_=zh-CN ; Chinese (Simplified)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/keywords.txt b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/keywords.txt
index fefce8d9d..592b5d99b 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/keywords.txt
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/keywords.txt
@@ -52,6 +52,7 @@ IRKelonAc KEYWORD1
IRKelvinatorAC KEYWORD1
IRLgAc KEYWORD1
IRMideaAC KEYWORD1
+IRMirageAc KEYWORD1
IRMitsubishi112 KEYWORD1
IRMitsubishi136 KEYWORD1
IRMitsubishiAC KEYWORD1
@@ -60,6 +61,7 @@ IRMitsubishiHeavy88Ac KEYWORD1
IRNeoclimaAc KEYWORD1
IRPanasonicAc KEYWORD1
IRPanasonicAc32 KEYWORD1
+IRRhossAc KEYWORD1
IRSamsungAc KEYWORD1
IRSanyoAc KEYWORD1
IRSanyoAc88 KEYWORD1
@@ -85,16 +87,19 @@ decode_type_t KEYWORD1
fanspeed_t KEYWORD1
fujitsu_ac_remote_model_t KEYWORD1
gree_ac_remote_model_t KEYWORD1
+haier_ac176_remote_model_t KEYWORD1
hitachi_ac1_remote_model_t KEYWORD1
irparams_t KEYWORD1
lg_ac_remote_model_t KEYWORD1
match_result_t KEYWORD1
+mirage_ac_remote_model_t KEYWORD1
opmode_t KEYWORD1
panasonic_ac_remote_model_t KEYWORD1
sharp_ac_remote_model_t KEYWORD1
state_t KEYWORD1
swingh_t KEYWORD1
swingv_t KEYWORD1
+tcl_ac_remote_model_t KEYWORD1
voltas_ac_remote_model_t KEYWORD1
whirlpool_ac_remote_model_t KEYWORD1
@@ -107,6 +112,8 @@ _cancelOffTimer KEYWORD2
_cancelOnTimer KEYWORD2
_delayMicroseconds KEYWORD2
_getEconoToggle KEYWORD2
+_getOffTimer KEYWORD2
+_getOnTimer KEYWORD2
_getTime KEYWORD2
_getTimer KEYWORD2
_isAKB73757604 KEYWORD2
@@ -117,6 +124,9 @@ _restoreState KEYWORD2
_sendSony KEYWORD2
_setEconoToggle KEYWORD2
_setMode KEYWORD2
+_setOffTimer KEYWORD2
+_setOnTimer KEYWORD2
+_setSleepTimer KEYWORD2
_setTemp KEYWORD2
_setTime KEYWORD2
_setTimer KEYWORD2
@@ -135,6 +145,7 @@ addSwingHToString KEYWORD2
addSwingVToString KEYWORD2
addTempFloatToString KEYWORD2
addTempToString KEYWORD2
+addToggleToString KEYWORD2
adjustRepeat KEYWORD2
airwell KEYWORD2
amcor KEYWORD2
@@ -189,10 +200,12 @@ daikin2 KEYWORD2
daikin216 KEYWORD2
daikin64 KEYWORD2
decode KEYWORD2
+decodeAirton KEYWORD2
decodeAirwell KEYWORD2
decodeAiwaRCT501 KEYWORD2
decodeAmcor KEYWORD2
decodeArgo KEYWORD2
+decodeArris KEYWORD2
decodeBose KEYWORD2
decodeCOOLIX KEYWORD2
decodeCarrierAC KEYWORD2
@@ -258,6 +271,7 @@ decodePioneer KEYWORD2
decodeRC5 KEYWORD2
decodeRC6 KEYWORD2
decodeRCMM KEYWORD2
+decodeRhoss KEYWORD2
decodeSAMSUNG KEYWORD2
decodeSamsung36 KEYWORD2
decodeSamsungAC KEYWORD2
@@ -298,6 +312,7 @@ enableIROut KEYWORD2
enableOffTimer KEYWORD2
enableOnTimer KEYWORD2
enableSleepTimer KEYWORD2
+encodeArris KEYWORD2
encodeDoshisha KEYWORD2
encodeJVC KEYWORD2
encodeLG KEYWORD2
@@ -319,6 +334,7 @@ fahrenheitToCelsius KEYWORD2
fanspeedToString KEYWORD2
fixChecksum KEYWORD2
fixup KEYWORD2
+fromCommon KEYWORD2
fujitsu KEYWORD2
get10CHeat KEYWORD2
get3D KEYWORD2
@@ -331,6 +347,7 @@ getBufSize KEYWORD2
getButton KEYWORD2
getCelsius KEYWORD2
getClean KEYWORD2
+getCleanToggle KEYWORD2
getClock KEYWORD2
getCmd KEYWORD2
getComfort KEYWORD2
@@ -367,6 +384,7 @@ getIonFilter KEYWORD2
getLed KEYWORD2
getLight KEYWORD2
getLightToggle KEYWORD2
+getLock KEYWORD2
getMax KEYWORD2
getMode KEYWORD2
getMold KEYWORD2
@@ -396,9 +414,11 @@ getSectionByte KEYWORD2
getSectionChecksum KEYWORD2
getSensor KEYWORD2
getSensorTemp KEYWORD2
+getSensorUpdate KEYWORD2
getSilent KEYWORD2
getSleep KEYWORD2
getSleepTime KEYWORD2
+getSleepTimer KEYWORD2
getSleepTimerEnabled KEYWORD2
getSpecial KEYWORD2
getSpeed KEYWORD2
@@ -481,6 +501,7 @@ isSwingH KEYWORD2
isSwingV KEYWORD2
isSwingVStep KEYWORD2
isSwingVToggle KEYWORD2
+isTcl KEYWORD2
isTimeCommand KEYWORD2
isTimerActive KEYWORD2
isTurboToggle KEYWORD2
@@ -509,6 +530,7 @@ matchSpaceRange KEYWORD2
midea KEYWORD2
minRepeats KEYWORD2
minsToString KEYWORD2
+mirage KEYWORD2
mitsubishi KEYWORD2
mitsubishi112 KEYWORD2
mitsubishi136 KEYWORD2
@@ -532,15 +554,18 @@ resultToSourceCode KEYWORD2
resultToTimingInfo KEYWORD2
resume KEYWORD2
reverseBits KEYWORD2
+rhoss KEYWORD2
samsung KEYWORD2
sanyo KEYWORD2
sanyo88 KEYWORD2
send KEYWORD2
sendAc KEYWORD2
+sendAirton KEYWORD2
sendAirwell KEYWORD2
sendAiwaRCT501 KEYWORD2
sendAmcor KEYWORD2
sendArgo KEYWORD2
+sendArris KEYWORD2
sendBose KEYWORD2
sendCOOLIX KEYWORD2
sendCarrierAC KEYWORD2
@@ -621,6 +646,7 @@ sendRC5 KEYWORD2
sendRC6 KEYWORD2
sendRCMM KEYWORD2
sendRaw KEYWORD2
+sendRhoss KEYWORD2
sendSAMSUNG KEYWORD2
sendSamsung36 KEYWORD2
sendSamsungAC KEYWORD2
@@ -662,6 +688,7 @@ setBreeze KEYWORD2
setButton KEYWORD2
setCelsius KEYWORD2
setClean KEYWORD2
+setCleanToggle KEYWORD2
setClock KEYWORD2
setCmd KEYWORD2
setComfort KEYWORD2
@@ -697,6 +724,7 @@ setIonFilter KEYWORD2
setLed KEYWORD2
setLight KEYWORD2
setLightToggle KEYWORD2
+setLock KEYWORD2
setMax KEYWORD2
setMode KEYWORD2
setModel KEYWORD2
@@ -725,6 +753,7 @@ setSave KEYWORD2
setSensor KEYWORD2
setSensorTemp KEYWORD2
setSensorTempRaw KEYWORD2
+setSensorUpdate KEYWORD2
setSilent KEYWORD2
setSleep KEYWORD2
setSleepTimer KEYWORD2
@@ -791,6 +820,7 @@ teco KEYWORD2
ticksHigh KEYWORD2
ticksLow KEYWORD2
toString KEYWORD2
+toggleArrisRelease KEYWORD2
toggleRC5 KEYWORD2
toggleRC6 KEYWORD2
toggleSwingHoriz KEYWORD2
@@ -821,6 +851,7 @@ xorBytes KEYWORD2
A705 LITERAL1
A903 LITERAL1
A907 LITERAL1
+AIRTON LITERAL1
AIRWELL LITERAL1
AIWA_RC_T501 LITERAL1
AIWA_RC_T501_BITS LITERAL1
@@ -857,6 +888,7 @@ ARJW2 LITERAL1
ARRAH2E LITERAL1
ARREB1E LITERAL1
ARREW4E LITERAL1
+ARRIS LITERAL1
ARRY4 LITERAL1
BOSE LITERAL1
CARRIER_AC LITERAL1
@@ -887,10 +919,12 @@ DAIKIN_HEAT LITERAL1
DAIKIN_MAX_TEMP LITERAL1
DAIKIN_MIN_TEMP LITERAL1
DECODE_AC LITERAL1
+DECODE_AIRTON LITERAL1
DECODE_AIRWELL LITERAL1
DECODE_AIWA_RC_T501 LITERAL1
DECODE_AMCOR LITERAL1
DECODE_ARGO LITERAL1
+DECODE_ARRIS LITERAL1
DECODE_BOSE LITERAL1
DECODE_CARRIER_AC LITERAL1
DECODE_CARRIER_AC40 LITERAL1
@@ -961,6 +995,7 @@ DECODE_PRONTO LITERAL1
DECODE_RC5 LITERAL1
DECODE_RC6 LITERAL1
DECODE_RCMM LITERAL1
+DECODE_RHOSS LITERAL1
DECODE_SAMSUNG LITERAL1
DECODE_SAMSUNG36 LITERAL1
DECODE_SAMSUNG_AC LITERAL1
@@ -1054,6 +1089,7 @@ GREE_SWING_MIDDLE_DOWN LITERAL1
GREE_SWING_MIDDLE_UP LITERAL1
GREE_SWING_UP LITERAL1
GREE_SWING_UP_AUTO LITERAL1
+GZ055BE1 LITERAL1
HAIER_AC LITERAL1
HAIER_AC176 LITERAL1
HAIER_AC_AUTO LITERAL1
@@ -1063,7 +1099,7 @@ HAIER_AC_CMD_MODE LITERAL1
HAIER_AC_CMD_OFF LITERAL1
HAIER_AC_CMD_ON LITERAL1
HAIER_AC_CMD_SLEEP LITERAL1
-HAIER_AC_CMD_SWING LITERAL1
+HAIER_AC_CMD_SWINGV LITERAL1
HAIER_AC_CMD_TEMP_DOWN LITERAL1
HAIER_AC_CMD_TEMP_UP LITERAL1
HAIER_AC_CMD_TIMER_CANCEL LITERAL1
@@ -1080,10 +1116,10 @@ HAIER_AC_HEAT LITERAL1
HAIER_AC_MAX_TEMP LITERAL1
HAIER_AC_MIN_TEMP LITERAL1
HAIER_AC_STATE_LENGTH LITERAL1
-HAIER_AC_SWING_CHG LITERAL1
-HAIER_AC_SWING_DOWN LITERAL1
-HAIER_AC_SWING_OFF LITERAL1
-HAIER_AC_SWING_UP LITERAL1
+HAIER_AC_SWINGV_CHG LITERAL1
+HAIER_AC_SWINGV_DOWN LITERAL1
+HAIER_AC_SWINGV_OFF LITERAL1
+HAIER_AC_SWINGV_UP LITERAL1
HAIER_AC_YRW02 LITERAL1
HAIER_AC_YRW02_AUTO LITERAL1
HAIER_AC_YRW02_BUTTON_FAN LITERAL1
@@ -1110,8 +1146,6 @@ HAIER_AC_YRW02_SWING_DOWN LITERAL1
HAIER_AC_YRW02_SWING_MIDDLE LITERAL1
HAIER_AC_YRW02_SWING_OFF LITERAL1
HAIER_AC_YRW02_SWING_TOP LITERAL1
-HAIER_AC_YRW02_TURBO_HIGH LITERAL1
-HAIER_AC_YRW02_TURBO_LOW LITERAL1
HAIER_AC_YRW02_TURBO_OFF LITERAL1
HIGH LITERAL1
HITACHI_AC LITERAL1
@@ -1144,6 +1178,8 @@ KELVINATOR_HEAT LITERAL1
KELVINATOR_MAX_TEMP LITERAL1
KELVINATOR_MIN_TEMP LITERAL1
KELVINATOR_STATE_LENGTH LITERAL1
+KKG29AC1 LITERAL1
+KKG9AC1 LITERAL1
LASERTAG LITERAL1
LASERTAG_BITS LITERAL1
LEGOPF LITERAL1
@@ -1224,6 +1260,7 @@ RC6_36_BITS LITERAL1
RC6_MODE0_BITS LITERAL1
RCMM LITERAL1
RCMM_BITS LITERAL1
+RHOSS LITERAL1
R_LT0541_HTA_A LITERAL1
R_LT0541_HTA_B LITERAL1
SAMSUNG LITERAL1
@@ -1236,10 +1273,12 @@ SANYO_AC88 LITERAL1
SANYO_LC7461 LITERAL1
SANYO_LC7461_BITS LITERAL1
SANYO_SA8650B_BITS LITERAL1
+SEND_AIRTON LITERAL1
SEND_AIRWELL LITERAL1
SEND_AIWA_RC_T501 LITERAL1
SEND_AMCOR LITERAL1
SEND_ARGO LITERAL1
+SEND_ARRIS LITERAL1
SEND_BOSE LITERAL1
SEND_CARRIER_AC LITERAL1
SEND_CARRIER_AC40 LITERAL1
@@ -1310,6 +1349,7 @@ SEND_RAW LITERAL1
SEND_RC5 LITERAL1
SEND_RC6 LITERAL1
SEND_RCMM LITERAL1
+SEND_RHOSS LITERAL1
SEND_SAMSUNG LITERAL1
SEND_SAMSUNG36 LITERAL1
SEND_SAMSUNG_AC LITERAL1
@@ -1347,6 +1387,7 @@ SONY_15_BITS LITERAL1
SONY_20_BITS LITERAL1
SONY_38K LITERAL1
SYMPHONY LITERAL1
+TAC09CHSD LITERAL1
TCL112AC LITERAL1
TECHNIBEL_AC LITERAL1
TECO LITERAL1
@@ -1381,6 +1422,8 @@ TRUMA LITERAL1
UNKNOWN LITERAL1
UNUSED LITERAL1
USE_IRAM_ATTR LITERAL1
+V9014557_A LITERAL1
+V9014557_B LITERAL1
VESTEL_AC LITERAL1
VOLTAS LITERAL1
WHIRLPOOL_AC LITERAL1
@@ -1390,11 +1433,25 @@ XMP LITERAL1
YAW1F LITERAL1
YBOFB LITERAL1
ZEPEAL LITERAL1
+k0Str LITERAL1
k10CHeatStr LITERAL1
+k122lzfStr LITERAL1
+k1Str LITERAL1
k3DStr LITERAL1
k6thSenseStr LITERAL1
k8CHeatStr LITERAL1
+kA705Str LITERAL1
+kA903Str LITERAL1
+kA907Str LITERAL1
kAirFlowStr LITERAL1
+kAirtonBitMark LITERAL1
+kAirtonBits LITERAL1
+kAirtonDefaultRepeat LITERAL1
+kAirtonFreq LITERAL1
+kAirtonHdrMark LITERAL1
+kAirtonHdrSpace LITERAL1
+kAirtonOneSpace LITERAL1
+kAirtonZeroSpace LITERAL1
kAirwellAuto LITERAL1
kAirwellBits LITERAL1
kAirwellCool LITERAL1
@@ -1420,6 +1477,9 @@ kAiwaRcT501PostBits LITERAL1
kAiwaRcT501PostData LITERAL1
kAiwaRcT501PreBits LITERAL1
kAiwaRcT501PreData LITERAL1
+kAkb73757604Str LITERAL1
+kAkb74955603Str LITERAL1
+kAkb75215403Str LITERAL1
kAllProtocolNamesStr LITERAL1
kAlokaBits LITERAL1
kAlokaLedBlue LITERAL1
@@ -1464,6 +1524,7 @@ kAmcorTolerance LITERAL1
kAmcorVentOn LITERAL1
kAmcorZeroMark LITERAL1
kAmcorZeroSpace LITERAL1
+kArdb1Str LITERAL1
kArgoAuto LITERAL1
kArgoBitMark LITERAL1
kArgoBits LITERAL1
@@ -1497,6 +1558,21 @@ kArgoOneSpace LITERAL1
kArgoStateLength LITERAL1
kArgoTempDelta LITERAL1
kArgoZeroSpace LITERAL1
+kArjw2Str LITERAL1
+kArrah2eStr LITERAL1
+kArreb1eStr LITERAL1
+kArrew4eStr LITERAL1
+kArrisBits LITERAL1
+kArrisChecksumSize LITERAL1
+kArrisCommandSize LITERAL1
+kArrisGapSpace LITERAL1
+kArrisHalfClockPeriod LITERAL1
+kArrisHdrMark LITERAL1
+kArrisHdrSpace LITERAL1
+kArrisOverhead LITERAL1
+kArrisReleaseBit LITERAL1
+kArrisReleaseToggle LITERAL1
+kArry4Str LITERAL1
kAuto LITERAL1
kAutoStr LITERAL1
kAutomaticStr LITERAL1
@@ -1558,6 +1634,7 @@ kCelsiusStr LITERAL1
kCentreStr LITERAL1
kChangeStr LITERAL1
kCirculateStr LITERAL1
+kCkpStr LITERAL1
kCleanStr LITERAL1
kClockStr LITERAL1
kCodeStr LITERAL1
@@ -1567,6 +1644,7 @@ kCommaSpaceStr LITERAL1
kCommandStr LITERAL1
kCool LITERAL1
kCoolStr LITERAL1
+kCoolingStr LITERAL1
kCoolixAuto LITERAL1
kCoolixBitMark LITERAL1
kCoolixBitMarkTicks LITERAL1
@@ -1866,10 +1944,12 @@ kDaikinSwingOn LITERAL1
kDaikinTolerance LITERAL1
kDaikinUnusedTime LITERAL1
kDaikinZeroSpace LITERAL1
+kDashStr LITERAL1
kDayStr LITERAL1
kDaysStr LITERAL1
kDefaultESP32Timer LITERAL1
kDefaultMessageGap LITERAL1
+kDehumidifyStr LITERAL1
kDelonghiAcAuto LITERAL1
kDelonghiAcBitMark LITERAL1
kDelonghiAcBits LITERAL1
@@ -1914,6 +1994,9 @@ kDenonOneSpaceTicks LITERAL1
kDenonTick LITERAL1
kDenonZeroSpace LITERAL1
kDenonZeroSpaceTicks LITERAL1
+kDg11j104Str LITERAL1
+kDg11j13aStr LITERAL1
+kDg11j191Str LITERAL1
kDishBitMark LITERAL1
kDishBitMarkTicks LITERAL1
kDishBits LITERAL1
@@ -1930,6 +2013,7 @@ kDishTick LITERAL1
kDishZeroSpace LITERAL1
kDishZeroSpaceTicks LITERAL1
kDisplayTempStr LITERAL1
+kDkeStr LITERAL1
kDoshishaBitMark LITERAL1
kDoshishaBits LITERAL1
kDoshishaHdrMark LITERAL1
@@ -1939,6 +2023,7 @@ kDoshishaZeroSpace LITERAL1
kDownStr LITERAL1
kDry LITERAL1
kDryStr LITERAL1
+kDryingStr LITERAL1
kDutyDefault LITERAL1
kDutyMax LITERAL1
kEcoclimAuto LITERAL1
@@ -1992,6 +2077,9 @@ kElectraAcMessageGap LITERAL1
kElectraAcMinRepeat LITERAL1
kElectraAcMinTemp LITERAL1
kElectraAcOneSpace LITERAL1
+kElectraAcSensorMaxTemp LITERAL1
+kElectraAcSensorMinTemp LITERAL1
+kElectraAcSensorTempDelta LITERAL1
kElectraAcStateLength LITERAL1
kElectraAcSwingOff LITERAL1
kElectraAcSwingOn LITERAL1
@@ -2008,8 +2096,11 @@ kEyeAutoStr LITERAL1
kEyeStr LITERAL1
kFalseStr LITERAL1
kFan LITERAL1
+kFanOnlyNoSpaceStr LITERAL1
kFanOnlyStr LITERAL1
+kFanOnlyWithSpaceStr LITERAL1
kFanStr LITERAL1
+kFan_OnlyStr LITERAL1
kFastStr LITERAL1
kFilterStr LITERAL1
kFixedStr LITERAL1
@@ -2064,6 +2155,7 @@ kFujitsuAcTempOffsetC LITERAL1
kFujitsuAcTempOffsetF LITERAL1
kFujitsuAcTimerMax LITERAL1
kFujitsuAcZeroSpace LITERAL1
+kGe6711ar2853mStr LITERAL1
kGicableBitMark LITERAL1
kGicableBits LITERAL1
kGicableHdrMark LITERAL1
@@ -2146,6 +2238,13 @@ kGreeStateLength LITERAL1
kGreeSwingAuto LITERAL1
kGreeSwingDown LITERAL1
kGreeSwingDownAuto LITERAL1
+kGreeSwingHAuto LITERAL1
+kGreeSwingHLeft LITERAL1
+kGreeSwingHMaxLeft LITERAL1
+kGreeSwingHMaxRight LITERAL1
+kGreeSwingHMiddle LITERAL1
+kGreeSwingHOff LITERAL1
+kGreeSwingHRight LITERAL1
kGreeSwingLastPos LITERAL1
kGreeSwingMiddle LITERAL1
kGreeSwingMiddleAuto LITERAL1
@@ -2155,6 +2254,7 @@ kGreeSwingUp LITERAL1
kGreeSwingUpAuto LITERAL1
kGreeTimerMax LITERAL1
kGreeZeroSpace LITERAL1
+kGz055be1Str LITERAL1
kHaierAC176Bits LITERAL1
kHaierAC176StateLength LITERAL1
kHaierACBits LITERAL1
@@ -2195,21 +2295,26 @@ kHaierAcMinTemp LITERAL1
kHaierAcOneSpace LITERAL1
kHaierAcPrefix LITERAL1
kHaierAcSleepBit LITERAL1
-kHaierAcSwingChg LITERAL1
-kHaierAcSwingDown LITERAL1
-kHaierAcSwingOff LITERAL1
-kHaierAcSwingUp LITERAL1
+kHaierAcSwingVChg LITERAL1
+kHaierAcSwingVDown LITERAL1
+kHaierAcSwingVOff LITERAL1
+kHaierAcSwingVUp LITERAL1
kHaierAcYrw02Auto LITERAL1
+kHaierAcYrw02ButtonCFAB LITERAL1
kHaierAcYrw02ButtonFan LITERAL1
kHaierAcYrw02ButtonHealth LITERAL1
+kHaierAcYrw02ButtonLock LITERAL1
kHaierAcYrw02ButtonMode LITERAL1
kHaierAcYrw02ButtonPower LITERAL1
kHaierAcYrw02ButtonSleep LITERAL1
-kHaierAcYrw02ButtonSwing LITERAL1
+kHaierAcYrw02ButtonSwingH LITERAL1
+kHaierAcYrw02ButtonSwingV LITERAL1
kHaierAcYrw02ButtonTempDown LITERAL1
kHaierAcYrw02ButtonTempUp LITERAL1
+kHaierAcYrw02ButtonTimer LITERAL1
kHaierAcYrw02ButtonTurbo LITERAL1
kHaierAcYrw02Cool LITERAL1
+kHaierAcYrw02DefTempC LITERAL1
kHaierAcYrw02DefaultRepeat LITERAL1
kHaierAcYrw02Dry LITERAL1
kHaierAcYrw02Fan LITERAL1
@@ -2218,26 +2323,35 @@ kHaierAcYrw02FanHigh LITERAL1
kHaierAcYrw02FanLow LITERAL1
kHaierAcYrw02FanMed LITERAL1
kHaierAcYrw02Heat LITERAL1
+kHaierAcYrw02MaxTempC LITERAL1
+kHaierAcYrw02MaxTempF LITERAL1
+kHaierAcYrw02MinTempC LITERAL1
+kHaierAcYrw02MinTempF LITERAL1
+kHaierAcYrw02ModelA LITERAL1
+kHaierAcYrw02ModelB LITERAL1
kHaierAcYrw02NoTimers LITERAL1
kHaierAcYrw02OffThenOnTimer LITERAL1
kHaierAcYrw02OffTimer LITERAL1
kHaierAcYrw02OnThenOffTimer LITERAL1
kHaierAcYrw02OnTimer LITERAL1
-kHaierAcYrw02Prefix LITERAL1
-kHaierAcYrw02SwingAuto LITERAL1
-kHaierAcYrw02SwingBottom LITERAL1
-kHaierAcYrw02SwingDown LITERAL1
-kHaierAcYrw02SwingMiddle LITERAL1
-kHaierAcYrw02SwingOff LITERAL1
-kHaierAcYrw02SwingTop LITERAL1
-kHaierAcYrw02TurboHigh LITERAL1
-kHaierAcYrw02TurboLow LITERAL1
-kHaierAcYrw02TurboOff LITERAL1
+kHaierAcYrw02SwingHAuto LITERAL1
+kHaierAcYrw02SwingHLeft LITERAL1
+kHaierAcYrw02SwingHLeftMax LITERAL1
+kHaierAcYrw02SwingHMiddle LITERAL1
+kHaierAcYrw02SwingHRight LITERAL1
+kHaierAcYrw02SwingHRightMax LITERAL1
+kHaierAcYrw02SwingVAuto LITERAL1
+kHaierAcYrw02SwingVBottom LITERAL1
+kHaierAcYrw02SwingVDown LITERAL1
+kHaierAcYrw02SwingVMiddle LITERAL1
+kHaierAcYrw02SwingVOff LITERAL1
+kHaierAcYrw02SwingVTop LITERAL1
kHaierAcZeroSpace LITERAL1
kHeader LITERAL1
kHealthStr LITERAL1
kHeat LITERAL1
kHeatStr LITERAL1
+kHeatingStr LITERAL1
kHiStr LITERAL1
kHigh LITERAL1
kHighNibble LITERAL1
@@ -2377,6 +2491,7 @@ kInaxTick LITERAL1
kInaxZeroSpace LITERAL1
kInsideStr LITERAL1
kIonStr LITERAL1
+kJkeStr LITERAL1
kJvcBitMark LITERAL1
kJvcBitMarkTicks LITERAL1
kJvcBits LITERAL1
@@ -2445,6 +2560,8 @@ kKelvinatorStateLength LITERAL1
kKelvinatorTick LITERAL1
kKelvinatorZeroSpace LITERAL1
kKelvinatorZeroSpaceTicks LITERAL1
+kKkg29ac1Str LITERAL1
+kKkg9ac1Str LITERAL1
kLasertagBits LITERAL1
kLasertagDelta LITERAL1
kLasertagExcess LITERAL1
@@ -2461,6 +2578,7 @@ kLastSwinghEnum LITERAL1
kLastSwingvEnum LITERAL1
kLeft LITERAL1
kLeftMax LITERAL1
+kLeftMaxNoSpaceStr LITERAL1
kLeftMaxStr LITERAL1
kLeftStr LITERAL1
kLegoPfBitMark LITERAL1
@@ -2544,7 +2662,9 @@ kLgRptSpace LITERAL1
kLgZeroSpace LITERAL1
kLightStr LITERAL1
kLightToggleStr LITERAL1
+kLkeStr LITERAL1
kLoStr LITERAL1
+kLockStr LITERAL1
kLoudStr LITERAL1
kLow LITERAL1
kLowNibble LITERAL1
@@ -2578,7 +2698,9 @@ kMarkExcess LITERAL1
kMarkState LITERAL1
kMax LITERAL1
kMaxAccurateUsecDelay LITERAL1
+kMaxLeftNoSpaceStr LITERAL1
kMaxLeftStr LITERAL1
+kMaxRightNoSpaceStr LITERAL1
kMaxRightStr LITERAL1
kMaxStr LITERAL1
kMaxTimeoutMs LITERAL1
@@ -2661,6 +2783,34 @@ kMinStr LITERAL1
kMinimumStr LITERAL1
kMinuteStr LITERAL1
kMinutesStr LITERAL1
+kMirageAcCool LITERAL1
+kMirageAcDry LITERAL1
+kMirageAcFan LITERAL1
+kMirageAcFanAuto LITERAL1
+kMirageAcFanHigh LITERAL1
+kMirageAcFanLow LITERAL1
+kMirageAcFanMed LITERAL1
+kMirageAcHeat LITERAL1
+kMirageAcKKG29AC1FanAuto LITERAL1
+kMirageAcKKG29AC1FanHigh LITERAL1
+kMirageAcKKG29AC1FanLow LITERAL1
+kMirageAcKKG29AC1FanMed LITERAL1
+kMirageAcKKG29AC1PowerOff LITERAL1
+kMirageAcKKG29AC1PowerOn LITERAL1
+kMirageAcMaxTemp LITERAL1
+kMirageAcMinTemp LITERAL1
+kMirageAcPowerOff LITERAL1
+kMirageAcRecycle LITERAL1
+kMirageAcSensorTempMax LITERAL1
+kMirageAcSensorTempOffset LITERAL1
+kMirageAcSwingVAuto LITERAL1
+kMirageAcSwingVHigh LITERAL1
+kMirageAcSwingVHighest LITERAL1
+kMirageAcSwingVLow LITERAL1
+kMirageAcSwingVLowest LITERAL1
+kMirageAcSwingVMiddle LITERAL1
+kMirageAcSwingVOff LITERAL1
+kMirageAcTempOffset LITERAL1
kMirageBitMark LITERAL1
kMirageBits LITERAL1
kMirageFreq LITERAL1
@@ -2954,6 +3104,7 @@ kNikaiOneSpaceTicks LITERAL1
kNikaiTick LITERAL1
kNikaiZeroSpace LITERAL1
kNikaiZeroSpaceTicks LITERAL1
+kNkeStr LITERAL1
kNoRepeat LITERAL1
kNoStr LITERAL1
kNowStr LITERAL1
@@ -3042,20 +3193,27 @@ kPanasonicAcTolerance LITERAL1
kPanasonicBitMark LITERAL1
kPanasonicBits LITERAL1
kPanasonicCkp LITERAL1
+kPanasonicCkpStr LITERAL1
kPanasonicDke LITERAL1
+kPanasonicDkeStr LITERAL1
kPanasonicEndGap LITERAL1
kPanasonicFreq LITERAL1
kPanasonicHdrMark LITERAL1
kPanasonicHdrSpace LITERAL1
kPanasonicJke LITERAL1
+kPanasonicJkeStr LITERAL1
kPanasonicKnownGoodState LITERAL1
kPanasonicLke LITERAL1
+kPanasonicLkeStr LITERAL1
kPanasonicManufacturer LITERAL1
kPanasonicMinCommandLength LITERAL1
kPanasonicMinGap LITERAL1
kPanasonicNke LITERAL1
+kPanasonicNkeStr LITERAL1
kPanasonicOneSpace LITERAL1
+kPanasonicPkrStr LITERAL1
kPanasonicRkr LITERAL1
+kPanasonicRkrStr LITERAL1
kPanasonicUnknown LITERAL1
kPanasonicZeroSpace LITERAL1
kPeriodOffset LITERAL1
@@ -3068,6 +3226,7 @@ kPioneerMinGap LITERAL1
kPioneerOneSpace LITERAL1
kPioneerTick LITERAL1
kPioneerZeroSpace LITERAL1
+kPkrStr LITERAL1
kPowerButtonStr LITERAL1
kPowerStr LITERAL1
kPowerToggleStr LITERAL1
@@ -3145,10 +3304,44 @@ kRcz01SignatureMask LITERAL1
kRecycleStr LITERAL1
kRepeat LITERAL1
kRepeatStr LITERAL1
+kRhossBitMark LITERAL1
+kRhossBits LITERAL1
+kRhossDefaultFan LITERAL1
+kRhossDefaultMode LITERAL1
+kRhossDefaultPower LITERAL1
+kRhossDefaultRepeat LITERAL1
+kRhossDefaultSwing LITERAL1
+kRhossDefaultTemp LITERAL1
+kRhossFanAuto LITERAL1
+kRhossFanMax LITERAL1
+kRhossFanMed LITERAL1
+kRhossFanMin LITERAL1
+kRhossFreq LITERAL1
+kRhossGap LITERAL1
+kRhossHdrMark LITERAL1
+kRhossHdrSpace LITERAL1
+kRhossModeAuto LITERAL1
+kRhossModeCool LITERAL1
+kRhossModeDry LITERAL1
+kRhossModeFan LITERAL1
+kRhossModeHeat LITERAL1
+kRhossOneSpace LITERAL1
+kRhossPowerOff LITERAL1
+kRhossPowerOn LITERAL1
+kRhossStateLength LITERAL1
+kRhossSwingOff LITERAL1
+kRhossSwingOn LITERAL1
+kRhossTempMax LITERAL1
+kRhossTempMin LITERAL1
+kRhossZeroSpace LITERAL1
kRight LITERAL1
kRightMax LITERAL1
+kRightMaxNoSpaceStr LITERAL1
kRightMaxStr LITERAL1
kRightStr LITERAL1
+kRkrStr LITERAL1
+kRlt0541htaaStr LITERAL1
+kRlt0541htabStr LITERAL1
kRoomStr LITERAL1
kSamsung36BitMark LITERAL1
kSamsung36Bits LITERAL1
@@ -3164,6 +3357,7 @@ kSamsungAcBreezeOn LITERAL1
kSamsungAcCool LITERAL1
kSamsungAcDefaultRepeat LITERAL1
kSamsungAcDry LITERAL1
+kSamsungAcEconoOn LITERAL1
kSamsungAcExtendedBits LITERAL1
kSamsungAcExtendedStateLength LITERAL1
kSamsungAcFan LITERAL1
@@ -3172,6 +3366,7 @@ kSamsungAcFanAuto2 LITERAL1
kSamsungAcFanHigh LITERAL1
kSamsungAcFanLow LITERAL1
kSamsungAcFanMed LITERAL1
+kSamsungAcFanSpecialOff LITERAL1
kSamsungAcFanTurbo LITERAL1
kSamsungAcHdrMark LITERAL1
kSamsungAcHdrSpace LITERAL1
@@ -3180,16 +3375,17 @@ kSamsungAcMaxTemp LITERAL1
kSamsungAcMinTemp LITERAL1
kSamsungAcOneSpace LITERAL1
kSamsungAcPowerSection LITERAL1
-kSamsungAcPowerful10On LITERAL1
-kSamsungAcPowerfulMask8 LITERAL1
+kSamsungAcPowerfulOn LITERAL1
kSamsungAcSectionGap LITERAL1
kSamsungAcSectionLength LITERAL1
kSamsungAcSectionMark LITERAL1
kSamsungAcSectionSpace LITERAL1
kSamsungAcSections LITERAL1
kSamsungAcStateLength LITERAL1
-kSamsungAcSwingMove LITERAL1
-kSamsungAcSwingStop LITERAL1
+kSamsungAcSwingBoth LITERAL1
+kSamsungAcSwingH LITERAL1
+kSamsungAcSwingOff LITERAL1
+kSamsungAcSwingV LITERAL1
kSamsungAcZeroSpace LITERAL1
kSamsungBitMark LITERAL1
kSamsungBitMarkTicks LITERAL1
@@ -3326,8 +3522,15 @@ kSharpAcSpecialTimer LITERAL1
kSharpAcSpecialTimerHalfHour LITERAL1
kSharpAcSpecialTurbo LITERAL1
kSharpAcStateLength LITERAL1
-kSharpAcSwingNoToggle LITERAL1
-kSharpAcSwingToggle LITERAL1
+kSharpAcSwingVCoanda LITERAL1
+kSharpAcSwingVHigh LITERAL1
+kSharpAcSwingVIgnore LITERAL1
+kSharpAcSwingVLast LITERAL1
+kSharpAcSwingVLow LITERAL1
+kSharpAcSwingVLowest LITERAL1
+kSharpAcSwingVMid LITERAL1
+kSharpAcSwingVOff LITERAL1
+kSharpAcSwingVToggle LITERAL1
kSharpAcTimerHoursMax LITERAL1
kSharpAcTimerHoursOff LITERAL1
kSharpAcTimerIncrement LITERAL1
@@ -3397,6 +3600,7 @@ kSymphonyOneMark LITERAL1
kSymphonyOneSpace LITERAL1
kSymphonyZeroMark LITERAL1
kSymphonyZeroSpace LITERAL1
+kTac09chsdStr LITERAL1
kTcl112AcAuto LITERAL1
kTcl112AcBitMark LITERAL1
kTcl112AcBits LITERAL1
@@ -3408,6 +3612,9 @@ kTcl112AcFanAuto LITERAL1
kTcl112AcFanHigh LITERAL1
kTcl112AcFanLow LITERAL1
kTcl112AcFanMed LITERAL1
+kTcl112AcFanMin LITERAL1
+kTcl112AcFanNight LITERAL1
+kTcl112AcFanQuiet LITERAL1
kTcl112AcGap LITERAL1
kTcl112AcHdrMark LITERAL1
kTcl112AcHdrMarkTolerance LITERAL1
@@ -3417,10 +3624,17 @@ kTcl112AcNormal LITERAL1
kTcl112AcOneSpace LITERAL1
kTcl112AcSpecial LITERAL1
kTcl112AcStateLength LITERAL1
+kTcl112AcSwingVHigh LITERAL1
+kTcl112AcSwingVHighest LITERAL1
+kTcl112AcSwingVLow LITERAL1
+kTcl112AcSwingVLowest LITERAL1
+kTcl112AcSwingVMiddle LITERAL1
kTcl112AcSwingVOff LITERAL1
kTcl112AcSwingVOn LITERAL1
kTcl112AcTempMax LITERAL1
kTcl112AcTempMin LITERAL1
+kTcl112AcTimerMax LITERAL1
+kTcl112AcTimerResolution LITERAL1
kTcl112AcTolerance LITERAL1
kTcl112AcZeroSpace LITERAL1
kTechnibelAcBitMark LITERAL1
@@ -3482,6 +3696,7 @@ kTempDownStr LITERAL1
kTempStr LITERAL1
kTempUpStr LITERAL1
kThreeLetterDayOfWeekStr LITERAL1
+kTimeSep LITERAL1
kTimeoutMs LITERAL1
kTimerModeStr LITERAL1
kTimerStr LITERAL1
@@ -3617,6 +3832,8 @@ kUnknownThreshold LITERAL1
kUpStr LITERAL1
kUpperStr LITERAL1
kUseDefTol LITERAL1
+kV9014557AStr LITERAL1
+kV9014557BStr LITERAL1
kVaneStr LITERAL1
kVestelAcAuto LITERAL1
kVestelAcBitMark LITERAL1
@@ -3737,6 +3954,8 @@ kXmpRepeatCodeAlt LITERAL1
kXmpSections LITERAL1
kXmpSpaceStep LITERAL1
kXmpWordSize LITERAL1
+kYaw1fStr LITERAL1
+kYbofbStr LITERAL1
kYesStr LITERAL1
kZepealBits LITERAL1
kZepealCommandOffOn LITERAL1
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json
index 5bce2238e..99160ec37 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.json
@@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
- "version": "2.7.20",
+ "version": "2.8.0",
"keywords": "infrared, ir, remote, esp8266, esp32",
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
"repository":
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties
index e4985e2a2..e7580dd2d 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/library.properties
@@ -1,5 +1,5 @@
name=IRremoteESP8266
-version=2.7.20
+version=2.8.0
author=David Conran, Sebastien Warin, Mark Szabo, Ken Shirriff
maintainer=David Conran, Mark Szabo, Sebastien Warin, Roi Dayan, Massimiliano Pinto, Christian Nilsson
sentence=Send and receive infrared signals with multiple protocols (ESP8266/ESP32)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp
index 9b4e10cbd..557e5593e 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.cpp
@@ -36,6 +36,7 @@
#include "ir_MitsubishiHeavy.h"
#include "ir_Neoclima.h"
#include "ir_Panasonic.h"
+#include "ir_Rhoss.h"
#include "ir_Samsung.h"
#include "ir_Sanyo.h"
#include "ir_Sharp.h"
@@ -50,6 +51,17 @@
#include "ir_Voltas.h"
#include "ir_Whirlpool.h"
+// On the ESP8266 platform we need to use a special version of string handling
+// functions to handle the strings stored in the flash address space.
+#ifndef STRCASECMP
+#if defined(ESP8266)
+#define STRCASECMP(LHS, RHS) \
+ strcasecmp_P(LHS, reinterpret_cast(RHS))
+#else // ESP8266
+#define STRCASECMP(LHS, RHS) strcasecmp(LHS, RHS)
+#endif // ESP8266
+#endif // STRCASECMP
+
/// Class constructor
/// @param[in] pin Gpio pin to use when transmitting IR messages.
/// @param[in] inverted true, gpio output defaults to high. false, to low.
@@ -233,7 +245,10 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#endif
#if SEND_MIDEA
case decode_type_t::MIDEA:
-#endif
+#endif // SEND_MIDEA
+#if SEND_MIRAGE
+ case decode_type_t::MIRAGE:
+#endif // SEND_MIRAGE
#if SEND_MITSUBISHI_AC
case decode_type_t::MITSUBISHI_AC:
#endif
@@ -256,6 +271,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_PANASONIC_AC32
case decode_type_t::PANASONIC_AC32:
#endif
+#if SEND_RHOSS
+ case decode_type_t::RHOSS:
+#endif
#if SEND_SAMSUNG_AC
case decode_type_t::SAMSUNG_AC:
#endif
@@ -277,6 +295,9 @@ bool IRac::isProtocolSupported(const decode_type_t protocol) {
#if SEND_TECO
case decode_type_t::TECO:
#endif
+#if SEND_TEKNOPOINT
+ case decode_type_t::TEKNOPOINT:
+#endif // SEND_TEKNOPOINT
#if SEND_TOSHIBA_AC
case decode_type_t::TOSHIBA_AC:
#endif
@@ -1018,15 +1039,18 @@ void IRac::goodweather(IRGoodweatherAc *ac,
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
+/// @param[in] swingh The horizontal swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
+/// @param[in] econo Toggle the device's economical mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo,
- const bool light, const bool clean, const int16_t sleep) {
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool turbo, const bool econo, const bool light,
+ const bool clean, const int16_t sleep) {
ac->begin();
ac->setModel(model);
ac->setPower(on);
@@ -1035,11 +1059,12 @@ void IRac::gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
ac->setFan(ac->convertFan(fan));
ac->setSwingVertical(swingv == stdAc::swingv_t::kAuto, // Set auto flag.
ac->convertSwingV(swingv));
+ ac->setSwingHorizontal(ac->convertSwingH(swingh));
ac->setLight(light);
ac->setTurbo(turbo);
+ ac->setEcono(econo);
ac->setXFan(clean);
ac->setSleep(sleep >= 0); // Sleep on this A/C is either on or off.
- // No Horizontal Swing setting available.
// No Econo setting available.
// No Filter setting available.
// No Beep setting available.
@@ -1068,7 +1093,7 @@ void IRac::haier(IRHaierAC *ac,
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
- ac->setSwing(ac->convertSwingV(swingv));
+ ac->setSwingV(ac->convertSwingV(swingv));
// No Horizontal Swing setting available.
// No Quiet setting available.
// No Turbo setting available.
@@ -1089,26 +1114,35 @@ void IRac::haier(IRHaierAC *ac,
#if SEND_HAIER_AC176
/// Send a Haier 176 bit A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRHaierAC176 object to use.
+/// @param[in] model The A/C model to use.
/// @param[in] on The power setting.
/// @param[in] mode The operation mode setting.
+/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit.
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
+/// @param[in] swingh The horizontal swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
+/// @param[in] quiet Run the device in quiet mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
-void IRac::haier176(IRHaierAC176 *ac,
+void IRac::haier176(IRHaierAC176 *ac, const haier_ac176_remote_model_t model,
const bool on, const stdAc::opmode_t mode,
- const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo,
- const bool filter, const int16_t sleep) {
+ const bool celsius, const float degrees,
+ const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv,
+ const stdAc::swingh_t swingh,
+ const bool turbo, const bool quiet, const bool filter,
+ const int16_t sleep) {
ac->begin();
+ ac->setModel(model);
ac->setMode(ac->convertMode(mode));
+ ac->setUseFahrenheit(!celsius);
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
- ac->setSwing(ac->convertSwingV(swingv));
- // No Horizontal Swing setting available.
- // No Quiet setting available.
+ ac->setSwingV(ac->convertSwingV(swingv));
+ ac->setSwingH(ac->convertSwingH(swingh));
+ ac->setQuiet(quiet);
ac->setTurbo(turbo);
// No Light setting available.
ac->setHealth(filter);
@@ -1125,24 +1159,31 @@ void IRac::haier176(IRHaierAC176 *ac,
/// @param[in, out] ac A Ptr to an IRHaierACYRW02 object to use.
/// @param[in] on The power setting.
/// @param[in] mode The operation mode setting.
+/// @param[in] celsius Temperature units. True is Celsius, False is Fahrenheit.
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
+/// @param[in] swingh The horizontal swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
+/// @param[in] quiet Run the device in quiet mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
/// @param[in] sleep Nr. of minutes for sleep mode. -1 is Off, >= 0 is on.
void IRac::haierYrwo2(IRHaierACYRW02 *ac,
const bool on, const stdAc::opmode_t mode,
- const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo,
- const bool filter, const int16_t sleep) {
+ const bool celsius, const float degrees,
+ const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv,
+ const stdAc::swingh_t swingh,
+ const bool turbo, const bool quiet, const bool filter,
+ const int16_t sleep) {
ac->begin();
ac->setMode(ac->convertMode(mode));
+ ac->setUseFahrenheit(!celsius);
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
- ac->setSwing(ac->convertSwingV(swingv));
- // No Horizontal Swing setting available.
- // No Quiet setting available.
+ ac->setSwingV(ac->convertSwingV(swingv));
+ ac->setSwingH(ac->convertSwingH(swingh));
+ ac->setQuiet(quiet);
ac->setTurbo(turbo);
// No Light setting available.
ac->setHealth(filter);
@@ -1450,6 +1491,17 @@ void IRac::midea(IRMideaAC *ac,
}
#endif // SEND_MIDEA
+#if SEND_MIRAGE
+/// Send a Mirage 120-bit A/C message with the supplied settings.
+/// @param[in, out] ac A Ptr to an IRMitsubishiAC object to use.
+/// @param[in] state The desired state to send.
+void IRac::mirage(IRMirageAc *ac, const stdAc::state_t state) {
+ ac->begin();
+ ac->fromCommon(state);
+ ac->send();
+}
+#endif // SEND_MIRAGE
+
#if SEND_MITSUBISHI_AC
/// Send a Mitsubishi A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRMitsubishiAC object to use.
@@ -1766,38 +1818,45 @@ void IRac::panasonic32(IRPanasonicAc32 *ac,
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
+/// @param[in] swingh The horizontal swing setting.
/// @param[in] quiet Run the device in quiet/silent mode.
/// @param[in] turbo Run the device in turbo/powerful mode.
+/// @param[in] econo Run the device in economical mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
-/// @param[in] clean Turn on the self-cleaning mode. e.g. Mould, dry filters etc
-/// @param[in] beep Enable/Disable beeps when receiving IR messages.
+/// @param[in] clean Toggle the self-cleaning mode. e.g. Mould, dry filters etc
+/// @param[in] beep Toggle beep setting for receiving IR messages.
+/// @param[in] sleep Nr. of minutes for sleep mode. <= 0 is Off, > 0 is on.
/// @param[in] prevpower The power setting from the previous A/C state.
-/// @param[in] forcepower Do we force send the special power message?
+/// @param[in] prevsleep Nr. of minutes for sleep from the previous A/C state.
+/// @param[in] forceextended Do we force sending the special extended message?
void IRac::samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode,
const float degrees,
- const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
- const bool quiet, const bool turbo, const bool light,
+ const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool quiet, const bool turbo, const bool econo,
+ const bool light,
const bool filter, const bool clean,
- const bool beep, const bool prevpower,
- const bool forcepower) {
+ const bool beep, const int16_t sleep,
+ const bool prevpower, const int16_t prevsleep,
+ const bool forceextended) {
ac->begin();
- ac->stateReset(forcepower, prevpower);
+ ac->stateReset(forceextended || (sleep != prevsleep), prevpower);
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
ac->setSwing(swingv != stdAc::swingv_t::kOff);
- // No Horizontal swing setting available.
+ ac->setSwingH(swingh != stdAc::swingh_t::kOff);
ac->setQuiet(quiet);
- ac->setPowerful(turbo);
+ ac->setPowerful(turbo); // FYI, `setEcono(true)` will override this.
ac->setDisplay(light);
- // No Econo setting available.
+ ac->setEcono(econo);
ac->setIon(filter);
- ac->setClean(clean);
- ac->setBeep(beep);
- // No Sleep setting available.
+ ac->setClean(clean); // Toggle
+ ac->setBeep(beep); // Toggle
+ ac->setSleepTimer((sleep <= 0) ? 0 : sleep);
// No Clock setting available.
// Do setMode() again as it can affect fan speed.
ac->setMode(ac->convertMode(mode));
@@ -1893,6 +1952,7 @@ void IRac::sanyo88(IRSanyoAc88 *ac,
/// @param[in] degrees The temperature setting in degrees.
/// @param[in] fan The speed setting for the fan.
/// @param[in] swingv The vertical swing setting.
+/// @param[in] swingv_prev The previous vertical swing setting.
/// @param[in] turbo Run the device in turbo/powerful mode.
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
@@ -1901,14 +1961,15 @@ void IRac::sharp(IRSharpAc *ac, const sharp_ac_remote_model_t model,
const bool on, const bool prev_power,
const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo,
+ const stdAc::swingv_t swingv,
+ const stdAc::swingv_t swingv_prev, const bool turbo,
const bool light, const bool filter, const bool clean) {
ac->begin();
ac->setModel(model);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan, model));
- ac->setSwingToggle(swingv != stdAc::swingv_t::kOff);
+ if (swingv != swingv_prev) ac->setSwingV(ac->convertSwingV(swingv));
// Econo deliberately not used as it cycles through 3 modes uncontrollably.
// ac->setEconoToggle(econo);
ac->setIon(filter);
@@ -1940,6 +2001,7 @@ void IRac::sharp(IRSharpAc *ac, const sharp_ac_remote_model_t model,
#if SEND_TCL112AC
/// Send a TCL 112-bit A/C message with the supplied settings.
/// @param[in, out] ac A Ptr to an IRTcl112Ac object to use.
+/// @param[in] model The A/C model to use.
/// @param[in] on The power setting.
/// @param[in] mode The operation mode setting.
/// @param[in] degrees The temperature setting in degrees.
@@ -1951,18 +2013,19 @@ void IRac::sharp(IRSharpAc *ac, const sharp_ac_remote_model_t model,
/// @param[in] light Turn on the LED/Display mode.
/// @param[in] econo Run the device in economical mode.
/// @param[in] filter Turn on the (ion/pollen/etc) filter mode.
-void IRac::tcl112(IRTcl112Ac *ac,
+void IRac::tcl112(IRTcl112Ac *ac, const tcl_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
const bool quiet, const bool turbo, const bool light,
const bool econo, const bool filter) {
ac->begin();
+ ac->setModel(model);
ac->setPower(on);
ac->setMode(ac->convertMode(mode));
ac->setTemp(degrees);
ac->setFan(ac->convertFan(fan));
- ac->setSwingVertical(swingv != stdAc::swingv_t::kOff);
+ ac->setSwingVertical(ac->convertSwingV(swingv));
ac->setSwingHorizontal(swingh != stdAc::swingh_t::kOff);
ac->setQuiet(quiet);
ac->setTurbo(turbo);
@@ -2341,6 +2404,35 @@ void IRac::transcold(IRTranscoldAc *ac,
}
#endif // SEND_TRANSCOLD
+#if SEND_RHOSS
+/// Send an Rhoss A/C message with the supplied settings.
+/// @param[in, out] ac A Ptr to an IRRhossAc object to use.
+/// @param[in] on The power setting.
+/// @param[in] mode The operation mode setting.
+/// @param[in] degrees The temperature setting in degrees.
+/// @param[in] fan The speed setting for the fan.
+/// @param[in] swing The swing setting.
+void IRac::rhoss(IRRhossAc *ac,
+ const bool on, const stdAc::opmode_t mode, const float degrees,
+ const stdAc::fanspeed_t fan, const stdAc::swingv_t swing) {
+ ac->begin();
+ ac->setPower(on);
+ ac->setMode(ac->convertMode(mode));
+ ac->setSwing(swing != stdAc::swingv_t::kOff);
+ ac->setTemp(degrees);
+ ac->setFan(ac->convertFan(fan));
+ // No Quiet setting available.
+ // No Light setting available.
+ // No Filter setting available.
+ // No Turbo setting available.
+ // No Economy setting available.
+ // No Clean setting available.
+ // No Beep setting available.
+ // No Sleep setting available.
+ ac->send();
+}
+#endif // SEND_RHOSS
+
/// Create a new state base on the provided state that has been suitably fixed.
/// @note This is for use with Home Assistant, which requires mode to be off if
/// the power is off.
@@ -2425,11 +2517,20 @@ stdAc::state_t IRac::handleToggles(const stdAc::state_t desired,
case decode_type_t::WHIRLPOOL_AC:
result.power = desired.power ^ prev->power;
break;
+ case decode_type_t::MIRAGE:
+ if (desired.model == mirage_ac_remote_model_t::KKG29AC1)
+ result.light = desired.light ^ prev->light;
+ result.clean = desired.clean ^ prev->clean;
+ break;
case decode_type_t::PANASONIC_AC:
// CKP models use a power mode toggle.
if (desired.model == panasonic_ac_remote_model_t::kPanasonicCkp)
result.power = desired.power ^ prev->power;
break;
+ case decode_type_t::SAMSUNG_AC:
+ result.beep = desired.beep ^ prev->beep;
+ result.clean = desired.clean ^ prev->clean;
+ break;
default:
{};
}
@@ -2494,11 +2595,12 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
// Construct a pointer-safe previous power state incase prev is NULL/NULLPTR.
#if (SEND_HITACHI_AC1 || SEND_SAMSUNG_AC || SEND_SHARP_AC)
const bool prev_power = (prev != NULL) ? prev->power : !send.power;
+ const int16_t prev_sleep = (prev != NULL) ? prev->sleep : -1;
#endif // (SEND_HITACHI_AC1 || SEND_SAMSUNG_AC || SEND_SHARP_AC)
-#if SEND_LG
+#if (SEND_LG || SEND_SHARP_AC)
const stdAc::swingv_t prev_swingv = (prev != NULL) ? prev->swingv
: stdAc::swingv_t::kOff;
-#endif // SEND_LG
+#endif // (SEND_LG || SEND_SHARP_AC)
// Per vendor settings & setup.
switch (send.protocol) {
#if SEND_AIRWELL
@@ -2678,8 +2780,8 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
IRGreeAC ac(_pin, (gree_ac_remote_model_t)send.model, _inverted,
_modulation);
gree(&ac, (gree_ac_remote_model_t)send.model, send.power, send.mode,
- send.celsius, send.degrees, send.fanspeed, send.swingv, send.turbo,
- send.light, send.clean, send.sleep);
+ send.celsius, send.degrees, send.fanspeed, send.swingv, send.swingh,
+ send.turbo, send.econo, send.light, send.clean, send.sleep);
break;
}
#endif // SEND_GREE
@@ -2696,8 +2798,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
case HAIER_AC176:
{
IRHaierAC176 ac(_pin, _inverted, _modulation);
- haier176(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
- send.turbo, send.filter, send.sleep);
+ haier176(&ac, (haier_ac176_remote_model_t)send.model, send.power,
+ send.mode, send.celsius, send.degrees, send.fanspeed,
+ send.swingv, send.swingh, send.turbo, send.filter, send.sleep);
break;
}
#endif // SEND_HAIER_AC176
@@ -2705,8 +2808,9 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
case HAIER_AC_YRW02:
{
IRHaierACYRW02 ac(_pin, _inverted, _modulation);
- haierYrwo2(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
- send.turbo, send.filter, send.sleep);
+ haierYrwo2(&ac, send.power, send.mode, send.celsius, send.degrees,
+ send.fanspeed, send.swingv, send.swingh, send.turbo,
+ send.filter, send.sleep);
break;
}
#endif // SEND_HAIER_AC_YRW02
@@ -2792,6 +2896,14 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_MIDEA
+#if SEND_MIRAGE
+ case MIRAGE:
+ {
+ IRMirageAc ac(_pin, _inverted, _modulation);
+ mirage(&ac, send);
+ break;
+ }
+#endif // SEND_MIRAGE
#if SEND_MITSUBISHI_AC
case MITSUBISHI_AC:
{
@@ -2866,13 +2978,22 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
break;
}
#endif // SEND_PANASONIC_AC32
+#if SEND_RHOSS
+ case RHOSS:
+ {
+ IRRhossAc ac(_pin, _inverted, _modulation);
+ rhoss(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv);
+ break;
+ }
+#endif // SEND_RHOSS
#if SEND_SAMSUNG_AC
case SAMSUNG_AC:
{
IRSamsungAc ac(_pin, _inverted, _modulation);
samsung(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
- send.quiet, send.turbo, send.light, send.filter, send.clean,
- send.beep, prev_power);
+ send.swingh, send.quiet, send.turbo, send.econo, send.light,
+ send.filter, send.clean, send.beep, send.sleep,
+ prev_power, prev_sleep);
break;
}
#endif // SEND_SAMSUNG_AC
@@ -2899,21 +3020,25 @@ bool IRac::sendAc(const stdAc::state_t desired, const stdAc::state_t *prev) {
{
IRSharpAc ac(_pin, _inverted, _modulation);
sharp(&ac, (sharp_ac_remote_model_t)send.model, send.power, prev_power,
- send.mode, degC, send.fanspeed, send.swingv, send.turbo, send.light,
- send.filter, send.clean);
+ send.mode, degC, send.fanspeed, send.swingv, prev_swingv,
+ send.turbo, send.light, send.filter, send.clean);
break;
}
#endif // SEND_SHARP_AC
-#if SEND_TCL112AC
+#if (SEND_TCL112AC || SEND_TEKNOPOINT)
case TCL112AC:
+ case TEKNOPOINT:
{
IRTcl112Ac ac(_pin, _inverted, _modulation);
- tcl112(&ac, send.power, send.mode, degC, send.fanspeed, send.swingv,
- send.swingh, send.quiet, send.turbo, send.light, send.econo,
- send.filter);
+ tcl_ac_remote_model_t model = (tcl_ac_remote_model_t)send.model;
+ if (send.protocol == decode_type_t::TEKNOPOINT)
+ model = tcl_ac_remote_model_t::GZ055BE1;
+ tcl112(&ac, model, send.power, send.mode,
+ degC, send.fanspeed, send.swingv, send.swingh, send.quiet,
+ send.turbo, send.light, send.econo, send.filter);
break;
}
-#endif // SEND_TCL112AC
+#endif // (SEND_TCL112AC || SEND_TEKNOPOINT)
#if SEND_TECHNIBEL_AC
case TECHNIBEL_AC:
{
@@ -3048,25 +3173,31 @@ bool IRac::hasStateChanged(void) { return cmpStates(next, _prev); }
/// @return The equivalent enum.
stdAc::opmode_t IRac::strToOpmode(const char *str,
const stdAc::opmode_t def) {
- if (!strcasecmp(str, kAutoStr) ||
- !strcasecmp(str, kAutomaticStr))
+ if (!STRCASECMP(str, kAutoStr) ||
+ !STRCASECMP(str, kAutomaticStr))
return stdAc::opmode_t::kAuto;
- else if (!strcasecmp(str, kOffStr) ||
- !strcasecmp(str, kStopStr))
+ else if (!STRCASECMP(str, kOffStr) ||
+ !STRCASECMP(str, kStopStr))
return stdAc::opmode_t::kOff;
- else if (!strcasecmp(str, kCoolStr) ||
- !strcasecmp(str, "COOLING"))
+ else if (!STRCASECMP(str, kCoolStr) ||
+ !STRCASECMP(str, kCoolingStr))
return stdAc::opmode_t::kCool;
- else if (!strcasecmp(str, kHeatStr) ||
- !strcasecmp(str, "HEATING"))
+ else if (!STRCASECMP(str, kHeatStr) ||
+ !STRCASECMP(str, kHeatingStr))
return stdAc::opmode_t::kHeat;
- else if (!strcasecmp(str, kDryStr) ||
- !strcasecmp(str, "DRYING") ||
- !strcasecmp(str, "DEHUMIDIFY"))
+ else if (!STRCASECMP(str, kDryStr) ||
+ !STRCASECMP(str, kDryingStr) ||
+ !STRCASECMP(str, kDehumidifyStr))
return stdAc::opmode_t::kDry;
- else if (!strcasecmp(str, kFanStr) ||
- !strcasecmp(str, "FANONLY") ||
- !strcasecmp(str, kFanOnlyStr))
+ else if (!STRCASECMP(str, kFanStr) ||
+ // The following Fans strings with "only" are required to help with
+ // HomeAssistant & Google Home Climate integration.
+ // For compatibility only.
+ // Ref: https://www.home-assistant.io/integrations/google_assistant/#climate-operation-modes
+ !STRCASECMP(str, kFanOnlyStr) ||
+ !STRCASECMP(str, kFan_OnlyStr) ||
+ !STRCASECMP(str, kFanOnlyWithSpaceStr) ||
+ !STRCASECMP(str, kFanOnlyNoSpaceStr))
return stdAc::opmode_t::kFan;
else
return def;
@@ -3078,26 +3209,26 @@ stdAc::opmode_t IRac::strToOpmode(const char *str,
/// @return The equivalent enum.
stdAc::fanspeed_t IRac::strToFanspeed(const char *str,
const stdAc::fanspeed_t def) {
- if (!strcasecmp(str, kAutoStr) ||
- !strcasecmp(str, kAutomaticStr))
+ if (!STRCASECMP(str, kAutoStr) ||
+ !STRCASECMP(str, kAutomaticStr))
return stdAc::fanspeed_t::kAuto;
- else if (!strcasecmp(str, kMinStr) ||
- !strcasecmp(str, kMinimumStr) ||
- !strcasecmp(str, kLowestStr))
+ else if (!STRCASECMP(str, kMinStr) ||
+ !STRCASECMP(str, kMinimumStr) ||
+ !STRCASECMP(str, kLowestStr))
return stdAc::fanspeed_t::kMin;
- else if (!strcasecmp(str, kLowStr) ||
- !strcasecmp(str, kLoStr))
+ else if (!STRCASECMP(str, kLowStr) ||
+ !STRCASECMP(str, kLoStr))
return stdAc::fanspeed_t::kLow;
- else if (!strcasecmp(str, kMedStr) ||
- !strcasecmp(str, kMediumStr) ||
- !strcasecmp(str, kMidStr))
+ else if (!STRCASECMP(str, kMedStr) ||
+ !STRCASECMP(str, kMediumStr) ||
+ !STRCASECMP(str, kMidStr))
return stdAc::fanspeed_t::kMedium;
- else if (!strcasecmp(str, kHighStr) ||
- !strcasecmp(str, kHiStr))
+ else if (!STRCASECMP(str, kHighStr) ||
+ !STRCASECMP(str, kHiStr))
return stdAc::fanspeed_t::kHigh;
- else if (!strcasecmp(str, kMaxStr) ||
- !strcasecmp(str, kMaximumStr) ||
- !strcasecmp(str, kHighestStr))
+ else if (!STRCASECMP(str, kMaxStr) ||
+ !STRCASECMP(str, kMaximumStr) ||
+ !STRCASECMP(str, kHighestStr))
return stdAc::fanspeed_t::kMax;
else
return def;
@@ -3109,36 +3240,36 @@ stdAc::fanspeed_t IRac::strToFanspeed(const char *str,
/// @return The equivalent enum.
stdAc::swingv_t IRac::strToSwingV(const char *str,
const stdAc::swingv_t def) {
- if (!strcasecmp(str, kAutoStr) ||
- !strcasecmp(str, kAutomaticStr) ||
- !strcasecmp(str, kOnStr) ||
- !strcasecmp(str, kSwingStr))
+ if (!STRCASECMP(str, kAutoStr) ||
+ !STRCASECMP(str, kAutomaticStr) ||
+ !STRCASECMP(str, kOnStr) ||
+ !STRCASECMP(str, kSwingStr))
return stdAc::swingv_t::kAuto;
- else if (!strcasecmp(str, kOffStr) ||
- !strcasecmp(str, kStopStr))
+ else if (!STRCASECMP(str, kOffStr) ||
+ !STRCASECMP(str, kStopStr))
return stdAc::swingv_t::kOff;
- else if (!strcasecmp(str, kMinStr) ||
- !strcasecmp(str, kMinimumStr) ||
- !strcasecmp(str, kLowestStr) ||
- !strcasecmp(str, kBottomStr) ||
- !strcasecmp(str, kDownStr))
+ else if (!STRCASECMP(str, kMinStr) ||
+ !STRCASECMP(str, kMinimumStr) ||
+ !STRCASECMP(str, kLowestStr) ||
+ !STRCASECMP(str, kBottomStr) ||
+ !STRCASECMP(str, kDownStr))
return stdAc::swingv_t::kLowest;
- else if (!strcasecmp(str, kLowStr))
+ else if (!STRCASECMP(str, kLowStr))
return stdAc::swingv_t::kLow;
- else if (!strcasecmp(str, kMidStr) ||
- !strcasecmp(str, kMiddleStr) ||
- !strcasecmp(str, kMedStr) ||
- !strcasecmp(str, kMediumStr) ||
- !strcasecmp(str, kCentreStr))
+ else if (!STRCASECMP(str, kMidStr) ||
+ !STRCASECMP(str, kMiddleStr) ||
+ !STRCASECMP(str, kMedStr) ||
+ !STRCASECMP(str, kMediumStr) ||
+ !STRCASECMP(str, kCentreStr))
return stdAc::swingv_t::kMiddle;
- else if (!strcasecmp(str, kHighStr) ||
- !strcasecmp(str, kHiStr))
+ else if (!STRCASECMP(str, kHighStr) ||
+ !STRCASECMP(str, kHiStr))
return stdAc::swingv_t::kHigh;
- else if (!strcasecmp(str, kHighestStr) ||
- !strcasecmp(str, kMaxStr) ||
- !strcasecmp(str, kMaximumStr) ||
- !strcasecmp(str, kTopStr) ||
- !strcasecmp(str, kUpStr))
+ else if (!STRCASECMP(str, kHighestStr) ||
+ !STRCASECMP(str, kMaxStr) ||
+ !STRCASECMP(str, kMaximumStr) ||
+ !STRCASECMP(str, kTopStr) ||
+ !STRCASECMP(str, kUpStr))
return stdAc::swingv_t::kHighest;
else
return def;
@@ -3150,34 +3281,34 @@ stdAc::swingv_t IRac::strToSwingV(const char *str,
/// @return The equivalent enum.
stdAc::swingh_t IRac::strToSwingH(const char *str,
const stdAc::swingh_t def) {
- if (!strcasecmp(str, kAutoStr) ||
- !strcasecmp(str, kAutomaticStr) ||
- !strcasecmp(str, kOnStr) || !strcasecmp(str, kSwingStr))
+ if (!STRCASECMP(str, kAutoStr) ||
+ !STRCASECMP(str, kAutomaticStr) ||
+ !STRCASECMP(str, kOnStr) || !STRCASECMP(str, kSwingStr))
return stdAc::swingh_t::kAuto;
- else if (!strcasecmp(str, kOffStr) ||
- !strcasecmp(str, kStopStr))
+ else if (!STRCASECMP(str, kOffStr) ||
+ !STRCASECMP(str, kStopStr))
return stdAc::swingh_t::kOff;
- else if (!strcasecmp(str, kLeftMaxStr) || // "LeftMax"
- !strcasecmp(str, D_STR_LEFT " " D_STR_MAX) || // "Left Max"
- !strcasecmp(str, D_STR_MAX D_STR_LEFT) || // "MaxLeft"
- !strcasecmp(str, kMaxLeftStr)) // "Max Left"
+ else if (!STRCASECMP(str, kLeftMaxNoSpaceStr) || // "LeftMax"
+ !STRCASECMP(str, kLeftMaxStr) || // "Left Max"
+ !STRCASECMP(str, kMaxLeftNoSpaceStr) || // "MaxLeft"
+ !STRCASECMP(str, kMaxLeftStr)) // "Max Left"
return stdAc::swingh_t::kLeftMax;
- else if (!strcasecmp(str, kLeftStr))
+ else if (!STRCASECMP(str, kLeftStr))
return stdAc::swingh_t::kLeft;
- else if (!strcasecmp(str, kMidStr) ||
- !strcasecmp(str, kMiddleStr) ||
- !strcasecmp(str, kMedStr) ||
- !strcasecmp(str, kMediumStr) ||
- !strcasecmp(str, kCentreStr))
+ else if (!STRCASECMP(str, kMidStr) ||
+ !STRCASECMP(str, kMiddleStr) ||
+ !STRCASECMP(str, kMedStr) ||
+ !STRCASECMP(str, kMediumStr) ||
+ !STRCASECMP(str, kCentreStr))
return stdAc::swingh_t::kMiddle;
- else if (!strcasecmp(str, kRightStr))
+ else if (!STRCASECMP(str, kRightStr))
return stdAc::swingh_t::kRight;
- else if (!strcasecmp(str, kRightMaxStr) || // "RightMax"
- !strcasecmp(str, D_STR_RIGHT " " D_STR_MAX) || // "Right Max"
- !strcasecmp(str, D_STR_MAX D_STR_RIGHT) || // "MaxRight"
- !strcasecmp(str, kMaxRightStr)) // "Max Right"
+ else if (!STRCASECMP(str, kRightMaxNoSpaceStr) || // "RightMax"
+ !STRCASECMP(str, kRightMaxStr) || // "Right Max"
+ !STRCASECMP(str, kMaxRightNoSpaceStr) || // "MaxRight"
+ !STRCASECMP(str, kMaxRightStr)) // "Max Right"
return stdAc::swingh_t::kRightMax;
- else if (!strcasecmp(str, kWideStr))
+ else if (!STRCASECMP(str, kWideStr))
return stdAc::swingh_t::kWide;
else
return def;
@@ -3188,59 +3319,86 @@ stdAc::swingh_t IRac::strToSwingH(const char *str,
/// @param[in] str A Ptr to a C-style string to be converted.
/// @param[in] def The enum to return if no conversion was possible.
/// @return The equivalent enum.
+/// @note After adding a new model you should update modelToStr() too.
int16_t IRac::strToModel(const char *str, const int16_t def) {
// Gree
- if (!strcasecmp(str, "YAW1F")) {
+ if (!STRCASECMP(str, kYaw1fStr)) {
return gree_ac_remote_model_t::YAW1F;
- } else if (!strcasecmp(str, "YBOFB")) {
+ } else if (!STRCASECMP(str, kYbofbStr)) {
return gree_ac_remote_model_t::YBOFB;
+ // Haier models
+ } else if (!STRCASECMP(str, kV9014557AStr)) {
+ return haier_ac176_remote_model_t::V9014557_A;
+ } else if (!STRCASECMP(str, kV9014557BStr)) {
+ return haier_ac176_remote_model_t::V9014557_B;
// HitachiAc1 models
- } else if (!strcasecmp(str, "R-LT0541-HTA-A")) {
+ } else if (!STRCASECMP(str, kRlt0541htaaStr)) {
return hitachi_ac1_remote_model_t::R_LT0541_HTA_A;
- } else if (!strcasecmp(str, "R-LT0541-HTA-B")) {
+ } else if (!STRCASECMP(str, kRlt0541htabStr)) {
return hitachi_ac1_remote_model_t::R_LT0541_HTA_B;
// Fujitsu A/C models
- } else if (!strcasecmp(str, "ARRAH2E")) {
+ } else if (!STRCASECMP(str, kArrah2eStr)) {
return fujitsu_ac_remote_model_t::ARRAH2E;
- } else if (!strcasecmp(str, "ARDB1")) {
+ } else if (!STRCASECMP(str, kArdb1Str)) {
return fujitsu_ac_remote_model_t::ARDB1;
- } else if (!strcasecmp(str, "ARREB1E")) {
+ } else if (!STRCASECMP(str, kArreb1eStr)) {
return fujitsu_ac_remote_model_t::ARREB1E;
- } else if (!strcasecmp(str, "ARJW2")) {
+ } else if (!STRCASECMP(str, kArjw2Str)) {
return fujitsu_ac_remote_model_t::ARJW2;
- } else if (!strcasecmp(str, "ARRY4")) {
+ } else if (!STRCASECMP(str, kArry4Str)) {
return fujitsu_ac_remote_model_t::ARRY4;
+ } else if (!STRCASECMP(str, kArrew4eStr)) {
+ return fujitsu_ac_remote_model_t::ARREW4E;
// LG A/C models
- } else if (!strcasecmp(str, "GE6711AR2853M")) {
+ } else if (!STRCASECMP(str, kGe6711ar2853mStr)) {
return lg_ac_remote_model_t::GE6711AR2853M;
- } else if (!strcasecmp(str, "AKB75215403")) {
+ } else if (!STRCASECMP(str, kAkb75215403Str)) {
return lg_ac_remote_model_t::AKB75215403;
- } else if (!strcasecmp(str, "AKB74955603")) {
+ } else if (!STRCASECMP(str, kAkb74955603Str)) {
return lg_ac_remote_model_t::AKB74955603;
- } else if (!strcasecmp(str, "AKB73757604")) {
+ } else if (!STRCASECMP(str, kAkb73757604Str)) {
return lg_ac_remote_model_t::AKB73757604;
// Panasonic A/C families
- } else if (!strcasecmp(str, "LKE") || !strcasecmp(str, "PANASONICLKE")) {
+ } else if (!STRCASECMP(str, kLkeStr) ||
+ !STRCASECMP(str, kPanasonicLkeStr)) {
return panasonic_ac_remote_model_t::kPanasonicLke;
- } else if (!strcasecmp(str, "NKE") || !strcasecmp(str, "PANASONICNKE")) {
+ } else if (!STRCASECMP(str, kNkeStr) ||
+ !STRCASECMP(str, kPanasonicNkeStr)) {
return panasonic_ac_remote_model_t::kPanasonicNke;
- } else if (!strcasecmp(str, "DKE") || !strcasecmp(str, "PANASONICDKE") ||
- !strcasecmp(str, "PKR") || !strcasecmp(str, "PANASONICPKR")) {
+ } else if (!STRCASECMP(str, kDkeStr) ||
+ !STRCASECMP(str, kPanasonicDkeStr) ||
+ !STRCASECMP(str, kPkrStr) ||
+ !STRCASECMP(str, kPanasonicPkrStr)) {
return panasonic_ac_remote_model_t::kPanasonicDke;
- } else if (!strcasecmp(str, "JKE") || !strcasecmp(str, "PANASONICJKE")) {
+ } else if (!STRCASECMP(str, kJkeStr) ||
+ !STRCASECMP(str, kPanasonicJkeStr)) {
return panasonic_ac_remote_model_t::kPanasonicJke;
- } else if (!strcasecmp(str, "CKP") || !strcasecmp(str, "PANASONICCKP")) {
+ } else if (!STRCASECMP(str, kCkpStr) ||
+ !STRCASECMP(str, kPanasonicCkpStr)) {
return panasonic_ac_remote_model_t::kPanasonicCkp;
- } else if (!strcasecmp(str, "RKR") || !strcasecmp(str, "PANASONICRKR")) {
+ } else if (!STRCASECMP(str, kRkrStr) ||
+ !STRCASECMP(str, kPanasonicRkrStr)) {
return panasonic_ac_remote_model_t::kPanasonicRkr;
+ // Sharp A/C Models
+ } else if (!STRCASECMP(str, kA907Str)) {
+ return sharp_ac_remote_model_t::A907;
+ } else if (!STRCASECMP(str, kA705Str)) {
+ return sharp_ac_remote_model_t::A705;
+ } else if (!STRCASECMP(str, kA903Str)) {
+ return sharp_ac_remote_model_t::A903;
+ // TCL A/C Models
+ } else if (!STRCASECMP(str, kTac09chsdStr)) {
+ return tcl_ac_remote_model_t::TAC09CHSD;
+ } else if (!STRCASECMP(str, kGz055be1Str)) {
+ return tcl_ac_remote_model_t::GZ055BE1;
// Voltas A/C models
- } else if (!strcasecmp(str, "122LZF")) {
+ } else if (!STRCASECMP(str, k122lzfStr)) {
return voltas_ac_remote_model_t::kVoltas122LZF;
// Whirlpool A/C models
- } else if (!strcasecmp(str, "DG11J13A") || !strcasecmp(str, "DG11J104") ||
- !strcasecmp(str, "DG11J1-04")) {
+ } else if (!STRCASECMP(str, kDg11j13aStr) ||
+ !STRCASECMP(str, kDg11j104Str)) {
return whirlpool_ac_remote_model_t::DG11J13A;
- } else if (!strcasecmp(str, "DG11J191")) {
+ } else if (!STRCASECMP(str, kDg11j191Str)) {
return whirlpool_ac_remote_model_t::DG11J191;
} else {
int16_t number = atoi(str);
@@ -3256,15 +3414,15 @@ int16_t IRac::strToModel(const char *str, const int16_t def) {
/// @param[in] def The boolean value to return if no conversion was possible.
/// @return The equivalent boolean value.
bool IRac::strToBool(const char *str, const bool def) {
- if (!strcasecmp(str, kOnStr) ||
- !strcasecmp(str, "1") ||
- !strcasecmp(str, kYesStr) ||
- !strcasecmp(str, kTrueStr))
+ if (!STRCASECMP(str, kOnStr) ||
+ !STRCASECMP(str, k1Str) ||
+ !STRCASECMP(str, kYesStr) ||
+ !STRCASECMP(str, kTrueStr))
return true;
- else if (!strcasecmp(str, kOffStr) ||
- !strcasecmp(str, "0") ||
- !strcasecmp(str, kNoStr) ||
- !strcasecmp(str, kFalseStr))
+ else if (!STRCASECMP(str, kOffStr) ||
+ !STRCASECMP(str, k0Str) ||
+ !STRCASECMP(str, kNoStr) ||
+ !STRCASECMP(str, kFalseStr))
return false;
else
return def;
@@ -3279,23 +3437,17 @@ String IRac::boolToString(const bool value) {
/// Convert the supplied operation mode into the appropriate String.
/// @param[in] mode The enum to be converted.
+/// @param[in] ha A flag to indicate we want GoogleHome/HomeAssistant output.
/// @return The equivalent String for the locale.
-String IRac::opmodeToString(const stdAc::opmode_t mode) {
+String IRac::opmodeToString(const stdAc::opmode_t mode, const bool ha) {
switch (mode) {
- case stdAc::opmode_t::kOff:
- return kOffStr;
- case stdAc::opmode_t::kAuto:
- return kAutoStr;
- case stdAc::opmode_t::kCool:
- return kCoolStr;
- case stdAc::opmode_t::kHeat:
- return kHeatStr;
- case stdAc::opmode_t::kDry:
- return kDryStr;
- case stdAc::opmode_t::kFan:
- return kFanOnlyStr;
- default:
- return kUnknownStr;
+ case stdAc::opmode_t::kOff: return kOffStr;
+ case stdAc::opmode_t::kAuto: return kAutoStr;
+ case stdAc::opmode_t::kCool: return kCoolStr;
+ case stdAc::opmode_t::kHeat: return kHeatStr;
+ case stdAc::opmode_t::kDry: return kDryStr;
+ case stdAc::opmode_t::kFan: return ha ? kFan_OnlyStr : kFanStr;
+ default: return kUnknownStr;
}
}
@@ -3304,20 +3456,13 @@ String IRac::opmodeToString(const stdAc::opmode_t mode) {
/// @return The equivalent String for the locale.
String IRac::fanspeedToString(const stdAc::fanspeed_t speed) {
switch (speed) {
- case stdAc::fanspeed_t::kAuto:
- return kAutoStr;
- case stdAc::fanspeed_t::kMax:
- return kMaxStr;
- case stdAc::fanspeed_t::kHigh:
- return kHighStr;
- case stdAc::fanspeed_t::kMedium:
- return kMediumStr;
- case stdAc::fanspeed_t::kLow:
- return kLowStr;
- case stdAc::fanspeed_t::kMin:
- return kMinStr;
- default:
- return kUnknownStr;
+ case stdAc::fanspeed_t::kAuto: return kAutoStr;
+ case stdAc::fanspeed_t::kMax: return kMaxStr;
+ case stdAc::fanspeed_t::kHigh: return kHighStr;
+ case stdAc::fanspeed_t::kMedium: return kMediumStr;
+ case stdAc::fanspeed_t::kLow: return kLowStr;
+ case stdAc::fanspeed_t::kMin: return kMinStr;
+ default: return kUnknownStr;
}
}
@@ -3326,22 +3471,14 @@ String IRac::fanspeedToString(const stdAc::fanspeed_t speed) {
/// @return The equivalent String for the locale.
String IRac::swingvToString(const stdAc::swingv_t swingv) {
switch (swingv) {
- case stdAc::swingv_t::kOff:
- return kOffStr;
- case stdAc::swingv_t::kAuto:
- return kAutoStr;
- case stdAc::swingv_t::kHighest:
- return kHighestStr;
- case stdAc::swingv_t::kHigh:
- return kHighStr;
- case stdAc::swingv_t::kMiddle:
- return kMiddleStr;
- case stdAc::swingv_t::kLow:
- return kLowStr;
- case stdAc::swingv_t::kLowest:
- return kLowestStr;
- default:
- return kUnknownStr;
+ case stdAc::swingv_t::kOff: return kOffStr;
+ case stdAc::swingv_t::kAuto: return kAutoStr;
+ case stdAc::swingv_t::kHighest: return kHighestStr;
+ case stdAc::swingv_t::kHigh: return kHighStr;
+ case stdAc::swingv_t::kMiddle: return kMiddleStr;
+ case stdAc::swingv_t::kLow: return kLowStr;
+ case stdAc::swingv_t::kLowest: return kLowestStr;
+ default: return kUnknownStr;
}
}
@@ -3350,24 +3487,15 @@ String IRac::swingvToString(const stdAc::swingv_t swingv) {
/// @return The equivalent String for the locale.
String IRac::swinghToString(const stdAc::swingh_t swingh) {
switch (swingh) {
- case stdAc::swingh_t::kOff:
- return kOffStr;
- case stdAc::swingh_t::kAuto:
- return kAutoStr;
- case stdAc::swingh_t::kLeftMax:
- return kLeftMaxStr;
- case stdAc::swingh_t::kLeft:
- return kLeftStr;
- case stdAc::swingh_t::kMiddle:
- return kMiddleStr;
- case stdAc::swingh_t::kRight:
- return kRightStr;
- case stdAc::swingh_t::kRightMax:
- return kRightMaxStr;
- case stdAc::swingh_t::kWide:
- return kWideStr;
- default:
- return kUnknownStr;
+ case stdAc::swingh_t::kOff: return kOffStr;
+ case stdAc::swingh_t::kAuto: return kAutoStr;
+ case stdAc::swingh_t::kLeftMax: return kLeftMaxStr;
+ case stdAc::swingh_t::kLeft: return kLeftStr;
+ case stdAc::swingh_t::kMiddle: return kMiddleStr;
+ case stdAc::swingh_t::kRight: return kRightStr;
+ case stdAc::swingh_t::kRightMax: return kRightMaxStr;
+ case stdAc::swingh_t::kWide: return kWideStr;
+ default: return kUnknownStr;
}
}
@@ -3407,6 +3535,21 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_CARRIER_AC64
+#if DECODE_COOLIX
+ case decode_type_t::COOLIX: {
+ IRCoolixAC ac(kGpioUnused);
+ ac.on();
+ ac.setRaw(result->value); // Coolix uses value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_COOLIX
+#if DECODE_CORONA_AC
+ case decode_type_t::CORONA_AC: {
+ IRCoronaAc ac(kGpioUnused);
+ ac.setRaw(result->state, result->bits / 8);
+ return ac.toString();
+ }
+#endif // DECODE_CORONA_AC
#if DECODE_DAIKIN
case decode_type_t::DAIKIN: {
IRDaikinESP ac(kGpioUnused);
@@ -3494,6 +3637,69 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_FUJITSU_AC
+#if DECODE_GOODWEATHER
+ case decode_type_t::GOODWEATHER: {
+ IRGoodweatherAc ac(kGpioUnused);
+ ac.setRaw(result->value); // Goodweather uses value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_GOODWEATHER
+#if DECODE_GREE
+ case decode_type_t::GREE: {
+ IRGreeAC ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_GREE
+#if DECODE_HAIER_AC
+ case decode_type_t::HAIER_AC: {
+ IRHaierAC ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HAIER_AC
+#if DECODE_HAIER_AC176
+ case decode_type_t::HAIER_AC176: {
+ IRHaierAC176 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HAIER_AC176
+#if DECODE_HAIER_AC_YRW02
+ case decode_type_t::HAIER_AC_YRW02: {
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HAIER_AC_YRW02
+#if DECODE_HITACHI_AC
+ case decode_type_t::HITACHI_AC: {
+ IRHitachiAc ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HITACHI_AC
+#if DECODE_HITACHI_AC1
+ case decode_type_t::HITACHI_AC1: {
+ IRHitachiAc1 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HITACHI_AC1
+#if DECODE_HITACHI_AC344
+ case decode_type_t::HITACHI_AC344: {
+ IRHitachiAc344 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HITACHI_AC344
+#if DECODE_HITACHI_AC424
+ case decode_type_t::HITACHI_AC424: {
+ IRHitachiAc424 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_HITACHI_AC424
#if DECODE_KELON
case decode_type_t::KELON: {
IRKelonAc ac(kGpioUnused);
@@ -3508,6 +3714,28 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_KELVINATOR
+#if DECODE_LG
+ case decode_type_t::LG:
+ case decode_type_t::LG2: {
+ IRLgAc ac(kGpioUnused);
+ ac.setRaw(result->value, result->decode_type); // Use value, not state.
+ return ac.isValidLgAc() ? ac.toString() : "";
+ }
+#endif // DECODE_LG
+#if DECODE_MIDEA
+ case decode_type_t::MIDEA: {
+ IRMideaAC ac(kGpioUnused);
+ ac.setRaw(result->value); // Midea uses value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_MIDEA
+#if DECODE_MIRAGE
+ case decode_type_t::MIRAGE: {
+ IRMirageAc ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_MIRAGE
#if DECODE_MITSUBISHI_AC
case decode_type_t::MITSUBISHI_AC: {
IRMitsubishiAC ac(kGpioUnused);
@@ -3548,76 +3776,33 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_NEOCLIMA
-#if DECODE_TOSHIBA_AC
- case decode_type_t::TOSHIBA_AC: {
- IRToshibaAC ac(kGpioUnused);
- ac.setRaw(result->state, result->bits / 8);
- return ac.toString();
+#if DECODE_PANASONIC_AC
+ case decode_type_t::PANASONIC_AC: {
+ if (result->bits > kPanasonicAcShortBits) {
+ IRPanasonicAc ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+ return "";
}
-#endif // DECODE_TOSHIBA_AC
-#if DECODE_TROTEC
- case decode_type_t::TROTEC: {
- IRTrotecESP ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
+#endif // DECODE_PANASONIC_AC
+#if DECODE_PANASONIC_AC32
+ case decode_type_t::PANASONIC_AC32: {
+ if (result->bits >= kPanasonicAc32Bits) {
+ IRPanasonicAc32 ac(kGpioUnused);
+ ac.setRaw(result->value); // Uses value instead of state.
+ return ac.toString();
+ }
+ return "";
}
-#endif // DECODE_TROTEC
-#if DECODE_TROTEC_3550
- case decode_type_t::TROTEC_3550: {
- IRTrotec3550 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_TROTEC_3550
-#if DECODE_TRUMA
- case decode_type_t::TRUMA: {
- IRTrumaAc ac(kGpioUnused);
- ac.setRaw(result->value); // Truma uses value instead of state.
- return ac.toString();
- }
-#endif // DECODE_TRUMA
-#if DECODE_GOODWEATHER
- case decode_type_t::GOODWEATHER: {
- IRGoodweatherAc ac(kGpioUnused);
- ac.setRaw(result->value); // Goodweather uses value instead of state.
- return ac.toString();
- }
-#endif // DECODE_GOODWEATHER
-#if DECODE_GREE
- case decode_type_t::GREE: {
- IRGreeAC ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_GREE
-#if DECODE_MIDEA
- case decode_type_t::MIDEA: {
- IRMideaAC ac(kGpioUnused);
- ac.setRaw(result->value); // Midea uses value instead of state.
- return ac.toString();
- }
-#endif // DECODE_MIDEA
-#if DECODE_HAIER_AC
- case decode_type_t::HAIER_AC: {
- IRHaierAC ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HAIER_AC
-#if DECODE_HAIER_AC176
- case decode_type_t::HAIER_AC176: {
- IRHaierAC176 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HAIER_AC176
-#if DECODE_HAIER_AC_YRW02
- case decode_type_t::HAIER_AC_YRW02: {
- IRHaierACYRW02 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HAIER_AC_YRW02
+#endif // DECODE_PANASONIC_AC
+#if DECODE_RHOSS
+ case decode_type_t::RHOSS: {
+ IRRhossAc ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_RHOSS
#if DECODE_SAMSUNG_AC
case decode_type_t::SAMSUNG_AC: {
IRSamsungAc ac(kGpioUnused);
@@ -3646,83 +3831,14 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_SHARP_AC
-#if DECODE_COOLIX
- case decode_type_t::COOLIX: {
- IRCoolixAC ac(kGpioUnused);
- ac.on();
- ac.setRaw(result->value); // Coolix uses value instead of state.
- return ac.toString();
- }
-#endif // DECODE_COOLIX
-#if DECODE_CORONA_AC
- case decode_type_t::CORONA_AC: {
- IRCoronaAc ac(kGpioUnused);
- ac.setRaw(result->state, result->bits / 8);
- return ac.toString();
- }
-#endif // DECODE_CORONA_AC
-#if DECODE_PANASONIC_AC
- case decode_type_t::PANASONIC_AC: {
- if (result->bits > kPanasonicAcShortBits) {
- IRPanasonicAc ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
- return "";
- }
-#endif // DECODE_PANASONIC_AC
-#if DECODE_PANASONIC_AC32
- case decode_type_t::PANASONIC_AC32: {
- if (result->bits >= kPanasonicAc32Bits) {
- IRPanasonicAc32 ac(kGpioUnused);
- ac.setRaw(result->value); // Uses value instead of state.
- return ac.toString();
- }
- return "";
- }
-#endif // DECODE_PANASONIC_AC
-#if DECODE_HITACHI_AC
- case decode_type_t::HITACHI_AC: {
- IRHitachiAc ac(kGpioUnused);
+#if (DECODE_TCL112AC || DECODE_TEKNOPOINT)
+ case decode_type_t::TCL112AC:
+ case decode_type_t::TEKNOPOINT: {
+ IRTcl112Ac ac(kGpioUnused);
ac.setRaw(result->state);
return ac.toString();
}
-#endif // DECODE_HITACHI_AC
-#if DECODE_HITACHI_AC1
- case decode_type_t::HITACHI_AC1: {
- IRHitachiAc1 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HITACHI_AC1
-#if DECODE_HITACHI_AC344
- case decode_type_t::HITACHI_AC344: {
- IRHitachiAc344 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HITACHI_AC344
-#if DECODE_HITACHI_AC424
- case decode_type_t::HITACHI_AC424: {
- IRHitachiAc424 ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_HITACHI_AC424
-#if DECODE_WHIRLPOOL_AC
- case decode_type_t::WHIRLPOOL_AC: {
- IRWhirlpoolAc ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_WHIRLPOOL_AC
-#if DECODE_VESTEL_AC
- case decode_type_t::VESTEL_AC: {
- IRVestelAc ac(kGpioUnused);
- ac.setRaw(result->value); // Like Coolix, use value instead of state.
- return ac.toString();
- }
-#endif // DECODE_VESTEL_AC
+#endif // (DECODE_TCL112AC || DECODE_TEKNOPOINT)
#if DECODE_TECHNIBEL_AC
case decode_type_t::TECHNIBEL_AC: {
IRTechnibelAc ac(kGpioUnused);
@@ -3730,13 +3846,6 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_TECHNIBEL_AC
-#if DECODE_VOLTAS
- case decode_type_t::VOLTAS: {
- IRVoltas ac(kGpioUnused);
- ac.setRaw(result->state);
- return ac.toString();
- }
-#endif // DECODE_VOLTAS
#if DECODE_TECO
case decode_type_t::TECO: {
IRTecoAc ac(kGpioUnused);
@@ -3744,21 +3853,13 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_TECO
-#if DECODE_TCL112AC
- case decode_type_t::TCL112AC: {
- IRTcl112Ac ac(kGpioUnused);
- ac.setRaw(result->state);
+#if DECODE_TOSHIBA_AC
+ case decode_type_t::TOSHIBA_AC: {
+ IRToshibaAC ac(kGpioUnused);
+ ac.setRaw(result->state, result->bits / 8);
return ac.toString();
}
-#endif // DECODE_TCL112AC
-#if DECODE_LG
- case decode_type_t::LG:
- case decode_type_t::LG2: {
- IRLgAc ac(kGpioUnused);
- ac.setRaw(result->value, result->decode_type); // Use value, not state.
- return ac.isValidLgAc() ? ac.toString() : "";
- }
-#endif // DECODE_LG
+#endif // DECODE_TOSHIBA_AC
#if DECODE_TRANSCOLD
case decode_type_t::TRANSCOLD: {
IRTranscoldAc ac(kGpioUnused);
@@ -3767,6 +3868,48 @@ namespace IRAcUtils {
return ac.toString();
}
#endif // DECODE_TRANSCOLD
+#if DECODE_TROTEC
+ case decode_type_t::TROTEC: {
+ IRTrotecESP ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_TROTEC
+#if DECODE_TROTEC_3550
+ case decode_type_t::TROTEC_3550: {
+ IRTrotec3550 ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_TROTEC_3550
+#if DECODE_TRUMA
+ case decode_type_t::TRUMA: {
+ IRTrumaAc ac(kGpioUnused);
+ ac.setRaw(result->value); // Truma uses value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_TRUMA
+#if DECODE_VESTEL_AC
+ case decode_type_t::VESTEL_AC: {
+ IRVestelAc ac(kGpioUnused);
+ ac.setRaw(result->value); // Like Coolix, use value instead of state.
+ return ac.toString();
+ }
+#endif // DECODE_VESTEL_AC
+#if DECODE_VOLTAS
+ case decode_type_t::VOLTAS: {
+ IRVoltas ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_VOLTAS
+#if DECODE_WHIRLPOOL_AC
+ case decode_type_t::WHIRLPOOL_AC: {
+ IRWhirlpoolAc ac(kGpioUnused);
+ ac.setRaw(result->state);
+ return ac.toString();
+ }
+#endif // DECODE_WHIRLPOOL_AC
default:
return "";
}
@@ -3812,6 +3955,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_ARGO
+#if DECODE_CARRIER_AC64
+ case decode_type_t::CARRIER_AC64: {
+ IRCarrierAc64 ac(kGpioUnused);
+ ac.setRaw(decode->value); // Uses value instead of state.
+ *result = ac.toCommon();
+ break;
+ }
+#endif // DECODE_CARRIER_AC64
#if DECODE_COOLIX
case decode_type_t::COOLIX: {
IRCoolixAC ac(kGpioUnused);
@@ -3828,14 +3979,6 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_CARRIER_AC64
-#if DECODE_CARRIER_AC64
- case decode_type_t::CARRIER_AC64: {
- IRCarrierAc64 ac(kGpioUnused);
- ac.setRaw(decode->value); // Uses value instead of state.
- *result = ac.toCommon();
- break;
- }
-#endif // DECODE_CARRIER_AC64
#if DECODE_DAIKIN
case decode_type_t::DAIKIN: {
IRDaikinESP ac(kGpioUnused);
@@ -4042,6 +4185,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_MIDEA
+#if DECODE_MIRAGE
+ case decode_type_t::MIRAGE: {
+ IRMirageAc ac(kGpioUnused);
+ ac.setRaw(decode->state);
+ *result = ac.toCommon();
+ break;
+ }
+#endif // DECODE_MIRAGE
#if DECODE_MITSUBISHI_AC
case decode_type_t::MITSUBISHI_AC: {
IRMitsubishiAC ac(kGpioUnused);
@@ -4108,6 +4259,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_PANASONIC_AC32
+#if DECODE_RHOSS
+ case decode_type_t::RHOSS: {
+ IRRhossAc ac(kGpioUnused);
+ ac.setRaw(decode->state);
+ *result = ac.toCommon();
+ break;
+ }
+#endif // DECODE_RHOSS
#if DECODE_SAMSUNG_AC
case decode_type_t::SAMSUNG_AC: {
IRSamsungAc ac(kGpioUnused);
@@ -4136,18 +4295,22 @@ namespace IRAcUtils {
case decode_type_t::SHARP_AC: {
IRSharpAc ac(kGpioUnused);
ac.setRaw(decode->state);
- *result = ac.toCommon();
- break;
- }
-#endif // DECODE_SHARP_AC
-#if DECODE_TCL112AC
- case decode_type_t::TCL112AC: {
- IRTcl112Ac ac(kGpioUnused);
- ac.setRaw(decode->state);
*result = ac.toCommon(prev);
break;
}
-#endif // DECODE_TCL112AC
+#endif // DECODE_SHARP_AC
+#if (DECODE_TCL112AC || DECODE_TEKNOPOINT)
+ case decode_type_t::TCL112AC:
+ case decode_type_t::TEKNOPOINT: {
+ IRTcl112Ac ac(kGpioUnused);
+ ac.setRaw(decode->state);
+ *result = ac.toCommon(prev);
+ // Teknopoint uses the TCL protocol, but with a different model number.
+ // Just keep the original protocol type ... for now.
+ result->protocol = decode->decode_type;
+ break;
+ }
+#endif // (DECODE_TCL112AC || DECODE_TEKNOPOINT)
#if DECODE_TECHNIBEL_AC
case decode_type_t::TECHNIBEL_AC: {
IRTechnibelAc ac(kGpioUnused);
@@ -4172,6 +4335,14 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_TOSHIBA_AC
+#if DECODE_TRANSCOLD
+ case decode_type_t::TRANSCOLD: {
+ IRTranscoldAc ac(kGpioUnused);
+ ac.setRaw(decode->value); // TRANSCOLD Uses value instead of state.
+ *result = ac.toCommon(prev);
+ break;
+ }
+#endif // DECODE_TRANSCOLD
#if DECODE_TROTEC
case decode_type_t::TROTEC: {
IRTrotecESP ac(kGpioUnused);
@@ -4220,14 +4391,6 @@ namespace IRAcUtils {
break;
}
#endif // DECODE_WHIRLPOOL_AC
-#if DECODE_TRANSCOLD
- case decode_type_t::TRANSCOLD: {
- IRTranscoldAc ac(kGpioUnused);
- ac.setRaw(decode->value); // TRANSCOLD Uses value instead of state.
- *result = ac.toCommon(prev);
- break;
- }
-#endif // DECODE_TRANSCOLD
default:
return false;
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.h
index 573e7ae7e..afa4bcee0 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRac.h
@@ -26,10 +26,12 @@
#include "ir_Kelvinator.h"
#include "ir_LG.h"
#include "ir_Midea.h"
+#include "ir_Mirage.h"
#include "ir_Mitsubishi.h"
#include "ir_MitsubishiHeavy.h"
#include "ir_Neoclima.h"
#include "ir_Panasonic.h"
+#include "ir_Rhoss.h"
#include "ir_Samsung.h"
#include "ir_Sanyo.h"
#include "ir_Sharp.h"
@@ -90,7 +92,8 @@ class IRac {
static stdAc::swingh_t strToSwingH(
const char *str, const stdAc::swingh_t def = stdAc::swingh_t::kOff);
static String boolToString(const bool value);
- static String opmodeToString(const stdAc::opmode_t mode);
+ static String opmodeToString(const stdAc::opmode_t mode,
+ const bool ha = false);
static String fanspeedToString(const stdAc::fanspeed_t speed);
static String swingvToString(const stdAc::swingv_t swingv);
static String swinghToString(const stdAc::swingh_t swingh);
@@ -245,7 +248,8 @@ void electra(IRElectraAc *ac,
void gree(IRGreeAC *ac, const gree_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo, const bool light,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool turbo, const bool econo, const bool light,
const bool clean, const int16_t sleep = -1);
#endif // SEND_GREE
#if SEND_HAIER_AC
@@ -257,18 +261,20 @@ void electra(IRElectraAc *ac,
#endif // SEND_HAIER_AC
#if SEND_HAIER_AC176
void haier176(IRHaierAC176 *ac,
- const bool on, const stdAc::opmode_t mode,
+ const haier_ac176_remote_model_t model, const bool on,
+ const stdAc::opmode_t mode, const bool celsius,
const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv,
- const bool turbo, const bool filter,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool turbo, const bool quiet, const bool filter,
const int16_t sleep = -1);
#endif // SEND_HAIER_AC176
#if SEND_HAIER_AC_YRW02
void haierYrwo2(IRHaierACYRW02 *ac,
const bool on, const stdAc::opmode_t mode,
- const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv,
- const bool turbo, const bool filter,
+ const bool celsius, const float degrees,
+ const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
+ const stdAc::swingh_t swingh, const bool turbo,
+ const bool quiet, const bool filter,
const int16_t sleep = -1);
#endif // SEND_HAIER_AC_YRW02
#if SEND_HITACHI_AC
@@ -326,6 +332,9 @@ void electra(IRElectraAc *ac,
const stdAc::swingv_t swingv, const bool turbo, const bool econo,
const bool light, const int16_t sleep = -1);
#endif // SEND_MIDEA
+#if SEND_MIRAGE
+ void mirage(IRMirageAc *ac, const stdAc::state_t state);
+#endif // SEND_MIRAGE
#if SEND_MITSUBISHI_AC
void mitsubishi(IRMitsubishiAC *ac,
const bool on, const stdAc::opmode_t mode,
@@ -386,14 +395,21 @@ void electra(IRElectraAc *ac,
const float degrees, const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh);
#endif // SEND_PANASONIC_AC32
+#if SEND_RHOSS
+ void rhoss(IRRhossAc *ac,
+ const bool on, const stdAc::opmode_t mode, const float degrees,
+ const stdAc::fanspeed_t fan, const stdAc::swingv_t swing);
+#endif // SEND_RHOSS
#if SEND_SAMSUNG_AC
void samsung(IRSamsungAc *ac,
const bool on, const stdAc::opmode_t mode, const float degrees,
- const stdAc::fanspeed_t fan, const stdAc::swingv_t swingv,
- const bool quiet, const bool turbo, const bool light,
- const bool filter, const bool clean,
- const bool beep, const bool prevpower = true,
- const bool forcepower = true);
+ const stdAc::fanspeed_t fan,
+ const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
+ const bool quiet, const bool turbo, const bool econo,
+ const bool light, const bool filter, const bool clean,
+ const bool beep, const int16_t sleep = -1,
+ const bool prevpower = true, const int16_t prevsleep = -1,
+ const bool forceextended = true);
#endif // SEND_SAMSUNG_AC
#if SEND_SANYO_AC
void sanyo(IRSanyoAc *ac,
@@ -413,11 +429,12 @@ void electra(IRElectraAc *ac,
void sharp(IRSharpAc *ac, const sharp_ac_remote_model_t model,
const bool on, const bool prev_power, const stdAc::opmode_t mode,
const float degrees, const stdAc::fanspeed_t fan,
- const stdAc::swingv_t swingv, const bool turbo, const bool light,
+ const stdAc::swingv_t swingv, const stdAc::swingv_t swingv_prev,
+ const bool turbo, const bool light,
const bool filter, const bool clean);
#endif // SEND_SHARP_AC
#if SEND_TCL112AC
- void tcl112(IRTcl112Ac *ac,
+ void tcl112(IRTcl112Ac *ac, const tcl_ac_remote_model_t model,
const bool on, const stdAc::opmode_t mode, const float degrees,
const stdAc::fanspeed_t fan,
const stdAc::swingv_t swingv, const stdAc::swingh_t swingh,
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp
index 9c7519cbd..4970dcf0b 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.cpp
@@ -830,8 +830,7 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Samsung AC (extended) decode");
// Check the extended size first, as it should fail fast due to longer
// length.
- if (decodeSamsungAC(results, offset, kSamsungAcExtendedBits, false))
- return true;
+ if (decodeSamsungAC(results, offset, kSamsungAcExtendedBits)) return true;
// Now check for the more common length.
DPRINTLN("Attempting Samsung AC decode");
if (decodeSamsungAC(results, offset, kSamsungAcBits)) return true;
@@ -1036,6 +1035,18 @@ bool IRrecv::decode(decode_results *results, irparams_t *save,
DPRINTLN("Attempting Bose decode");
if (decodeBose(results, offset)) return true;
#endif // DECODE_BOSE
+#if DECODE_ARRIS
+ DPRINTLN("Attempting Arris decode");
+ if (decodeArris(results, offset)) return true;
+#endif // DECODE_ARRIS
+#if DECODE_RHOSS
+ DPRINTLN("Attempting Rhoss decode");
+ if (decodeRhoss(results, offset)) return true;
+#endif // DECODE_RHOSS
+#if DECODE_AIRTON
+ DPRINTLN("Attempting Airton decode");
+ if (decodeAirton(results, offset)) return true;
+#endif // DECODE_AIRTON
// Typically new protocols are added above this line.
}
#if DECODE_HASH
@@ -1811,6 +1822,7 @@ uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr,
const int16_t excess,
const bool MSBfirst,
const bool GEThomas) {
+ DPRINTLN("DEBUG: Entered matchManchesterData");
uint16_t offset = 0;
uint64_t data = 0;
uint16_t nr_half_periods = 0;
@@ -1824,7 +1836,10 @@ uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr,
uint16_t min_remaining = nbits;
// Check if there is enough capture buffer to possibly have the message.
- if (remaining < min_remaining) return 0; // Nope, so abort.
+ if (remaining < min_remaining) {
+ DPRINTLN("DEBUG: Ran out of capture buffer!");
+ return 0; // Nope, so abort.
+ }
// Convert to ticks. Optimisation: Saves on math/extra instructions later.
uint16_t bank = starting_balance / kRawTick;
@@ -1847,22 +1862,39 @@ uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr,
while ((offset < remaining || bank) &&
nr_half_periods < expected_half_periods) {
// Get the next entry if we haven't anything existing to process.
+ DPRINT("DEBUG: Offset = ");
+ DPRINTLN(offset);
if (!bank) bank = *(data_ptr + offset++);
+ DPRINT("DEBUG: Bank = ");
+ DPRINTLN(bank * kRawTick);
// Check if we don't have a short interval.
- if (!match(bank, half_period, tolerance, excess)) return 0; // Not valid.
+ DPRINTLN("DEBUG: Checking for short interval");
+ if (!match(bank, half_period, tolerance, excess)) {
+ DPRINTLN("DEBUG: It is. Exiting");
+ return 0; // Not valid.
+ }
// We've succeeded in matching half a period, so count it.
nr_half_periods++;
+ DPRINT("DEBUG: Half Periods = ");
+ DPRINTLN(nr_half_periods);
// We've now used up our bank, so refill it with the next item, unless we
// are at the end of the capture buffer.
// If we are assume a single half period of "space".
- if (offset < remaining)
+ if (offset < remaining) {
+ DPRINT("DEBUG: Offset = ");
+ DPRINTLN(offset);
bank = *(data_ptr + offset++);
- else if (offset == remaining)
+ } else if (offset == remaining) {
bank = raw_half_period;
- else
+ } else {
return 0; // We are out of buffer, so abort!
+ }
+ DPRINT("DEBUG: Bank = ");
+ DPRINTLN(bank * kRawTick);
// Shift the data along and add our new bit.
+ DPRINT("DEBUG: Adding bit: ");
+ DPRINTLN((currentBit ? "1" : "0"));
data <<= 1;
data |= currentBit;
@@ -1870,10 +1902,12 @@ uint16_t IRrecv::matchManchesterData(volatile const uint16_t *data_ptr,
if (match(bank, half_period * 2, tolerance, excess)) {
// It is, so flip the bit we need to append, and remove a half_period of
// time from the bank.
+ DPRINTLN("DEBUG: long interval detected");
currentBit = !currentBit;
bank -= raw_half_period;
} else if (match(bank, half_period, tolerance, excess)) {
// It is a short interval, so eat up all the time and move on.
+ DPRINTLN("DEBUG: short interval detected");
bank = 0;
} else if (nr_half_periods == expected_half_periods - 1 &&
matchAtLeast(bank, half_period, tolerance, excess)) {
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.h
index 1a883d509..f4932b5a6 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRrecv.h
@@ -18,7 +18,7 @@
const uint16_t kHeader = 2; // Usual nr. of header entries.
const uint16_t kFooter = 2; // Usual nr. of footer (stop bits) entries.
const uint16_t kStartOffset = 1; // Usual rawbuf entry to start from.
-#define MS_TO_USEC(x) (x * 1000U) // Convert milli-Seconds to micro-Seconds.
+#define MS_TO_USEC(x) ((x) * 1000U) // Convert milli-Seconds to micro-Seconds.
// Marks tend to be 100us too long, and spaces 100us too short
// when received due to sensor lag.
const uint16_t kMarkExcess = 50;
@@ -287,6 +287,10 @@ class IRrecv {
bool decodeArgo(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kArgoBits, const bool strict = true);
#endif // DECODE_ARGO
+#if DECODE_ARRIS
+ bool decodeArris(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kArrisBits, const bool strict = true);
+#endif // DECODE_ARRIS
#if DECODE_SONY
bool decodeSony(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kSonyMinBits,
@@ -766,6 +770,15 @@ class IRrecv {
bool decodeBose(decode_results *results, uint16_t offset = kStartOffset,
const uint16_t nbits = kBoseBits, const bool strict = true);
#endif // DECODE_BOSE
+#if DECODE_RHOSS
+ bool decodeRhoss(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kRhossBits, const bool strict = true);
+#endif // DECODE_RHOSS
+#if DECODE_AIRTON
+ bool decodeAirton(decode_results *results, uint16_t offset = kStartOffset,
+ const uint16_t nbits = kAirtonBits,
+ const bool strict = true);
+#endif // DECODE_AIRTON
};
#endif // IRRECV_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h
index 35b45d958..09a3011ce 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRremoteESP8266.h
@@ -53,7 +53,7 @@
#endif // UNIT_TEST
// Library Version
-#define _IRREMOTEESP8266_VERSION_ "2.7.20"
+#define _IRREMOTEESP8266_VERSION_ "2.8.0"
// Set the language & locale for the library. See the `locale` dir for options.
#ifndef _IR_LOCALE_
@@ -790,6 +790,27 @@
#define SEND_BOSE _IR_ENABLE_DEFAULT_
#endif // SEND_BOSE
+#ifndef DECODE_ARRIS
+#define DECODE_ARRIS _IR_ENABLE_DEFAULT_
+#endif // DECODE_ARRIS
+#ifndef SEND_ARRIS
+#define SEND_ARRIS _IR_ENABLE_DEFAULT_
+#endif // SEND_ARRIS
+
+#ifndef DECODE_RHOSS
+#define DECODE_RHOSS _IR_ENABLE_DEFAULT_
+#endif // DECODE_RHOSS
+#ifndef SEND_RHOSS
+#define SEND_RHOSS _IR_ENABLE_DEFAULT_
+#endif // SEND_RHOSS
+
+#ifndef DECODE_AIRTON
+#define DECODE_AIRTON _IR_ENABLE_DEFAULT_
+#endif // DECODE_AIRTON
+#ifndef SEND_AIRTON
+#define SEND_AIRTON _IR_ENABLE_DEFAULT_
+#endif // SEND_AIRTON
+
#if (DECODE_ARGO || DECODE_DAIKIN || DECODE_FUJITSU_AC || DECODE_GREE || \
DECODE_KELVINATOR || DECODE_MITSUBISHI_AC || DECODE_TOSHIBA_AC || \
DECODE_TROTEC || DECODE_HAIER_AC || DECODE_HITACHI_AC || \
@@ -804,7 +825,7 @@
DECODE_HITACHI_AC344 || DECODE_CORONA_AC || DECODE_SANYO_AC || \
DECODE_VOLTAS || DECODE_MIRAGE || DECODE_HAIER_AC176 || \
DECODE_TEKNOPOINT || DECODE_KELON || DECODE_TROTEC_3550 || \
- DECODE_SANYO_AC88 || \
+ DECODE_SANYO_AC88 || DECODE_RHOSS || \
false)
// Add any DECODE to the above if it uses result->state (see kStateSizeMax)
// you might also want to add the protocol to hasACState function
@@ -951,14 +972,19 @@ enum decode_type_t {
TROTEC_3550,
SANYO_AC88, // 105
BOSE,
+ ARRIS,
+ RHOSS,
+ AIRTON,
// Add new entries before this one, and update it to point to the last entry.
- kLastDecodeType = BOSE,
+ kLastDecodeType = AIRTON,
};
// Message lengths & required repeat values
const uint16_t kNoRepeat = 0;
const uint16_t kSingleRepeat = 1;
+const uint16_t kAirtonBits = 56;
+const uint16_t kAirtonDefaultRepeat = kNoRepeat;
const uint16_t kAirwellBits = 34;
const uint16_t kAirwellMinRepeats = 2;
const uint16_t kAiwaRcT501Bits = 15;
@@ -970,6 +996,7 @@ const uint16_t kAmcorDefaultRepeat = kSingleRepeat;
const uint16_t kArgoStateLength = 12;
const uint16_t kArgoBits = kArgoStateLength * 8;
const uint16_t kArgoDefaultRepeat = kNoRepeat;
+const uint16_t kArrisBits = 32;
const uint16_t kCoolixBits = 24;
const uint16_t kCoolixDefaultRepeat = kSingleRepeat;
const uint16_t kCarrierAcBits = 32;
@@ -1195,6 +1222,9 @@ const uint16_t kMilesTag2ShotBits = 14;
const uint16_t kMilesTag2MsgBits = 24;
const uint16_t kMilesMinRepeat = 0;
const uint16_t kBoseBits = 16;
+const uint16_t kRhossStateLength = 12;
+const uint16_t kRhossBits = kRhossStateLength * 8;
+const uint16_t kRhossDefaultRepeat = 0;
// Legacy defines. (Deprecated)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.cpp
index 4814bd431..e20b97045 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.cpp
@@ -637,6 +637,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
case LG:
case LG2:
return 28;
+ case ARRIS:
case CARRIER_AC:
case ELITESCREENS:
case EPSON:
@@ -665,6 +666,7 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
case MIDEA:
case PANASONIC:
return 48;
+ case AIRTON:
case ECOCLIM:
case MAGIQUEST:
case VESTEL_AC:
@@ -738,6 +740,8 @@ uint16_t IRsend::defaultBits(const decode_type_t protocol) {
return kNeoclimaBits;
case PANASONIC_AC:
return kPanasonicAcBits;
+ case RHOSS:
+ return kRhossBits;
case SAMSUNG_AC:
return kSamsungAcBits;
case SANYO_AC:
@@ -781,6 +785,11 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
uint16_t min_repeat __attribute__((unused)) =
std::max(IRsend::minRepeats(type), repeat);
switch (type) {
+#if SEND_AIRTON
+ case AIRTON:
+ sendAirton(data, nbits, min_repeat);
+ break;
+#endif // SEND_AIRTON
#if SEND_AIRWELL
case AIRWELL:
sendAirwell(data, nbits, min_repeat);
@@ -790,7 +799,12 @@ bool IRsend::send(const decode_type_t type, const uint64_t data,
case AIWA_RC_T501:
sendAiwaRCT501(data, nbits, min_repeat);
break;
-#endif
+#endif // SEND_AIWA_RC_T501
+#if SEND_ARRIS
+ case ARRIS:
+ sendArris(data, nbits, min_repeat);
+ break;
+#endif // SEND_ARRIS
#if SEND_BOSE
case BOSE:
sendBose(data, nbits, min_repeat);
@@ -1247,6 +1261,11 @@ bool IRsend::send(const decode_type_t type, const uint8_t *state,
sendPanasonicAC(state, nbytes);
break;
#endif // SEND_PANASONIC_AC
+#if SEND_RHOSS
+ case RHOSS:
+ sendRhoss(state, nbytes);
+ break;
+#endif // SEND_RHOSS
#if SEND_SAMSUNG_AC
case SAMSUNG_AC:
sendSamsungAC(state, nbytes);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h
index c20fc64bc..d55ce0238 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRsend.h
@@ -136,12 +136,24 @@ enum gree_ac_remote_model_t {
YBOFB, // (2) Green, YBOFB2, YAPOF3
};
+/// HAIER_AC176 A/C model numbers
+enum haier_ac176_remote_model_t {
+ V9014557_A = 1, // (1) V9014557 Remote in "A" setting. (Default)
+ V9014557_B, // (2) V9014557 Remote in "B" setting.
+};
+
/// HITACHI_AC1 A/C model numbers
enum hitachi_ac1_remote_model_t {
R_LT0541_HTA_A = 1, // (1) R-LT0541-HTA Remote in "A" setting. (Default)
R_LT0541_HTA_B, // (2) R-LT0541-HTA Remote in "B" setting.
};
+/// MIRAGE A/C model numbers
+enum mirage_ac_remote_model_t {
+ KKG9AC1 = 1, // (1) KKG9A-C1 Remote. (Default)
+ KKG29AC1, // (2) KKG29A-C1 Remote.
+};
+
/// Panasonic A/C model numbers
enum panasonic_ac_remote_model_t {
kPanasonicUnknown = 0,
@@ -160,6 +172,12 @@ enum sharp_ac_remote_model_t {
A903 = 3, // 820 too
};
+/// TCL A/C model numbers
+enum tcl_ac_remote_model_t {
+ TAC09CHSD = 1,
+ GZ055BE1 = 2,
+};
+
/// Voltas A/C model numbers
enum voltas_ac_remote_model_t {
kVoltasUnknown = 0, // Full Function
@@ -737,6 +755,21 @@ class IRsend {
void sendBose(const uint64_t data, const uint16_t nbits = kBoseBits,
const uint16_t repeat = kNoRepeat);
#endif // SEND_BOSE
+#if SEND_ARRIS
+ void sendArris(const uint64_t data, const uint16_t nbits = kArrisBits,
+ const uint16_t repeat = kNoRepeat);
+ static uint32_t toggleArrisRelease(const uint32_t data);
+ static uint32_t encodeArris(const uint32_t command, const bool release);
+#endif // SEND_ARRIS
+#if SEND_RHOSS
+ void sendRhoss(const unsigned char data[],
+ const uint16_t nbytes = kRhossStateLength,
+ const uint16_t repeat = kRhossDefaultRepeat);
+#endif // SEND_RHOSS
+#if SEND_AIRTON
+ void sendAirton(const uint64_t data, const uint16_t nbits = kAirtonBits,
+ const uint16_t repeat = kAirtonDefaultRepeat);
+#endif // SEND_AIRTON
protected:
#ifdef UNIT_TEST
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.cpp
index a7bd7de29..a580bff9f 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.cpp
@@ -1,9 +1,10 @@
-// Copyright 2019-2020 - David Conran (@crankyoldgit)
+// Copyright 2019-2021 - David Conran (@crankyoldgit)
/// @file IRtext.cpp
/// @warning If you add or remove an entry in this file, you should run:
/// '../tools/generate_irtext_h.sh' to rebuild the `IRtext.h` file.
+#include "IRtext.h"
#ifndef UNIT_TEST
#include
#endif // UNIT_TEST
@@ -14,178 +15,263 @@
#define PROGMEM // Pretend we have the PROGMEM macro even if we really don't.
#endif
+#ifndef FPSTR
+#define FPSTR(X) X // Also pretend we have flash-string helper class cast.
+#endif
+
+#define IRTEXT_CONST_BLOB_NAME(NAME)\
+ NAME ## Blob
+
+#define IRTEXT_CONST_BLOB_DECL(NAME)\
+ const char IRTEXT_CONST_BLOB_NAME(NAME) [] PROGMEM
+
+#define IRTEXT_CONST_BLOB_PTR(NAME)\
+ IRTEXT_CONST_PTR(NAME) {\
+ IRTEXT_CONST_PTR_CAST(IRTEXT_CONST_BLOB_NAME(NAME)) }
+
+#define IRTEXT_CONST_STRING(NAME, VALUE)\
+ static IRTEXT_CONST_BLOB_DECL(NAME) { VALUE };\
+ IRTEXT_CONST_PTR(NAME) PROGMEM {\
+ IRTEXT_CONST_PTR_CAST(&(IRTEXT_CONST_BLOB_NAME(NAME))[0]) }
+
// Common
-const PROGMEM char* kUnknownStr = D_STR_UNKNOWN; ///< "Unknown"
-const PROGMEM char* kProtocolStr = D_STR_PROTOCOL; ///< "Protocol"
-const PROGMEM char* kPowerStr = D_STR_POWER; ///< "Power"
-const PROGMEM char* kOnStr = D_STR_ON; ///< "On"
-const PROGMEM char* kOffStr = D_STR_OFF; ///< "Off"
-const PROGMEM char* kModeStr = D_STR_MODE; ///< "Mode"
-const PROGMEM char* kToggleStr = D_STR_TOGGLE; ///< "Toggle"
-const PROGMEM char* kTurboStr = D_STR_TURBO; ///< "Turbo"
-const PROGMEM char* kSuperStr = D_STR_SUPER; ///< "Super"
-const PROGMEM char* kSleepStr = D_STR_SLEEP; ///< "Sleep"
-const PROGMEM char* kLightStr = D_STR_LIGHT; ///< "Light"
-const PROGMEM char* kPowerfulStr = D_STR_POWERFUL; ///< "Powerful"
-const PROGMEM char* kQuietStr = D_STR_QUIET; ///< "Quiet"
-const PROGMEM char* kEconoStr = D_STR_ECONO; ///< "Econo"
-const PROGMEM char* kSwingStr = D_STR_SWING; ///< "Swing"
-const PROGMEM char* kSwingHStr = D_STR_SWINGH; ///< "SwingH"
-const PROGMEM char* kSwingVStr = D_STR_SWINGV; ///< "SwingV"
-const PROGMEM char* kBeepStr = D_STR_BEEP; ///< "Beep"
-const PROGMEM char* kZoneFollowStr = D_STR_ZONEFOLLOW; ///< "Zone Follow"
-const PROGMEM char* kFixedStr = D_STR_FIXED; ///< "Fixed"
-const PROGMEM char* kMouldStr = D_STR_MOULD; ///< "Mould"
-const PROGMEM char* kCleanStr = D_STR_CLEAN; ///< "Clean"
-const PROGMEM char* kPurifyStr = D_STR_PURIFY; ///< "Purify"
-const PROGMEM char* kTimerStr = D_STR_TIMER; ///< "Timer"
-const PROGMEM char* kOnTimerStr = D_STR_ONTIMER; ///< "On Timer"
-const PROGMEM char* kOffTimerStr = D_STR_OFFTIMER; ///< "Off Timer"
-const PROGMEM char* kTimerModeStr = D_STR_TIMERMODE; ///< "Timer Mode"
-const PROGMEM char* kClockStr = D_STR_CLOCK; ///< "Clock"
-const PROGMEM char* kCommandStr = D_STR_COMMAND; ///< "Command"
-const PROGMEM char* kXFanStr = D_STR_XFAN; ///< "XFan"
-const PROGMEM char* kHealthStr = D_STR_HEALTH; ///< "Health"
-const PROGMEM char* kModelStr = D_STR_MODEL; ///< "Model"
-const PROGMEM char* kTempStr = D_STR_TEMP; ///< "Temp"
-const PROGMEM char* kIFeelStr = D_STR_IFEEL; ///< "IFeel"
-const PROGMEM char* kHumidStr = D_STR_HUMID; ///< "Humid"
-const PROGMEM char* kSaveStr = D_STR_SAVE; ///< "Save"
-const PROGMEM char* kEyeStr = D_STR_EYE; ///< "Eye"
-const PROGMEM char* kFollowStr = D_STR_FOLLOW; ///< "Follow"
-const PROGMEM char* kIonStr = D_STR_ION; ///< "Ion"
-const PROGMEM char* kFreshStr = D_STR_FRESH; ///< "Fresh"
-const PROGMEM char* kHoldStr = D_STR_HOLD; ///< "Hold"
-const PROGMEM char* kButtonStr = D_STR_BUTTON; ///< "Button"
-const PROGMEM char* k8CHeatStr = D_STR_8C_HEAT; ///< "8C Heat"
-const PROGMEM char* k10CHeatStr = D_STR_10C_HEAT; ///< "10C Heat"
-const PROGMEM char* kNightStr = D_STR_NIGHT; ///< "Night"
-const PROGMEM char* kSilentStr = D_STR_SILENT; ///< "Silent"
-const PROGMEM char* kFilterStr = D_STR_FILTER; ///< "Filter"
-const PROGMEM char* k3DStr = D_STR_3D; ///< "3D"
-const PROGMEM char* kCelsiusStr = D_STR_CELSIUS; ///< "Celsius"
-const PROGMEM char* kCelsiusFahrenheitStr = D_STR_CELSIUS_FAHRENHEIT; ///<
+IRTEXT_CONST_STRING(kUnknownStr, D_STR_UNKNOWN); ///< "Unknown"
+IRTEXT_CONST_STRING(kProtocolStr, D_STR_PROTOCOL); ///< "Protocol"
+IRTEXT_CONST_STRING(kPowerStr, D_STR_POWER); ///< "Power"
+IRTEXT_CONST_STRING(kOnStr, D_STR_ON); ///< "On"
+IRTEXT_CONST_STRING(kOffStr, D_STR_OFF); ///< "Off"
+IRTEXT_CONST_STRING(k1Str, D_STR_1); ///< "1"
+IRTEXT_CONST_STRING(k0Str, D_STR_0); ///< "0"
+IRTEXT_CONST_STRING(kModeStr, D_STR_MODE); ///< "Mode"
+IRTEXT_CONST_STRING(kToggleStr, D_STR_TOGGLE); ///< "Toggle"
+IRTEXT_CONST_STRING(kTurboStr, D_STR_TURBO); ///< "Turbo"
+IRTEXT_CONST_STRING(kSuperStr, D_STR_SUPER); ///< "Super"
+IRTEXT_CONST_STRING(kSleepStr, D_STR_SLEEP); ///< "Sleep"
+IRTEXT_CONST_STRING(kLightStr, D_STR_LIGHT); ///< "Light"
+IRTEXT_CONST_STRING(kPowerfulStr, D_STR_POWERFUL); ///< "Powerful"
+IRTEXT_CONST_STRING(kQuietStr, D_STR_QUIET); ///< "Quiet"
+IRTEXT_CONST_STRING(kEconoStr, D_STR_ECONO); ///< "Econo"
+IRTEXT_CONST_STRING(kSwingStr, D_STR_SWING); ///< "Swing"
+IRTEXT_CONST_STRING(kSwingHStr, D_STR_SWINGH); ///< "SwingH"
+IRTEXT_CONST_STRING(kSwingVStr, D_STR_SWINGV); ///< "SwingV"
+IRTEXT_CONST_STRING(kBeepStr, D_STR_BEEP); ///< "Beep"
+IRTEXT_CONST_STRING(kZoneFollowStr, D_STR_ZONEFOLLOW); ///< "Zone Follow"
+IRTEXT_CONST_STRING(kFixedStr, D_STR_FIXED); ///< "Fixed"
+IRTEXT_CONST_STRING(kMouldStr, D_STR_MOULD); ///< "Mould"
+IRTEXT_CONST_STRING(kCleanStr, D_STR_CLEAN); ///< "Clean"
+IRTEXT_CONST_STRING(kPurifyStr, D_STR_PURIFY); ///< "Purify"
+IRTEXT_CONST_STRING(kTimerStr, D_STR_TIMER); ///< "Timer"
+IRTEXT_CONST_STRING(kOnTimerStr, D_STR_ONTIMER); ///< "On Timer"
+IRTEXT_CONST_STRING(kOffTimerStr, D_STR_OFFTIMER); ///< "Off Timer"
+IRTEXT_CONST_STRING(kTimerModeStr, D_STR_TIMERMODE); ///< "Timer Mode"
+IRTEXT_CONST_STRING(kClockStr, D_STR_CLOCK); ///< "Clock"
+IRTEXT_CONST_STRING(kCommandStr, D_STR_COMMAND); ///< "Command"
+IRTEXT_CONST_STRING(kXFanStr, D_STR_XFAN); ///< "XFan"
+IRTEXT_CONST_STRING(kHealthStr, D_STR_HEALTH); ///< "Health"
+IRTEXT_CONST_STRING(kModelStr, D_STR_MODEL); ///< "Model"
+IRTEXT_CONST_STRING(kTempStr, D_STR_TEMP); ///< "Temp"
+IRTEXT_CONST_STRING(kIFeelStr, D_STR_IFEEL); ///< "IFeel"
+IRTEXT_CONST_STRING(kHumidStr, D_STR_HUMID); ///< "Humid"
+IRTEXT_CONST_STRING(kSaveStr, D_STR_SAVE); ///< "Save"
+IRTEXT_CONST_STRING(kEyeStr, D_STR_EYE); ///< "Eye"
+IRTEXT_CONST_STRING(kFollowStr, D_STR_FOLLOW); ///< "Follow"
+IRTEXT_CONST_STRING(kIonStr, D_STR_ION); ///< "Ion"
+IRTEXT_CONST_STRING(kFreshStr, D_STR_FRESH); ///< "Fresh"
+IRTEXT_CONST_STRING(kHoldStr, D_STR_HOLD); ///< "Hold"
+IRTEXT_CONST_STRING(kButtonStr, D_STR_BUTTON); ///< "Button"
+IRTEXT_CONST_STRING(k8CHeatStr, D_STR_8C_HEAT); ///< "8C Heat"
+IRTEXT_CONST_STRING(k10CHeatStr, D_STR_10C_HEAT); ///< "10C Heat"
+IRTEXT_CONST_STRING(kNightStr, D_STR_NIGHT); ///< "Night"
+IRTEXT_CONST_STRING(kSilentStr, D_STR_SILENT); ///< "Silent"
+IRTEXT_CONST_STRING(kFilterStr, D_STR_FILTER); ///< "Filter"
+IRTEXT_CONST_STRING(k3DStr, D_STR_3D); ///< "3D"
+IRTEXT_CONST_STRING(kCelsiusStr, D_STR_CELSIUS); ///< "Celsius"
+IRTEXT_CONST_STRING(kCelsiusFahrenheitStr, D_STR_CELSIUS_FAHRENHEIT); ///<
///< "Celsius/Fahrenheit"
-const PROGMEM char* kTempUpStr = D_STR_TEMPUP; ///< "Temp Up"
-const PROGMEM char* kTempDownStr = D_STR_TEMPDOWN; ///< "Temp Down"
-const PROGMEM char* kStartStr = D_STR_START; ///< "Start"
-const PROGMEM char* kStopStr = D_STR_STOP; ///< "Stop"
-const PROGMEM char* kMoveStr = D_STR_MOVE; ///< "Move"
-const PROGMEM char* kSetStr = D_STR_SET; ///< "Set"
-const PROGMEM char* kCancelStr = D_STR_CANCEL; ///< "Cancel"
-const PROGMEM char* kUpStr = D_STR_UP; ///< "Up"
-const PROGMEM char* kDownStr = D_STR_DOWN; ///< "Down"
-const PROGMEM char* kChangeStr = D_STR_CHANGE; ///< "Change"
-const PROGMEM char* kComfortStr = D_STR_COMFORT; ///< "Comfort"
-const PROGMEM char* kSensorStr = D_STR_SENSOR; ///< "Sensor"
-const PROGMEM char* kWeeklyTimerStr = D_STR_WEEKLYTIMER; ///< "WeeklyTimer"
-const PROGMEM char* kWifiStr = D_STR_WIFI; ///< "Wifi"
-const PROGMEM char* kLastStr = D_STR_LAST; ///< "Last"
-const PROGMEM char* kFastStr = D_STR_FAST; ///< "Fast"
-const PROGMEM char* kSlowStr = D_STR_SLOW; ///< "Slow"
-const PROGMEM char* kAirFlowStr = D_STR_AIRFLOW; ///< "Air Flow"
-const PROGMEM char* kStepStr = D_STR_STEP; ///< "Step"
-const PROGMEM char* kNAStr = D_STR_NA; ///< "N/A"
-const PROGMEM char* kInsideStr = D_STR_INSIDE; ///< "Inside"
-const PROGMEM char* kOutsideStr = D_STR_OUTSIDE; ///< "Outside"
-const PROGMEM char* kLoudStr = D_STR_LOUD; ///< "Loud"
-const PROGMEM char* kLowerStr = D_STR_LOWER; ///< "Lower"
-const PROGMEM char* kUpperStr = D_STR_UPPER; ///< "Upper"
-const PROGMEM char* kBreezeStr = D_STR_BREEZE; ///< "Breeze"
-const PROGMEM char* kCirculateStr = D_STR_CIRCULATE; ///< "Circulate"
-const PROGMEM char* kCeilingStr = D_STR_CEILING; ///< "Ceiling"
-const PROGMEM char* kWallStr = D_STR_WALL; ///< "Wall"
-const PROGMEM char* kRoomStr = D_STR_ROOM; ///< "Room"
-const PROGMEM char* k6thSenseStr = D_STR_6THSENSE; ///< "6th Sense"
-const PROGMEM char* kTypeStr = D_STR_TYPE; ///< "Type"
-const PROGMEM char* kSpecialStr = D_STR_SPECIAL; ///< "Special"
-const PROGMEM char* kIdStr = D_STR_ID; ///< "Id" / Device Identifier
-const PROGMEM char* kVaneStr = D_STR_VANE; ///< "Vane"
+IRTEXT_CONST_STRING(kTempUpStr, D_STR_TEMPUP); ///< "Temp Up"
+IRTEXT_CONST_STRING(kTempDownStr, D_STR_TEMPDOWN); ///< "Temp Down"
+IRTEXT_CONST_STRING(kStartStr, D_STR_START); ///< "Start"
+IRTEXT_CONST_STRING(kStopStr, D_STR_STOP); ///< "Stop"
+IRTEXT_CONST_STRING(kMoveStr, D_STR_MOVE); ///< "Move"
+IRTEXT_CONST_STRING(kSetStr, D_STR_SET); ///< "Set"
+IRTEXT_CONST_STRING(kCancelStr, D_STR_CANCEL); ///< "Cancel"
+IRTEXT_CONST_STRING(kUpStr, D_STR_UP); ///< "Up"
+IRTEXT_CONST_STRING(kDownStr, D_STR_DOWN); ///< "Down"
+IRTEXT_CONST_STRING(kChangeStr, D_STR_CHANGE); ///< "Change"
+IRTEXT_CONST_STRING(kComfortStr, D_STR_COMFORT); ///< "Comfort"
+IRTEXT_CONST_STRING(kSensorStr, D_STR_SENSOR); ///< "Sensor"
+IRTEXT_CONST_STRING(kWeeklyTimerStr, D_STR_WEEKLYTIMER); ///< "WeeklyTimer"
+IRTEXT_CONST_STRING(kWifiStr, D_STR_WIFI); ///< "Wifi"
+IRTEXT_CONST_STRING(kLastStr, D_STR_LAST); ///< "Last"
+IRTEXT_CONST_STRING(kFastStr, D_STR_FAST); ///< "Fast"
+IRTEXT_CONST_STRING(kSlowStr, D_STR_SLOW); ///< "Slow"
+IRTEXT_CONST_STRING(kAirFlowStr, D_STR_AIRFLOW); ///< "Air Flow"
+IRTEXT_CONST_STRING(kStepStr, D_STR_STEP); ///< "Step"
+IRTEXT_CONST_STRING(kNAStr, D_STR_NA); ///< "N/A"
+IRTEXT_CONST_STRING(kInsideStr, D_STR_INSIDE); ///< "Inside"
+IRTEXT_CONST_STRING(kOutsideStr, D_STR_OUTSIDE); ///< "Outside"
+IRTEXT_CONST_STRING(kLoudStr, D_STR_LOUD); ///< "Loud"
+IRTEXT_CONST_STRING(kLowerStr, D_STR_LOWER); ///< "Lower"
+IRTEXT_CONST_STRING(kUpperStr, D_STR_UPPER); ///< "Upper"
+IRTEXT_CONST_STRING(kBreezeStr, D_STR_BREEZE); ///< "Breeze"
+IRTEXT_CONST_STRING(kCirculateStr, D_STR_CIRCULATE); ///< "Circulate"
+IRTEXT_CONST_STRING(kCeilingStr, D_STR_CEILING); ///< "Ceiling"
+IRTEXT_CONST_STRING(kWallStr, D_STR_WALL); ///< "Wall"
+IRTEXT_CONST_STRING(kRoomStr, D_STR_ROOM); ///< "Room"
+IRTEXT_CONST_STRING(k6thSenseStr, D_STR_6THSENSE); ///< "6th Sense"
+IRTEXT_CONST_STRING(kTypeStr, D_STR_TYPE); ///< "Type"
+IRTEXT_CONST_STRING(kSpecialStr, D_STR_SPECIAL); ///< "Special"
+IRTEXT_CONST_STRING(kIdStr, D_STR_ID); ///< "Id" / Device Identifier
+IRTEXT_CONST_STRING(kVaneStr, D_STR_VANE); ///< "Vane"
+IRTEXT_CONST_STRING(kLockStr, D_STR_LOCK); ///< "Lock"
-const PROGMEM char* kAutoStr = D_STR_AUTO; ///< "Auto"
-const PROGMEM char* kAutomaticStr = D_STR_AUTOMATIC; ///< "Automatic"
-const PROGMEM char* kManualStr = D_STR_MANUAL; ///< "Manual"
-const PROGMEM char* kCoolStr = D_STR_COOL; ///< "Cool"
-const PROGMEM char* kHeatStr = D_STR_HEAT; ///< "Heat"
-const PROGMEM char* kFanStr = D_STR_FAN; ///< "Fan"
-const PROGMEM char* kDryStr = D_STR_DRY; ///< "Dry"
-const PROGMEM char* kFanOnlyStr = D_STR_FANONLY; ///< "fan_only"
-const PROGMEM char* kRecycleStr = D_STR_RECYCLE; ///< "Recycle"
+IRTEXT_CONST_STRING(kAutoStr, D_STR_AUTO); ///< "Auto"
+IRTEXT_CONST_STRING(kAutomaticStr, D_STR_AUTOMATIC); ///< "Automatic"
+IRTEXT_CONST_STRING(kManualStr, D_STR_MANUAL); ///< "Manual"
+IRTEXT_CONST_STRING(kCoolStr, D_STR_COOL); ///< "Cool"
+IRTEXT_CONST_STRING(kCoolingStr, D_STR_COOLING); ///< "Cooling"
+IRTEXT_CONST_STRING(kHeatStr, D_STR_HEAT); ///< "Heat"
+IRTEXT_CONST_STRING(kHeatingStr, D_STR_HEATING); ///< "Heating"
+IRTEXT_CONST_STRING(kDryStr, D_STR_DRY); ///< "Dry"
+IRTEXT_CONST_STRING(kDryingStr, D_STR_DRYING); ///< "Drying"
+IRTEXT_CONST_STRING(kDehumidifyStr, D_STR_DEHUMIDIFY); ///< "Dehumidify"
+IRTEXT_CONST_STRING(kFanStr, D_STR_FAN); ///< "Fan"
+// The following Fans strings with "only" are required to help with
+// HomeAssistant & Google Home Climate integration. For compatibility only.
+// Ref: https://www.home-assistant.io/integrations/google_assistant/#climate-operation-modes
+IRTEXT_CONST_STRING(kFanOnlyStr, D_STR_FANONLY); ///< "fan-only"
+IRTEXT_CONST_STRING(kFan_OnlyStr, D_STR_FAN_ONLY); ///< "fan_only" (HA/legacy)
+IRTEXT_CONST_STRING(kFanOnlyWithSpaceStr, D_STR_FANSPACEONLY); ///< "Fan Only"
+IRTEXT_CONST_STRING(kFanOnlyNoSpaceStr, D_STR_FANONLYNOSPACE); ///< "FanOnly"
-const PROGMEM char* kMaxStr = D_STR_MAX; ///< "Max"
-const PROGMEM char* kMaximumStr = D_STR_MAXIMUM; ///< "Maximum"
-const PROGMEM char* kMinStr = D_STR_MIN; ///< "Min"
-const PROGMEM char* kMinimumStr = D_STR_MINIMUM; ///< "Minimum"
-const PROGMEM char* kMedStr = D_STR_MED; ///< "Med"
-const PROGMEM char* kMediumStr = D_STR_MEDIUM; ///< "Medium"
+IRTEXT_CONST_STRING(kRecycleStr, D_STR_RECYCLE); ///< "Recycle"
-const PROGMEM char* kHighestStr = D_STR_HIGHEST; ///< "Highest"
-const PROGMEM char* kHighStr = D_STR_HIGH; ///< "High"
-const PROGMEM char* kHiStr = D_STR_HI; ///< "Hi"
-const PROGMEM char* kMidStr = D_STR_MID; ///< "Mid"
-const PROGMEM char* kMiddleStr = D_STR_MIDDLE; ///< "Middle"
-const PROGMEM char* kLowStr = D_STR_LOW; ///< "Low"
-const PROGMEM char* kLoStr = D_STR_LO; ///< "Lo"
-const PROGMEM char* kLowestStr = D_STR_LOWEST; ///< "Lowest"
-const PROGMEM char* kMaxRightStr = D_STR_MAXRIGHT; ///< "Max Right"
-const PROGMEM char* kRightMaxStr = D_STR_RIGHTMAX_NOSPACE; ///< "RightMax"
-const PROGMEM char* kRightStr = D_STR_RIGHT; ///< "Right"
-const PROGMEM char* kLeftStr = D_STR_LEFT; ///< "Left"
-const PROGMEM char* kMaxLeftStr = D_STR_MAXLEFT; ///< "Max Left"
-const PROGMEM char* kLeftMaxStr = D_STR_LEFTMAX_NOSPACE; ///< "LeftMax"
-const PROGMEM char* kWideStr = D_STR_WIDE; ///< "Wide"
-const PROGMEM char* kCentreStr = D_STR_CENTRE; ///< "Centre"
-const PROGMEM char* kTopStr = D_STR_TOP; ///< "Top"
-const PROGMEM char* kBottomStr = D_STR_BOTTOM; ///< "Bottom"
+IRTEXT_CONST_STRING(kMaxStr, D_STR_MAX); ///< "Max"
+IRTEXT_CONST_STRING(kMaximumStr, D_STR_MAXIMUM); ///< "Maximum"
+IRTEXT_CONST_STRING(kMinStr, D_STR_MIN); ///< "Min"
+IRTEXT_CONST_STRING(kMinimumStr, D_STR_MINIMUM); ///< "Minimum"
+IRTEXT_CONST_STRING(kMedStr, D_STR_MED); ///< "Med"
+IRTEXT_CONST_STRING(kMediumStr, D_STR_MEDIUM); ///< "Medium"
+
+IRTEXT_CONST_STRING(kHighestStr, D_STR_HIGHEST); ///< "Highest"
+IRTEXT_CONST_STRING(kHighStr, D_STR_HIGH); ///< "High"
+IRTEXT_CONST_STRING(kHiStr, D_STR_HI); ///< "Hi"
+IRTEXT_CONST_STRING(kMidStr, D_STR_MID); ///< "Mid"
+IRTEXT_CONST_STRING(kMiddleStr, D_STR_MIDDLE); ///< "Middle"
+IRTEXT_CONST_STRING(kLowStr, D_STR_LOW); ///< "Low"
+IRTEXT_CONST_STRING(kLoStr, D_STR_LO); ///< "Lo"
+IRTEXT_CONST_STRING(kLowestStr, D_STR_LOWEST); ///< "Lowest"
+IRTEXT_CONST_STRING(kMaxRightStr, D_STR_MAXRIGHT); ///< "Max Right"
+IRTEXT_CONST_STRING(kMaxRightNoSpaceStr, D_STR_MAXRIGHT_NOSPACE); ///<
+ ///< "MaxRight"
+IRTEXT_CONST_STRING(kRightMaxStr, D_STR_RIGHTMAX); ///< "Right Max"
+IRTEXT_CONST_STRING(kRightMaxNoSpaceStr, D_STR_RIGHTMAX_NOSPACE); ///<
+ ///< "RightMax"
+IRTEXT_CONST_STRING(kRightStr, D_STR_RIGHT); ///< "Right"
+IRTEXT_CONST_STRING(kLeftStr, D_STR_LEFT); ///< "Left"
+IRTEXT_CONST_STRING(kMaxLeftStr, D_STR_MAXLEFT); ///< "Max Left"
+IRTEXT_CONST_STRING(kMaxLeftNoSpaceStr, D_STR_MAXLEFT_NOSPACE); ///< "MaxLeft"
+IRTEXT_CONST_STRING(kLeftMaxStr, D_STR_LEFTMAX); ///< "Left Max"
+IRTEXT_CONST_STRING(kLeftMaxNoSpaceStr, D_STR_LEFTMAX_NOSPACE); ///< "LeftMax"
+IRTEXT_CONST_STRING(kWideStr, D_STR_WIDE); ///< "Wide"
+IRTEXT_CONST_STRING(kCentreStr, D_STR_CENTRE); ///< "Centre"
+IRTEXT_CONST_STRING(kTopStr, D_STR_TOP); ///< "Top"
+IRTEXT_CONST_STRING(kBottomStr, D_STR_BOTTOM); ///< "Bottom"
// Compound words/phrases/descriptions from pre-defined words.
-const PROGMEM char* kEconoToggleStr = D_STR_ECONOTOGGLE; ///< "Econo Toggle"
-const PROGMEM char* kEyeAutoStr = D_STR_EYEAUTO; ///< "Eye Auto"
-const PROGMEM char* kLightToggleStr = D_STR_LIGHTTOGGLE; ///< "Light Toggle"
-const PROGMEM char* kOutsideQuietStr = D_STR_OUTSIDEQUIET; ///< "Outside Quiet"
-const PROGMEM char* kPowerToggleStr = D_STR_POWERTOGGLE; ///< "Power Toggle"
-const PROGMEM char* kPowerButtonStr = D_STR_POWERBUTTON; ///< "Power Button"
-const PROGMEM char* kPreviousPowerStr = D_STR_PREVIOUSPOWER; ///<
+IRTEXT_CONST_STRING(kEconoToggleStr, D_STR_ECONOTOGGLE); ///< "Econo Toggle"
+IRTEXT_CONST_STRING(kEyeAutoStr, D_STR_EYEAUTO); ///< "Eye Auto"
+IRTEXT_CONST_STRING(kLightToggleStr, D_STR_LIGHTTOGGLE); ///< "Light Toggle"
+///< "Outside Quiet"
+IRTEXT_CONST_STRING(kOutsideQuietStr, D_STR_OUTSIDEQUIET);
+IRTEXT_CONST_STRING(kPowerToggleStr, D_STR_POWERTOGGLE); ///< "Power Toggle"
+IRTEXT_CONST_STRING(kPowerButtonStr, D_STR_POWERBUTTON); ///< "Power Button"
+IRTEXT_CONST_STRING(kPreviousPowerStr, D_STR_PREVIOUSPOWER); ///<
///< "Previous Power"
-const PROGMEM char* kDisplayTempStr = D_STR_DISPLAYTEMP; ///< "Display Temp"
-const PROGMEM char* kSensorTempStr = D_STR_SENSORTEMP; ///< "Sensor Temp"
-const PROGMEM char* kSleepTimerStr = D_STR_SLEEP_TIMER; ///< "Sleep Timer"
-const PROGMEM char* kSwingVModeStr = D_STR_SWINGVMODE; ///< "Swing(V) Mode"
-const PROGMEM char* kSwingVToggleStr = D_STR_SWINGVTOGGLE; ///<
+IRTEXT_CONST_STRING(kDisplayTempStr, D_STR_DISPLAYTEMP); ///< "Display Temp"
+IRTEXT_CONST_STRING(kSensorTempStr, D_STR_SENSORTEMP); ///< "Sensor Temp"
+IRTEXT_CONST_STRING(kSleepTimerStr, D_STR_SLEEP_TIMER); ///< "Sleep Timer"
+IRTEXT_CONST_STRING(kSwingVModeStr, D_STR_SWINGVMODE); ///< "Swing(V) Mode"
+IRTEXT_CONST_STRING(kSwingVToggleStr, D_STR_SWINGVTOGGLE); ///<
///< "Swing(V) Toggle"
-const PROGMEM char* kTurboToggleStr = D_STR_TURBOTOGGLE; ///< "Turbo Toggle"
+IRTEXT_CONST_STRING(kTurboToggleStr, D_STR_TURBOTOGGLE); ///< "Turbo Toggle"
-// Separators
-char kTimeSep = D_CHR_TIME_SEP; ///< ':'
-const PROGMEM char* kSpaceLBraceStr = D_STR_SPACELBRACE; ///< " ("
-const PROGMEM char* kCommaSpaceStr = D_STR_COMMASPACE; ///< ", "
-const PROGMEM char* kColonSpaceStr = D_STR_COLONSPACE; ///< ": "
+// Separators & Punctuation
+const char kTimeSep = D_CHR_TIME_SEP; ///< ':'
+IRTEXT_CONST_STRING(kSpaceLBraceStr, D_STR_SPACELBRACE); ///< " ("
+IRTEXT_CONST_STRING(kCommaSpaceStr, D_STR_COMMASPACE); ///< ", "
+IRTEXT_CONST_STRING(kColonSpaceStr, D_STR_COLONSPACE); ///< ": "
+IRTEXT_CONST_STRING(kDashStr, D_STR_DASH); ///< "-"
// IRutils
// - Time
-const PROGMEM char* kDayStr = D_STR_DAY; ///< "Day"
-const PROGMEM char* kDaysStr = D_STR_DAYS; ///< "Days"
-const PROGMEM char* kHourStr = D_STR_HOUR; ///< "Hour"
-const PROGMEM char* kHoursStr = D_STR_HOURS; ///< "Hours"
-const PROGMEM char* kMinuteStr = D_STR_MINUTE; ///< "Minute"
-const PROGMEM char* kMinutesStr = D_STR_MINUTES; ///< "Minutes"
-const PROGMEM char* kSecondStr = D_STR_SECOND; ///< "Second"
-const PROGMEM char* kSecondsStr = D_STR_SECONDS; ///< "Seconds"
-const PROGMEM char* kNowStr = D_STR_NOW; ///< "Now"
-const PROGMEM char* kThreeLetterDayOfWeekStr = D_STR_THREELETTERDAYS; ///<
+IRTEXT_CONST_STRING(kDayStr, D_STR_DAY); ///< "Day"
+IRTEXT_CONST_STRING(kDaysStr, D_STR_DAYS); ///< "Days"
+IRTEXT_CONST_STRING(kHourStr, D_STR_HOUR); ///< "Hour"
+IRTEXT_CONST_STRING(kHoursStr, D_STR_HOURS); ///< "Hours"
+IRTEXT_CONST_STRING(kMinuteStr, D_STR_MINUTE); ///< "Minute"
+IRTEXT_CONST_STRING(kMinutesStr, D_STR_MINUTES); ///< "Minutes"
+IRTEXT_CONST_STRING(kSecondStr, D_STR_SECOND); ///< "Second"
+IRTEXT_CONST_STRING(kSecondsStr, D_STR_SECONDS); ///< "Seconds"
+IRTEXT_CONST_STRING(kNowStr, D_STR_NOW); ///< "Now"
+IRTEXT_CONST_STRING(kThreeLetterDayOfWeekStr, D_STR_THREELETTERDAYS); ///<
///< "SunMonTueWedThuFriSat"
-const PROGMEM char* kYesStr = D_STR_YES; ///< "Yes"
-const PROGMEM char* kNoStr = D_STR_NO; ///< "No"
-const PROGMEM char* kTrueStr = D_STR_TRUE; ///< "True"
-const PROGMEM char* kFalseStr = D_STR_FALSE; ///< "False"
+IRTEXT_CONST_STRING(kYesStr, D_STR_YES); ///< "Yes"
+IRTEXT_CONST_STRING(kNoStr, D_STR_NO); ///< "No"
+IRTEXT_CONST_STRING(kTrueStr, D_STR_TRUE); ///< "True"
+IRTEXT_CONST_STRING(kFalseStr, D_STR_FALSE); ///< "False"
-const PROGMEM char* kRepeatStr = D_STR_REPEAT; ///< "Repeat"
-const PROGMEM char* kCodeStr = D_STR_CODE; ///< "Code"
-const PROGMEM char* kBitsStr = D_STR_BITS; ///< "Bits"
+IRTEXT_CONST_STRING(kRepeatStr, D_STR_REPEAT); ///< "Repeat"
+IRTEXT_CONST_STRING(kCodeStr, D_STR_CODE); ///< "Code"
+IRTEXT_CONST_STRING(kBitsStr, D_STR_BITS); ///< "Bits"
+
+// Model Names
+IRTEXT_CONST_STRING(kYaw1fStr, D_STR_YAW1F); ///< "YAW1F"
+IRTEXT_CONST_STRING(kYbofbStr, D_STR_YBOFB); ///< "YBOFB"
+IRTEXT_CONST_STRING(kV9014557AStr, D_STR_V9014557_A); ///< "V9014557-A"
+IRTEXT_CONST_STRING(kV9014557BStr, D_STR_V9014557_B); ///< "V9014557-B"
+IRTEXT_CONST_STRING(kRlt0541htaaStr, D_STR_RLT0541HTA_A); ///< "R-LT0541-HTA-A"
+IRTEXT_CONST_STRING(kRlt0541htabStr, D_STR_RLT0541HTA_B); ///< "R-LT0541-HTA-B"
+IRTEXT_CONST_STRING(kArrah2eStr, D_STR_ARRAH2E); ///< "ARRAH2E"
+IRTEXT_CONST_STRING(kArdb1Str, D_STR_ARDB1); ///< "ARDB1"
+IRTEXT_CONST_STRING(kArreb1eStr, D_STR_ARREB1E); ///< "ARREB1E"
+IRTEXT_CONST_STRING(kArjw2Str, D_STR_ARJW2); ///< "ARJW2"
+IRTEXT_CONST_STRING(kArry4Str, D_STR_ARRY4); ///< "ARRY4"
+IRTEXT_CONST_STRING(kArrew4eStr, D_STR_ARREW4E); ///< "ARREW4E"
+IRTEXT_CONST_STRING(kGe6711ar2853mStr, D_STR_GE6711AR2853M); ///<
+ ///< "GE6711AR2853M"
+IRTEXT_CONST_STRING(kAkb75215403Str, D_STR_AKB75215403); ///< "AKB75215403"
+IRTEXT_CONST_STRING(kAkb74955603Str, D_STR_AKB74955603); ///< "AKB74955603"
+IRTEXT_CONST_STRING(kAkb73757604Str, D_STR_AKB73757604); ///< "AKB73757604"
+IRTEXT_CONST_STRING(kKkg9ac1Str, D_STR_KKG9AC1); ///< "KKG9AC1"
+IRTEXT_CONST_STRING(kKkg29ac1Str, D_STR_KKG29AC1); ///< "KKG29AC1"
+IRTEXT_CONST_STRING(kLkeStr, D_STR_LKE); ///< "LKE"
+IRTEXT_CONST_STRING(kNkeStr, D_STR_NKE); ///< "NKE"
+IRTEXT_CONST_STRING(kDkeStr, D_STR_DKE); ///< "DKE"
+IRTEXT_CONST_STRING(kPkrStr, D_STR_PKR); ///< "PKR"
+IRTEXT_CONST_STRING(kJkeStr, D_STR_JKE); ///< "JKE"
+IRTEXT_CONST_STRING(kCkpStr, D_STR_CKP); ///< "CKP"
+IRTEXT_CONST_STRING(kRkrStr, D_STR_RKR); ///< "RKR"
+IRTEXT_CONST_STRING(kPanasonicLkeStr, D_STR_PANASONICLKE); ///< "PANASONICLKE"
+IRTEXT_CONST_STRING(kPanasonicNkeStr, D_STR_PANASONICNKE); ///< "PANASONICNKE"
+IRTEXT_CONST_STRING(kPanasonicDkeStr, D_STR_PANASONICDKE); ///< "PANASONICDKE"
+IRTEXT_CONST_STRING(kPanasonicPkrStr, D_STR_PANASONICPKR); ///< "PANASONICPKR"
+IRTEXT_CONST_STRING(kPanasonicJkeStr, D_STR_PANASONICJKE); ///< "PANASONICJKE"
+IRTEXT_CONST_STRING(kPanasonicCkpStr, D_STR_PANASONICCKP); ///< "PANASONICCKP"
+IRTEXT_CONST_STRING(kPanasonicRkrStr, D_STR_PANASONICRKR); ///< "PANASONICRKR"
+IRTEXT_CONST_STRING(kA907Str, D_STR_A907); ///< "A907"
+IRTEXT_CONST_STRING(kA705Str, D_STR_A705); ///< "A705"
+IRTEXT_CONST_STRING(kA903Str, D_STR_A903); ///< "A903"
+IRTEXT_CONST_STRING(kTac09chsdStr, D_STR_TAC09CHSD); ///< "TAC09CHSD"
+IRTEXT_CONST_STRING(kGz055be1Str, D_STR_GZ055BE1); ///< "GZ055BE1"
+IRTEXT_CONST_STRING(k122lzfStr, D_STR_122LZF); ///< "122LZF"
+IRTEXT_CONST_STRING(kDg11j13aStr, D_STR_DG11J13A); ///< "DG11J13A"
+IRTEXT_CONST_STRING(kDg11j104Str, D_STR_DG11J104); ///< "DG11J104"
+IRTEXT_CONST_STRING(kDg11j191Str, D_STR_DG11J191); ///< "DG11J191"
// Protocol Names
// Needs to be in decode_type_t order.
-const PROGMEM char *kAllProtocolNamesStr =
+IRTEXT_CONST_BLOB_DECL(kAllProtocolNamesStr) {
D_STR_UNUSED "\x0"
D_STR_RC5 "\x0"
D_STR_RC6 "\x0"
@@ -293,5 +379,11 @@ const PROGMEM char *kAllProtocolNamesStr =
D_STR_TROTEC_3550 "\x0"
D_STR_SANYO_AC88 "\x0"
D_STR_BOSE "\x0"
+ D_STR_ARRIS "\x0"
+ D_STR_RHOSS "\x0"
+ D_STR_AIRTON "\x0"
///< New protocol strings should be added just above this line.
- "\x0"; ///< This string requires double null termination.
+ "\x0" ///< This string requires double null termination.
+};
+
+IRTEXT_CONST_BLOB_PTR(kAllProtocolNamesStr);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.h
index 55840688d..ee8ea5934 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRtext.h
@@ -12,158 +12,224 @@
// Constant text to be shared across all object files.
// This means there is only one copy of the character/string/text etc.
-extern char kTimeSep;
-extern const char* k10CHeatStr;
-extern const char* k3DStr;
-extern const char* k6thSenseStr;
-extern const char* k8CHeatStr;
-extern const char* kAirFlowStr;
-extern const char *kAllProtocolNamesStr;
-extern const char* kAutomaticStr;
-extern const char* kAutoStr;
-extern const char* kBeepStr;
-extern const char* kBitsStr;
-extern const char* kBottomStr;
-extern const char* kBreezeStr;
-extern const char* kButtonStr;
-extern const char* kCancelStr;
-extern const char* kCeilingStr;
-extern const char* kCelsiusFahrenheitStr;
-extern const char* kCelsiusStr;
-extern const char* kCentreStr;
-extern const char* kChangeStr;
-extern const char* kCirculateStr;
-extern const char* kCleanStr;
-extern const char* kClockStr;
-extern const char* kCodeStr;
-extern const char* kColonSpaceStr;
-extern const char* kComfortStr;
-extern const char* kCommandStr;
-extern const char* kCommaSpaceStr;
-extern const char* kCoolStr;
-extern const char* kDaysStr;
-extern const char* kDayStr;
-extern const char* kDisplayTempStr;
-extern const char* kDownStr;
-extern const char* kDryStr;
-extern const char* kEconoStr;
-extern const char* kEconoToggleStr;
-extern const char* kEyeAutoStr;
-extern const char* kEyeStr;
-extern const char* kFalseStr;
-extern const char* kFanOnlyStr;
-extern const char* kFanStr;
-extern const char* kFastStr;
-extern const char* kFilterStr;
-extern const char* kFixedStr;
-extern const char* kFollowStr;
-extern const char* kFreshStr;
-extern const char* kHealthStr;
-extern const char* kHeatStr;
-extern const char* kHighestStr;
-extern const char* kHighStr;
-extern const char* kHiStr;
-extern const char* kHoldStr;
-extern const char* kHoursStr;
-extern const char* kHourStr;
-extern const char* kHumidStr;
-extern const char* kIdStr;
-extern const char* kIFeelStr;
-extern const char* kInsideStr;
-extern const char* kIonStr;
-extern const char* kLastStr;
-extern const char* kLeftMaxStr;
-extern const char* kLeftStr;
-extern const char* kLightStr;
-extern const char* kLightToggleStr;
-extern const char* kLoStr;
-extern const char* kLoudStr;
-extern const char* kLowerStr;
-extern const char* kLowestStr;
-extern const char* kLowStr;
-extern const char* kManualStr;
-extern const char* kMaximumStr;
-extern const char* kMaxLeftStr;
-extern const char* kMaxRightStr;
-extern const char* kMaxStr;
-extern const char* kMediumStr;
-extern const char* kMedStr;
-extern const char* kMiddleStr;
-extern const char* kMidStr;
-extern const char* kMinimumStr;
-extern const char* kMinStr;
-extern const char* kMinutesStr;
-extern const char* kMinuteStr;
-extern const char* kModelStr;
-extern const char* kModeStr;
-extern const char* kMouldStr;
-extern const char* kMoveStr;
-extern const char* kNAStr;
-extern const char* kNightStr;
-extern const char* kNoStr;
-extern const char* kNowStr;
-extern const char* kOffStr;
-extern const char* kOffTimerStr;
-extern const char* kOnStr;
-extern const char* kOnTimerStr;
-extern const char* kOutsideQuietStr;
-extern const char* kOutsideStr;
-extern const char* kPowerButtonStr;
-extern const char* kPowerfulStr;
-extern const char* kPowerStr;
-extern const char* kPowerToggleStr;
-extern const char* kPreviousPowerStr;
-extern const char* kProtocolStr;
-extern const char* kPurifyStr;
-extern const char* kQuietStr;
-extern const char* kRecycleStr;
-extern const char* kRepeatStr;
-extern const char* kRightMaxStr;
-extern const char* kRightStr;
-extern const char* kRoomStr;
-extern const char* kSaveStr;
-extern const char* kSecondsStr;
-extern const char* kSecondStr;
-extern const char* kSensorStr;
-extern const char* kSensorTempStr;
-extern const char* kSetStr;
-extern const char* kSilentStr;
-extern const char* kSleepStr;
-extern const char* kSleepTimerStr;
-extern const char* kSlowStr;
-extern const char* kSpaceLBraceStr;
-extern const char* kSpecialStr;
-extern const char* kStartStr;
-extern const char* kStepStr;
-extern const char* kStopStr;
-extern const char* kSuperStr;
-extern const char* kSwingHStr;
-extern const char* kSwingStr;
-extern const char* kSwingVModeStr;
-extern const char* kSwingVStr;
-extern const char* kSwingVToggleStr;
-extern const char* kTempDownStr;
-extern const char* kTempStr;
-extern const char* kTempUpStr;
-extern const char* kThreeLetterDayOfWeekStr;
-extern const char* kTimerModeStr;
-extern const char* kTimerStr;
-extern const char* kToggleStr;
-extern const char* kTopStr;
-extern const char* kTrueStr;
-extern const char* kTurboStr;
-extern const char* kTurboToggleStr;
-extern const char* kTypeStr;
-extern const char* kUnknownStr;
-extern const char* kUpperStr;
-extern const char* kUpStr;
-extern const char* kVaneStr;
-extern const char* kWallStr;
-extern const char* kWeeklyTimerStr;
-extern const char* kWideStr;
-extern const char* kWifiStr;
-extern const char* kXFanStr;
-extern const char* kYesStr;
-extern const char* kZoneFollowStr;
+#ifdef ESP8266
+class __FlashStringHelper;
+#define IRTEXT_CONST_PTR_CAST(PTR)\
+ reinterpret_cast(PTR)
+#define IRTEXT_CONST_PTR(NAME) const __FlashStringHelper* const NAME
+#else // ESP8266
+#define IRTEXT_CONST_PTR_CAST(PTR) PTR
+#define IRTEXT_CONST_PTR(NAME) const char* const NAME
+#endif // ESP8266
+
+extern const char kTimeSep;
+extern IRTEXT_CONST_PTR(k0Str);
+extern IRTEXT_CONST_PTR(k10CHeatStr);
+extern IRTEXT_CONST_PTR(k122lzfStr);
+extern IRTEXT_CONST_PTR(k1Str);
+extern IRTEXT_CONST_PTR(k3DStr);
+extern IRTEXT_CONST_PTR(k6thSenseStr);
+extern IRTEXT_CONST_PTR(k8CHeatStr);
+extern IRTEXT_CONST_PTR(kA705Str);
+extern IRTEXT_CONST_PTR(kA903Str);
+extern IRTEXT_CONST_PTR(kA907Str);
+extern IRTEXT_CONST_PTR(kAirFlowStr);
+extern IRTEXT_CONST_PTR(kAkb73757604Str);
+extern IRTEXT_CONST_PTR(kAkb74955603Str);
+extern IRTEXT_CONST_PTR(kAkb75215403Str);
+extern IRTEXT_CONST_PTR(kArdb1Str);
+extern IRTEXT_CONST_PTR(kArjw2Str);
+extern IRTEXT_CONST_PTR(kArrah2eStr);
+extern IRTEXT_CONST_PTR(kArreb1eStr);
+extern IRTEXT_CONST_PTR(kArrew4eStr);
+extern IRTEXT_CONST_PTR(kArry4Str);
+extern IRTEXT_CONST_PTR(kAutomaticStr);
+extern IRTEXT_CONST_PTR(kAutoStr);
+extern IRTEXT_CONST_PTR(kBeepStr);
+extern IRTEXT_CONST_PTR(kBitsStr);
+extern IRTEXT_CONST_PTR(kBottomStr);
+extern IRTEXT_CONST_PTR(kBreezeStr);
+extern IRTEXT_CONST_PTR(kButtonStr);
+extern IRTEXT_CONST_PTR(kCancelStr);
+extern IRTEXT_CONST_PTR(kCeilingStr);
+extern IRTEXT_CONST_PTR(kCelsiusFahrenheitStr);
+extern IRTEXT_CONST_PTR(kCelsiusStr);
+extern IRTEXT_CONST_PTR(kCentreStr);
+extern IRTEXT_CONST_PTR(kChangeStr);
+extern IRTEXT_CONST_PTR(kCirculateStr);
+extern IRTEXT_CONST_PTR(kCkpStr);
+extern IRTEXT_CONST_PTR(kCleanStr);
+extern IRTEXT_CONST_PTR(kClockStr);
+extern IRTEXT_CONST_PTR(kCodeStr);
+extern IRTEXT_CONST_PTR(kColonSpaceStr);
+extern IRTEXT_CONST_PTR(kComfortStr);
+extern IRTEXT_CONST_PTR(kCommandStr);
+extern IRTEXT_CONST_PTR(kCommaSpaceStr);
+extern IRTEXT_CONST_PTR(kCoolingStr);
+extern IRTEXT_CONST_PTR(kCoolStr);
+extern IRTEXT_CONST_PTR(kDashStr);
+extern IRTEXT_CONST_PTR(kDaysStr);
+extern IRTEXT_CONST_PTR(kDayStr);
+extern IRTEXT_CONST_PTR(kDehumidifyStr);
+extern IRTEXT_CONST_PTR(kDg11j104Str);
+extern IRTEXT_CONST_PTR(kDg11j13aStr);
+extern IRTEXT_CONST_PTR(kDg11j191Str);
+extern IRTEXT_CONST_PTR(kDisplayTempStr);
+extern IRTEXT_CONST_PTR(kDkeStr);
+extern IRTEXT_CONST_PTR(kDownStr);
+extern IRTEXT_CONST_PTR(kDryingStr);
+extern IRTEXT_CONST_PTR(kDryStr);
+extern IRTEXT_CONST_PTR(kEconoStr);
+extern IRTEXT_CONST_PTR(kEconoToggleStr);
+extern IRTEXT_CONST_PTR(kEyeAutoStr);
+extern IRTEXT_CONST_PTR(kEyeStr);
+extern IRTEXT_CONST_PTR(kFalseStr);
+extern IRTEXT_CONST_PTR(kFanOnlyNoSpaceStr);
+extern IRTEXT_CONST_PTR(kFan_OnlyStr);
+extern IRTEXT_CONST_PTR(kFanOnlyStr);
+extern IRTEXT_CONST_PTR(kFanOnlyWithSpaceStr);
+extern IRTEXT_CONST_PTR(kFanStr);
+extern IRTEXT_CONST_PTR(kFastStr);
+extern IRTEXT_CONST_PTR(kFilterStr);
+extern IRTEXT_CONST_PTR(kFixedStr);
+extern IRTEXT_CONST_PTR(kFollowStr);
+extern IRTEXT_CONST_PTR(kFreshStr);
+extern IRTEXT_CONST_PTR(kGe6711ar2853mStr);
+extern IRTEXT_CONST_PTR(kGz055be1Str);
+extern IRTEXT_CONST_PTR(kHealthStr);
+extern IRTEXT_CONST_PTR(kHeatingStr);
+extern IRTEXT_CONST_PTR(kHeatStr);
+extern IRTEXT_CONST_PTR(kHighestStr);
+extern IRTEXT_CONST_PTR(kHighStr);
+extern IRTEXT_CONST_PTR(kHiStr);
+extern IRTEXT_CONST_PTR(kHoldStr);
+extern IRTEXT_CONST_PTR(kHoursStr);
+extern IRTEXT_CONST_PTR(kHourStr);
+extern IRTEXT_CONST_PTR(kHumidStr);
+extern IRTEXT_CONST_PTR(kIdStr);
+extern IRTEXT_CONST_PTR(kIFeelStr);
+extern IRTEXT_CONST_PTR(kInsideStr);
+extern IRTEXT_CONST_PTR(kIonStr);
+extern IRTEXT_CONST_PTR(kJkeStr);
+extern IRTEXT_CONST_PTR(kKkg29ac1Str);
+extern IRTEXT_CONST_PTR(kKkg9ac1Str);
+extern IRTEXT_CONST_PTR(kLastStr);
+extern IRTEXT_CONST_PTR(kLeftMaxNoSpaceStr);
+extern IRTEXT_CONST_PTR(kLeftMaxStr);
+extern IRTEXT_CONST_PTR(kLeftStr);
+extern IRTEXT_CONST_PTR(kLightStr);
+extern IRTEXT_CONST_PTR(kLightToggleStr);
+extern IRTEXT_CONST_PTR(kLkeStr);
+extern IRTEXT_CONST_PTR(kLoStr);
+extern IRTEXT_CONST_PTR(kLockStr);
+extern IRTEXT_CONST_PTR(kLoudStr);
+extern IRTEXT_CONST_PTR(kLowerStr);
+extern IRTEXT_CONST_PTR(kLowestStr);
+extern IRTEXT_CONST_PTR(kLowStr);
+extern IRTEXT_CONST_PTR(kManualStr);
+extern IRTEXT_CONST_PTR(kMaximumStr);
+extern IRTEXT_CONST_PTR(kMaxLeftNoSpaceStr);
+extern IRTEXT_CONST_PTR(kMaxLeftStr);
+extern IRTEXT_CONST_PTR(kMaxRightNoSpaceStr);
+extern IRTEXT_CONST_PTR(kMaxRightStr);
+extern IRTEXT_CONST_PTR(kMaxStr);
+extern IRTEXT_CONST_PTR(kMediumStr);
+extern IRTEXT_CONST_PTR(kMedStr);
+extern IRTEXT_CONST_PTR(kMiddleStr);
+extern IRTEXT_CONST_PTR(kMidStr);
+extern IRTEXT_CONST_PTR(kMinimumStr);
+extern IRTEXT_CONST_PTR(kMinStr);
+extern IRTEXT_CONST_PTR(kMinutesStr);
+extern IRTEXT_CONST_PTR(kMinuteStr);
+extern IRTEXT_CONST_PTR(kModelStr);
+extern IRTEXT_CONST_PTR(kModeStr);
+extern IRTEXT_CONST_PTR(kMouldStr);
+extern IRTEXT_CONST_PTR(kMoveStr);
+extern IRTEXT_CONST_PTR(kNAStr);
+extern IRTEXT_CONST_PTR(kNightStr);
+extern IRTEXT_CONST_PTR(kNkeStr);
+extern IRTEXT_CONST_PTR(kNoStr);
+extern IRTEXT_CONST_PTR(kNowStr);
+extern IRTEXT_CONST_PTR(kOffStr);
+extern IRTEXT_CONST_PTR(kOffTimerStr);
+extern IRTEXT_CONST_PTR(kOnStr);
+extern IRTEXT_CONST_PTR(kOnTimerStr);
+extern IRTEXT_CONST_PTR(kOutsideQuietStr);
+extern IRTEXT_CONST_PTR(kOutsideStr);
+extern IRTEXT_CONST_PTR(kPanasonicCkpStr);
+extern IRTEXT_CONST_PTR(kPanasonicDkeStr);
+extern IRTEXT_CONST_PTR(kPanasonicJkeStr);
+extern IRTEXT_CONST_PTR(kPanasonicLkeStr);
+extern IRTEXT_CONST_PTR(kPanasonicNkeStr);
+extern IRTEXT_CONST_PTR(kPanasonicPkrStr);
+extern IRTEXT_CONST_PTR(kPanasonicRkrStr);
+extern IRTEXT_CONST_PTR(kPkrStr);
+extern IRTEXT_CONST_PTR(kPowerButtonStr);
+extern IRTEXT_CONST_PTR(kPowerfulStr);
+extern IRTEXT_CONST_PTR(kPowerStr);
+extern IRTEXT_CONST_PTR(kPowerToggleStr);
+extern IRTEXT_CONST_PTR(kPreviousPowerStr);
+extern IRTEXT_CONST_PTR(kProtocolStr);
+extern IRTEXT_CONST_PTR(kPurifyStr);
+extern IRTEXT_CONST_PTR(kQuietStr);
+extern IRTEXT_CONST_PTR(kRecycleStr);
+extern IRTEXT_CONST_PTR(kRepeatStr);
+extern IRTEXT_CONST_PTR(kRightMaxNoSpaceStr);
+extern IRTEXT_CONST_PTR(kRightMaxStr);
+extern IRTEXT_CONST_PTR(kRightStr);
+extern IRTEXT_CONST_PTR(kRkrStr);
+extern IRTEXT_CONST_PTR(kRlt0541htaaStr);
+extern IRTEXT_CONST_PTR(kRlt0541htabStr);
+extern IRTEXT_CONST_PTR(kRoomStr);
+extern IRTEXT_CONST_PTR(kSaveStr);
+extern IRTEXT_CONST_PTR(kSecondsStr);
+extern IRTEXT_CONST_PTR(kSecondStr);
+extern IRTEXT_CONST_PTR(kSensorStr);
+extern IRTEXT_CONST_PTR(kSensorTempStr);
+extern IRTEXT_CONST_PTR(kSetStr);
+extern IRTEXT_CONST_PTR(kSilentStr);
+extern IRTEXT_CONST_PTR(kSleepStr);
+extern IRTEXT_CONST_PTR(kSleepTimerStr);
+extern IRTEXT_CONST_PTR(kSlowStr);
+extern IRTEXT_CONST_PTR(kSpaceLBraceStr);
+extern IRTEXT_CONST_PTR(kSpecialStr);
+extern IRTEXT_CONST_PTR(kStartStr);
+extern IRTEXT_CONST_PTR(kStepStr);
+extern IRTEXT_CONST_PTR(kStopStr);
+extern IRTEXT_CONST_PTR(kSuperStr);
+extern IRTEXT_CONST_PTR(kSwingHStr);
+extern IRTEXT_CONST_PTR(kSwingStr);
+extern IRTEXT_CONST_PTR(kSwingVModeStr);
+extern IRTEXT_CONST_PTR(kSwingVStr);
+extern IRTEXT_CONST_PTR(kSwingVToggleStr);
+extern IRTEXT_CONST_PTR(kTac09chsdStr);
+extern IRTEXT_CONST_PTR(kTempDownStr);
+extern IRTEXT_CONST_PTR(kTempStr);
+extern IRTEXT_CONST_PTR(kTempUpStr);
+extern IRTEXT_CONST_PTR(kThreeLetterDayOfWeekStr);
+extern IRTEXT_CONST_PTR(kTimerModeStr);
+extern IRTEXT_CONST_PTR(kTimerStr);
+extern IRTEXT_CONST_PTR(kToggleStr);
+extern IRTEXT_CONST_PTR(kTopStr);
+extern IRTEXT_CONST_PTR(kTrueStr);
+extern IRTEXT_CONST_PTR(kTurboStr);
+extern IRTEXT_CONST_PTR(kTurboToggleStr);
+extern IRTEXT_CONST_PTR(kTypeStr);
+extern IRTEXT_CONST_PTR(kUnknownStr);
+extern IRTEXT_CONST_PTR(kUpperStr);
+extern IRTEXT_CONST_PTR(kUpStr);
+extern IRTEXT_CONST_PTR(kV9014557AStr);
+extern IRTEXT_CONST_PTR(kV9014557BStr);
+extern IRTEXT_CONST_PTR(kVaneStr);
+extern IRTEXT_CONST_PTR(kWallStr);
+extern IRTEXT_CONST_PTR(kWeeklyTimerStr);
+extern IRTEXT_CONST_PTR(kWideStr);
+extern IRTEXT_CONST_PTR(kWifiStr);
+extern IRTEXT_CONST_PTR(kXFanStr);
+extern IRTEXT_CONST_PTR(kYaw1fStr);
+extern IRTEXT_CONST_PTR(kYbofbStr);
+extern IRTEXT_CONST_PTR(kYesStr);
+extern IRTEXT_CONST_PTR(kZoneFollowStr);
+extern IRTEXT_CONST_PTR(kAllProtocolNamesStr);
#endif // IRTEXT_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp
index f9892d2a4..d3a83c507 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.cpp
@@ -1,4 +1,4 @@
-// Copyright 2017 David Conran
+// Copyright 2017-2021 David Conran
#include "IRutils.h"
#ifndef UNIT_TEST
@@ -17,6 +17,27 @@
#include "IRsend.h"
#include "IRtext.h"
+// On the ESP8266 platform we need to use a set of ..._P functions
+// to handle the strings stored in the flash address space.
+#ifndef STRCASECMP
+#if defined(ESP8266)
+#define STRCASECMP(LHS, RHS) \
+ strcasecmp_P(LHS, reinterpret_cast(RHS))
+#else // ESP8266
+#define STRCASECMP strcasecmp
+#endif // ESP8266
+#endif // STRCASECMP
+#ifndef STRLEN
+#if defined(ESP8266)
+#define STRLEN(PTR) strlen_P(PTR)
+#else // ESP8266
+#define STRLEN(PTR) strlen(PTR)
+#endif // ESP8266
+#endif // STRLEN
+#ifndef FPSTR
+#define FPSTR(X) X
+#endif // FPSTR
+
/// Reverse the order of the requested least significant nr. of bits.
/// @param[in] input Bit pattern/integer to reverse.
/// @param[in] nbits Nr. of bits to reverse. (LSB -> MSB)
@@ -74,7 +95,10 @@ String uint64ToString(uint64_t input, uint8_t base) {
/// @returns A String representation of the integer.
String int64ToString(int64_t input, uint8_t base) {
if (input < 0) {
- return "-" + uint64ToString(-input, base);
+ // Using String(kDashStr) to keep compatible with old arduino
+ // frameworks. Not needed with 3.0.2.
+ ///> @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1639#issuecomment-944906016
+ return String(kDashStr) + uint64ToString(-input, base);
}
return uint64ToString(input, base);
}
@@ -93,21 +117,20 @@ void serialPrintUint64(uint64_t input, uint8_t base) {
/// @param[in] str A C-style string containing a protocol name or number.
/// @return A decode_type_t enum. (decode_type_t::UNKNOWN if no match.)
decode_type_t strToDecodeType(const char * const str) {
- const char *ptr = kAllProtocolNamesStr;
- uint16_t length = strlen(ptr);
+ auto *ptr = reinterpret_cast(kAllProtocolNamesStr);
+ uint16_t length = STRLEN(ptr);
for (uint16_t i = 0; length; i++) {
- if (!strcasecmp(str, ptr)) return (decode_type_t)i;
+ if (!STRCASECMP(str, ptr)) return (decode_type_t)i;
ptr += length + 1;
- length = strlen(ptr);
+ length = STRLEN(ptr);
}
-
// Handle integer values of the type by converting to a string and back again.
decode_type_t result = strToDecodeType(
typeToString((decode_type_t)atoi(str)).c_str());
if (result > 0)
return result;
- else
- return decode_type_t::UNKNOWN;
+
+ return decode_type_t::UNKNOWN;
}
/// Convert a protocol type (enum etc) to a human readable string.
@@ -117,16 +140,20 @@ decode_type_t strToDecodeType(const char * const str) {
String typeToString(const decode_type_t protocol, const bool isRepeat) {
String result = "";
result.reserve(30); // Size of longest protocol name + " (Repeat)"
- const char *ptr = kAllProtocolNamesStr;
if (protocol > kLastDecodeType || protocol == decode_type_t::UNKNOWN) {
result = kUnknownStr;
} else {
- for (uint16_t i = 0; i <= protocol && strlen(ptr); i++) {
- if (i == protocol) {
- result = ptr;
- break;
+ auto *ptr = reinterpret_cast(kAllProtocolNamesStr);
+ if (protocol > kLastDecodeType || protocol == decode_type_t::UNKNOWN) {
+ result = kUnknownStr;
+ } else {
+ for (uint16_t i = 0; i <= protocol && STRLEN(ptr); i++) {
+ if (i == protocol) {
+ result = FPSTR(ptr);
+ break;
+ }
+ ptr += STRLEN(ptr) + 1;
}
- ptr += strlen(ptr) + 1;
}
}
if (isRepeat) {
@@ -175,6 +202,7 @@ bool hasACState(const decode_type_t protocol) {
case MWM:
case NEOCLIMA:
case PANASONIC_AC:
+ case RHOSS:
case SAMSUNG_AC:
case SANYO_AC:
case SANYO_AC88:
@@ -318,7 +346,7 @@ String resultToTimingInfo(const decode_results * const results) {
for (uint16_t i = 1; i < results->rawlen; i++) {
if (i % 2 == 0)
- output += '-'; // even
+ output += kDashStr; // even
else
output += F(" +"); // odd
value = uint64ToString(results->rawbuf[i] * kRawTick);
@@ -515,7 +543,18 @@ namespace irutils {
/// @return The resulting String.
String addBoolToString(const bool value, const String label,
const bool precomma) {
- return addLabeledString((value ? kOnStr : kOffStr), label, precomma);
+ return addLabeledString(value ? kOnStr : kOffStr, label, precomma);
+ }
+
+ /// Create a String with a colon separated toggle flag suitable for Humans.
+ /// e.g. "Light: Toggle", "Light: -"
+ /// @param[in] toggle The value of the toggle to come after the label.
+ /// @param[in] label The label to precede the value.
+ /// @param[in] precomma Should the output string start with ", " or not?
+ /// @return The resulting String.
+ String addToggleToString(const bool toggle, const String label,
+ const bool precomma) {
+ return addLabeledString(toggle ? kToggleStr : kDashStr, label, precomma);
}
/// Create a String with a colon separated labeled Integer suitable for
@@ -547,75 +586,101 @@ namespace irutils {
/// @param[in] protocol The IR protocol.
/// @param[in] model The model number for that protocol.
/// @return The resulting String.
+ /// @note After adding a new model you should update IRac::strToModel() too.
String modelToStr(const decode_type_t protocol, const int16_t model) {
switch (protocol) {
case decode_type_t::FUJITSU_AC:
switch (model) {
- case fujitsu_ac_remote_model_t::ARRAH2E: return F("ARRAH2E");
- case fujitsu_ac_remote_model_t::ARDB1: return F("ARDB1");
- case fujitsu_ac_remote_model_t::ARREB1E: return F("ARREB1E");
- case fujitsu_ac_remote_model_t::ARJW2: return F("ARJW2");
- case fujitsu_ac_remote_model_t::ARRY4: return F("ARRY4");
- case fujitsu_ac_remote_model_t::ARREW4E: return F("ARREW4E");
- default: return kUnknownStr;
+ case fujitsu_ac_remote_model_t::ARRAH2E: return kArrah2eStr;
+ case fujitsu_ac_remote_model_t::ARDB1: return kArdb1Str;
+ case fujitsu_ac_remote_model_t::ARREB1E: return kArreb1eStr;
+ case fujitsu_ac_remote_model_t::ARJW2: return kArjw2Str;
+ case fujitsu_ac_remote_model_t::ARRY4: return kArry4Str;
+ case fujitsu_ac_remote_model_t::ARREW4E: return kArrew4eStr;
+ default: return kUnknownStr;
}
break;
case decode_type_t::GREE:
switch (model) {
- case gree_ac_remote_model_t::YAW1F: return F("YAW1F");
- case gree_ac_remote_model_t::YBOFB: return F("YBOFB");
- default: return kUnknownStr;
+ case gree_ac_remote_model_t::YAW1F: return kYaw1fStr;
+ case gree_ac_remote_model_t::YBOFB: return kYbofbStr;
+ default: return kUnknownStr;
+ }
+ break;
+ case decode_type_t::HAIER_AC176:
+ switch (model) {
+ case haier_ac176_remote_model_t::V9014557_A:
+ return kV9014557AStr;
+ case haier_ac176_remote_model_t::V9014557_B:
+ return kV9014557BStr;
+ default:
+ return kUnknownStr;
}
break;
case decode_type_t::HITACHI_AC1:
switch (model) {
case hitachi_ac1_remote_model_t::R_LT0541_HTA_A:
- return F("R-LT0541-HTA-A");
+ return kRlt0541htaaStr;
case hitachi_ac1_remote_model_t::R_LT0541_HTA_B:
- return F("R-LT0541-HTA-B");
- default: return kUnknownStr;
+ return kRlt0541htabStr;
+ default:
+ return kUnknownStr;
}
break;
case decode_type_t::LG:
case decode_type_t::LG2:
switch (model) {
- case lg_ac_remote_model_t::GE6711AR2853M: return F("GE6711AR2853M");
- case lg_ac_remote_model_t::AKB75215403: return F("AKB75215403");
- case lg_ac_remote_model_t::AKB74955603: return F("AKB74955603");
- case lg_ac_remote_model_t::AKB73757604: return F("AKB73757604");
- default: return kUnknownStr;
+ case lg_ac_remote_model_t::GE6711AR2853M: return kGe6711ar2853mStr;
+ case lg_ac_remote_model_t::AKB75215403: return kAkb75215403Str;
+ case lg_ac_remote_model_t::AKB74955603: return kAkb74955603Str;
+ case lg_ac_remote_model_t::AKB73757604: return kAkb73757604Str;
+ default: return kUnknownStr;
}
break;
- case decode_type_t::SHARP_AC:
+ case decode_type_t::MIRAGE:
switch (model) {
- case sharp_ac_remote_model_t::A907: return F("A907");
- case sharp_ac_remote_model_t::A705: return F("A705");
- case sharp_ac_remote_model_t::A903: return F("A903");
- default: return kUnknownStr;
+ case mirage_ac_remote_model_t::KKG9AC1: return kKkg9ac1Str;
+ case mirage_ac_remote_model_t::KKG29AC1: return kKkg29ac1Str;
+ default: return kUnknownStr;
}
break;
case decode_type_t::PANASONIC_AC:
switch (model) {
- case panasonic_ac_remote_model_t::kPanasonicLke: return F("LKE");
- case panasonic_ac_remote_model_t::kPanasonicNke: return F("NKE");
- case panasonic_ac_remote_model_t::kPanasonicDke: return F("DKE");
- case panasonic_ac_remote_model_t::kPanasonicJke: return F("JKE");
- case panasonic_ac_remote_model_t::kPanasonicCkp: return F("CKP");
- case panasonic_ac_remote_model_t::kPanasonicRkr: return F("RKR");
- default: return kUnknownStr;
+ case panasonic_ac_remote_model_t::kPanasonicLke: return kLkeStr;
+ case panasonic_ac_remote_model_t::kPanasonicNke: return kNkeStr;
+ case panasonic_ac_remote_model_t::kPanasonicDke: return kDkeStr;
+ case panasonic_ac_remote_model_t::kPanasonicJke: return kJkeStr;
+ case panasonic_ac_remote_model_t::kPanasonicCkp: return kCkpStr;
+ case panasonic_ac_remote_model_t::kPanasonicRkr: return kRkrStr;
+ default: return kUnknownStr;
+ }
+ break;
+ case decode_type_t::SHARP_AC:
+ switch (model) {
+ case sharp_ac_remote_model_t::A907: return kA907Str;
+ case sharp_ac_remote_model_t::A705: return kA705Str;
+ case sharp_ac_remote_model_t::A903: return kA903Str;
+ default: return kUnknownStr;
+ }
+ break;
+ case decode_type_t::TCL112AC:
+ switch (model) {
+ case tcl_ac_remote_model_t::TAC09CHSD: return kTac09chsdStr;
+ case tcl_ac_remote_model_t::GZ055BE1: return kGz055be1Str;
+ default: return kUnknownStr;
}
break;
case decode_type_t::VOLTAS:
switch (model) {
- case voltas_ac_remote_model_t::kVoltas122LZF: return F("122LZF");
- default: return kUnknownStr;
+ case voltas_ac_remote_model_t::kVoltas122LZF: return k122lzfStr;
+ default: return kUnknownStr;
}
break;
case decode_type_t::WHIRLPOOL_AC:
switch (model) {
- case whirlpool_ac_remote_model_t::DG11J13A: return F("DG11J13A");
- case whirlpool_ac_remote_model_t::DG11J191: return F("DG11J191");
- default: return kUnknownStr;
+ case whirlpool_ac_remote_model_t::DG11J13A: return kDg11j13aStr;
+ case whirlpool_ac_remote_model_t::DG11J191: return kDg11j191Str;
+ default: return kUnknownStr;
}
break;
default: return kUnknownStr;
@@ -690,8 +755,8 @@ namespace irutils {
if (mode == automatic) result += kAutoStr;
else if (mode == cool) result += kCoolStr;
else if (mode == heat) result += kHeatStr;
- else if (mode == dry) result += kDryStr;
- else if (mode == fan) result += kFanStr;
+ else if (mode == dry) result += kDryStr;
+ else if (mode == fan) result += kFanStr;
else
result += kUnknownStr;
return result + ')';
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.h
index fdda6d7ae..61fe8b269 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/IRutils.h
@@ -48,6 +48,8 @@ float fahrenheitToCelsius(const float deg);
namespace irutils {
String addBoolToString(const bool value, const String label,
const bool precomma = true);
+ String addToggleToString(const bool toggle, const String label,
+ const bool precomma = true);
String addIntToString(const uint16_t value, const String label,
const bool precomma = true);
String addSignedIntToString(const int16_t value, const String label,
@@ -97,10 +99,10 @@ namespace irutils {
bool getBit(const uint64_t data, const uint8_t position,
const uint8_t size = 64);
bool getBit(const uint8_t data, const uint8_t position);
-#define GETBIT8(a, b) (a & ((uint8_t)1 << b))
-#define GETBIT16(a, b) (a & ((uint16_t)1 << b))
-#define GETBIT32(a, b) (a & ((uint32_t)1 << b))
-#define GETBIT64(a, b) (a & ((uint64_t)1 << b))
+#define GETBIT8(a, b) ((a) & ((uint8_t)1 << (b)))
+#define GETBIT16(a, b) ((a) & ((uint16_t)1 << (b)))
+#define GETBIT32(a, b) ((a) & ((uint32_t)1 << (b)))
+#define GETBIT64(a, b) ((a) & ((uint64_t)1 << (b)))
#define GETBITS8(data, offset, size) \
(((data) & (((uint8_t)UINT8_MAX >> (8 - (size))) << (offset))) >> (offset))
#define GETBITS16(data, offset, size) \
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Airton.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Airton.cpp
new file mode 100644
index 000000000..507894f37
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Airton.cpp
@@ -0,0 +1,70 @@
+// Copyright 2021 David Conran (crankyoldgit)
+/// @file
+/// @brief Support for Airton protocol
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1670
+
+// Supports:
+// Brand: Airton, Model: SMVH09B-2A2A3NH ref. 409730 A/C
+// Brand: Airton, Model: RD1A1 remote
+
+#include "IRrecv.h"
+#include "IRsend.h"
+#include "IRutils.h"
+
+const uint16_t kAirtonHdrMark = 6630;
+const uint16_t kAirtonBitMark = 400;
+const uint16_t kAirtonHdrSpace = 3350;
+const uint16_t kAirtonOneSpace = 1260;
+const uint16_t kAirtonZeroSpace = 430;
+const uint16_t kAirtonFreq = 38000; // Hz. (Just a guess)
+
+#if SEND_AIRTON
+// Function should be safe up to 64 bits.
+/// Send a Airton formatted message.
+/// Status: STABLE / Confirmed working.
+/// @param[in] data containing the IR command.
+/// @param[in] nbits Nr. of bits to send. usually kAirtonBits
+/// @param[in] repeat Nr. of times the message is to be repeated.
+void IRsend::sendAirton(const uint64_t data, const uint16_t nbits,
+ const uint16_t repeat) {
+ sendGeneric(kAirtonHdrMark, kAirtonHdrSpace,
+ kAirtonBitMark, kAirtonOneSpace,
+ kAirtonBitMark, kAirtonZeroSpace,
+ kAirtonBitMark, kDefaultMessageGap,
+ data, nbits, kAirtonFreq, false, repeat, kDutyDefault);
+}
+#endif // SEND_AIRTON
+
+#if DECODE_AIRTON
+/// Decode the supplied Airton message.
+/// Status: STABLE / Confirmed working. LSBF ordering confirmed via temperature.
+/// @param[in,out] results Ptr to the data to decode & where to store the decode
+/// @param[in] offset The starting index to use when attempting to decode the
+/// raw data. Typically/Defaults to kStartOffset.
+/// @param[in] nbits The number of data bits to expect.
+/// @param[in] strict Flag indicating if we should perform strict matching.
+/// @return A boolean. True if it can decode it, false if it can't.
+bool IRrecv::decodeAirton(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ if (results->rawlen < 2 * nbits + kHeader + kFooter - offset)
+ return false; // Too short a message to match.
+ if (strict && nbits != kAirtonBits)
+ return false;
+
+ // Header + Data + Footer
+ if (!matchGeneric(&(results->rawbuf[offset]), &(results->value),
+ results->rawlen - offset, nbits,
+ kAirtonHdrMark, kAirtonHdrSpace,
+ kAirtonBitMark, kAirtonOneSpace,
+ kAirtonBitMark, kAirtonZeroSpace,
+ kAirtonBitMark, kDefaultMessageGap,
+ true, kUseDefTol, kMarkExcess, false)) return false;
+
+ // Success
+ results->decode_type = decode_type_t::AIRTON;
+ results->bits = nbits;
+ results->command = 0;
+ results->address = 0;
+ return true;
+}
+#endif // DECODE_AIRTON
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Arris.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Arris.cpp
new file mode 100644
index 000000000..5b39808c8
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Arris.cpp
@@ -0,0 +1,123 @@
+// Copyright 2021 David Conran
+#include "IRrecv.h"
+#include "IRsend.h"
+#include "IRutils.h"
+
+/// @file
+/// @brief Arris "Manchester code" based protocol.
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1595
+
+// Supports:
+// Brand: Arris, Model: VIP1113M Set-top box
+// Brand: Arris, Model: 120A V1.0 A18 remote
+
+const uint8_t kArrisOverhead = 2;
+const uint16_t kArrisHalfClockPeriod = 320; // uSeconds
+const uint16_t kArrisHdrMark = 8 * kArrisHalfClockPeriod; // uSeconds
+const uint16_t kArrisHdrSpace = 6 * kArrisHalfClockPeriod; // uSeconds
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1595#issuecomment-913755841
+// aka. 77184 uSeconds.
+const uint32_t kArrisGapSpace = 102144 - ((8 + 6 + kArrisBits * 2) *
+ kArrisHalfClockPeriod); // uSeconds
+const uint32_t kArrisReleaseToggle = 0x800008;
+const uint8_t kArrisChecksumSize = 4;
+const uint8_t kArrisCommandSize = 19;
+const uint8_t kArrisReleaseBit = kArrisChecksumSize + kArrisCommandSize;
+
+using irutils::sumNibbles;
+
+#if SEND_ARRIS
+/// Send an Arris Manchester Code formatted message.
+/// Status: STABLE / Confirmed working.
+/// @param[in] data The message to be sent.
+/// @param[in] nbits The number of bits of the message to be sent.
+/// @param[in] repeat The number of times the command is to be repeated.
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1595
+void IRsend::sendArris(const uint64_t data, const uint16_t nbits,
+ const uint16_t repeat) {
+ enableIROut(38);
+ for (uint16_t r = 0; r <= repeat; r++) {
+ // Header (part 1)
+ mark(kArrisHdrMark);
+ space(kArrisHdrSpace);
+ // Header (part 2) + Data + Footer
+ sendManchester(kArrisHalfClockPeriod * 2, 0, kArrisHalfClockPeriod,
+ 0, kArrisGapSpace, data, nbits);
+ }
+}
+
+/// Flip the toggle button release bits of an Arris message.
+/// Used to indicate a change of remote button's state. e.g. Press vs. Release.
+/// @param[in] data The existing Arris message.
+/// @return A data message suitable for use in sendArris() with the release bits
+/// flipped.
+uint32_t IRsend::toggleArrisRelease(const uint32_t data) {
+ return data ^ kArrisReleaseToggle;
+}
+
+/// Construct a raw 32-bit Arris message code from the supplied command &
+/// release setting.
+/// @param[in] command The command code.
+/// @param[in] release The button/command action: press (false), release (true)
+/// @return A raw 32-bit Arris message code suitable for sendArris() etc.
+/// @note Sequence of bits = header + release + command + checksum.
+uint32_t IRsend::encodeArris(const uint32_t command, const bool release) {
+ uint32_t result = 0x10000000;
+ irutils::setBits(&result, kArrisChecksumSize, kArrisCommandSize, command);
+ irutils::setBit(&result, kArrisReleaseBit, release);
+ return result + sumNibbles(result);
+}
+#endif // SEND_ARRIS
+
+#if DECODE_ARRIS
+/// Decode the supplied Arris "Manchester code" message.
+/// Status: STABLE / Confirmed working.
+/// @param[in,out] results Ptr to the data to decode & where to store the decode
+/// result.
+/// @param[in] offset The starting index to use when attempting to decode the
+/// raw data. Typically/Defaults to kStartOffset.
+/// @param[in] nbits The number of data bits to expect.
+/// @param[in] strict Flag indicating if we should perform strict matching.
+/// @return A boolean. True if it can decode it, false if it can't.
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1595
+bool IRrecv::decodeArris(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ if (results->rawlen < nbits + kArrisOverhead - offset)
+ return false; // Too short a message to match.
+
+ // Compliance
+ if (strict && nbits != kArrisBits)
+ return false; // Doesn't match our protocol defn.
+
+ // Header (part 1)
+ if (!matchMark(results->rawbuf[offset++], kArrisHdrMark)) return false;
+ if (!matchSpace(results->rawbuf[offset++], kArrisHdrSpace)) return false;
+
+ // Header (part 2) + Data
+ uint64_t data = 0;
+ if (!matchManchester(results->rawbuf + offset, &data,
+ results->rawlen - offset, nbits,
+ kArrisHalfClockPeriod * 2, 0,
+ kArrisHalfClockPeriod, 0, 0,
+ false, kUseDefTol, kMarkExcess, true, false))
+ return false;
+
+ // Compliance
+ if (strict)
+ // Validate the checksum.
+ if (GETBITS32(data, 0, kArrisChecksumSize) !=
+ sumNibbles(data >> kArrisChecksumSize))
+ return false;
+
+ // Success
+ results->decode_type = decode_type_t::ARRIS;
+ results->bits = nbits;
+ results->value = data;
+ // Set the address as the Release Bit for something useful.
+ results->address = static_cast(GETBIT32(data, kArrisReleaseBit));
+ // The last 4 bits are likely a checksum value, so skip those. Everything else
+ // after the release bit. e.g. Bits 10-28
+ results->command = GETBITS32(data, kArrisChecksumSize, kArrisCommandSize);
+ return true;
+}
+#endif // DECODE_ARRIS
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp
index 1c3a40a62..f5cacf0e7 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Coolix.cpp
@@ -611,7 +611,11 @@ String IRCoolixAC::toString(void) const {
result += addBoolToString(getZoneFollow(), kZoneFollowStr);
result += addLabeledString(
(getSensorTemp() == kCoolixSensorTempIgnoreCode)
- ? kOffStr : uint64ToString(getSensorTemp()) + 'C', kSensorTempStr);
+ // Encasing with String(blah) to keep compatible with old arduino
+ // frameworks. Not needed with 3.0.2.
+ ///> @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1639#issuecomment-944906016
+ ? kOffStr : String(uint64ToString(getSensorTemp()) + 'C'),
+ kSensorTempStr);
return result;
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.cpp
index fd70e4bd6..b4d670b88 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.cpp
@@ -1,4 +1,4 @@
-// Copyright 2018, 2019 David Conran
+// Copyright 2018-2021 David Conran
/// @file
/// @brief Support for Electra A/C protocols.
/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp
@@ -28,6 +28,7 @@ using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addFanToString;
using irutils::addTempToString;
+using irutils::addToggleToString;
#if SEND_ELECTRA_AC
/// Send a Electra A/C formatted message.
@@ -309,6 +310,52 @@ bool IRElectraAc::getTurbo(void) const {
return _.Turbo;
}
+/// Get the IFeel mode of the A/C.
+/// @return true, the setting is on. false, the setting is off.
+bool IRElectraAc::getIFeel(void) const { return _.IFeel; }
+
+/// Set the IFeel mode of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRElectraAc::setIFeel(const bool on) {
+ _.IFeel = on;
+ if (_.IFeel)
+ // Make sure there is a reasonable value in _.SensorTemp
+ setSensorTemp(getSensorTemp());
+ else
+ // Clear any previous stored temp..
+ _.SensorTemp = kElectraAcSensorMinTemp;
+}
+
+/// Get the silent Sensor Update setting of the message.
+/// i.e. Is this _just_ a sensor temp update message from the remote?
+/// @note The A/C just takes the sensor temp value from the message and
+/// will not follow any of the other settings in the message.
+/// @return true, the setting is on. false, the setting is off.
+bool IRElectraAc::getSensorUpdate(void) const { return _.SensorUpdate; }
+
+/// Set the silent Sensor Update setting of the message.
+/// i.e. Is this _just_ a sensor temp update message from the remote?
+/// @note The A/C will just take the sensor temp value from the message and
+/// will not follow any of the other settings in the message. If set, the A/C
+/// unit will also not beep in response to the message.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRElectraAc::setSensorUpdate(const bool on) { _.SensorUpdate = on; }
+
+/// Set the Sensor temperature for the IFeel mode.
+/// @param[in] temp The temperature in degrees celsius.
+void IRElectraAc::setSensorTemp(const uint8_t temp) {
+ _.SensorTemp = std::min(kElectraAcSensorMaxTemp,
+ std::max(kElectraAcSensorMinTemp, temp)) +
+ kElectraAcSensorTempDelta;
+}
+
+/// Get the current sensor temperature setting for the IFeel mode.
+/// @return The current setting for temp. in degrees celsius.
+uint8_t IRElectraAc::getSensorTemp(void) const {
+ return std::max(kElectraAcSensorTempDelta, _.SensorTemp) -
+ kElectraAcSensorTempDelta;
+}
+
/// Convert the current internal state into its stdAc::state_t equivalent.
/// @return The stdAc equivalent of the native settings.
stdAc::state_t IRElectraAc::toCommon(void) const {
@@ -341,19 +388,26 @@ stdAc::state_t IRElectraAc::toCommon(void) const {
/// @return A human readable string.
String IRElectraAc::toString(void) const {
String result = "";
- result.reserve(130); // Reserve some heap for the string to reduce fragging.
- result += addBoolToString(_.Power, kPowerStr, false);
- result += addModeToString(_.Mode, kElectraAcAuto, kElectraAcCool,
- kElectraAcHeat, kElectraAcDry, kElectraAcFan);
- result += addTempToString(getTemp());
- result += addFanToString(_.Fan, kElectraAcFanHigh, kElectraAcFanLow,
- kElectraAcFanAuto, kElectraAcFanAuto,
- kElectraAcFanMed);
- result += addBoolToString(getSwingV(), kSwingVStr);
- result += addBoolToString(getSwingH(), kSwingHStr);
- result += addLabeledString(getLightToggle() ? kToggleStr : "-", kLightStr);
- result += addBoolToString(_.Clean, kCleanStr);
- result += addBoolToString(_.Turbo, kTurboStr);
+ result.reserve(160); // Reserve some heap for the string to reduce fragging.
+ if (!_.SensorUpdate) {
+ result += addBoolToString(_.Power, kPowerStr, false);
+ result += addModeToString(_.Mode, kElectraAcAuto, kElectraAcCool,
+ kElectraAcHeat, kElectraAcDry, kElectraAcFan);
+ result += addTempToString(getTemp());
+ result += addFanToString(_.Fan, kElectraAcFanHigh, kElectraAcFanLow,
+ kElectraAcFanAuto, kElectraAcFanAuto,
+ kElectraAcFanMed);
+ result += addBoolToString(getSwingV(), kSwingVStr);
+ result += addBoolToString(getSwingH(), kSwingHStr);
+ result += addToggleToString(getLightToggle(), kLightStr);
+ result += addBoolToString(_.Clean, kCleanStr);
+ result += addBoolToString(_.Turbo, kTurboStr);
+ result += addBoolToString(_.IFeel, kIFeelStr);
+ }
+ if (_.IFeel || _.SensorUpdate) {
+ result += addIntToString(getSensorTemp(), kSensorTempStr, !_.SensorUpdate);
+ result += 'C';
+ }
return result;
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.h
index 886a92c56..8fd4ee182 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Electra.h
@@ -1,4 +1,4 @@
-// Copyright 2019 David Conran
+// Copyright 2019-2021 David Conran
/// @file
/// @brief Support for Electra A/C protocols.
/// @see https://github.com/ToniA/arduino-heatpumpir/blob/master/AUXHeatpumpIR.cpp
@@ -9,6 +9,10 @@
// Brand: Electra, Model: Classic INV 17 / AXW12DCS A/C
// Brand: Electra, Model: YKR-M/003E remote
// Brand: Frigidaire, Model: FGPC102AB1 A/C
+// Brand: Subtropic, Model: SUB-07HN1_18Y A/C
+// Brand: Subtropic, Model: YKR-H/102E remote
+// Brand: Centek, Model: SCT-65Q09 A/C
+// Brand: Centek, Model: YKR-P/002E remote
#ifndef IR_ELECTRA_H_
#define IR_ELECTRA_H_
@@ -37,7 +41,9 @@ union ElectraProtocol {
uint8_t :5;
uint8_t SwingH :3;
// Byte 3
- uint8_t :8;
+ uint8_t :6;
+ uint8_t SensorUpdate :1;
+ uint8_t :1;
// Byte 4
uint8_t :5;
uint8_t Fan :3;
@@ -46,10 +52,12 @@ union ElectraProtocol {
uint8_t Turbo :1;
uint8_t :1;
// Byte 6
- uint8_t :5;
+ uint8_t :3;
+ uint8_t IFeel :1;
+ uint8_t :1;
uint8_t Mode :3;
// Byte 7
- uint8_t :8;
+ uint8_t SensorTemp :8;
// Byte 8
uint8_t :8;
// Byte 9
@@ -93,6 +101,11 @@ const uint8_t kElectraAcLightToggleMask = 0x11;
// and known OFF values of 0x08 (0b00001000) & 0x05 (0x00000101)
const uint8_t kElectraAcLightToggleOff = 0x08;
+// Re: Byte[7]. Or Delta == 0xA and Temperature are stored in last 6 bits,
+// and bit 7 stores Unknown flag
+const uint8_t kElectraAcSensorTempDelta = 0x4A;
+const uint8_t kElectraAcSensorMinTemp = 0; // 0C
+const uint8_t kElectraAcSensorMaxTemp = 50; // 50C
// Classes
/// Class for handling detailed Electra A/C messages.
@@ -130,6 +143,12 @@ class IRElectraAc {
bool getLightToggle(void) const;
void setTurbo(const bool on);
bool getTurbo(void) const;
+ void setIFeel(const bool on);
+ bool getIFeel(void) const;
+ void setSensorUpdate(const bool on);
+ bool getSensorUpdate(void) const;
+ void setSensorTemp(const uint8_t temp);
+ uint8_t getSensorTemp(void) const;
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kElectraAcStateLength);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Epson.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Epson.cpp
index 4f92704bc..a92beef4f 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Epson.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Epson.cpp
@@ -6,6 +6,13 @@
// Supports:
// Brand: Epson, Model: EN-TW9100W Projector
+// Brand: Epson, Model: VS230 Projector
+// Brand: Epson, Model: VS330 Projector
+// Brand: Epson, Model: EX3220 Projector
+// Brand: Epson, Model: EX5220 Projector
+// Brand: Epson, Model: EX5230 Projector
+// Brand: Epson, Model: EX6220 Projector
+// Brand: Epson, Model: EX7220 Projector
#define __STDC_LIMIT_MACROS
#include
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Goodweather.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Goodweather.cpp
index c86797ad5..1d6918e7f 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Goodweather.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Goodweather.cpp
@@ -21,6 +21,7 @@ using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addFanToString;
using irutils::addTempToString;
+using irutils::addToggleToString;
#if SEND_GOODWEATHER
/// Send a Goodweather HVAC formatted message.
@@ -346,9 +347,10 @@ String IRGoodweatherAc::toString(void) const {
result += addFanToString(_.Fan, kGoodweatherFanHigh, kGoodweatherFanLow,
kGoodweatherFanAuto, kGoodweatherFanAuto,
kGoodweatherFanMed);
- result += addLabeledString(_.Turbo ? kToggleStr : "-", kTurboStr);
- result += addLabeledString(_.Light ? kToggleStr : "-", kLightStr);
- result += addLabeledString(_.Sleep ? kToggleStr : "-", kSleepStr);
+
+ result += addToggleToString(_.Turbo, kTurboStr);
+ result += addToggleToString(_.Light, kLightStr);
+ result += addToggleToString(_.Sleep, kSleepStr);
result += addIntToString(_.Swing, kSwingStr);
result += kSpaceLBraceStr;
switch (_.Swing) {
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.cpp
index 1d1371b2d..3c3a8583e 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.cpp
@@ -35,6 +35,7 @@ using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addModelToString;
using irutils::addFanToString;
+using irutils::addSwingHToString;
using irutils::addTempToString;
using irutils::minsToString;
@@ -220,15 +221,11 @@ bool IRGreeAC::getPower(void) const {
/// Set the default temperature units to use.
/// @param[in] on Use Fahrenheit as the units.
/// true is Fahrenheit, false is Celsius.
-void IRGreeAC::setUseFahrenheit(const bool on) {
- _.UseFahrenheit = on;
-}
+void IRGreeAC::setUseFahrenheit(const bool on) { _.UseFahrenheit = on; }
/// Get the default temperature units in use.
/// @return true is Fahrenheit, false is Celsius.
-bool IRGreeAC::getUseFahrenheit(void) const {
- return _.UseFahrenheit;
-}
+bool IRGreeAC::getUseFahrenheit(void) const { return _.UseFahrenheit; }
/// Set the temp. in degrees
/// @param[in] temp Desired temperature in Degrees.
@@ -281,9 +278,7 @@ void IRGreeAC::setFan(const uint8_t speed) {
/// Get the current fan speed setting.
/// @return The current fan speed.
-uint8_t IRGreeAC::getFan(void) const {
- return _.Fan;
-}
+uint8_t IRGreeAC::getFan(void) const { return _.Fan; }
/// Set the operating mode of the A/C.
/// @param[in] new_mode The desired operating mode.
@@ -305,81 +300,63 @@ void IRGreeAC::setMode(const uint8_t new_mode) {
/// Get the operating mode setting of the A/C.
/// @return The current operating mode setting.
-uint8_t IRGreeAC::getMode(void) const {
- return _.Mode;
-}
+uint8_t IRGreeAC::getMode(void) const { return _.Mode; }
/// Set the Light (LED) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setLight(const bool on) {
- _.Light = on;
-}
+void IRGreeAC::setLight(const bool on) { _.Light = on; }
/// Get the Light (LED) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getLight(void) const {
- return _.Light;
-}
+bool IRGreeAC::getLight(void) const { return _.Light; }
/// Set the IFeel setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setIFeel(const bool on) {
- _.IFeel = on;
-}
+void IRGreeAC::setIFeel(const bool on) { _.IFeel = on; }
/// Get the IFeel setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getIFeel(void) const {
- return _.IFeel;
-}
+bool IRGreeAC::getIFeel(void) const { return _.IFeel; }
/// Set the Wifi (enabled) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setWiFi(const bool on) {
- _.WiFi = on;
-}
+void IRGreeAC::setWiFi(const bool on) { _.WiFi = on; }
/// Get the Wifi (enabled) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getWiFi(void) const {
- return _.WiFi;
-}
+bool IRGreeAC::getWiFi(void) const { return _.WiFi; }
/// Set the XFan (Mould) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setXFan(const bool on) {
- _.Xfan = on;
-}
+void IRGreeAC::setXFan(const bool on) { _.Xfan = on; }
/// Get the XFan (Mould) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getXFan(void) const {
- return _.Xfan;
-}
+bool IRGreeAC::getXFan(void) const { return _.Xfan; }
/// Set the Sleep setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setSleep(const bool on) {
- _.Sleep = on;
-}
+void IRGreeAC::setSleep(const bool on) { _.Sleep = on; }
/// Get the Sleep setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getSleep(void) const {
- return _.Sleep;
-}
+bool IRGreeAC::getSleep(void) const { return _.Sleep; }
/// Set the Turbo setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setTurbo(const bool on) {
- _.Turbo = on;
-}
+void IRGreeAC::setTurbo(const bool on) { _.Turbo = on; }
/// Get the Turbo setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getTurbo(void) const {
- return _.Turbo;
-}
+bool IRGreeAC::getTurbo(void) const { return _.Turbo; }
+
+/// Set the Econo setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRGreeAC::setEcono(const bool on) { _.Econo = on; }
+
+/// Get the Econo setting of the A/C.
+/// @return true, the setting is on. false, the setting is off.
+bool IRGreeAC::getEcono(void) const { return _.Econo; }
/// Set the Vertical Swing mode of the A/C.
/// @param[in] automatic Do we use the automatic setting?
@@ -409,32 +386,37 @@ void IRGreeAC::setSwingVertical(const bool automatic, const uint8_t position) {
new_position = kGreeSwingAuto;
}
}
- _.Swing = new_position;
+ _.SwingV = new_position;
}
/// Get the Vertical Swing Automatic mode setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getSwingVerticalAuto(void) const {
- return _.SwingAuto;
-}
+bool IRGreeAC::getSwingVerticalAuto(void) const { return _.SwingAuto; }
/// Get the Vertical Swing position setting of the A/C.
/// @return The native position/mode.
-uint8_t IRGreeAC::getSwingVerticalPosition(void) const {
- return _.Swing;
+uint8_t IRGreeAC::getSwingVerticalPosition(void) const { return _.SwingV; }
+
+/// Get the Horizontal Swing position setting of the A/C.
+/// @return The native position/mode.
+uint8_t IRGreeAC::getSwingHorizontal(void) const { return _.SwingH; }
+
+/// Set the Horizontal Swing mode of the A/C.
+/// @param[in] position The position/mode to set the vanes to.
+void IRGreeAC::setSwingHorizontal(const uint8_t position) {
+ if (position <= kGreeSwingHMaxRight)
+ _.SwingH = position;
+ else
+ _.SwingH = kGreeSwingHOff;
}
/// Set the timer enable setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRGreeAC::setTimerEnabled(const bool on) {
- _.TimerEnabled = on;
-}
+void IRGreeAC::setTimerEnabled(const bool on) { _.TimerEnabled = on; }
/// Get the timer enabled setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRGreeAC::getTimerEnabled(void) const {
- return _.TimerEnabled;
-}
+bool IRGreeAC::getTimerEnabled(void) const { return _.TimerEnabled; }
/// Get the timer time value from the A/C.
/// @return The number of minutes the timer is set for.
@@ -478,9 +460,7 @@ void IRGreeAC::setDisplayTempSource(const uint8_t mode) {
/// Get the temperature display mode.
/// i.e. Internal, External temperature sensing.
/// @return The current temp source being displayed.
-uint8_t IRGreeAC::getDisplayTempSource(void) const {
- return _.DisplayTemp;
-}
+uint8_t IRGreeAC::getDisplayTempSource(void) const { return _.DisplayTemp; }
/// Convert a stdAc::opmode_t enum into its native mode.
/// @param[in] mode The enum to be converted.
@@ -523,6 +503,21 @@ uint8_t IRGreeAC::convertSwingV(const stdAc::swingv_t swingv) {
}
}
+/// Convert a stdAc::swingh_t enum into it's native setting.
+/// @param[in] swingh The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRGreeAC::convertSwingH(const stdAc::swingh_t swingh) {
+ switch (swingh) {
+ case stdAc::swingh_t::kAuto: return kGreeSwingHAuto;
+ case stdAc::swingh_t::kLeftMax: return kGreeSwingHMaxLeft;
+ case stdAc::swingh_t::kLeft: return kGreeSwingHLeft;
+ case stdAc::swingh_t::kMiddle: return kGreeSwingHMiddle;
+ case stdAc::swingh_t::kRight: return kGreeSwingHRight;
+ case stdAc::swingh_t::kRightMax: return kGreeSwingHMaxRight;
+ default: return kGreeSwingHOff;
+ }
+}
+
/// Convert a native mode into its stdAc equivalent.
/// @param[in] mode The native setting to be converted.
/// @return The stdAc equivalent of the native setting.
@@ -530,9 +525,9 @@ stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) {
switch (mode) {
case kGreeCool: return stdAc::opmode_t::kCool;
case kGreeHeat: return stdAc::opmode_t::kHeat;
- case kGreeDry: return stdAc::opmode_t::kDry;
- case kGreeFan: return stdAc::opmode_t::kFan;
- default: return stdAc::opmode_t::kAuto;
+ case kGreeDry: return stdAc::opmode_t::kDry;
+ case kGreeFan: return stdAc::opmode_t::kFan;
+ default: return stdAc::opmode_t::kAuto;
}
}
@@ -541,10 +536,10 @@ stdAc::opmode_t IRGreeAC::toCommonMode(const uint8_t mode) {
/// @return The stdAc equivalent of the native setting.
stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) {
switch (speed) {
- case kGreeFanMax: return stdAc::fanspeed_t::kMax;
+ case kGreeFanMax: return stdAc::fanspeed_t::kMax;
case kGreeFanMax - 1: return stdAc::fanspeed_t::kMedium;
- case kGreeFanMin: return stdAc::fanspeed_t::kMin;
- default: return stdAc::fanspeed_t::kAuto;
+ case kGreeFanMin: return stdAc::fanspeed_t::kMin;
+ default: return stdAc::fanspeed_t::kAuto;
}
}
@@ -553,12 +548,27 @@ stdAc::fanspeed_t IRGreeAC::toCommonFanSpeed(const uint8_t speed) {
/// @return The stdAc equivalent of the native setting.
stdAc::swingv_t IRGreeAC::toCommonSwingV(const uint8_t pos) {
switch (pos) {
- case kGreeSwingUp: return stdAc::swingv_t::kHighest;
- case kGreeSwingMiddleUp: return stdAc::swingv_t::kHigh;
- case kGreeSwingMiddle: return stdAc::swingv_t::kMiddle;
+ case kGreeSwingUp: return stdAc::swingv_t::kHighest;
+ case kGreeSwingMiddleUp: return stdAc::swingv_t::kHigh;
+ case kGreeSwingMiddle: return stdAc::swingv_t::kMiddle;
case kGreeSwingMiddleDown: return stdAc::swingv_t::kLow;
- case kGreeSwingDown: return stdAc::swingv_t::kLowest;
- default: return stdAc::swingv_t::kAuto;
+ case kGreeSwingDown: return stdAc::swingv_t::kLowest;
+ default: return stdAc::swingv_t::kAuto;
+ }
+}
+
+/// Convert a native Horizontal Swing into its stdAc equivalent.
+/// @param[in] pos The native setting to be converted.
+/// @return The stdAc equivalent of the native setting.
+stdAc::swingh_t IRGreeAC::toCommonSwingH(const uint8_t pos) {
+ switch (pos) {
+ case kGreeSwingHAuto: return stdAc::swingh_t::kAuto;
+ case kGreeSwingHMaxLeft: return stdAc::swingh_t::kLeftMax;
+ case kGreeSwingHLeft: return stdAc::swingh_t::kLeft;
+ case kGreeSwingHMiddle: return stdAc::swingh_t::kMiddle;
+ case kGreeSwingHRight: return stdAc::swingh_t::kRight;
+ case kGreeSwingHMaxRight: return stdAc::swingh_t::kRightMax;
+ default: return stdAc::swingh_t::kOff;
}
}
@@ -576,15 +586,15 @@ stdAc::state_t IRGreeAC::toCommon(void) {
if (_.SwingAuto)
result.swingv = stdAc::swingv_t::kAuto;
else
- result.swingv = toCommonSwingV(_.Swing);
+ result.swingv = toCommonSwingV(_.SwingV);
+ result.swingh = toCommonSwingH(_.SwingH);
result.turbo = _.Turbo;
+ result.econo = _.Econo;
result.light = _.Light;
result.clean = _.Xfan;
result.sleep = _.Sleep ? 0 : -1;
// Not supported.
- result.swingh = stdAc::swingh_t::kOff;
result.quiet = false;
- result.econo = false;
result.filter = false;
result.beep = false;
result.clock = -1;
@@ -604,6 +614,7 @@ String IRGreeAC::toString(void) {
result += addFanToString(_.Fan, kGreeFanMax, kGreeFanMin, kGreeFanAuto,
kGreeFanAuto, kGreeFanMed);
result += addBoolToString(_.Turbo, kTurboStr);
+ result += addBoolToString(_.Econo, kEconoStr);
result += addBoolToString(_.IFeel, kIFeelStr);
result += addBoolToString(_.WiFi, kWifiStr);
result += addBoolToString(_.Xfan, kXFanStr);
@@ -611,9 +622,9 @@ String IRGreeAC::toString(void) {
result += addBoolToString(_.Sleep, kSleepStr);
result += addLabeledString(_.SwingAuto ? kAutoStr : kManualStr,
kSwingVModeStr);
- result += addIntToString(_.Swing, kSwingVStr);
+ result += addIntToString(_.SwingV, kSwingVStr);
result += kSpaceLBraceStr;
- switch (_.Swing) {
+ switch (_.SwingV) {
case kGreeSwingLastPos:
result += kLastStr;
break;
@@ -623,6 +634,12 @@ String IRGreeAC::toString(void) {
default: result += kUnknownStr;
}
result += ')';
+ result += addSwingHToString(_.SwingH, kGreeSwingHAuto, kGreeSwingHMaxLeft,
+ kGreeSwingHLeft, kGreeSwingHMiddle,
+ kGreeSwingHRight, kGreeSwingHMaxRight,
+ kGreeSwingHOff,
+ // rest are unused.
+ 0xFF, 0xFF, 0xFF, 0xFF);
result += addLabeledString(
_.TimerEnabled ? minsToString(getTimer()) : kOffStr, kTimerStr);
uint8_t src = _.DisplayTemp;
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.h
index 4f89fde5c..be5ac31ce 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Gree.h
@@ -14,10 +14,15 @@
// Brand: Green, Model: YBOFB2 remote
// Brand: Gree, Model: YAA1FBF remote
// Brand: Gree, Model: YB1F2F remote
+// Brand: Gree, Model: YAN1F1 remote
+// Brand: Gree, Model: VIR09HP115V1AH A/C
+// Brand: Gree, Model: VIR12HP230V1AH A/C
// Brand: Amana, Model: PBC093G00CC A/C
// Brand: Amana, Model: YX1FF remote
// Brand: Cooper & Hunter, Model: YB1F2 remote
// Brand: Cooper & Hunter, Model: CH-S09FTXG A/C
+// Brand: Vailland, Model: YACIFB remote
+// Brand: Vailland, Model: VAI5-035WNI A/C
#ifndef IR_GREE_H_
#define IR_GREE_H_
@@ -60,19 +65,22 @@ union GreeProtocol{
uint8_t UseFahrenheit :1;
uint8_t unknown1 :4; // value=0b0101
// Byte 4
- uint8_t Swing:4;
- uint8_t :0;
+ uint8_t SwingV :4;
+ uint8_t SwingH :3;
+ uint8_t :1;
// Byte 5
uint8_t DisplayTemp :2;
uint8_t IFeel :1;
uint8_t unknown2 :3; // value = 0b100
uint8_t WiFi :1;
- uint8_t :0;
+ uint8_t :1;
// Byte 6
- uint8_t :8;
+ uint8_t :8;
// Byte 7
- uint8_t :4;
- uint8_t Sum:4;
+ uint8_t :2;
+ uint8_t Econo :1;
+ uint8_t :1;
+ uint8_t Sum :4;
};
};
@@ -95,16 +103,24 @@ const uint8_t kGreeMinTempF = 61; // Fahrenheit
const uint8_t kGreeMaxTempF = 86; // Fahrenheit
const uint16_t kGreeTimerMax = 24 * 60;
-const uint8_t kGreeSwingLastPos = 0b0000;
-const uint8_t kGreeSwingAuto = 0b0001;
-const uint8_t kGreeSwingUp = 0b0010;
-const uint8_t kGreeSwingMiddleUp = 0b0011;
-const uint8_t kGreeSwingMiddle = 0b0100;
-const uint8_t kGreeSwingMiddleDown = 0b0101;
-const uint8_t kGreeSwingDown = 0b0110;
-const uint8_t kGreeSwingDownAuto = 0b0111;
-const uint8_t kGreeSwingMiddleAuto = 0b1001;
-const uint8_t kGreeSwingUpAuto = 0b1011;
+const uint8_t kGreeSwingLastPos = 0b0000; // 0
+const uint8_t kGreeSwingAuto = 0b0001; // 1
+const uint8_t kGreeSwingUp = 0b0010; // 2
+const uint8_t kGreeSwingMiddleUp = 0b0011; // 3
+const uint8_t kGreeSwingMiddle = 0b0100; // 4
+const uint8_t kGreeSwingMiddleDown = 0b0101; // 5
+const uint8_t kGreeSwingDown = 0b0110; // 6
+const uint8_t kGreeSwingDownAuto = 0b0111; // 7
+const uint8_t kGreeSwingMiddleAuto = 0b1001; // 9
+const uint8_t kGreeSwingUpAuto = 0b1011; // 11
+
+const uint8_t kGreeSwingHOff = 0b000; // 0
+const uint8_t kGreeSwingHAuto = 0b001; // 1
+const uint8_t kGreeSwingHMaxLeft = 0b010; // 2
+const uint8_t kGreeSwingHLeft = 0b011; // 3
+const uint8_t kGreeSwingHMiddle = 0b100; // 4
+const uint8_t kGreeSwingHRight = 0b101; // 5
+const uint8_t kGreeSwingHMaxRight = 0b110; // 6
const uint8_t kGreeDisplayTempOff = 0b00; // 0
const uint8_t kGreeDisplayTempSet = 0b01; // 1
@@ -171,6 +187,8 @@ class IRGreeAC {
bool getSleep(void) const;
void setTurbo(const bool on);
bool getTurbo(void) const;
+ void setEcono(const bool on);
+ bool getEcono(void) const;
void setIFeel(const bool on);
bool getIFeel(void) const;
void setWiFi(const bool on);
@@ -178,6 +196,8 @@ class IRGreeAC {
void setSwingVertical(const bool automatic, const uint8_t position);
bool getSwingVerticalAuto(void) const;
uint8_t getSwingVerticalPosition(void) const;
+ void setSwingHorizontal(const uint8_t position);
+ uint8_t getSwingHorizontal(void) const;
uint16_t getTimer(void) const;
void setTimer(const uint16_t minutes);
void setDisplayTempSource(const uint8_t mode);
@@ -185,9 +205,11 @@ class IRGreeAC {
static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t speed);
static uint8_t convertSwingV(const stdAc::swingv_t swingv);
+ static uint8_t convertSwingH(const stdAc::swingh_t swingh);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+ static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
stdAc::state_t toCommon(void);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[]);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.cpp
index a43e9400d..5c9f2a36d 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.cpp
@@ -32,6 +32,8 @@ using irutils::addBoolToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
+using irutils::addModelToString;
+using irutils::addSwingHToString;
using irutils::addFanToString;
using irutils::addTempToString;
using irutils::minsToString;
@@ -322,22 +324,22 @@ void IRHaierAC::setCurrTime(const uint16_t nr_mins) {
}
/// Get the Vertical Swing position setting of the A/C.
-/// @return The native swing mode.
-uint8_t IRHaierAC::getSwing(void) const {
- return _.Swing;
+/// @return The native vertical swing mode.
+uint8_t IRHaierAC::getSwingV(void) const {
+ return _.SwingV;
}
/// Set the Vertical Swing mode of the A/C.
/// @param[in] state The mode to set the vanes to.
-void IRHaierAC::setSwing(const uint8_t state) {
- if (state == _.Swing) return; // Nothing to do.
+void IRHaierAC::setSwingV(const uint8_t state) {
+ if (state == _.SwingV) return; // Nothing to do.
switch (state) {
- case kHaierAcSwingOff:
- case kHaierAcSwingUp:
- case kHaierAcSwingDown:
- case kHaierAcSwingChg:
+ case kHaierAcSwingVOff:
+ case kHaierAcSwingVUp:
+ case kHaierAcSwingVDown:
+ case kHaierAcSwingVChg:
_.Command = kHaierAcCmdSwing;
- _.Swing = state;
+ _.SwingV = state;
break;
}
}
@@ -376,11 +378,11 @@ uint8_t IRHaierAC::convertSwingV(const stdAc::swingv_t position) {
switch (position) {
case stdAc::swingv_t::kHighest:
case stdAc::swingv_t::kHigh:
- case stdAc::swingv_t::kMiddle: return kHaierAcSwingUp;
+ case stdAc::swingv_t::kMiddle: return kHaierAcSwingVUp;
case stdAc::swingv_t::kLow:
- case stdAc::swingv_t::kLowest: return kHaierAcSwingDown;
- case stdAc::swingv_t::kOff: return kHaierAcSwingOff;
- default: return kHaierAcSwingChg;
+ case stdAc::swingv_t::kLowest: return kHaierAcSwingVDown;
+ case stdAc::swingv_t::kOff: return kHaierAcSwingVOff;
+ default: return kHaierAcSwingVChg;
}
}
@@ -414,10 +416,10 @@ stdAc::fanspeed_t IRHaierAC::toCommonFanSpeed(const uint8_t speed) {
/// @return The native equivalent of the enum.
stdAc::swingv_t IRHaierAC::toCommonSwingV(const uint8_t pos) {
switch (pos) {
- case kHaierAcSwingUp: return stdAc::swingv_t::kHighest;
- case kHaierAcSwingDown: return stdAc::swingv_t::kLowest;
- case kHaierAcSwingOff: return stdAc::swingv_t::kOff;
- default: return stdAc::swingv_t::kAuto;
+ case kHaierAcSwingVUp: return stdAc::swingv_t::kHighest;
+ case kHaierAcSwingVDown: return stdAc::swingv_t::kLowest;
+ case kHaierAcSwingVOff: return stdAc::swingv_t::kOff;
+ default: return stdAc::swingv_t::kAuto;
}
}
@@ -433,7 +435,7 @@ stdAc::state_t IRHaierAC::toCommon(void) const {
result.celsius = true;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(getFan());
- result.swingv = toCommonSwingV(_.Swing);
+ result.swingv = toCommonSwingV(_.SwingV);
result.filter = _.Health;
result.sleep = _.Sleep ? 0 : -1;
// Not supported.
@@ -443,7 +445,7 @@ stdAc::state_t IRHaierAC::toCommon(void) const {
result.econo = false;
result.light = false;
result.clean = false;
- result.beep = false;
+ result.beep = true;
result.clock = -1;
return result;
}
@@ -452,7 +454,7 @@ stdAc::state_t IRHaierAC::toCommon(void) const {
/// @return A human readable string.
String IRHaierAC::toString(void) const {
String result = "";
- result.reserve(150); // Reserve some heap for the string to reduce fragging.
+ result.reserve(170); // Reserve some heap for the string to reduce fragging.
uint8_t cmd = _.Command;
result += addIntToString(cmd, kCommandStr, false);
result += kSpaceLBraceStr;
@@ -492,7 +494,7 @@ String IRHaierAC::toString(void) const {
result += kHealthStr;
break;
case kHaierAcCmdSwing:
- result += kSwingStr;
+ result += kSwingVStr;
break;
default:
result += kUnknownStr;
@@ -503,19 +505,19 @@ String IRHaierAC::toString(void) const {
result += addTempToString(getTemp());
result += addFanToString(getFan(), kHaierAcFanHigh, kHaierAcFanLow,
kHaierAcFanAuto, kHaierAcFanAuto, kHaierAcFanMed);
- result += addIntToString(_.Swing, kSwingStr);
+ result += addIntToString(_.SwingV, kSwingVStr);
result += kSpaceLBraceStr;
- switch (_.Swing) {
- case kHaierAcSwingOff:
+ switch (_.SwingV) {
+ case kHaierAcSwingVOff:
result += kOffStr;
break;
- case kHaierAcSwingUp:
+ case kHaierAcSwingVUp:
result += kUpStr;
break;
- case kHaierAcSwingDown:
+ case kHaierAcSwingVDown:
result += kDownStr;
break;
- case kHaierAcSwingChg:
+ case kHaierAcSwingVChg:
result += kChangeStr;
break;
default:
@@ -581,9 +583,9 @@ bool IRHaierAC176::validChecksum(const uint8_t state[], const uint16_t length) {
/// Reset the internal state to a fixed known good state.
void IRHaierAC176::stateReset(void) {
std::memset(_.raw, 0, sizeof _.raw);
- _.Prefix = kHaierAcYrw02Prefix;
+ _.Model = kHaierAcYrw02ModelA;
_.Prefix2 = kHaierAc176Prefix;
- _.Temp = kHaierAcDefTemp - kHaierAcMinTemp;
+ _.Temp = kHaierAcYrw02DefTempC - kHaierAcYrw02MinTempC;
_.Health = true;
setFan(kHaierAcYrw02FanAuto);
_.Power = true;
@@ -609,17 +611,42 @@ void IRHaierAC176::setButton(uint8_t button) {
switch (button) {
case kHaierAcYrw02ButtonTempUp:
case kHaierAcYrw02ButtonTempDown:
- case kHaierAcYrw02ButtonSwing:
+ case kHaierAcYrw02ButtonSwingV:
+ case kHaierAcYrw02ButtonSwingH:
case kHaierAcYrw02ButtonFan:
case kHaierAcYrw02ButtonPower:
case kHaierAcYrw02ButtonMode:
case kHaierAcYrw02ButtonHealth:
case kHaierAcYrw02ButtonTurbo:
case kHaierAcYrw02ButtonSleep:
+ case kHaierAcYrw02ButtonLock:
+ case kHaierAcYrw02ButtonCFAB:
_.Button = button;
}
}
+/// Get/Detect the model of the A/C.
+/// @return The enum of the compatible model.
+haier_ac176_remote_model_t IRHaierAC176::getModel(void) const {
+ switch (_.Model) {
+ case kHaierAcYrw02ModelB: return haier_ac176_remote_model_t::V9014557_B;
+ default: return haier_ac176_remote_model_t::V9014557_A;
+ }
+}
+
+/// Set the model of the A/C to emulate.
+/// @param[in] model The enum of the appropriate model.
+void IRHaierAC176::setModel(haier_ac176_remote_model_t model) {
+ _.Button = kHaierAcYrw02ButtonCFAB;
+ switch (model) {
+ case haier_ac176_remote_model_t::V9014557_B:
+ _.Model = kHaierAcYrw02ModelB;
+ break;
+ default:
+ _.Model = kHaierAcYrw02ModelA;
+ }
+}
+
/// Get the Button/Command setting of the A/C.
/// @return The value of the button/command that was pressed.
uint8_t IRHaierAC176::getButton(void) const {
@@ -629,47 +656,118 @@ uint8_t IRHaierAC176::getButton(void) const {
/// Set the operating mode of the A/C.
/// @param[in] mode The desired operating mode.
void IRHaierAC176::setMode(uint8_t mode) {
- uint8_t new_mode = mode;
- _.Button = kHaierAcYrw02ButtonMode;
switch (mode) {
case kHaierAcYrw02Auto:
- case kHaierAcYrw02Cool:
case kHaierAcYrw02Dry:
+ case kHaierAcYrw02Fan:
+ // Turbo & Quiet is only available in Cool/Heat mode.
+ _.Turbo = false;
+ _.Quiet = false;
+ // FALL-THRU
+ case kHaierAcYrw02Cool:
case kHaierAcYrw02Heat:
- case kHaierAcYrw02Fan: break;
- default: new_mode = kHaierAcYrw02Auto; // Unexpected, default to auto mode.
+ _.Button = kHaierAcYrw02ButtonMode;
+ _.Mode = mode;
+ break;
+ default:
+ setMode(kHaierAcYrw02Auto); // Unexpected, default to auto mode.
}
- _.Mode = new_mode;
}
/// Get the operating mode setting of the A/C.
/// @return The current operating mode setting.
-uint8_t IRHaierAC176::getMode(void) const {
- return _.Mode;
-}
+uint8_t IRHaierAC176::getMode(void) const { return _.Mode; }
+
+/// Set the default temperature units to use.
+/// @param[in] on Use Fahrenheit as the units.
+/// true is Fahrenheit, false is Celsius.
+void IRHaierAC176::setUseFahrenheit(const bool on) { _.UseFahrenheit = on; }
+
+/// Get the default temperature units in use.
+/// @return true is Fahrenheit, false is Celsius.
+bool IRHaierAC176::getUseFahrenheit(void) const { return _.UseFahrenheit; }
/// Set the temperature.
-/// @param[in] celsius The temperature in degrees celsius.
-void IRHaierAC176::setTemp(const uint8_t celsius) {
- uint8_t temp = celsius;
- if (temp < kHaierAcMinTemp)
- temp = kHaierAcMinTemp;
- else if (temp > kHaierAcMaxTemp)
- temp = kHaierAcMaxTemp;
-
+/// @param[in] degree The temperature in degrees.
+/// @param[in] fahrenheit Use units of Fahrenheit and set that as units used.
+void IRHaierAC176::setTemp(const uint8_t degree, const bool fahrenheit) {
uint8_t old_temp = getTemp();
- if (old_temp == temp) return;
- if (old_temp > temp)
- _.Button = kHaierAcYrw02ButtonTempDown;
- else
- _.Button = kHaierAcYrw02ButtonTempUp;
- _.Temp = temp - kHaierAcMinTemp;
+ if (old_temp == degree) return;
+
+ if (_.UseFahrenheit == fahrenheit) {
+ if (old_temp > degree)
+ _.Button = kHaierAcYrw02ButtonTempDown;
+ else
+ _.Button = kHaierAcYrw02ButtonTempUp;
+ } else {
+ _.Button = kHaierAcYrw02ButtonCFAB;
+ }
+ _.UseFahrenheit = fahrenheit;
+
+ uint8_t temp = degree;
+ if (fahrenheit) {
+ if (temp < kHaierAcYrw02MinTempF)
+ temp = kHaierAcYrw02MinTempF;
+ else if (temp > kHaierAcYrw02MaxTempF)
+ temp = kHaierAcYrw02MaxTempF;
+ if (degree >= 77) { temp++; }
+ if (degree >= 79) { temp++; }
+ // See at IRHaierAC176::getTemp() comments for clarification
+ _.ExtraDegreeF = temp % 2;
+ _.Temp = (temp - kHaierAcYrw02MinTempF -_.ExtraDegreeF) >> 1;
+ } else {
+ if (temp < kHaierAcYrw02MinTempC)
+ temp = kHaierAcYrw02MinTempC;
+ else if (temp > kHaierAcYrw02MaxTempC)
+ temp = kHaierAcYrw02MaxTempC;
+ _.Temp = temp - kHaierAcYrw02MinTempC;
+ }
}
/// Get the current temperature setting.
-/// @return The current setting for temp. in degrees celsius.
+/// The unit of temperature is specified by UseFahrenheit value.
+/// @return The current setting for temperature.
uint8_t IRHaierAC176::getTemp(void) const {
- return _.Temp + kHaierAcMinTemp;
+ if (!_.UseFahrenheit) { return _.Temp + kHaierAcYrw02MinTempC; }
+ uint8_t degree = _.Temp*2 + kHaierAcYrw02MinTempF + _.ExtraDegreeF;
+ // The way of coding the temperature in degree Fahrenheit is
+ // kHaierAcYrw02MinTempF + Temp*2 + ExtraDegreeF, for example
+ // Temp = 0b0011, ExtraDegreeF = 0b1, temperature is 60 + 3*2 + 1 = 67F
+ // But around 78F there is unconsistency, see table below
+ //
+ // | Fahrenheit | Temp | ExtraDegreeF |
+ // | 60F | 0b0000 | 0b0 |
+ // | 61F | 0b0000 | 0b1 |
+ // | 62F | 0b0001 | 0b0 |
+ // | 63F | 0b0001 | 0b1 |
+ // | 64F | 0b0010 | 0b0 |
+ // | 65F | 0b0010 | 0b1 |
+ // | 66F | 0b0011 | 0b0 |
+ // | 67F | 0b0011 | 0b1 |
+ // | 68F | 0b0100 | 0b0 |
+ // | 69F | 0b0100 | 0b1 |
+ // | 70F | 0b0101 | 0b0 |
+ // | 71F | 0b0101 | 0b1 |
+ // | 72F | 0b0110 | 0b0 |
+ // | 73F | 0b0110 | 0b1 |
+ // | 74F | 0b0111 | 0b0 |
+ // | 75F | 0b0111 | 0b1 |
+ // | 76F | 0b1000 | 0b0 |
+ // | Not Used | 0b1000 | 0b1 |
+ // | 77F | 0b1001 | 0b0 |
+ // | Not Used | 0b1001 | 0b1 |
+ // | 78F | 0b1010 | 0b0 |
+ // | 79F | 0b1010 | 0b1 |
+ // | 80F | 0b1011 | 0b0 |
+ // | 81F | 0b1011 | 0b1 |
+ // | 82F | 0b1100 | 0b0 |
+ // | 83F | 0b1100 | 0b1 |
+ // | 84F | 0b1101 | 0b0 |
+ // | 86F | 0b1110 | 0b0 |
+ // | 85F | 0b1101 | 0b1 |
+ if (degree >= 77) { degree--; }
+ if (degree >= 79) { degree--; }
+ return degree;
}
/// Set the Health (filter) setting of the A/C.
@@ -681,15 +779,11 @@ void IRHaierAC176::setHealth(const bool on) {
/// Get the Health (filter) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRHaierAC176::getHealth(void) const {
- return _.Health;
-}
+bool IRHaierAC176::getHealth(void) const { return _.Health; }
/// Get the value of the current power setting.
/// @return true, the setting is on. false, the setting is off.
-bool IRHaierAC176::getPower(void) const {
- return _.Power;
-}
+bool IRHaierAC176::getPower(void) const { return _.Power; }
/// Change the power setting.
/// @param[in] on true, the setting is on. false, the setting is off.
@@ -706,9 +800,7 @@ void IRHaierAC176::off(void) { setPower(false); }
/// Get the Sleep setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRHaierAC176::getSleep(void) const {
- return _.Sleep;
-}
+bool IRHaierAC176::getSleep(void) const { return _.Sleep; }
/// Set the Sleep setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
@@ -718,30 +810,42 @@ void IRHaierAC176::setSleep(const bool on) {
}
/// Get the Turbo setting of the A/C.
-/// @return The current turbo speed setting.
-uint8_t IRHaierAC176::getTurbo(void) const {
- return _.Turbo;
-}
+/// @return The current turbo setting.
+bool IRHaierAC176::getTurbo(void) const { return _.Turbo; }
/// Set the Turbo setting of the A/C.
-/// @param[in] speed The desired turbo speed setting.
-/// @note Valid speeds are kHaierAcYrw02TurboOff, kHaierAcYrw02TurboLow, &
-/// kHaierAcYrw02TurboHigh.
-void IRHaierAC176::setTurbo(uint8_t speed) {
- switch (speed) {
- case kHaierAcYrw02TurboOff:
- case kHaierAcYrw02TurboLow:
- case kHaierAcYrw02TurboHigh:
- _.Turbo = speed;
+/// @param[in] on The desired turbo setting.
+/// @note Turbo & Quiet can't be on at the same time, and only in Heat/Cool mode
+void IRHaierAC176::setTurbo(const bool on) {
+ switch (getMode()) {
+ case kHaierAcYrw02Cool:
+ case kHaierAcYrw02Heat:
+ _.Turbo = on;
_.Button = kHaierAcYrw02ButtonTurbo;
+ if (on) _.Quiet = false;
+ }
+}
+
+/// Get the Quiet setting of the A/C.
+/// @return The current Quiet setting.
+bool IRHaierAC176::getQuiet(void) const { return _.Quiet; }
+
+/// Set the Quiet setting of the A/C.
+/// @param[in] on The desired Quiet setting.
+/// @note Turbo & Quiet can't be on at the same time, and only in Heat/Cool mode
+void IRHaierAC176::setQuiet(const bool on) {
+ switch (getMode()) {
+ case kHaierAcYrw02Cool:
+ case kHaierAcYrw02Heat:
+ _.Quiet = on;
+ _.Button = kHaierAcYrw02ButtonTurbo;
+ if (on) _.Turbo = false;
}
}
/// Get the current fan speed setting.
/// @return The current fan speed.
-uint8_t IRHaierAC176::getFan(void) const {
- return _.Fan;
-}
+uint8_t IRHaierAC176::getFan(void) const { return _.Fan; }
/// Set the speed of the fan.
/// @param[in] speed The desired setting.
@@ -757,30 +861,61 @@ void IRHaierAC176::setFan(uint8_t speed) {
}
}
+/// For backward compatibility. Use getSwingV() instead.
/// Get the Vertical Swing position setting of the A/C.
/// @return The native position/mode.
-uint8_t IRHaierAC176::getSwing(void) const { return _.Swing; }
+uint8_t IRHaierAC176::getSwing(void) const {
+ return IRHaierAC176::getSwingV();
+}
+
+/// For backward compatibility. Use setSwingV() instead.
+/// Set the Vertical Swing mode of the A/C.
+/// @param[in] pos The position/mode to set the vanes to.
+void IRHaierAC176::setSwing(uint8_t pos) { setSwingV(pos); }
+
+/// Get the Vertical Swing position setting of the A/C.
+/// @return The native position/mode.
+uint8_t IRHaierAC176::getSwingV(void) const { return _.SwingV; }
/// Set the Vertical Swing mode of the A/C.
/// @param[in] pos The position/mode to set the vanes to.
-void IRHaierAC176::setSwing(uint8_t pos) {
+void IRHaierAC176::setSwingV(uint8_t pos) {
uint8_t newpos = pos;
switch (pos) {
- case kHaierAcYrw02SwingOff:
- case kHaierAcYrw02SwingAuto:
- case kHaierAcYrw02SwingTop:
- case kHaierAcYrw02SwingMiddle:
- case kHaierAcYrw02SwingBottom:
- case kHaierAcYrw02SwingDown: _.Button = kHaierAcYrw02ButtonSwing; break;
+ case kHaierAcYrw02SwingVOff:
+ case kHaierAcYrw02SwingVAuto:
+ case kHaierAcYrw02SwingVTop:
+ case kHaierAcYrw02SwingVMiddle:
+ case kHaierAcYrw02SwingVBottom:
+ case kHaierAcYrw02SwingVDown: _.Button = kHaierAcYrw02ButtonSwingV; break;
default: return; // Unexpected value so don't do anything.
}
// Heat mode has no MIDDLE setting, use BOTTOM instead.
- if (pos == kHaierAcYrw02SwingMiddle && _.Mode == kHaierAcYrw02Heat)
- newpos = kHaierAcYrw02SwingBottom;
+ if (pos == kHaierAcYrw02SwingVMiddle && _.Mode == kHaierAcYrw02Heat)
+ newpos = kHaierAcYrw02SwingVBottom;
// BOTTOM is only allowed if we are in Heat mode, otherwise MIDDLE.
- if (pos == kHaierAcYrw02SwingBottom && _.Mode != kHaierAcYrw02Heat)
- newpos = kHaierAcYrw02SwingMiddle;
- _.Swing = newpos;
+ if (pos == kHaierAcYrw02SwingVBottom && _.Mode != kHaierAcYrw02Heat)
+ newpos = kHaierAcYrw02SwingVMiddle;
+ _.SwingV = newpos;
+}
+
+/// Get the Horizontal Swing position setting of the A/C.
+/// @return The native position/mode.
+uint8_t IRHaierAC176::getSwingH(void) const { return _.SwingH; }
+
+/// Set the Horizontal Swing mode of the A/C.
+/// @param[in] pos The position/mode to set the vanes to.
+void IRHaierAC176::setSwingH(uint8_t pos) {
+ switch (pos) {
+ case kHaierAcYrw02SwingHMiddle:
+ case kHaierAcYrw02SwingHLeftMax:
+ case kHaierAcYrw02SwingHLeft:
+ case kHaierAcYrw02SwingHRight:
+ case kHaierAcYrw02SwingHRightMax:
+ case kHaierAcYrw02SwingHAuto: _.Button = kHaierAcYrw02ButtonSwingH; break;
+ default: return; // Unexpected value so don't do anything.
+ }
+ _.SwingH = pos;
}
@@ -867,6 +1002,17 @@ uint16_t IRHaierAC176::getOffTimer(void) const {
return _.OffTimerHrs * 60 + _.OffTimerMins;
}
+/// Get the Lock setting of the A/C.
+/// @return true, the setting is on. false, the setting is off.
+bool IRHaierAC176::getLock(void) const { return _.Lock; }
+
+/// Set the Lock setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRHaierAC176::setLock(const bool on) {
+ _.Button = kHaierAcYrw02ButtonLock;
+ _.Lock = on;
+}
+
/// Convert a stdAc::opmode_t enum into its native mode.
/// @param[in] mode The enum to be converted.
/// @return The native equivalent of the enum.
@@ -900,12 +1046,27 @@ uint8_t IRHaierAC176::convertFan(const stdAc::fanspeed_t speed) {
uint8_t IRHaierAC176::convertSwingV(const stdAc::swingv_t position) {
switch (position) {
case stdAc::swingv_t::kHighest:
- case stdAc::swingv_t::kHigh: return kHaierAcYrw02SwingTop;
- case stdAc::swingv_t::kMiddle: return kHaierAcYrw02SwingMiddle;
- case stdAc::swingv_t::kLow: return kHaierAcYrw02SwingDown;
- case stdAc::swingv_t::kLowest: return kHaierAcYrw02SwingBottom;
- case stdAc::swingv_t::kOff: return kHaierAcYrw02SwingOff;
- default: return kHaierAcYrw02SwingAuto;
+ case stdAc::swingv_t::kHigh: return kHaierAcYrw02SwingVTop;
+ case stdAc::swingv_t::kMiddle: return kHaierAcYrw02SwingVMiddle;
+ case stdAc::swingv_t::kLow: return kHaierAcYrw02SwingVDown;
+ case stdAc::swingv_t::kLowest: return kHaierAcYrw02SwingVBottom;
+ case stdAc::swingv_t::kOff: return kHaierAcYrw02SwingVOff;
+ default: return kHaierAcYrw02SwingVAuto;
+ }
+}
+
+/// Convert a stdAc::swingh_t enum into it's native setting.
+/// @param[in] position The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRHaierAC176::convertSwingH(const stdAc::swingh_t position) {
+ switch (position) {
+ case stdAc::swingh_t::kMiddle: return kHaierAcYrw02SwingHMiddle;
+ case stdAc::swingh_t::kLeftMax: return kHaierAcYrw02SwingHLeftMax;
+ case stdAc::swingh_t::kLeft: return kHaierAcYrw02SwingHLeft;
+ case stdAc::swingh_t::kRight: return kHaierAcYrw02SwingHRight;
+ case stdAc::swingh_t::kRightMax: return kHaierAcYrw02SwingHRightMax;
+ case stdAc::swingh_t::kAuto: return kHaierAcYrw02SwingHAuto;
+ default: return kHaierAcYrw02SwingHMiddle;
}
}
@@ -939,12 +1100,27 @@ stdAc::fanspeed_t IRHaierAC176::toCommonFanSpeed(const uint8_t speed) {
/// @return The native equivalent of the enum.
stdAc::swingv_t IRHaierAC176::toCommonSwingV(const uint8_t pos) {
switch (pos) {
- case kHaierAcYrw02SwingTop: return stdAc::swingv_t::kHighest;
- case kHaierAcYrw02SwingMiddle: return stdAc::swingv_t::kMiddle;
- case kHaierAcYrw02SwingDown: return stdAc::swingv_t::kLow;
- case kHaierAcYrw02SwingBottom: return stdAc::swingv_t::kLowest;
- case kHaierAcYrw02SwingOff: return stdAc::swingv_t::kOff;
- default: return stdAc::swingv_t::kAuto;
+ case kHaierAcYrw02SwingVTop: return stdAc::swingv_t::kHighest;
+ case kHaierAcYrw02SwingVMiddle: return stdAc::swingv_t::kMiddle;
+ case kHaierAcYrw02SwingVDown: return stdAc::swingv_t::kLow;
+ case kHaierAcYrw02SwingVBottom: return stdAc::swingv_t::kLowest;
+ case kHaierAcYrw02SwingVOff: return stdAc::swingv_t::kOff;
+ default: return stdAc::swingv_t::kAuto;
+ }
+}
+
+/// Convert a stdAc::swingh_t enum into it's native setting.
+/// @param[in] pos The enum to be converted.
+/// @return The native equivalent of the enum.
+stdAc::swingh_t IRHaierAC176::toCommonSwingH(const uint8_t pos) {
+ switch (pos) {
+ case kHaierAcYrw02SwingHMiddle: return stdAc::swingh_t::kMiddle;
+ case kHaierAcYrw02SwingHLeftMax: return stdAc::swingh_t::kLeftMax;
+ case kHaierAcYrw02SwingHLeft: return stdAc::swingh_t::kLeft;
+ case kHaierAcYrw02SwingHRight: return stdAc::swingh_t::kRight;
+ case kHaierAcYrw02SwingHRightMax: return stdAc::swingh_t::kRightMax;
+ case kHaierAcYrw02SwingHAuto: return stdAc::swingh_t::kAuto;
+ default: return stdAc::swingh_t::kOff;
}
}
@@ -953,23 +1129,23 @@ stdAc::swingv_t IRHaierAC176::toCommonSwingV(const uint8_t pos) {
stdAc::state_t IRHaierAC176::toCommon(void) const {
stdAc::state_t result;
result.protocol = decode_type_t::HAIER_AC_YRW02;
- result.model = -1; // No models used.
+ result.model = getModel();
result.power = _.Power;
result.mode = toCommonMode(_.Mode);
- result.celsius = true;
+ result.celsius = !_.UseFahrenheit;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
- result.swingv = toCommonSwingV(_.Swing);
+ result.swingv = toCommonSwingV(_.SwingV);
+ result.swingh = toCommonSwingH(_.SwingH);
result.filter = _.Health;
result.sleep = _.Sleep ? 0 : -1;
+ result.turbo = _.Turbo;
+ result.quiet = _.Quiet;
// Not supported.
- result.swingh = stdAc::swingh_t::kOff;
- result.quiet = false;
- result.turbo = false;
result.econo = false;
result.light = false;
result.clean = false;
- result.beep = false;
+ result.beep = true;
result.clock = -1;
return result;
}
@@ -978,8 +1154,9 @@ stdAc::state_t IRHaierAC176::toCommon(void) const {
/// @return A human readable string.
String IRHaierAC176::toString(void) const {
String result = "";
- result.reserve(130); // Reserve some heap for the string to reduce fragging.
- result += addBoolToString(_.Power, kPowerStr, false);
+ result.reserve(280); // Reserve some heap for the string to reduce fragging.
+ result += addModelToString(decode_type_t::HAIER_AC176, getModel(), false);
+ result += addBoolToString(_.Power, kPowerStr);
uint8_t cmd = _.Button;
result += addIntToString(cmd, kButtonStr);
result += kSpaceLBraceStr;
@@ -1005,12 +1182,24 @@ String IRHaierAC176::toString(void) const {
case kHaierAcYrw02ButtonHealth:
result += kHealthStr;
break;
- case kHaierAcYrw02ButtonSwing:
- result += kSwingStr;
+ case kHaierAcYrw02ButtonSwingV:
+ result += kSwingVStr;
+ break;
+ case kHaierAcYrw02ButtonSwingH:
+ result += kSwingHStr;
break;
case kHaierAcYrw02ButtonTurbo:
result += kTurboStr;
break;
+ case kHaierAcYrw02ButtonTimer:
+ result += kTimerStr;
+ break;
+ case kHaierAcYrw02ButtonLock:
+ result += kLockStr;
+ break;
+ case kHaierAcYrw02ButtonCFAB:
+ result += kCelsiusFahrenheitStr;
+ break;
default:
result += kUnknownStr;
}
@@ -1018,51 +1207,49 @@ String IRHaierAC176::toString(void) const {
result += addModeToString(_.Mode, kHaierAcYrw02Auto, kHaierAcYrw02Cool,
kHaierAcYrw02Heat, kHaierAcYrw02Dry,
kHaierAcYrw02Fan);
- result += addTempToString(getTemp());
+ result += addTempToString(getTemp(), !_.UseFahrenheit);
result += addFanToString(_.Fan, kHaierAcYrw02FanHigh, kHaierAcYrw02FanLow,
kHaierAcYrw02FanAuto, kHaierAcYrw02FanAuto,
kHaierAcYrw02FanMed);
- result += addIntToString(_.Turbo, kTurboStr);
+ result += addBoolToString(_.Turbo, kTurboStr);
+ result += addBoolToString(_.Quiet, kQuietStr);
+ result += addIntToString(_.SwingV, kSwingVStr);
result += kSpaceLBraceStr;
- switch (_.Turbo) {
- case kHaierAcYrw02TurboOff:
+ switch (_.SwingV) {
+ case kHaierAcYrw02SwingVOff:
result += kOffStr;
break;
- case kHaierAcYrw02TurboLow:
- result += kLowStr;
- break;
- case kHaierAcYrw02TurboHigh:
- result += kHighStr;
- break;
- default:
- result += kUnknownStr;
- }
- result += ')';
- result += addIntToString(_.Swing, kSwingStr);
- result += kSpaceLBraceStr;
- switch (_.Swing) {
- case kHaierAcYrw02SwingOff:
- result += kOffStr;
- break;
- case kHaierAcYrw02SwingAuto:
+ case kHaierAcYrw02SwingVAuto:
result += kAutoStr;
break;
- case kHaierAcYrw02SwingBottom:
+ case kHaierAcYrw02SwingVBottom:
result += kLowestStr;
break;
- case kHaierAcYrw02SwingDown:
+ case kHaierAcYrw02SwingVDown:
result += kLowStr;
break;
- case kHaierAcYrw02SwingTop:
+ case kHaierAcYrw02SwingVTop:
result += kHighestStr;
break;
- case kHaierAcYrw02SwingMiddle:
+ case kHaierAcYrw02SwingVMiddle:
result += kMiddleStr;
break;
default:
result += kUnknownStr;
}
result += ')';
+ result += addSwingHToString(_.SwingH, kHaierAcYrw02SwingHAuto,
+ kHaierAcYrw02SwingHLeftMax,
+ kHaierAcYrw02SwingHLeft,
+ kHaierAcYrw02SwingHMiddle,
+ kHaierAcYrw02SwingHRight,
+ kHaierAcYrw02SwingHRightMax,
+ // Below are unused.
+ kHaierAcYrw02SwingHMiddle,
+ kHaierAcYrw02SwingHMiddle,
+ kHaierAcYrw02SwingHMiddle,
+ kHaierAcYrw02SwingHMiddle,
+ kHaierAcYrw02SwingHMiddle);
result += addBoolToString(_.Sleep, kSleepStr);
result += addBoolToString(_.Health, kHealthStr);
const uint8_t tmode = getTimerMode();
@@ -1098,6 +1285,7 @@ String IRHaierAC176::toString(void) const {
result += addLabeledString((tmode != kHaierAcYrw02NoTimers &&
tmode != kHaierAcYrw02OnTimer) ?
minsToString(getOffTimer()) : kOffStr, kOffTimerStr);
+ result += addBoolToString(_.Lock, kLockStr);
return result;
}
// End of IRHaierAC176 class.
@@ -1203,7 +1391,7 @@ bool IRrecv::decodeHaierACYRW02(decode_results* results, uint16_t offset,
// Compliance
if (strict) {
- if (results->state[0] != kHaierAcYrw02Prefix) return false;
+ if (results->state[0] != kHaierAcYrw02ModelA) return false;
if (!IRHaierACYRW02::validChecksum(results->state, nbits / 8)) return false;
}
@@ -1236,7 +1424,8 @@ bool IRrecv::decodeHaierAC176(decode_results* results, uint16_t offset,
// Compliance
if (strict) {
- if (results->state[0] != kHaierAcYrw02Prefix) return false;
+ if ((results->state[0] != kHaierAcYrw02ModelA) &&
+ (results->state[0] != kHaierAcYrw02ModelB)) return false;
if (!IRHaierAC176::validChecksum(results->state, nbits / 8)) return false;
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.h
index 2e287cd12..4e5c8e64c 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Haier.h
@@ -1,4 +1,4 @@
-// Copyright 2018 crankyoldgit
+// Copyright 2018-2021 crankyoldgit
/// @file
/// @brief Support for Haier A/C protocols.
/// The specifics of reverse engineering the protocols details:
@@ -13,8 +13,10 @@
// Brand: Haier, Model: HSU07-HEA03 remote (HAIER_AC)
// Brand: Haier, Model: YR-W02 remote (HAIER_AC_YRW02)
// Brand: Haier, Model: HSU-09HMC203 A/C (HAIER_AC_YRW02)
+// Brand: Haier, Model: V9014557 M47 8D remote (HAIER_AC176)
// Brand: Mabe, Model: MMI18HDBWCA6MI8 A/C (HAIER_AC176)
// Brand: Mabe, Model: V12843 HJ200223 remote (HAIER_AC176)
+// Brand: Daichi, Model: D-H A/C (HAIER_AC176)
#ifndef IR_HAIER_H_
#define IR_HAIER_H_
@@ -41,7 +43,7 @@ union HaierProtocol{
// Byte 2
uint8_t CurrHours:5;
uint8_t unknown :1; // value=1
- uint8_t Swing :2;
+ uint8_t SwingV :2;
// Byte 3
uint8_t CurrMins:6;
uint8_t OffTimer:1;
@@ -84,10 +86,10 @@ const uint8_t kHaierAcCmdTimerCancel = 0b1010;
const uint8_t kHaierAcCmdHealth = 0b1100;
const uint8_t kHaierAcCmdSwing = 0b1101;
-const uint8_t kHaierAcSwingOff = 0b00;
-const uint8_t kHaierAcSwingUp = 0b01;
-const uint8_t kHaierAcSwingDown = 0b10;
-const uint8_t kHaierAcSwingChg = 0b11;
+const uint8_t kHaierAcSwingVOff = 0b00;
+const uint8_t kHaierAcSwingVUp = 0b01;
+const uint8_t kHaierAcSwingVDown = 0b10;
+const uint8_t kHaierAcSwingVChg = 0b11;
const uint8_t kHaierAcAuto = 0;
const uint8_t kHaierAcCool = 1;
@@ -118,11 +120,11 @@ const uint8_t kHaierAcSleepBit = 0b01000000;
#define HAIER_AC_CMD_TIMER_SET kHaierAcCmdTimerSet
#define HAIER_AC_CMD_TIMER_CANCEL kHaierAcCmdTimerCancel
#define HAIER_AC_CMD_HEALTH kHaierAcCmdHealth
-#define HAIER_AC_CMD_SWING kHaierAcCmdSwing
-#define HAIER_AC_SWING_OFF kHaierAcSwingOff
-#define HAIER_AC_SWING_UP kHaierAcSwingUp
-#define HAIER_AC_SWING_DOWN kHaierAcSwingDown
-#define HAIER_AC_SWING_CHG kHaierAcSwingChg
+#define HAIER_AC_CMD_SWINGV kHaierAcCmdSwing
+#define HAIER_AC_SWINGV_OFF kHaierAcSwingVOff
+#define HAIER_AC_SWINGV_UP kHaierAcSwingVUp
+#define HAIER_AC_SWINGV_DOWN kHaierAcSwingVDown
+#define HAIER_AC_SWINGV_CHG kHaierAcSwingVChg
#define HAIER_AC_AUTO kHaierAcAuto
#define HAIER_AC_COOL kHaierAcCool
#define HAIER_AC_DRY kHaierAcDry
@@ -133,85 +135,54 @@ const uint8_t kHaierAcSleepBit = 0b01000000;
#define HAIER_AC_FAN_MED kHaierAcFanMed
#define HAIER_AC_FAN_HIGH kHaierAcFanHigh
-/// Native representation of a Haier YRW02 A/C message.
-union HaierYRW02Protocol{
- uint8_t raw[kHaierACYRW02StateLength]; ///< The state in native form
- struct {
- // Byte 0
- uint8_t Prefix;
- // Byte 1
- uint8_t Swing:4;
- uint8_t Temp :4; // 16C~30C
- // Byte 2
- uint8_t :8;
- // Byte 3
- uint8_t :1;
- uint8_t Health:1;
- uint8_t :6;
- // Byte 4
- uint8_t :6;
- uint8_t Power:1;
- uint8_t :1;
- // Byte 5
- uint8_t :5;
- uint8_t Fan:3;
- // Byte 6
- uint8_t :6;
- uint8_t Turbo:2;
- // Byte 7
- uint8_t :5;
- uint8_t Mode:3;
- // Byte 8
- uint8_t :7;
- uint8_t Sleep:1;
- // Byte 9
- uint8_t :8;
- // Byte 10
- uint8_t :8;
- // Byte 11
- uint8_t :8;
- // Byte 12
- uint8_t Button:4;
- uint8_t :4;
- // Byte 13
- uint8_t Sum;
- };
-};
+const uint8_t kHaierAcYrw02MinTempC = 16;
+const uint8_t kHaierAcYrw02MaxTempC = 30;
+const uint8_t kHaierAcYrw02MinTempF = 60;
+const uint8_t kHaierAcYrw02MaxTempF = 86;
+const uint8_t kHaierAcYrw02DefTempC = 25;
-const uint8_t kHaierAcYrw02Prefix = 0xA6;
+const uint8_t kHaierAcYrw02ModelA = 0xA6;
+const uint8_t kHaierAcYrw02ModelB = 0x59;
const uint8_t kHaierAc176Prefix = 0xB7;
-const uint8_t kHaierAcYrw02SwingOff = 0x0;
-const uint8_t kHaierAcYrw02SwingTop = 0x1;
-const uint8_t kHaierAcYrw02SwingMiddle = 0x2; // Not available in heat mode.
-const uint8_t kHaierAcYrw02SwingBottom = 0x3; // Only available in heat mode.
-const uint8_t kHaierAcYrw02SwingDown = 0xA;
-const uint8_t kHaierAcYrw02SwingAuto = 0xC; // Airflow
+const uint8_t kHaierAcYrw02SwingVOff = 0x0;
+const uint8_t kHaierAcYrw02SwingVTop = 0x1;
+const uint8_t kHaierAcYrw02SwingVMiddle = 0x2; // Not available in heat mode.
+const uint8_t kHaierAcYrw02SwingVBottom = 0x3; // Only available in heat mode.
+const uint8_t kHaierAcYrw02SwingVDown = 0xA;
+const uint8_t kHaierAcYrw02SwingVAuto = 0xC; // Airflow
+
+const uint8_t kHaierAcYrw02SwingHMiddle = 0x0;
+const uint8_t kHaierAcYrw02SwingHLeftMax = 0x3;
+const uint8_t kHaierAcYrw02SwingHLeft = 0x4;
+const uint8_t kHaierAcYrw02SwingHRight = 0x5;
+const uint8_t kHaierAcYrw02SwingHRightMax = 0x6;
+const uint8_t kHaierAcYrw02SwingHAuto = 0x7;
const uint8_t kHaierAcYrw02FanHigh = 0b001;
const uint8_t kHaierAcYrw02FanMed = 0b010;
const uint8_t kHaierAcYrw02FanLow = 0b011;
const uint8_t kHaierAcYrw02FanAuto = 0b101; // HAIER_AC176 uses `0` in Fan2
-const uint8_t kHaierAcYrw02TurboOff = 0x0;
-const uint8_t kHaierAcYrw02TurboHigh = 0x1;
-const uint8_t kHaierAcYrw02TurboLow = 0x2;
-
const uint8_t kHaierAcYrw02Auto = 0b000; // 0
const uint8_t kHaierAcYrw02Cool = 0b001; // 1
const uint8_t kHaierAcYrw02Dry = 0b010; // 2
const uint8_t kHaierAcYrw02Heat = 0b100; // 4
const uint8_t kHaierAcYrw02Fan = 0b110; // 5
-const uint8_t kHaierAcYrw02ButtonTempUp = 0x0;
-const uint8_t kHaierAcYrw02ButtonTempDown = 0x1;
-const uint8_t kHaierAcYrw02ButtonSwing = 0x2;
-const uint8_t kHaierAcYrw02ButtonFan = 0x4;
-const uint8_t kHaierAcYrw02ButtonPower = 0x5;
-const uint8_t kHaierAcYrw02ButtonMode = 0x6;
-const uint8_t kHaierAcYrw02ButtonHealth = 0x7;
-const uint8_t kHaierAcYrw02ButtonTurbo = 0x8;
-const uint8_t kHaierAcYrw02ButtonSleep = 0xB;
+const uint8_t kHaierAcYrw02ButtonTempUp = 0b00000;
+const uint8_t kHaierAcYrw02ButtonTempDown = 0b00001;
+const uint8_t kHaierAcYrw02ButtonSwingV = 0b00010;
+const uint8_t kHaierAcYrw02ButtonSwingH = 0b00011;
+const uint8_t kHaierAcYrw02ButtonFan = 0b00100;
+const uint8_t kHaierAcYrw02ButtonPower = 0b00101;
+const uint8_t kHaierAcYrw02ButtonMode = 0b00110;
+const uint8_t kHaierAcYrw02ButtonHealth = 0b00111;
+const uint8_t kHaierAcYrw02ButtonTurbo = 0b01000;
+const uint8_t kHaierAcYrw02ButtonSleep = 0b01011;
+const uint8_t kHaierAcYrw02ButtonTimer = 0b10000;
+const uint8_t kHaierAcYrw02ButtonLock = 0b10100;
+const uint8_t kHaierAcYrw02ButtonCFAB = 0b11010;
const uint8_t kHaierAcYrw02NoTimers = 0b000;
const uint8_t kHaierAcYrw02OffTimer = 0b001;
@@ -224,12 +195,13 @@ union HaierAc176Protocol{
uint8_t raw[kHaierAC176StateLength]; ///< The state in native form
struct {
// Byte 0
- uint8_t Prefix :8;
+ uint8_t Model :8;
// Byte 1
- uint8_t Swing :4;
+ uint8_t SwingV :4;
uint8_t Temp :4; // 16C~30C
// Byte 2
- uint8_t :8;
+ uint8_t :5;
+ uint8_t SwingH :3;
// Byte 3
uint8_t :1;
uint8_t Health :1;
@@ -244,7 +216,8 @@ union HaierAc176Protocol{
uint8_t Fan :3;
// Byte 6
uint8_t OffTimerMins:6;
- uint8_t Turbo:2;
+ uint8_t Turbo :1;
+ uint8_t Quiet :1;
// Byte 7
uint8_t OnTimerHrs :5;
uint8_t Mode :3;
@@ -255,12 +228,16 @@ union HaierAc176Protocol{
// Byte 9
uint8_t :8;
// Byte 10
- uint8_t :8;
+ uint8_t ExtraDegreeF :1;
+ uint8_t :4;
+ uint8_t UseFahrenheit:1;
+ uint8_t :2;
// Byte 11
uint8_t :8;
// Byte 12
- uint8_t Button :4;
- uint8_t :4;
+ uint8_t Button :5;
+ uint8_t Lock :1;
+ uint8_t :2;
// Byte 13
uint8_t Sum :8;
// Byte 14
@@ -295,8 +272,6 @@ union HaierAc176Protocol{
#define HAIER_AC_YRW02_FAN_LOW kHaierAcYrw02FanLow
#define HAIER_AC_YRW02_FAN_AUTO kHaierAcYrw02FanAuto
#define HAIER_AC_YRW02_TURBO_OFF kHaierAcYrw02TurboOff
-#define HAIER_AC_YRW02_TURBO_HIGH kHaierAcYrw02TurboHigh
-#define HAIER_AC_YRW02_TURBO_LOW kHaierAcYrw02TurboLow
#define HAIER_AC_YRW02_AUTO kHaierAcYrw02Auto
#define HAIER_AC_YRW02_COOL kHaierAcYrw02Cool
#define HAIER_AC_YRW02_DRY kHaierAcYrw02Dry
@@ -355,8 +330,8 @@ class IRHaierAC {
uint16_t getCurrTime(void) const;
void setCurrTime(const uint16_t mins);
- uint8_t getSwing(void) const;
- void setSwing(const uint8_t state);
+ uint8_t getSwingV(void) const;
+ void setSwingV(const uint8_t state);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[]);
@@ -400,10 +375,15 @@ class IRHaierAC176 {
void begin(void);
void stateReset(void);
+ void setModel(const haier_ac176_remote_model_t model);
+ haier_ac176_remote_model_t getModel(void) const;
+
void setButton(const uint8_t button);
uint8_t getButton(void) const;
- void setTemp(const uint8_t temp);
+ void setUseFahrenheit(const bool on);
+ bool getUseFahrenheit(void) const;
+ void setTemp(const uint8_t temp, const bool fahrenheit = false);
uint8_t getTemp(void) const;
void setFan(const uint8_t speed);
@@ -422,9 +402,18 @@ class IRHaierAC176 {
bool getHealth(void) const;
void setHealth(const bool on);
- uint8_t getTurbo(void) const;
- void setTurbo(const uint8_t speed);
+ bool getTurbo(void) const;
+ void setTurbo(const bool on);
+ bool getQuiet(void) const;
+ void setQuiet(const bool on);
+ uint8_t getSwingV(void) const;
+ void setSwingV(const uint8_t pos);
+ uint8_t getSwingH(void) const;
+ void setSwingH(const uint8_t pos);
+
+ /// These functions are for backward compatibility.
+ /// Use getSwingV() and setSwingV() instead.
uint8_t getSwing(void) const;
void setSwing(const uint8_t pos);
@@ -435,6 +424,9 @@ class IRHaierAC176 {
void setOffTimer(const uint16_t mins);
uint16_t getOffTimer(void) const;
+ bool getLock(void) const;
+ void setLock(const bool on);
+
uint8_t* getRaw(void);
virtual void setRaw(const uint8_t new_code[]);
static bool validChecksum(const uint8_t state[],
@@ -442,9 +434,13 @@ class IRHaierAC176 {
static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t speed);
static uint8_t convertSwingV(const stdAc::swingv_t position);
+ static uint8_t convertSwingH(const stdAc::swingh_t position);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+ static stdAc::swingh_t toCommonSwingH(const uint8_t pos);
+ static bool toCommonTurbo(const uint8_t speed);
+ static bool toCommonQuiet(const uint8_t speed);
stdAc::state_t toCommon(void) const;
String toString(void) const;
#ifndef UNIT_TEST
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_LG.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_LG.h
index 6010282ca..2bd7dbc1c 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_LG.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_LG.h
@@ -15,6 +15,8 @@
// Brand: LG, Model: AMNW09GSJA0 A/C (LG2 - AKB74955603)
// Brand: LG, Model: AMNW24GTPA1 A/C (LG2 - AKB73757604)
// Brand: LG, Model: AKB73757604 remote (LG2 - AKB73757604)
+// Brand: LG, Model: AKB73315611 remote (LG2 - AKB74955603)
+// Brand: LG, Model: MS05SQ NW0 A/C (LG2 - AKB74955603)
// Brand: General Electric, Model: AG1BH09AW101 Split A/C (LG)
// Brand: General Electric, Model: 6711AR2853M A/C Remote (LG)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.cpp
index 8a573a8dc..a806937b1 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.cpp
@@ -1,15 +1,35 @@
-// Copyright 2020 David Conran (crankyoldgit)
+// Copyright 2020-2021 David Conran (crankyoldgit)
/// @file
/// @brief Support for Mirage protocol
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1289
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1573
-// Supports:
-// Brand: Mirage, Model: VLU series A/C
+#include "ir_Mirage.h"
+#include
+#include
+#ifndef ARDUINO
+#include
+#endif
#include "IRrecv.h"
#include "IRsend.h"
+#include "IRtext.h"
#include "IRutils.h"
+using irutils::addBoolToString;
+using irutils::addFanToString;
+using irutils::addIntToString;
+using irutils::addLabeledString;
+using irutils::addModeToString;
+using irutils::addModelToString;
+using irutils::addSwingHToString;
+using irutils::addSwingVToString;
+using irutils::addTempToString;
+using irutils::addToggleToString;
+using irutils::minsToString;
+using irutils::bcdToUint8;
+using irutils::uint8ToBcd;
+using irutils::sumNibbles;
// Constants
const uint16_t kMirageHdrMark = 8360; ///< uSeconds
@@ -20,6 +40,9 @@ const uint16_t kMirageZeroSpace = 545; ///< uSeconds
const uint32_t kMirageGap = kDefaultMessageGap; ///< uSeconds (just a guess)
const uint16_t kMirageFreq = 38000; ///< Hz. (Just a guess)
+const uint8_t kMirageAcKKG29AC1PowerOn = 0b00; // 0
+const uint8_t kMirageAcKKG29AC1PowerOff = 0b11; // 3
+
#if SEND_MIRAGE
/// Send a Mirage formatted message.
@@ -58,6 +81,8 @@ bool IRrecv::decodeMirage(decode_results *results, uint16_t offset,
kMirageBitMark, kMirageZeroSpace,
kMirageBitMark, kMirageGap, true,
kUseDefTol, kMarkExcess, false)) return false;
+ // Compliance
+ if (strict && !IRMirageAc::validChecksum(results->state)) return false;
// Success
results->decode_type = decode_type_t::MIRAGE;
@@ -67,4 +92,756 @@ bool IRrecv::decodeMirage(decode_results *results, uint16_t offset,
// is a union data type.
return true;
}
+
+// Code to emulate Mirage A/C IR remote control unit.
+
+/// Class constructor
+/// @param[in] pin GPIO to be used when sending.
+/// @param[in] inverted Is the output signal to be inverted?
+/// @param[in] use_modulation Is frequency modulation to be used?
+IRMirageAc::IRMirageAc(const uint16_t pin, const bool inverted,
+ const bool use_modulation)
+ : _irsend(pin, inverted, use_modulation) { stateReset(); }
+
+/// Reset the state of the remote to a known good state/sequence.
+void IRMirageAc::stateReset(void) {
+ // The state of the IR remote in IR code form.
+ static const uint8_t kReset[kMirageStateLength] = {
+ 0x56, 0x6C, 0x00, 0x00, 0x20, 0x1A, 0x00, 0x00,
+ 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x42};
+ setRaw(kReset);
+ _model = mirage_ac_remote_model_t::KKG9AC1;
+}
+
+/// Set up hardware to be able to send a message.
+void IRMirageAc::begin(void) { _irsend.begin(); }
+
+#if SEND_MITSUBISHI_AC
+/// Send the current internal state as an IR message.
+/// @param[in] repeat Nr. of times the message will be repeated.
+void IRMirageAc::send(const uint16_t repeat) {
+ _irsend.sendMirage(getRaw(), kMirageStateLength, repeat);
+ // Reset any toggles after a send.
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ setCleanToggle(false);
+ setLight(false); // For this model (only), Light is a toggle.
+ break;
+ default:
+ break;
+ }
+}
+#endif // SEND_MITSUBISHI_AC
+
+/// Get a PTR to the internal state/code for this protocol.
+/// @return PTR to a code for this protocol based on the current internal state.
+uint8_t *IRMirageAc::getRaw(void) {
+ checksum();
+ return _.raw;
+}
+
+/// Set the internal state from a valid code for this protocol.
+/// @param[in] data A valid code for this protocol.
+void IRMirageAc::setRaw(const uint8_t *data) {
+ std::memcpy(_.raw, data, kMirageStateLength);
+ _model = getModel(true);
+}
+
+/// Guess the Mirage remote model from the supplied state code.
+/// @param[in] state A valid state code for this protocol.
+/// @return The model code.
+/// @note This result isn't perfect. Both protocols can look the same but have
+/// wildly different settings.
+mirage_ac_remote_model_t IRMirageAc::getModel(const uint8_t *state) {
+ Mirage120Protocol p;
+ std::memcpy(p.raw, state, kMirageStateLength);
+ // Check for KKG29AC1 specific settings.
+ if (p.RecycleHeat || p.Filter || p.Sleep_Kkg29ac1 || p.CleanToggle ||
+ p.IFeel || p.OffTimerEnable || p.OnTimerEnable)
+ return mirage_ac_remote_model_t::KKG29AC1;
+ // Check for things specific to KKG9AC1
+ if ((p.Minutes || p.Seconds) || // Is part of the clock set?
+ // Are the timer times set, but not enabled? (enable check filtered above)
+ (p.OffTimerHours || p.OffTimerMins) ||
+ (p.OnTimerHours || p.OnTimerMins))
+ return mirage_ac_remote_model_t::KKG9AC1;
+ // As the above test has a 1 in 3600+ (for 1 second an hour) chance of a false
+ // negative in theory, we are going assume that anything left should be a
+ // KKG29AC1 model.
+ return mirage_ac_remote_model_t::KKG29AC1; // Default.
+}
+
+/// Get the model code of the interal message state.
+/// @param[in] useRaw If set, we try to get the model info from just the state.
+/// @return The model code.
+mirage_ac_remote_model_t IRMirageAc::getModel(const bool useRaw) const {
+ return useRaw ? getModel(_.raw) : _model;
+}
+
+/// Set the model code of the interal message state.
+/// @param[in] model The desired model to use for the settings.
+void IRMirageAc::setModel(const mirage_ac_remote_model_t model) {
+ if (model != _model) { // Only change things if we need to.
+ // Save the old settings.
+ stdAc::state_t state = toCommon();
+ const uint16_t ontimer = getOnTimer();
+ const uint16_t offtimer = getOffTimer();
+ const bool ifeel = getIFeel();
+ const uint8_t sensor = getSensorTemp();
+ // Change the model.
+ state.model = model;
+ // Restore/Convert the settings.
+ fromCommon(state);
+ setOnTimer(ontimer);
+ setOffTimer(offtimer);
+ setIFeel(ifeel);
+ setSensorTemp(sensor);
+ }
+}
+
+/// Calculate and set the checksum values for the internal state.
+void IRMirageAc::checksum(void) { _.Sum = calculateChecksum(_.raw); }
+
+/// Verify the checksum is valid for a given state.
+/// @param[in] data The array to verify the checksum of.
+/// @return true, if the state has a valid checksum. Otherwise, false.
+bool IRMirageAc::validChecksum(const uint8_t *data) {
+ return calculateChecksum(data) == data[kMirageStateLength - 1];
+}
+
+/// Calculate the checksum for a given state.
+/// @param[in] data The value to calc the checksum of.
+/// @return The calculated checksum value.
+uint8_t IRMirageAc::calculateChecksum(const uint8_t *data) {
+ return sumNibbles(data, kMirageStateLength - 1);
+}
+
+/// Set the requested power state of the A/C to on.
+void IRMirageAc::on(void) { setPower(true); }
+
+/// Set the requested power state of the A/C to off.
+void IRMirageAc::off(void) { setPower(false); }
+
+/// Change the power setting.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setPower(bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Power = on ? kMirageAcKKG29AC1PowerOn : kMirageAcKKG29AC1PowerOff;
+ break;
+ default:
+ // In order to change the power setting, it seems must be less than
+ // kMirageAcPowerOff. kMirageAcPowerOff is larger than half of the
+ // possible value stored in the allocated bit space.
+ // Thus if the value is larger than kMirageAcPowerOff the power is off.
+ // Less than, then power is on.
+ // We can't just aribitarily add or subtract the value (which analysis
+ // indicates is how the power status changes. Very weird, I know!) as that
+ // is not an idempotent action, we must check if the addition or
+ // substraction is needed first. e.g. via getPower()
+ // i.e. If we added or subtracted twice, we would cause a wrap of the
+ // integer and not get the desired result.
+ if (on)
+ _.SwingAndPower -= getPower() ? 0 : kMirageAcPowerOff;
+ else
+ _.SwingAndPower += getPower() ? kMirageAcPowerOff : 0;
+ }
+}
+
+/// Get the value of the current power setting.
+/// @return true, the setting is on. false, the setting is off.
+bool IRMirageAc::getPower(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return _.Power == kMirageAcKKG29AC1PowerOn;
+ default:
+ return _.SwingAndPower < kMirageAcPowerOff;
+ }
+}
+
+/// Get the operating mode setting of the A/C.
+/// @return The current operating mode setting.
+uint8_t IRMirageAc::getMode(void) const { return _.Mode; }
+
+/// Set the operating mode of the A/C.
+/// @param[in] mode The desired operating mode.
+void IRMirageAc::setMode(const uint8_t mode) {
+ switch (mode) {
+ case kMirageAcCool:
+ case kMirageAcDry:
+ case kMirageAcHeat:
+ case kMirageAcFan:
+ case kMirageAcRecycle:
+ _.Mode = mode;
+ // Reset turbo if we have to.
+ setTurbo(getTurbo());
+ break;
+ default: // Default to cool mode for anything else.
+ setMode(kMirageAcCool);
+ }
+}
+
+/// Set the temperature.
+/// @param[in] degrees The temperature in degrees celsius.
+void IRMirageAc::setTemp(const uint8_t degrees) {
+ // Make sure we have desired temp in the correct range.
+ uint8_t celsius = std::max(degrees, kMirageAcMinTemp);
+ _.Temp = std::min(celsius, kMirageAcMaxTemp) + kMirageAcTempOffset;
+}
+
+/// Get the current temperature setting.
+/// @return The current setting for temp. in degrees celsius.
+uint8_t IRMirageAc::getTemp(void) const { return _.Temp - kMirageAcTempOffset; }
+
+/// Set the speed of the fan.
+/// @param[in] speed The desired setting.
+void IRMirageAc::setFan(const uint8_t speed) {
+ _.Fan = (speed <= kMirageAcFanLow) ? speed : kMirageAcFanAuto;
+}
+
+/// Get the current fan speed setting.
+/// @return The current fan speed/mode.
+uint8_t IRMirageAc::getFan(void) const { return _.Fan; }
+
+/// Change the Turbo setting.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setTurbo(bool on) {
+ const bool value = (on && (getMode() == kMirageAcCool));
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Turbo_Kkg29ac1 = value;
+ break;
+ default:
+ _.Turbo_Kkg9ac1 = value;
+ }
+}
+
+/// Get the value of the current Turbo setting.
+/// @return true, the setting is on. false, the setting is off.
+bool IRMirageAc::getTurbo(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.Turbo_Kkg29ac1;
+ default: return _.Turbo_Kkg9ac1;
+ }
+}
+
+/// Change the Sleep setting.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setSleep(bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Sleep_Kkg29ac1 = on;
+ break;
+ default:
+ _.Sleep_Kkg9ac1 = on;
+ }
+}
+
+/// Get the value of the current Sleep setting.
+/// @return true, the setting is on. false, the setting is off.
+bool IRMirageAc::getSleep(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.Sleep_Kkg29ac1;
+ default: return _.Sleep_Kkg9ac1;
+ }
+}
+
+/// Change the Light/Display setting.
+/// @param[in] on true, the setting is on. false, the setting is off.
+/// @note Light is a toggle on the KKG29AC1 model.
+void IRMirageAc::setLight(bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.LightToggle_Kkg29ac1 = on;
+ break;
+ default:
+ _.Light_Kkg9ac1 = on;
+ }
+}
+
+/// Get the value of the current Light/Display setting.
+/// @return true, the setting is on. false, the setting is off.
+/// @note Light is a toggle on the KKG29AC1 model.
+bool IRMirageAc::getLight(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.LightToggle_Kkg29ac1;
+ default: return _.Light_Kkg9ac1;
+ }
+}
+
+/// Get the clock time of the A/C unit.
+/// @return Nr. of seconds past midnight.
+uint32_t IRMirageAc::getClock(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return 0;
+ default:
+ return ((bcdToUint8(_.Hours) * 60) + bcdToUint8(_.Minutes)) * 60 +
+ bcdToUint8(_.Seconds);
+ }
+}
+
+/// Set the clock time on the A/C unit.
+/// @param[in] nr_of_seconds Nr. of seconds past midnight.
+void IRMirageAc::setClock(const uint32_t nr_of_seconds) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Minutes = _.Seconds = 0; // No clock setting. Clear it just in case.
+ break;
+ default:
+ uint32_t remaining = std::min(
+ nr_of_seconds, (uint32_t)(24 * 60 * 60 - 1)); // Limit to 23:59:59.
+ _.Seconds = uint8ToBcd(remaining % 60);
+ remaining /= 60;
+ _.Minutes = uint8ToBcd(remaining % 60);
+ remaining /= 60;
+ _.Hours = uint8ToBcd(remaining);
+ }
+}
+
+/// Set the Vertical Swing setting/position of the A/C.
+/// @param[in] position The desired swing setting.
+void IRMirageAc::setSwingV(const uint8_t position) {
+ switch (position) {
+ case kMirageAcSwingVOff:
+ case kMirageAcSwingVLowest:
+ case kMirageAcSwingVLow:
+ case kMirageAcSwingVMiddle:
+ case kMirageAcSwingVHigh:
+ case kMirageAcSwingVHighest:
+ case kMirageAcSwingVAuto:
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.SwingV = (position != kMirageAcSwingVOff);
+ break;
+ default:
+ const bool power = getPower();
+ _.SwingAndPower = position;
+ // Power needs to be reapplied after overwriting SwingAndPower
+ setPower(power);
+ }
+ break;
+ default: // Default to Auto for anything else.
+ setSwingV(kMirageAcSwingVAuto);
+ }
+}
+
+/// Get the Vertical Swing setting/position of the A/C.
+/// @return The desired Vertical Swing setting/position.
+uint8_t IRMirageAc::getSwingV(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return _.SwingV ? kMirageAcSwingVAuto : kMirageAcSwingVOff;
+ default:
+ return _.SwingAndPower - (getPower() ? 0 : kMirageAcPowerOff);
+ }
+}
+
+/// Set the Horizontal Swing setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setSwingH(const bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.SwingH = on;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the Horizontal Swing setting of the A/C.
+/// @return on true, the setting is on. false, the setting is off.
+bool IRMirageAc::getSwingH(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.SwingH;
+ default: return false;
+ }
+}
+
+/// Set the Quiet setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setQuiet(const bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Quiet = on;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the Quiet setting of the A/C.
+/// @return on true, the setting is on. false, the setting is off.
+bool IRMirageAc::getQuiet(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.Quiet;
+ default: return false;
+ }
+}
+
+/// Set the CleanToggle setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setCleanToggle(const bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.CleanToggle = on;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the Clean Toggle setting of the A/C.
+/// @return on true, the setting is on. false, the setting is off.
+bool IRMirageAc::getCleanToggle(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.CleanToggle;
+ default: return false;
+ }
+}
+
+/// Set the Filter setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setFilter(const bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.Filter = on;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the Filter setting of the A/C.
+/// @return on true, the setting is on. false, the setting is off.
+bool IRMirageAc::getFilter(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.Filter;
+ default: return false;
+ }
+}
+
+/// Set the IFeel setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRMirageAc::setIFeel(const bool on) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.IFeel = on;
+ if (on) {
+ // If no previous sensor temp, default to currently desired temp.
+ if (!_.SensorTemp) _.SensorTemp = getTemp();
+ } else {
+ _.SensorTemp = 0; // When turning it off, clear the Sensor Temp.
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the IFeel setting of the A/C.
+/// @return on true, the setting is on. false, the setting is off.
+bool IRMirageAc::getIFeel(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1: return _.IFeel;
+ default: return false;
+ }
+}
+
+/// Set the Sensor Temp setting of the A/C's remote.
+/// @param[in] degrees The desired sensor temp. in degrees celsius.
+void IRMirageAc::setSensorTemp(const uint8_t degrees) {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.SensorTemp = std::min(kMirageAcSensorTempMax, degrees) +
+ kMirageAcSensorTempOffset;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the Sensor Temp setting of the A/C's remote.
+/// @return The current setting for the sensor temp. in degrees celsius.
+uint16_t IRMirageAc::getSensorTemp(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return _.SensorTemp - kMirageAcSensorTempOffset;
+ default:
+ return false;
+ }
+}
+
+/// Get the number of minutes the On Timer is currently set for.
+/// @return Nr. of Minutes the timer is set for. 0, is the timer is not in use.
+uint16_t IRMirageAc::getOnTimer(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return _.OnTimerEnable ? _.OnTimerHours * 60 + _.OnTimerMins : 0;
+ default:
+ return 0;
+ }
+}
+
+/// Set the number of minutes for the On Timer.
+/// @param[in] nr_of_mins How long to set the timer for. 0 disables the timer.
+void IRMirageAc::setOnTimer(const uint16_t nr_of_mins) {
+ uint16_t mins = std::min(nr_of_mins, (uint16_t)(24 * 60));
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.OnTimerEnable = (mins > 0);
+ _.OnTimerHours = mins / 60;
+ _.OnTimerMins = mins % 60;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Get the number of minutes the Off Timer is currently set for.
+/// @return Nr. of Minutes the timer is set for. 0, is the timer is not in use.
+uint16_t IRMirageAc::getOffTimer(void) const {
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ return _.OffTimerEnable ? _.OffTimerHours * 60 + _.OffTimerMins : 0;
+ default:
+ return 0;
+ }
+}
+
+/// Set the number of minutes for the Off Timer.
+/// @param[in] nr_of_mins How long to set the timer for. 0 disables the timer.
+void IRMirageAc::setOffTimer(const uint16_t nr_of_mins) {
+ uint16_t mins = std::min(nr_of_mins, (uint16_t)(24 * 60));
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ _.OffTimerEnable = (mins > 0);
+ _.OffTimerHours = mins / 60;
+ _.OffTimerMins = mins % 60;
+ break;
+ default:
+ break;
+ }
+}
+
+/// Convert a native mode into its stdAc equivalent.
+/// @param[in] mode The native setting to be converted.
+/// @return The stdAc equivalent of the native setting.
+stdAc::opmode_t IRMirageAc::toCommonMode(const uint8_t mode) {
+ switch (mode) {
+ case kMirageAcHeat: return stdAc::opmode_t::kHeat;
+ case kMirageAcDry: return stdAc::opmode_t::kDry;
+ case kMirageAcFan: return stdAc::opmode_t::kFan;
+ default: return stdAc::opmode_t::kCool;
+ }
+}
+
+/// Convert a native fan speed into its stdAc equivalent.
+/// @param[in] speed The native setting to be converted.
+/// @param[in] model The model type to use to influence the conversion.
+/// @return The stdAc equivalent of the native setting.
+stdAc::fanspeed_t IRMirageAc::toCommonFanSpeed(const uint8_t speed,
+ const mirage_ac_remote_model_t model) {
+ switch (model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ switch (speed) {
+ case kMirageAcKKG29AC1FanHigh: return stdAc::fanspeed_t::kHigh;
+ case kMirageAcKKG29AC1FanMed: return stdAc::fanspeed_t::kMedium;
+ case kMirageAcKKG29AC1FanLow: return stdAc::fanspeed_t::kLow;
+ default: return stdAc::fanspeed_t::kAuto;
+ }
+ break;
+ default:
+ switch (speed) {
+ case kMirageAcFanHigh: return stdAc::fanspeed_t::kHigh;
+ case kMirageAcFanMed: return stdAc::fanspeed_t::kMedium;
+ case kMirageAcFanLow: return stdAc::fanspeed_t::kLow;
+ default: return stdAc::fanspeed_t::kAuto;
+ }
+ }
+}
+
+/// Convert a stdAc::opmode_t enum into its native mode.
+/// @param[in] mode The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRMirageAc::convertMode(const stdAc::opmode_t mode) {
+ switch (mode) {
+ case stdAc::opmode_t::kHeat: return kMirageAcHeat;
+ case stdAc::opmode_t::kDry: return kMirageAcDry;
+ case stdAc::opmode_t::kFan: return kMirageAcFan;
+ default: return kMirageAcCool;
+ }
+}
+
+/// Convert a stdAc::fanspeed_t enum into it's native speed.
+/// @param[in] speed The enum to be converted.
+/// @param[in] model The model type to use to influence the conversion.
+/// @return The native equivalent of the enum.
+uint8_t IRMirageAc::convertFan(const stdAc::fanspeed_t speed,
+ const mirage_ac_remote_model_t model) {
+ uint8_t low;
+ uint8_t med;
+ switch (model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ low = kMirageAcKKG29AC1FanLow;
+ med = kMirageAcKKG29AC1FanMed;
+ break;
+ default:
+ low = kMirageAcFanLow;
+ med = kMirageAcFanMed;
+ }
+ switch (speed) {
+ case stdAc::fanspeed_t::kMin:
+ case stdAc::fanspeed_t::kLow: return low;
+ case stdAc::fanspeed_t::kMedium: return med;
+ case stdAc::fanspeed_t::kHigh:
+ case stdAc::fanspeed_t::kMax: return kMirageAcFanHigh;
+ default: return kMirageAcFanAuto;
+ }
+}
+
+/// Convert a stdAc::swingv_t enum into it's native setting.
+/// @param[in] position The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRMirageAc::convertSwingV(const stdAc::swingv_t position) {
+ switch (position) {
+ case stdAc::swingv_t::kHighest: return kMirageAcSwingVHighest;
+ case stdAc::swingv_t::kHigh: return kMirageAcSwingVHigh;
+ case stdAc::swingv_t::kMiddle: return kMirageAcSwingVMiddle;
+ case stdAc::swingv_t::kLow: return kMirageAcSwingVLow;
+ case stdAc::swingv_t::kLowest: return kMirageAcSwingVLowest;
+ case stdAc::swingv_t::kOff: return kMirageAcSwingVOff;
+ default: return kMirageAcSwingVAuto;
+ }
+}
+
+/// Convert a native vertical swing postion to it's common equivalent.
+/// @param[in] pos A native position to convert.
+/// @return The common vertical swing position.
+stdAc::swingv_t IRMirageAc::toCommonSwingV(const uint8_t pos) {
+ switch (pos) {
+ case kMirageAcSwingVHighest: return stdAc::swingv_t::kHighest;
+ case kMirageAcSwingVHigh: return stdAc::swingv_t::kHigh;
+ case kMirageAcSwingVMiddle: return stdAc::swingv_t::kMiddle;
+ case kMirageAcSwingVLow: return stdAc::swingv_t::kLow;
+ case kMirageAcSwingVLowest: return stdAc::swingv_t::kLowest;
+ case kMirageAcSwingVAuto: return stdAc::swingv_t::kAuto;
+ default: return stdAc::swingv_t::kOff;
+ }
+}
+
+/// Convert the current internal state into its stdAc::state_t equivalent.
+/// @return The stdAc equivalent of the native settings.
+stdAc::state_t IRMirageAc::toCommon(void) const {
+ stdAc::state_t result;
+ result.protocol = decode_type_t::MIRAGE;
+ result.model = _model;
+ result.power = getPower();
+ result.mode = toCommonMode(_.Mode);
+ result.celsius = true;
+ result.degrees = getTemp();
+ result.fanspeed = toCommonFanSpeed(getFan(), _model);
+ result.swingv = toCommonSwingV(getSwingV());
+ result.swingh = getSwingH() ? stdAc::swingh_t::kAuto : stdAc::swingh_t::kOff;
+ result.turbo = getTurbo();
+ result.light = getLight();
+ result.clean = getCleanToggle();
+ result.filter = getFilter();
+ result.sleep = getSleep() ? 0 : -1;
+ result.quiet = getQuiet();
+ result.clock = getClock() / 60;
+ // Not supported.
+ result.econo = false;
+ result.beep = false;
+ return result;
+}
+
+/// Convert & set a stdAc::state_t to its equivalent internal settings.
+/// @param[in] state The desired state in stdAc::state_t form.
+void IRMirageAc::fromCommon(const stdAc::state_t state) {
+ stateReset();
+ _model = (mirage_ac_remote_model_t)state.model; // Set directly to avoid loop
+ setPower(state.power);
+ setTemp(state.celsius ? state.degrees : fahrenheitToCelsius(state.degrees));
+ setMode(convertMode(state.mode));
+ setFan(convertFan(state.fanspeed, _model));
+ setTurbo(state.turbo);
+ setSleep(state.sleep >= 0);
+ setLight(state.light);
+ setSwingV(convertSwingV(state.swingv));
+ setSwingH(state.swingh != stdAc::swingh_t::kOff);
+ setQuiet(state.quiet);
+ setCleanToggle(state.clean);
+ setFilter(state.filter);
+ // setClock() expects seconds, not minutes.
+ setClock((state.clock > 0) ? state.clock * 60 : 0);
+ // Non-common settings.
+ setOnTimer(0);
+ setOffTimer(0);
+ setIFeel(false);
+}
+
+/// Convert the internal state into a human readable string.
+/// @return A string containing the settings in human-readable form.
+String IRMirageAc::toString(void) const {
+ String result = "";
+ result.reserve(240); // Reserve some heap for the string to reduce fragging.
+ result += addModelToString(decode_type_t::MIRAGE, _model, false);
+ result += addBoolToString(getPower(), kPowerStr);
+ result += addModeToString(_.Mode, 0xFF, kMirageAcCool,
+ kMirageAcHeat, kMirageAcDry,
+ kMirageAcFan);
+ result += addTempToString(getTemp());
+ uint8_t fanlow;
+ uint8_t fanmed;
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ fanlow = kMirageAcKKG29AC1FanLow;
+ fanmed = kMirageAcKKG29AC1FanMed;
+ break;
+ default: // e.g. Model KKG9AC1
+ fanlow = kMirageAcFanLow;
+ fanmed = kMirageAcFanMed;
+ }
+ result += addFanToString(_.Fan, kMirageAcFanHigh, fanlow, kMirageAcFanAuto,
+ kMirageAcFanAuto, fanmed);
+ result += addBoolToString(getTurbo(), kTurboStr);
+ result += addBoolToString(getSleep(), kSleepStr);
+ switch (_model) {
+ case mirage_ac_remote_model_t::KKG29AC1:
+ result += addBoolToString(_.Quiet, kQuietStr);
+ result += addToggleToString(getLight(), kLightStr);
+ result += addBoolToString(_.SwingV, kSwingVStr);
+ result += addBoolToString(_.SwingH, kSwingHStr);
+ result += addBoolToString(_.Filter, kFilterStr);
+ result += addToggleToString(_.CleanToggle, kCleanStr);
+ result += addLabeledString(getOnTimer() ? minsToString(getOnTimer())
+ : kOffStr,
+ kOnTimerStr);
+ result += addLabeledString(getOffTimer() ? minsToString(getOffTimer())
+ : kOffStr,
+ kOffTimerStr);
+ result += addBoolToString(_.IFeel, kIFeelStr);
+ if (_.IFeel) {
+ result += addIntToString(getSensorTemp(), kSensorTempStr);
+ result += 'C';
+ }
+ break;
+ default: // e.g. Model KKG9AC1
+ result += addBoolToString(getLight(), kLightStr);
+ result += addSwingVToString(getSwingV(),
+ kMirageAcSwingVAuto,
+ kMirageAcSwingVHighest,
+ kMirageAcSwingVHigh,
+ 0xFF, // Unused.
+ kMirageAcSwingVMiddle,
+ 0xFF, // Unused.
+ kMirageAcSwingVLow,
+ kMirageAcSwingVLowest,
+ kMirageAcSwingVOff,
+ 0xFF, 0xFF, 0xFF); // Unused.
+ result += addLabeledString(minsToString(getClock() / 60), kClockStr);
+ }
+ return result;
+}
#endif // DECODE_MIRAGE
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.h
new file mode 100644
index 000000000..b2b39e759
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mirage.h
@@ -0,0 +1,277 @@
+// Copyright 2020-2021 David Conran (crankyoldgit)
+/// @file
+/// @brief Support for Mirage protocol
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1289
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1573
+
+
+// Supports:
+// Brand: Mirage, Model: VLU series A/C
+// Brand: Maxell, Model: MX-CH18CF A/C
+// Brand: Maxell, Model: KKG9A-C1 remote
+// Brand: Tronitechnik, Model: Reykir 9000 A/C
+// Brand: Tronitechnik, Model: KKG29A-C1 remote
+
+#ifndef IR_MIRAGE_H_
+#define IR_MIRAGE_H_
+
+#define __STDC_LIMIT_MACROS
+#include
+#ifndef UNIT_TEST
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRsend.h"
+#ifdef UNIT_TEST
+#include "IRsend_test.h"
+#endif
+
+/// Native representation of a Mirage 120-bit A/C message.
+/// @see https://docs.google.com/spreadsheets/d/1Ucu9mOOIIJoWQjUJq_VCvwgV3EwKaRk8K2AuZgccYEk/edit#gid=0
+union Mirage120Protocol{
+ uint8_t raw[kMirageStateLength]; ///< The state in code form.
+ struct { // Common
+ // Byte 0
+ uint8_t Header :8; // Header. (0x56)
+ // Byte 1
+ uint8_t Temp :8; // Celsius minus 0x5C.
+ // Byte 2
+ uint8_t :8; // Unknown / Unused.
+ // Byte 3
+ uint8_t :8; // Unknown / Unused.
+ // Byte 4
+ uint8_t Fan :2; // Fan Speed.
+ uint8_t :2; // Unknown / Unused.
+ uint8_t Mode :4; // Cool, Heat, Dry, Fan, Recycle
+ // Byte 5
+ uint8_t :8;
+ // Byte 6
+ uint8_t :8;
+ // Byte 7
+ uint8_t :8;
+ // Byte 8
+ uint8_t :8;
+ // Byte 9
+ uint8_t :8;
+ // Byte 10
+ uint8_t :8;
+ // Byte 11
+ uint8_t :8;
+ // Byte 12
+ uint8_t :8;
+ // Byte 13
+ uint8_t :8;
+ // Byte 14
+ uint8_t Sum :8; // Sum of all the previous nibbles.
+ };
+ struct { // KKG9AC1 remote
+ // Byte 0
+ uint8_t :8; // Header
+ // Byte 1
+ uint8_t :8; // Temp
+ // Byte 2
+ uint8_t :8; // Unknown / Unused.
+ // Byte 3
+ uint8_t :3; // Unknown / Unused.
+ uint8_t Light_Kkg9ac1 :1; // Aka. Display. Seems linked to Sleep mode.
+ uint8_t :4; // Unknown / Unused.
+ // Byte 4
+ uint8_t :8; // Fan & Mode
+ // Byte 5
+ uint8_t :1; // Unknown
+ uint8_t SwingAndPower :7;
+ // Byte 6
+ uint8_t :7; // Unknown / Unused.
+ uint8_t Sleep_Kkg9ac1 :1; // Sleep mode on or off.
+ // Byte 7
+ uint8_t :3; // Unknown / Unused.
+ uint8_t Turbo_Kkg9ac1 :1; // Turbo mode on or off. Only works in Cool mode.
+ uint8_t :4; // Unknown / Unused.
+ // Byte 8
+ uint8_t :8; // Unknown / Unused.
+ // Byte 9
+ uint8_t :8; // Unknown / Unused.
+ // Byte 10
+ uint8_t :8; // Unknown / Unused.
+ // Byte 11
+ uint8_t Seconds :8; // Nr. of Seconds in BCD.
+ // Byte 12
+ uint8_t Minutes :8; // Nr. of Minutes in BCD.
+ // Byte 13
+ uint8_t Hours :8; // Nr. of Hours in BCD.
+ // Byte 14
+ uint8_t :8; // Sum
+ };
+ struct { // KKG29A-C1 remote
+ // Byte 0
+ uint8_t :8; // Header
+ // Byte 1
+ uint8_t :8; // Temp
+ // Byte 2
+ uint8_t :8;
+ // Byte 3
+ uint8_t Quiet :1;
+ uint8_t :7;
+ // Byte 4
+ uint8_t :2; // Fan
+ uint8_t OffTimerEnable :1;
+ uint8_t OnTimerEnable :1;
+ uint8_t :3; // Mode
+ uint8_t :1;
+ // Byte 5
+ uint8_t SwingH :1;
+ uint8_t SwingV :1;
+ uint8_t LightToggle_Kkg29ac1 :1; // Aka. Display Toggle.
+ uint8_t :3;
+ uint8_t Power :2;
+ // Byte 6
+ uint8_t :1;
+ uint8_t Filter :1; // Aka. UVC
+ uint8_t :1;
+ uint8_t Sleep_Kkg29ac1 :1; // Sleep mode on or off.
+ uint8_t :2;
+ uint8_t RecycleHeat :1;
+ uint8_t :1;
+ // Byte 7
+ uint8_t SensorTemp :6; // Temperature at the remote
+ uint8_t CleanToggle :1;
+ uint8_t IFeel :1;
+ // Byte 8
+ uint8_t OnTimerHours :5;
+ uint8_t :2;
+ uint8_t Turbo_Kkg29ac1 :1; // Turbo mode on or off.
+ // Byte 9
+ uint8_t OnTimerMins :6;
+ uint8_t :2;
+ // Byte 10
+ uint8_t OffTimerHours :5;
+ uint8_t :3;
+ // Byte 11
+ uint8_t OffTimerMins :6;
+ uint8_t :2;
+ // Byte 12
+ uint8_t :8;
+ // Byte 13
+ uint8_t :8;
+ // Byte 14
+ uint8_t :8; // Sum
+ };
+};
+
+// Constants
+const uint8_t kMirageAcHeat = 0b001; // 1
+const uint8_t kMirageAcCool = 0b010; // 2
+const uint8_t kMirageAcDry = 0b011; // 3
+const uint8_t kMirageAcRecycle = 0b100; // 4
+const uint8_t kMirageAcFan = 0b101; // 5
+
+const uint8_t kMirageAcFanAuto = 0b00; // 0
+const uint8_t kMirageAcFanHigh = 0b01; // 1
+const uint8_t kMirageAcFanMed = 0b10; // 2
+const uint8_t kMirageAcFanLow = 0b11; // 3
+const uint8_t kMirageAcKKG29AC1FanAuto = 0b00; // 0
+const uint8_t kMirageAcKKG29AC1FanHigh = 0b01; // 1
+const uint8_t kMirageAcKKG29AC1FanLow = 0b10; // 2
+const uint8_t kMirageAcKKG29AC1FanMed = 0b11; // 3
+
+const uint8_t kMirageAcMinTemp = 16; // 16C
+const uint8_t kMirageAcMaxTemp = 32; // 32C
+const uint8_t kMirageAcTempOffset = 0x5C;
+const uint8_t kMirageAcSensorTempOffset = 20;
+const uint8_t kMirageAcSensorTempMax = 43; // Celsius
+
+const uint8_t kMirageAcPowerOff = 0x5F;
+const uint8_t kMirageAcSwingVOff = 0b0000; // 0
+const uint8_t kMirageAcSwingVLowest = 0b0011; // 3
+const uint8_t kMirageAcSwingVLow = 0b0101; // 5
+const uint8_t kMirageAcSwingVMiddle = 0b0111; // 7
+const uint8_t kMirageAcSwingVHigh = 0b1001; // 9
+const uint8_t kMirageAcSwingVHighest = 0b1011; // 11
+const uint8_t kMirageAcSwingVAuto = 0b1101; // 13
+
+
+/// Class for handling detailed Mirage 120-bit A/C messages.
+/// @note Inspired and derived from the work done at: https://github.com/r45635/HVAC-IR-Control
+/// @warning Consider this very alpha code. Seems to work, but not validated.
+class IRMirageAc {
+ public:
+ explicit IRMirageAc(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+ void stateReset(void);
+#if SEND_MIRAGE
+ void send(const uint16_t repeat = kMirageMinRepeat);
+ /// Run the calibration to calculate uSec timing offsets for this platform.
+ /// @return The uSec timing offset needed per modulation of the IR Led.
+ /// @note This will produce a 65ms IR signal pulse at 38kHz.
+ /// Only ever needs to be run once per object instantiation, if at all.
+ int8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_MIRAGE
+ void begin(void);
+ void on(void);
+ void off(void);
+ void setPower(const bool on);
+ bool getPower(void) const;
+ void setTemp(const uint8_t degrees);
+ uint8_t getTemp(void) const;
+ void setFan(const uint8_t speed);
+ uint8_t getFan(void) const;
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void) const;
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t* data);
+ uint32_t getClock(void) const;
+ void setClock(const uint32_t nr_of_seconds);
+ void setTurbo(const bool on);
+ bool getTurbo(void) const;
+ void setLight(const bool on);
+ bool getLight(void) const;
+ void setSleep(const bool on);
+ bool getSleep(void) const;
+ void setSwingV(const uint8_t position);
+ uint8_t getSwingV(void) const;
+ void setSwingH(const bool on);
+ bool getSwingH(void) const;
+ void setQuiet(const bool on);
+ bool getQuiet(void) const;
+ void setCleanToggle(const bool on);
+ bool getCleanToggle(void) const;
+ void setFilter(const bool on);
+ bool getFilter(void) const;
+ void setIFeel(const bool on);
+ bool getIFeel(void) const;
+ void setSensorTemp(const uint8_t degrees);
+ uint16_t getSensorTemp(void) const;
+ uint16_t getOnTimer(void) const;
+ uint16_t getOffTimer(void) const;
+ void setOnTimer(const uint16_t nr_of_mins);
+ void setOffTimer(const uint16_t nr_of_mins);
+ mirage_ac_remote_model_t getModel(const bool useRaw = false) const;
+ void setModel(const mirage_ac_remote_model_t model);
+ static mirage_ac_remote_model_t getModel(const uint8_t *state);
+ static bool validChecksum(const uint8_t* data);
+ static uint8_t calculateChecksum(const uint8_t* data);
+ static uint8_t convertMode(const stdAc::opmode_t mode);
+ static uint8_t convertFan(const stdAc::fanspeed_t speed,
+ const mirage_ac_remote_model_t model = mirage_ac_remote_model_t::KKG9AC1);
+ static uint8_t convertSwingV(const stdAc::swingv_t position);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed,
+ const mirage_ac_remote_model_t model = mirage_ac_remote_model_t::KKG9AC1);
+ static stdAc::swingv_t toCommonSwingV(const uint8_t pos);
+ stdAc::state_t toCommon(void) const;
+ void fromCommon(const stdAc::state_t state);
+ String toString(void) const;
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend; ///< Instance of the IR send class
+#else // UNIT_TEST
+ /// @cond IGNORE
+ IRsendTest _irsend; ///< Instance of the testing IR send class
+ /// @endcond
+#endif // UNIT_TEST
+ Mirage120Protocol _;
+ mirage_ac_remote_model_t _model;
+ void checksum(void);
+};
+#endif // IR_MIRAGE_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mitsubishi.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mitsubishi.cpp
index 03e562ef5..160a882bf 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mitsubishi.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Mitsubishi.cpp
@@ -1166,7 +1166,7 @@ void IRsend::sendMitsubishi112(const unsigned char data[],
}
#endif // SEND_MITSUBISHI112
-#if DECODE_MITSUBISHI112 || DECODE_TCL112AC
+#if (DECODE_MITSUBISHI112 || DECODE_TCL112AC)
/// Decode the supplied Mitsubishi/TCL 112-bit A/C message.
/// (MITSUBISHI112, TCL112AC)
/// Status: STABLE / Reported as working.
@@ -1212,7 +1212,7 @@ bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset,
gap = kMitsubishi112Gap;
}
#endif // DECODE_MITSUBISHI112
-#if DECODE_TCL112AC
+#if (DECODE_TCL112AC || DECODE_TEKNOPOINT)
if (typeguess == decode_type_t::UNKNOWN && // We didn't match Mitsubishi112
matchMark(results->rawbuf[offset], kTcl112AcHdrMark,
kTcl112AcHdrMarkTolerance, 0)) {
@@ -1224,7 +1224,7 @@ bool IRrecv::decodeMitsubishi112(decode_results *results, uint16_t offset,
gap = kTcl112AcGap;
tolerance += kTcl112AcTolerance;
}
-#endif // DECODE_TCL112AC
+#endif // (DECODE_TCL112AC || DECODE_TEKNOPOINT)
if (typeguess == decode_type_t::UNKNOWN) return false; // No header matched.
offset++;
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.cpp
new file mode 100644
index 000000000..f906f49be
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.cpp
@@ -0,0 +1,364 @@
+// Copyright 2021 Tom Rosenback
+
+/// @file
+/// @brief Support for Rhoss protocols.
+
+#include "ir_Rhoss.h"
+#include
+#include
+#include "IRrecv.h"
+#include "IRsend.h"
+#include "IRtext.h"
+#include "IRutils.h"
+
+const uint16_t kRhossHdrMark = 3042;
+const uint16_t kRhossHdrSpace = 4248;
+const uint16_t kRhossBitMark = 648;
+const uint16_t kRhossOneSpace = 1545;
+const uint16_t kRhossZeroSpace = 457;
+const uint32_t kRhossGap = kDefaultMessageGap;
+const uint16_t kRhossFreq = 38;
+
+using irutils::addBoolToString;
+using irutils::addModeToString;
+using irutils::addFanToString;
+using irutils::addTempToString;
+
+#if SEND_RHOSS
+/// Send a Rhoss HVAC formatted message.
+/// Status: STABLE / Reported as working.
+/// @param[in] data The message to be sent.
+/// @param[in] nbytes The number of bytes of message to be sent.
+/// @param[in] repeat The number of times the command is to be repeated.
+void IRsend::sendRhoss(const unsigned char data[], const uint16_t nbytes,
+ const uint16_t repeat) {
+ // Check if we have enough bytes to send a proper message.
+ if (nbytes < kRhossStateLength) return;
+
+ // We always send a message, even for repeat=0, hence '<= repeat'.
+ for (uint16_t r = 0; r <= repeat; r++) {
+ sendGeneric(kRhossHdrMark, kRhossHdrSpace, kRhossBitMark,
+ kRhossOneSpace, kRhossBitMark, kRhossZeroSpace,
+ kRhossBitMark, kRhossZeroSpace,
+ data, nbytes, kRhossFreq, false, 0, kDutyDefault);
+ mark(kRhossBitMark);
+ // Gap
+ space(kRhossGap);
+ }
+}
+#endif // SEND_RHOSS
+
+#if DECODE_RHOSS
+/// Decode the supplied Rhoss formatted message.
+/// Status: STABLE / Known working.
+/// @param[in,out] results Ptr to the data to decode & where to store the result
+/// @param[in] offset The starting index to use when attempting to decode the
+/// raw data. Typically/Defaults to kStartOffset.
+/// @param[in] nbits The number of data bits to expect.
+/// @param[in] strict Flag indicating if we should perform strict matching.
+bool IRrecv::decodeRhoss(decode_results *results, uint16_t offset,
+ const uint16_t nbits, const bool strict) {
+ if (strict && nbits != kRhossBits) return false;
+
+ if (results->rawlen <= 2 * nbits + kHeader + kFooter - 1 + offset) {
+ return false; // Can't possibly be a valid Rhoss message.
+ }
+
+ uint16_t used;
+ // Header + Data Block (96 bits) + Footer
+ used = matchGeneric(results->rawbuf + offset, results->state,
+ results->rawlen - offset, kRhossBits,
+ kRhossHdrMark, kRhossHdrSpace,
+ kRhossBitMark, kRhossOneSpace,
+ kRhossBitMark, kRhossZeroSpace,
+ kRhossBitMark, kRhossZeroSpace,
+ false, kUseDefTol, kMarkExcess, false);
+
+ if (!used) return false;
+ offset += used;
+
+ // Footer (Part 2)
+ if (!matchMark(results->rawbuf[offset++], kRhossBitMark)) {
+ return false;
+ }
+
+ if (offset < results->rawlen &&
+ !matchAtLeast(results->rawbuf[offset], kRhossGap)) {
+ return false;
+ }
+
+ if (strict && !IRRhossAc::validChecksum(results->state)) return false;
+
+ // Success
+ results->decode_type = decode_type_t::RHOSS;
+ results->bits = nbits;
+ // No need to record the state as we stored it as we decoded it.
+ // As we use result->state, we don't record value, address, or command as it
+ // is a union data type.
+ return true;
+}
+
+#endif // DECODE_RHOSS
+
+/// Class constructor
+/// @param[in] pin GPIO to be used when sending.
+/// @param[in] inverted Is the output signal to be inverted?
+/// @param[in] use_modulation Is frequency modulation to be used?
+IRRhossAc::IRRhossAc(const uint16_t pin, const bool inverted,
+ const bool use_modulation)
+ : _irsend(pin, inverted, use_modulation) { this->stateReset(); }
+
+/// Set up hardware to be able to send a message.
+void IRRhossAc::begin(void) { _irsend.begin(); }
+
+#if SEND_RHOSS
+/// Send the current internal state as an IR message.
+/// @param[in] repeat Nr. of times the message will be repeated.
+void IRRhossAc::send(const uint16_t repeat) {
+ _irsend.sendRhoss(getRaw(), kRhossStateLength, repeat);
+}
+#endif // SEND_RHOSS
+
+/// Calculate the checksum for the supplied state.
+/// @param[in] state The source state to generate the checksum from.
+/// @param[in] length Length of the supplied state to checksum.
+/// @return The checksum value.
+uint8_t IRRhossAc::calcChecksum(const uint8_t state[], const uint16_t length) {
+ return sumBytes(state, length - 1);
+}
+
+/// Verify the checksum is valid for a given state.
+/// @param[in] state The array to verify the checksum of.
+/// @param[in] length The size of the state.
+/// @return A boolean indicating if it's checksum is valid.
+bool IRRhossAc::validChecksum(const uint8_t state[], const uint16_t length) {
+ return (state[length - 1] == IRRhossAc::calcChecksum(state, length));
+}
+
+/// Update the checksum value for the internal state.
+void IRRhossAc::checksum(void) {
+ _.Sum = IRRhossAc::calcChecksum(_.raw, kRhossStateLength);
+ _.raw[kRhossStateLength - 1] = _.Sum;
+}
+
+/// Reset the internals of the object to a known good state.
+void IRRhossAc::stateReset(void) {
+ for (uint8_t i = 1; i < kRhossStateLength; i++) _.raw[i] = 0x0;
+ _.raw[0] = 0xAA;
+ _.raw[2] = 0x60;
+ _.raw[6] = 0x54;
+ _.Power = kRhossDefaultPower;
+ _.Fan = kRhossDefaultFan;
+ _.Mode = kRhossDefaultMode;
+ _.Swing = kRhossDefaultSwing;
+ _.Temp = kRhossDefaultTemp - kRhossTempMin;
+}
+
+/// Get the raw state of the object, suitable to be sent with the appropriate
+/// IRsend object method.
+/// @return A PTR to the internal state.
+uint8_t* IRRhossAc::getRaw(void) {
+ checksum(); // Ensure correct bit array before returning
+ return _.raw;
+}
+
+/// Set the raw state of the object.
+/// @param[state] state The raw state from the native IR message.
+void IRRhossAc::setRaw(const uint8_t state[]) {
+ std::memcpy(_.raw, state, kRhossStateLength);
+}
+
+/// Set the internal state to have the power on.
+void IRRhossAc::on(void) { setPower(true); }
+
+/// Set the internal state to have the power off.
+void IRRhossAc::off(void) { setPower(false); }
+
+/// Set the internal state to have the desired power.
+/// @param[in] on The desired power state.
+void IRRhossAc::setPower(const bool on) {
+ _.Power = (on ? kRhossPowerOn : kRhossPowerOff);
+}
+
+/// Get the power setting from the internal state.
+/// @return A boolean indicating the power setting.
+bool IRRhossAc::getPower(void) const {
+ return _.Power == kRhossPowerOn;
+}
+
+/// Set the temperature.
+/// @param[in] degrees The temperature in degrees celsius.
+void IRRhossAc::setTemp(const uint8_t degrees) {
+ uint8_t temp = std::max(kRhossTempMin, degrees);
+ _.Temp = std::min(kRhossTempMax, temp) - kRhossTempMin;
+}
+
+/// Get the current temperature setting.
+/// @return Get current setting for temp. in degrees celsius.
+uint8_t IRRhossAc::getTemp(void) const {
+ return _.Temp + kRhossTempMin;
+}
+
+/// Set the speed of the fan.
+/// @param[in] speed The desired setting.
+void IRRhossAc::setFan(const uint8_t speed) {
+ switch (speed) {
+ case kRhossFanAuto:
+ case kRhossFanMin:
+ case kRhossFanMed:
+ case kRhossFanMax:
+ _.Fan = speed;
+ break;
+ default:
+ _.Fan = kRhossFanAuto;
+ }
+}
+
+/// Get the current fan speed setting.
+/// @return The current fan speed.
+uint8_t IRRhossAc::getFan(void) const {
+ return _.Fan;
+}
+
+/// Set the Vertical Swing mode of the A/C.
+/// @param[in] state true, the Swing is on. false, the Swing is off.
+void IRRhossAc::setSwing(const bool state) {
+ _.Swing = state;
+}
+
+/// Get the Vertical Swing speed of the A/C.
+/// @return The native swing speed setting.
+uint8_t IRRhossAc::getSwing(void) const {
+ return _.Swing;
+}
+
+/// Get the current operation mode setting.
+/// @return The current operation mode.
+uint8_t IRRhossAc::getMode(void) const {
+ return _.Mode;
+}
+
+/// Set the desired operation mode.
+/// @param[in] mode The desired operation mode.
+void IRRhossAc::setMode(const uint8_t mode) {
+ switch (mode) {
+ case kRhossModeFan:
+ case kRhossModeCool:
+ case kRhossModeDry:
+ case kRhossModeHeat:
+ case kRhossModeAuto:
+ _.Mode = mode;
+ return;
+ default:
+ _.Mode = kRhossDefaultMode;
+ break;
+ }
+}
+
+/// Convert a stdAc::opmode_t enum into its native mode.
+/// @param[in] mode The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRRhossAc::convertMode(const stdAc::opmode_t mode) {
+ switch (mode) {
+ case stdAc::opmode_t::kCool:
+ return kRhossModeCool;
+ case stdAc::opmode_t::kHeat:
+ return kRhossModeHeat;
+ case stdAc::opmode_t::kDry:
+ return kRhossModeDry;
+ case stdAc::opmode_t::kFan:
+ return kRhossModeFan;
+ case stdAc::opmode_t::kAuto:
+ return kRhossModeAuto;
+ default:
+ return kRhossDefaultMode;
+ }
+}
+
+/// Convert a stdAc::fanspeed_t enum into it's native speed.
+/// @param[in] speed The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRRhossAc::convertFan(const stdAc::fanspeed_t speed) {
+ switch (speed) {
+ case stdAc::fanspeed_t::kMin:
+ case stdAc::fanspeed_t::kLow:
+ return kRhossFanMin;
+ case stdAc::fanspeed_t::kMedium:
+ return kRhossFanMed;
+ case stdAc::fanspeed_t::kHigh:
+ case stdAc::fanspeed_t::kMax:
+ return kRhossFanMax;
+ default:
+ return kRhossDefaultFan;
+ }
+}
+
+/// Convert a native mode into its stdAc equivalent.
+/// @param[in] mode The native setting to be converted.
+/// @return The stdAc equivalent of the native setting.
+stdAc::opmode_t IRRhossAc::toCommonMode(const uint8_t mode) {
+ switch (mode) {
+ case kRhossModeCool: return stdAc::opmode_t::kCool;
+ case kRhossModeHeat: return stdAc::opmode_t::kHeat;
+ case kRhossModeDry: return stdAc::opmode_t::kDry;
+ case kRhossModeFan: return stdAc::opmode_t::kFan;
+ case kRhossModeAuto: return stdAc::opmode_t::kAuto;
+ default: return stdAc::opmode_t::kAuto;
+ }
+}
+
+/// Convert a native fan speed into its stdAc equivalent.
+/// @param[in] speed The native setting to be converted.
+/// @return The stdAc equivalent of the native setting.
+stdAc::fanspeed_t IRRhossAc::toCommonFanSpeed(const uint8_t speed) {
+ switch (speed) {
+ case kRhossFanMax: return stdAc::fanspeed_t::kMax;
+ case kRhossFanMed: return stdAc::fanspeed_t::kMedium;
+ case kRhossFanMin: return stdAc::fanspeed_t::kMin;
+ case kRhossFanAuto:
+ default:
+ return stdAc::fanspeed_t::kAuto;
+ }
+}
+
+/// Convert the current internal state into its stdAc::state_t equivalent.
+/// @return The stdAc equivalent of the native settings.
+stdAc::state_t IRRhossAc::toCommon(void) const {
+ stdAc::state_t result;
+ result.protocol = decode_type_t::RHOSS;
+ result.power = getPower();
+ result.mode = toCommonMode(_.Mode);
+ result.celsius = true;
+ result.degrees = _.Temp;
+ result.fanspeed = toCommonFanSpeed(_.Fan);
+ result.swingv = _.Swing ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
+ // Not supported.
+ result.model = -1;
+ result.turbo = false;
+ result.swingh = stdAc::swingh_t::kOff;
+ result.light = false;
+ result.filter = false;
+ result.econo = false;
+ result.quiet = false;
+ result.clean = false;
+ result.beep = false;
+ result.sleep = -1;
+ result.clock = -1;
+ return result;
+}
+
+/// Convert the current internal state into a human readable string.
+/// @return A human readable string.
+String IRRhossAc::toString(void) const {
+ String result = "";
+ result.reserve(70); // Reserve some heap for the string to reduce fragging.
+ result += addBoolToString(getPower(), kPowerStr, false);
+ result += addModeToString(getMode(), kRhossModeAuto, kRhossModeCool,
+ kRhossModeHeat, kRhossModeDry, kRhossModeFan);
+ result += addTempToString(getTemp());
+ result += addFanToString(getFan(), kRhossFanMax, kRhossFanMin,
+ kRhossFanAuto, kRhossFanAuto,
+ kRhossFanMed);
+ result += addBoolToString(getSwing(), kSwingVStr);
+ return result;
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.h
new file mode 100644
index 000000000..8f66ce738
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Rhoss.h
@@ -0,0 +1,145 @@
+// Copyright 2021 Tom Rosenback
+
+/// @file
+/// @brief Support for Rhoss A/C protocol
+// Supports:
+// Brand: Rhoss, Model: Idrowall MPCV 20-30-35-40
+
+#ifndef IR_RHOSS_H_
+#define IR_RHOSS_H_
+
+#define __STDC_LIMIT_MACROS
+#include
+#ifndef UNIT_TEST
+#include
+#endif
+#include "IRremoteESP8266.h"
+#include "IRsend.h"
+#ifdef UNIT_TEST
+#include "IRsend_test.h"
+#endif
+
+
+/// Native representation of a Rhoss A/C message.
+union RhossProtocol{
+ uint8_t raw[kRhossStateLength]; // The state of the IR remote.
+ struct {
+ // Byte 0
+ uint8_t :8; // Typically 0xAA
+ // Byte 1
+ uint8_t Temp :4;
+ uint8_t :4; // Typically 0x0
+ // Byte 2
+ uint8_t :8; // Typically 0x60
+ // Byte 3
+ uint8_t :8; // Typically 0x0
+ // Byte 4
+ uint8_t Fan :2;
+ uint8_t :2; // Typically 0x0
+ uint8_t Mode :4;
+ // Byte 5
+ uint8_t Swing :1;
+ uint8_t :5; // Typically 0x0
+ uint8_t Power :2;
+ // Byte 6
+ uint8_t :8; // Typically 0x54
+ // Byte 7
+ uint8_t :8; // Typically 0x0
+ // Byte 8
+ uint8_t :8; // Typically 0x0
+ // Byte 9
+ uint8_t :8; // Typically 0x0
+ // Byte 10
+ uint8_t :8; // Typically 0x0
+ // Byte 11
+ uint8_t Sum :8;
+ };
+};
+
+// Constants
+
+// Fan Control
+const uint8_t kRhossFanAuto = 0b00;
+const uint8_t kRhossFanMin = 0b01;
+const uint8_t kRhossFanMed = 0b10;
+const uint8_t kRhossFanMax = 0b11;
+// Modes
+const uint8_t kRhossModeHeat = 0b0001;
+const uint8_t kRhossModeCool = 0b0010;
+const uint8_t kRhossModeDry = 0b0011;
+const uint8_t kRhossModeFan = 0b0100;
+const uint8_t kRhossModeAuto = 0b0101;
+
+// Temperature
+const uint8_t kRhossTempMin = 16; // Celsius
+const uint8_t kRhossTempMax = 30; // Celsius
+
+// Power
+const uint8_t kRhossPowerOn = 0b10; // 0x2
+const uint8_t kRhossPowerOff = 0b01; // 0x1
+
+// Swing
+const uint8_t kRhossSwingOn = 0b1; // 0x1
+const uint8_t kRhossSwingOff = 0b0; // 0x0
+
+const uint8_t kRhossDefaultFan = kRhossFanAuto;
+const uint8_t kRhossDefaultMode = kRhossModeCool;
+const uint8_t kRhossDefaultTemp = 21; // Celsius
+const bool kRhossDefaultPower = false;
+const bool kRhossDefaultSwing = false;
+
+// Classes
+
+/// Class for handling detailed Rhoss A/C messages.
+class IRRhossAc {
+ public:
+ explicit IRRhossAc(const uint16_t pin, const bool inverted = false,
+ const bool use_modulation = true);
+
+ void stateReset();
+#if SEND_RHOSS
+ void send(const uint16_t repeat = kRhossDefaultRepeat);
+ /// Run the calibration to calculate uSec timing offsets for this platform.
+ /// @return The uSec timing offset needed per modulation of the IR Led.
+ /// @note This will produce a 65ms IR signal pulse at 38kHz.
+ /// Only ever needs to be run once per object instantiation, if at all.
+ int8_t calibrate(void) { return _irsend.calibrate(); }
+#endif // SEND_RHOSS
+ void begin();
+ static uint8_t calcChecksum(const uint8_t state[],
+ const uint16_t length = kRhossStateLength);
+ static bool validChecksum(const uint8_t state[],
+ const uint16_t length = kRhossStateLength);
+ void setPower(const bool state);
+ bool getPower(void) const;
+ void on(void);
+ void off(void);
+ void setTemp(const uint8_t temp);
+ uint8_t getTemp(void) const;
+ void setFan(const uint8_t speed);
+ uint8_t getFan(void) const;
+ void setSwing(const bool state);
+ uint8_t getSwing(void) const;
+ void setMode(const uint8_t mode);
+ uint8_t getMode(void) const;
+ uint8_t* getRaw(void);
+ void setRaw(const uint8_t state[]);
+ static uint8_t convertMode(const stdAc::opmode_t mode);
+ static uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static stdAc::opmode_t toCommonMode(const uint8_t mode);
+ static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ stdAc::state_t toCommon(void) const;
+ String toString(void) const;
+#ifndef UNIT_TEST
+
+ private:
+ IRsend _irsend;
+#else
+ /// @cond IGNORE
+ IRsendTest _irsend;
+ /// @endcond
+#endif
+ RhossProtocol _;
+ void checksum(void);
+};
+#endif // IR_RHOSS_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp
index 9e1ad4669..94cb52bba 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.cpp
@@ -1,5 +1,5 @@
// Copyright 2009 Ken Shirriff
-// Copyright 2017, 2018, 2019 David Conran
+// Copyright 2017-2021 David Conran
/// @file
/// @brief Support for Samsung protocols.
/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/
@@ -62,12 +62,25 @@ const uint16_t kSamsung36BitMark = 512; /// < uSeconds
const uint16_t kSamsung36OneSpace = 1468; /// < uSeconds
const uint16_t kSamsung36ZeroSpace = 490; /// < uSeconds
+// _.Swing
+const uint8_t kSamsungAcSwingV = 0b010;
+const uint8_t kSamsungAcSwingH = 0b011;
+const uint8_t kSamsungAcSwingBoth = 0b100;
+const uint8_t kSamsungAcSwingOff = 0b111;
+// _.FanSpecial
+const uint8_t kSamsungAcFanSpecialOff = 0b000;
+const uint8_t kSamsungAcPowerfulOn = 0b011;
+const uint8_t kSamsungAcBreezeOn = 0b101;
+const uint8_t kSamsungAcEconoOn = 0b111;
+
using irutils::addBoolToString;
using irutils::addFanToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addTempToString;
+using irutils::addToggleToString;
+using irutils::minsToString;
#if SEND_SAMSUNG
/// Send a 32-bit Samsung formatted message.
@@ -275,17 +288,22 @@ IRSamsungAc::IRSamsungAc(const uint16_t pin, const bool inverted,
}
/// Reset the internal state of the emulation.
-/// @param[in] forcepower A flag indicating if force sending a special power
+/// @param[in] extended A flag indicating if force sending a special extended
/// message with the first `send()` call.
/// @param[in] initialPower Set the initial power state. True, on. False, off.
-void IRSamsungAc::stateReset(const bool forcepower, const bool initialPower) {
+void IRSamsungAc::stateReset(const bool extended, const bool initialPower) {
static const uint8_t kReset[kSamsungAcExtendedStateLength] = {
0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
0x01, 0x02, 0xAE, 0x71, 0x00, 0x15, 0xF0};
std::memcpy(_.raw, kReset, kSamsungAcExtendedStateLength);
- _forcepower = forcepower;
+ _forceextended = extended;
_lastsentpowerstate = initialPower;
setPower(initialPower);
+ _OnTimerEnable = false;
+ _OffTimerEnable = false;
+ _Sleep = false;
+ _lastSleep = false;
+ _OnTimer = _OffTimer = _lastOnTimer = _lastOffTimer = 0;
}
/// Set up hardware to be able to send a message.
@@ -351,30 +369,28 @@ void IRSamsungAc::checksum(void) {
#if SEND_SAMSUNG_AC
/// Send the current internal state as an IR message.
/// @param[in] repeat Nr. of times the message will be repeated.
-/// @param[in] calcchecksum Do we update the checksum before sending?
/// @note Use for most function/mode/settings changes to the unit.
/// i.e. When the device is already running.
-void IRSamsungAc::send(const uint16_t repeat, const bool calcchecksum) {
- // Do we need to send a the special power on/off message? i.e. An Extended Msg
- if (getPower() != _lastsentpowerstate || _forcepower) { // We do.
- sendExtended(repeat, calcchecksum);
- _forcepower = false; // It has now been sent, so clear the flag if set.
- } else { // No, it's just a normal message.
- if (calcchecksum) checksum();
- _irsend.sendSamsungAC(_.raw, kSamsungAcStateLength, repeat);
- }
+void IRSamsungAc::send(const uint16_t repeat) {
+ // Do we need to send a special (extended) message?
+ if (getPower() != _lastsentpowerstate || _forceextended ||
+ (_lastOnTimer != _OnTimer) || (_lastOffTimer != _OffTimer) ||
+ (_Sleep != _lastSleep)) // We do.
+ sendExtended(repeat);
+ else // No, it's just a normal message.
+ _irsend.sendSamsungAC(getRaw(), kSamsungAcStateLength, repeat);
}
/// Send the extended current internal state as an IR message.
/// @param[in] repeat Nr. of times the message will be repeated.
-/// @param[in] calcchecksum Do we update the checksum before sending?
-/// @note Use this for when you need to power on/off the device.
-/// Samsung A/C requires an extended length message when you want to
-/// change the power operating mode of the A/C unit.
-void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) {
+/// @note Samsung A/C requires an extended length message when you want to
+/// change the power operating mode, Timers, or Sleep setting of the A/C unit.
+void IRSamsungAc::sendExtended(const uint16_t repeat) {
+ _lastsentpowerstate = getPower(); // Remember the last power state sent.
+ _lastOnTimer = _OnTimer;
+ _lastOffTimer = _OffTimer;
static const uint8_t extended_middle_section[kSamsungAcSectionLength] = {
0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00};
- if (calcchecksum) checksum();
// Copy/convert the internal state to an extended state by
// copying the second section to the third section, and inserting the extended
// middle (second) section.
@@ -383,13 +399,16 @@ void IRSamsungAc::sendExtended(const uint16_t repeat, const bool calcchecksum) {
kSamsungAcSectionLength);
std::memcpy(_.raw + kSamsungAcSectionLength, extended_middle_section,
kSamsungAcSectionLength);
+ _setOnTimer();
+ _setSleepTimer(); // This also sets any Off Timer if needed too.
// Send it.
- _irsend.sendSamsungAC(_.raw, kSamsungAcExtendedStateLength, repeat);
+ _irsend.sendSamsungAC(getRaw(), kSamsungAcExtendedStateLength, repeat);
// Now revert it by copying the third section over the second section.
std::memcpy(_.raw + kSamsungAcSectionLength,
- _.raw + 2* kSamsungAcSectionLength,
+ _.raw + 2 * kSamsungAcSectionLength,
kSamsungAcSectionLength);
- _lastsentpowerstate = getPower(); // Remember the last power state sent.
+
+ _forceextended = false; // It has now been sent, so clear the flag if set.
}
/// Send the special extended "On" message as the library can't seem to
@@ -434,6 +453,11 @@ void IRSamsungAc::setRaw(const uint8_t new_code[], const uint16_t length) {
kSamsungAcExtendedStateLength));
// Shrink the extended state into a normal state.
if (length > kSamsungAcStateLength) {
+ _OnTimerEnable = _.OnTimerEnable;
+ _OffTimerEnable = _.OffTimerEnable;
+ _Sleep = _.Sleep5 && _.Sleep12;
+ _OnTimer = _getOnTimer();
+ _OffTimer = _getOffTimer();
for (uint8_t i = kSamsungAcStateLength; i < length; i++)
_.raw[i - kSamsungAcSectionLength] = _.raw[i];
}
@@ -448,14 +472,13 @@ void IRSamsungAc::off(void) { setPower(false); }
/// Change the power setting.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setPower(const bool on) {
- _.Power1 = !on; // Cleared when on.
- _.Power6 = (on ? 0b11 : 0b00);
+ _.Power1 = _.Power2 = (on ? 0b11 : 0b00);
}
/// Get the value of the current power setting.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getPower(void) const {
- return (_.Power6 == 0b11) && !_.Power1;
+ return _.Power1 == 0b11 && _.Power2 == 0b11;
}
/// Set the temperature.
@@ -524,56 +547,79 @@ uint8_t IRSamsungAc::getFan(void) const {
/// Get the vertical swing setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1.
-/// e.g. 0xAE or 0XAF for swing move.
bool IRSamsungAc::getSwing(void) const {
- return _.Swing == kSamsungAcSwingMove;
+ switch (_.Swing) {
+ case kSamsungAcSwingV:
+ case kSamsungAcSwingBoth: return true;
+ default: return false;
+ }
}
/// Set the vertical swing setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-/// @todo (Hollako) Explain why sometimes the LSB of remote_state[9] is a 1.
-/// e.g. 0xAE or 0XAF for swing move.
void IRSamsungAc::setSwing(const bool on) {
- _.Swing = (on ? kSamsungAcSwingMove : kSamsungAcSwingStop);
+ switch (_.Swing) {
+ case kSamsungAcSwingBoth:
+ case kSamsungAcSwingH:
+ _.Swing = on ? kSamsungAcSwingBoth : kSamsungAcSwingH;
+ break;
+ default:
+ _.Swing = on ? kSamsungAcSwingV : kSamsungAcSwingOff;
+ }
}
-/// Get the Beep setting of the A/C.
+/// Get the horizontal swing setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRSamsungAc::getBeep(void) const {
- return _.Beep;
+bool IRSamsungAc::getSwingH(void) const {
+ switch (_.Swing) {
+ case kSamsungAcSwingH:
+ case kSamsungAcSwingBoth: return true;
+ default: return false;
+ }
}
-/// Set the Beep setting of the A/C.
+/// Set the horizontal swing setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRSamsungAc::setBeep(const bool on) {
- _.Beep = on;
+void IRSamsungAc::setSwingH(const bool on) {
+ switch (_.Swing) {
+ case kSamsungAcSwingV:
+ case kSamsungAcSwingBoth:
+ _.Swing = on ? kSamsungAcSwingBoth : kSamsungAcSwingV;
+ break;
+ default:
+ _.Swing = on ? kSamsungAcSwingH : kSamsungAcSwingOff;
+ }
}
-/// Get the Clean setting of the A/C.
+/// Get the Beep toggle setting of the A/C.
+/// @return true, the setting is on. false, the setting is off.
+bool IRSamsungAc::getBeep(void) const { return _.BeepToggle; }
+
+/// Set the Beep toggle setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRSamsungAc::setBeep(const bool on) { _.BeepToggle = on; }
+
+/// Get the Clean toggle setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getClean(void) const {
- return _.Clean10 && _.Clean11;
+ return _.CleanToggle10 && _.CleanToggle11;
}
-/// Set the Clean setting of the A/C.
+/// Set the Clean toggle setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setClean(const bool on) {
- _.Clean10 = on;
- _.Clean11 = on;
+ _.CleanToggle10 = on;
+ _.CleanToggle11 = on;
}
/// Get the Quiet setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRSamsungAc::getQuiet(void) const {
- return !_.Quiet1 && _.Quiet5;
-}
+bool IRSamsungAc::getQuiet(void) const { return _.Quiet; }
/// Set the Quiet setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setQuiet(const bool on) {
- _.Quiet1 = !on; // Cleared when on.
- _.Quiet5 = on;
+ _.Quiet = on;
if (on) {
// Quiet mode seems to set fan speed to auto.
setFan(kSamsungAcFanAuto);
@@ -584,25 +630,20 @@ void IRSamsungAc::setQuiet(const bool on) {
/// Get the Powerful (Turbo) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSamsungAc::getPowerful(void) const {
- return !(_.Powerful8 & kSamsungAcPowerfulMask8) &&
- (_.Powerful10 == kSamsungAcPowerful10On) &&
+ return (_.FanSpecial == kSamsungAcPowerfulOn) &&
(_.Fan == kSamsungAcFanTurbo);
}
/// Set the Powerful (Turbo) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSamsungAc::setPowerful(const bool on) {
- uint8_t off_value = getBreeze() ? kSamsungAcBreezeOn : 0b000;
- _.Powerful10 = (on ? kSamsungAcPowerful10On : off_value);
+ uint8_t off_value = (getBreeze() || getEcono()) ? _.FanSpecial
+ : kSamsungAcFanSpecialOff;
+ _.FanSpecial = (on ? kSamsungAcPowerfulOn : off_value);
if (on) {
- _.Powerful8 &= ~kSamsungAcPowerfulMask8; // Bit needs to be cleared.
// Powerful mode sets fan speed to Turbo.
setFan(kSamsungAcFanTurbo);
setQuiet(false); // Powerful 'on' is mutually exclusive to Quiet.
- } else {
- _.Powerful8 |= kSamsungAcPowerfulMask8; // Bit needs to be set.
- // Turning off Powerful mode sets fan speed to Auto if we were in Turbo mode
- if (_.Fan == kSamsungAcFanTurbo) setFan(kSamsungAcFanAuto);
}
}
@@ -610,7 +651,7 @@ void IRSamsungAc::setPowerful(const bool on) {
/// @return true, the setting is on. false, the setting is off.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
bool IRSamsungAc::getBreeze(void) const {
- return (_.Breeze == kSamsungAcBreezeOn) &&
+ return (_.FanSpecial == kSamsungAcBreezeOn) &&
(_.Fan == kSamsungAcFanAuto && !getSwing());
}
@@ -618,36 +659,155 @@ bool IRSamsungAc::getBreeze(void) const {
/// @param[in] on true, the setting is on. false, the setting is off.
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
void IRSamsungAc::setBreeze(const bool on) {
- uint8_t off_value = getPowerful() ? kSamsungAcPowerful10On : 0b000;
- _.Breeze = (on ? kSamsungAcBreezeOn : off_value);
+ const uint8_t off_value = (getPowerful() ||
+ getEcono()) ? _.FanSpecial
+ : kSamsungAcFanSpecialOff;
+ _.FanSpecial = (on ? kSamsungAcBreezeOn : off_value);
if (on) {
setFan(kSamsungAcFanAuto);
setSwing(false);
}
}
+/// Get the current Economy (Eco) setting of the A/C.
+/// @return true, the setting is on. false, the setting is off.
+bool IRSamsungAc::getEcono(void) const {
+ return (_.FanSpecial == kSamsungAcEconoOn) &&
+ (_.Fan == kSamsungAcFanAuto && getSwing());
+}
+
+/// Set the current Economy (Eco) setting of the A/C.
+/// @param[in] on true, the setting is on. false, the setting is off.
+void IRSamsungAc::setEcono(const bool on) {
+ const uint8_t off_value = (getBreeze() ||
+ getPowerful()) ? _.FanSpecial
+ : kSamsungAcFanSpecialOff;
+ _.FanSpecial = (on ? kSamsungAcEconoOn : off_value);
+ if (on) {
+ setFan(kSamsungAcFanAuto);
+ setSwing(true);
+ }
+}
+
/// Get the Display (Light/LED) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRSamsungAc::getDisplay(void) const {
- return _.Display;
-}
+bool IRSamsungAc::getDisplay(void) const { return _.Display; }
/// Set the Display (Light/LED) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRSamsungAc::setDisplay(const bool on) {
- _.Display = on;
-}
+void IRSamsungAc::setDisplay(const bool on) { _.Display = on; }
/// Get the Ion (Filter) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRSamsungAc::getIon(void) const {
- return _.Ion;
-}
+bool IRSamsungAc::getIon(void) const { return _.Ion; }
/// Set the Ion (Filter) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
-void IRSamsungAc::setIon(const bool on) {
- _.Ion = on;
+void IRSamsungAc::setIon(const bool on) { _.Ion = on; }
+
+/// Get the On Timer setting of the A/C from a raw extended state.
+/// @return The Nr. of minutes the On Timer is set for.
+uint16_t IRSamsungAc::_getOnTimer(void) const {
+ if (_.OnTimeDay) return 24 * 60;
+ return (_.OnTimeHrs2 * 2 + _.OnTimeHrs1) * 60 + _.OnTimeMins * 10;
+}
+
+/// Set the current On Timer value of the A/C into the raw extended state.
+void IRSamsungAc::_setOnTimer(void) {
+ _.OnTimerEnable = _OnTimerEnable = (_OnTimer > 0);
+ _.OnTimeDay = (_OnTimer >= 24 * 60);
+ if (_.OnTimeDay) {
+ _.OnTimeHrs2 = _.OnTimeHrs1 = _.OnTimeMins = 0;
+ return;
+ }
+ _.OnTimeMins = (_OnTimer % 60) / 10;
+ const uint8_t hours = _OnTimer / 60;
+ _.OnTimeHrs1 = hours & 0b1;
+ _.OnTimeHrs2 = hours >> 1;
+}
+
+/// Get the Off Timer setting of the A/C from a raw extended state.
+/// @return The Nr. of minutes the Off Timer is set for.
+uint16_t IRSamsungAc::_getOffTimer(void) const {
+ if (_.OffTimeDay) return 24 * 60;
+ return (_.OffTimeHrs2 * 2 + _.OffTimeHrs1) * 60 + _.OffTimeMins * 10;
+}
+
+/// Set the current Off Timer value of the A/C into the raw extended state.
+void IRSamsungAc::_setOffTimer(void) {
+ _.OffTimerEnable = _OffTimerEnable = (_OffTimer > 0);
+ _.OffTimeDay = (_OffTimer >= 24 * 60);
+ if (_.OffTimeDay) {
+ _.OffTimeHrs2 = _.OffTimeHrs1 = _.OffTimeMins = 0;
+ return;
+ }
+ _.OffTimeMins = (_OffTimer % 60) / 10;
+ const uint8_t hours = _OffTimer / 60;
+ _.OffTimeHrs1 = hours & 0b1;
+ _.OffTimeHrs2 = hours >> 1;
+}
+
+// Set the current Sleep Timer value of the A/C into the raw extended state.
+void IRSamsungAc::_setSleepTimer(void) {
+ _setOffTimer();
+ // The Sleep mode/timer should only be engaged if an off time has been set.
+ _.Sleep5 = _Sleep && _OffTimerEnable;
+ _.Sleep12 = _.Sleep5;
+}
+
+/// Get the On Timer setting of the A/C.
+/// @return The Nr. of minutes the On Timer is set for.
+uint16_t IRSamsungAc::getOnTimer(void) const { return _OnTimer; }
+
+/// Get the Off Timer setting of the A/C.
+/// @return The Nr. of minutes the Off Timer is set for.
+/// @note Sleep & Off Timer share the same timer.
+uint16_t IRSamsungAc::getOffTimer(void) const {
+ return _Sleep ? 0 : _OffTimer;
+}
+
+/// Get the Sleep Timer setting of the A/C.
+/// @return The Nr. of minutes the Off Timer is set for.
+/// @note Sleep & Off Timer share the same timer.
+uint16_t IRSamsungAc::getSleepTimer(void) const {
+ return _Sleep ? _OffTimer : 0;
+}
+
+#define TIMER_RESOLUTION(mins) \
+ (((std::min((mins), (uint16_t)(24 * 60))) / 10) * 10)
+
+/// Set the On Timer value of the A/C.
+/// @param[in] nr_of_mins The number of minutes the timer should be.
+/// @note The timer time only has a resolution of 10 mins.
+/// @note Setting the On Timer active will cancel the Sleep timer/setting.
+void IRSamsungAc::setOnTimer(const uint16_t nr_of_mins) {
+ // Limit to one day, and round down to nearest 10 min increment.
+ _OnTimer = TIMER_RESOLUTION(nr_of_mins);
+ _OnTimerEnable = _OnTimer > 0;
+ if (_OnTimer) _Sleep = false;
+}
+
+/// Set the Off Timer value of the A/C.
+/// @param[in] nr_of_mins The number of minutes the timer should be.
+/// @note The timer time only has a resolution of 10 mins.
+/// @note Setting the Off Timer active will cancel the Sleep timer/setting.
+void IRSamsungAc::setOffTimer(const uint16_t nr_of_mins) {
+ // Limit to one day, and round down to nearest 10 min increment.
+ _OffTimer = TIMER_RESOLUTION(nr_of_mins);
+ _OffTimerEnable = _OffTimer > 0;
+ if (_OffTimer) _Sleep = false;
+}
+
+/// Set the Sleep Timer value of the A/C.
+/// @param[in] nr_of_mins The number of minutes the timer should be.
+/// @note The timer time only has a resolution of 10 mins.
+/// @note Sleep timer acts as an Off timer, and cancels any On Timer.
+void IRSamsungAc::setSleepTimer(const uint16_t nr_of_mins) {
+ // Limit to one day, and round down to nearest 10 min increment.
+ _OffTimer = TIMER_RESOLUTION(nr_of_mins);
+ if (_OffTimer) setOnTimer(0); // Clear the on timer if set.
+ _Sleep = _OffTimer > 0;
+ _OffTimerEnable = _Sleep;
}
/// Convert a stdAc::opmode_t enum into its native mode.
@@ -714,18 +874,17 @@ stdAc::state_t IRSamsungAc::toCommon(void) const {
result.celsius = true;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
- result.swingv = getSwing() ? stdAc::swingv_t::kAuto :
- stdAc::swingv_t::kOff;
+ result.swingv = getSwing() ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
+ result.swingh = getSwingH() ? stdAc::swingh_t::kAuto : stdAc::swingh_t::kOff;
result.quiet = getQuiet();
result.turbo = getPowerful();
+ result.econo = getEcono();
result.clean = getClean();
- result.beep = _.Beep;
+ result.beep = _.BeepToggle;
result.light = _.Display;
result.filter = _.Ion;
+ result.sleep = _Sleep ? getSleepTimer() : -1;
// Not supported.
- result.swingh = stdAc::swingh_t::kOff;
- result.econo = false;
- result.sleep = -1;
result.clock = -1;
return result;
}
@@ -734,7 +893,7 @@ stdAc::state_t IRSamsungAc::toCommon(void) const {
/// @return A human readable string.
String IRSamsungAc::toString(void) const {
String result = "";
- result.reserve(115); // Reserve some heap for the string to reduce fragging.
+ result.reserve(230); // Reserve some heap for the string to reduce fragging.
result += addBoolToString(getPower(), kPowerStr, false);
result += addModeToString(_.Mode, kSamsungAcAuto, kSamsungAcCool,
kSamsungAcHeat, kSamsungAcDry,
@@ -764,14 +923,21 @@ String IRSamsungAc::toString(void) const {
break;
}
result += ')';
- result += addBoolToString(getSwing(), kSwingStr);
- result += addBoolToString(_.Beep, kBeepStr);
- result += addBoolToString(getClean(), kCleanStr);
+ result += addBoolToString(getSwing(), kSwingVStr);
+ result += addBoolToString(getSwingH(), kSwingHStr);
+ result += addToggleToString(_.BeepToggle, kBeepStr);
+ result += addToggleToString(getClean(), kCleanStr);
result += addBoolToString(getQuiet(), kQuietStr);
result += addBoolToString(getPowerful(), kPowerfulStr);
+ result += addBoolToString(getEcono(), kEconoStr);
result += addBoolToString(getBreeze(), kBreezeStr);
result += addBoolToString(_.Display, kLightStr);
result += addBoolToString(_.Ion, kIonStr);
+ if (_OnTimerEnable)
+ result += addLabeledString(minsToString(_OnTimer), kOnTimerStr);
+ if (_OffTimerEnable)
+ result += addLabeledString(minsToString(_OffTimer),
+ _Sleep ? kSleepTimerStr : kOffTimerStr);
return result;
}
@@ -811,9 +977,6 @@ bool IRrecv::decodeSamsungAC(decode_results *results, uint16_t offset,
offset += used;
}
// Compliance
- // Is the signature correct?
- DPRINTLN("DEBUG: Checking signature.");
- if (results->state[0] != 0x02 || results->state[2] != 0x0F) return false;
if (strict) {
// Is the checksum valid?
if (!IRSamsungAc::validChecksum(results->state, nbits / 8)) {
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.h
index bf9215edc..acabb3648 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Samsung.h
@@ -1,4 +1,4 @@
-// Copyright 2018 David Conran
+// Copyright 2018-2021 David Conran
/// @file
/// @brief Support for Samsung protocols.
/// Samsung originally added from https://github.com/shirriff/Arduino-IRremote/
@@ -7,6 +7,7 @@
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1062
/// @see http://elektrolab.wz.cz/katalog/samsung_protocol.pdf
/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1538 (Checksum)
+/// @see https://github.com/crankyoldgit/IRremoteESP8266/issues/1277 (Timers)
// Supports:
// Brand: Samsung, Model: UA55H6300 TV (SAMSUNG)
@@ -18,11 +19,13 @@
// Brand: Samsung, Model: AH59-02692E Soundbar remote (SAMSUNG36)
// Brand: Samsung, Model: HW-J551 Soundbar (SAMSUNG36)
// Brand: Samsung, Model: AR09FSSDAWKNFA A/C (SAMSUNG_AC)
+// Brand: Samsung, Model: AR09HSFSBWKN A/C (SAMSUNG_AC)
// Brand: Samsung, Model: AR12KSFPEWQNET A/C (SAMSUNG_AC)
// Brand: Samsung, Model: AR12HSSDBWKNEU A/C (SAMSUNG_AC)
// Brand: Samsung, Model: AR12NXCXAWKXEU A/C (SAMSUNG_AC)
-// Brand: Samsung, Model: AR09HSFSBWKN A/C (SAMSUNG_AC)
+// Brand: Samsung, Model: AR12TXEAAWKNEU A/C (SAMSUNG_AC)
// Brand: Samsung, Model: DB93-14195A remote (SAMSUNG_AC)
+// Brand: Samsung, Model: DB96-24901C remote (SAMSUNG_AC)
#ifndef IR_SAMSUNG_H_
#define IR_SAMSUNG_H_
@@ -41,116 +44,125 @@
/// Native representation of a Samsung A/C message.
union SamsungProtocol{
uint8_t raw[kSamsungAcExtendedStateLength]; ///< State in code form.
- struct {
+ struct { // Standard message map
// Byte 0
- uint8_t :8;
+ uint8_t :8;
// Byte 1
uint8_t :4;
- uint8_t Quiet1 :1;
- uint8_t Power1 :1;
- uint8_t :2;
- // Byte 2~4
- uint8_t pad0[3];
+ uint8_t :4; // Sum1Lower
+ // Byte 2
+ uint8_t :4; // Sum1Upper
+ uint8_t :4;
+ // Byte 3
+ uint8_t :8;
+ // Byte 4
+ uint8_t :8;
// Byte 5
- uint8_t :5;
- uint8_t Quiet5 :1;
+ uint8_t :4;
+ uint8_t Sleep5 :1;
+ uint8_t Quiet :1;
uint8_t :2;
// Byte 6
uint8_t :4;
- uint8_t Power6 :2;
+ uint8_t Power1 :2;
uint8_t :2;
// Byte 7
- uint8_t :8;
+ uint8_t :8;
// Byte 8
- uint8_t Powerful8 :8;
+ uint8_t :4;
+ uint8_t :4; // Sum2Lower
// Byte 9
- uint8_t :4;
- uint8_t Swing :3;
- uint8_t :1;
+ uint8_t :4; // Sum1Upper
+ uint8_t Swing :3;
+ uint8_t :1;
// Byte 10
- uint8_t :1;
- uint8_t Powerful10 :3;
- uint8_t Display :1;
- uint8_t :2;
- uint8_t Clean10 :1;
+ uint8_t :1;
+ uint8_t FanSpecial :3; // Powerful, Breeze/WindFree, Econo
+ uint8_t Display :1;
+ uint8_t :2;
+ uint8_t CleanToggle10 :1;
// Byte 11
- uint8_t Ion :1;
- uint8_t Clean11 :1;
- uint8_t :2;
- uint8_t Temp :4;
+ uint8_t Ion :1;
+ uint8_t CleanToggle11 :1;
+ uint8_t :2;
+ uint8_t Temp :4;
// Byte 12
uint8_t :1;
uint8_t Fan :3;
uint8_t Mode :3;
uint8_t :1;
// Byte 13
- uint8_t :1;
- uint8_t Beep :1;
- uint8_t :6;
+ uint8_t :2;
+ uint8_t BeepToggle :1;
+ uint8_t :1;
+ uint8_t Power2 :2;
+ uint8_t :2;
};
- struct {
+ struct { // Extended message map
// 1st Section
// Byte 0
- uint8_t :8;
+ uint8_t :8;
// Byte 1
- uint8_t :4;
- uint8_t Sum1Lower :4;
+ uint8_t :4;
+ uint8_t Sum1Lower :4;
// Byte 2
- uint8_t Sum1Upper :4;
- uint8_t :4;
+ uint8_t Sum1Upper :4;
+ uint8_t :4;
// Byte 3
- uint8_t :8;
+ uint8_t :8;
// Byte 4
- uint8_t :8;
+ uint8_t :8;
// Byte 5
- uint8_t :8;
+ uint8_t :8;
// Byte 6
- uint8_t :8;
+ uint8_t :8;
// 2nd Section
// Byte 7
- uint8_t :8;
+ uint8_t :8;
// Byte 8
- uint8_t :4;
- uint8_t Sum2Lower :4;
+ uint8_t :4;
+ uint8_t Sum2Lower :4;
// Byte 9
- uint8_t Sum2Upper :4;
- uint8_t :4;
+ uint8_t Sum2Upper :4;
+ uint8_t OffTimeMins :3; // In units of 10's of mins
+ uint8_t OffTimeHrs1 :1; // LSB of the number of hours.
// Byte 10
- uint8_t :1;
- uint8_t Breeze :3; // WindFree
- uint8_t :4;
+ uint8_t OffTimeHrs2 :4; // MSBs of the number of hours.
+ uint8_t OnTimeMins :3; // In units of 10's of mins
+ uint8_t OnTimeHrs1 :1; // LSB of the number of hours.
// Byte 11
- uint8_t :8;
+ uint8_t OnTimeHrs2 :4; // MSBs of the number of hours.
+ uint8_t :4;
// Byte 12
- uint8_t :8;
+ uint8_t OffTimeDay :1;
+ uint8_t OnTimerEnable :1;
+ uint8_t OffTimerEnable :1;
+ uint8_t Sleep12 :1;
+ uint8_t OnTimeDay :1;
+ uint8_t :3;
// Byte 13
- uint8_t :8;
+ uint8_t :8;
// 3rd Section
// Byte 14
- uint8_t :8;
+ uint8_t :8;
// Byte 15
- uint8_t :4;
- uint8_t Sum3Lower :4;
+ uint8_t :4;
+ uint8_t Sum3Lower :4;
// Byte 16
- uint8_t Sum3Upper :4;
- uint8_t :4;
+ uint8_t Sum3Upper :4;
+ uint8_t :4;
// Byte 17
- uint8_t :8;
+ uint8_t :8;
// Byte 18
- uint8_t :8;
+ uint8_t :8;
// Byte 19
- uint8_t :8;
+ uint8_t :8;
// Byte 20
- uint8_t :8;
+ uint8_t :8;
};
};
// Constants
-const uint8_t kSamsungAcPowerfulMask8 = 0b01010000;
-const uint8_t kSamsungAcSwingMove = 0b010;
-const uint8_t kSamsungAcSwingStop = 0b111;
-const uint8_t kSamsungAcPowerful10On = 0b011;
-const uint8_t kSamsungAcBreezeOn = 0b101;
const uint8_t kSamsungAcMinTemp = 16; // C Mask 0b11110000
const uint8_t kSamsungAcMaxTemp = 30; // C Mask 0b11110000
const uint8_t kSamsungAcAutoTemp = 25; // C Mask 0b11110000
@@ -174,12 +186,10 @@ class IRSamsungAc {
public:
explicit IRSamsungAc(const uint16_t pin, const bool inverted = false,
const bool use_modulation = true);
- void stateReset(const bool forcepower = true, const bool initialPower = true);
+ void stateReset(const bool extended = true, const bool initialPower = true);
#if SEND_SAMSUNG_AC
- void send(const uint16_t repeat = kSamsungAcDefaultRepeat,
- const bool calcchecksum = true);
- void sendExtended(const uint16_t repeat = kSamsungAcDefaultRepeat,
- const bool calcchecksum = true);
+ void send(const uint16_t repeat = kSamsungAcDefaultRepeat);
+ void sendExtended(const uint16_t repeat = kSamsungAcDefaultRepeat);
void sendOn(const uint16_t repeat = kSamsungAcDefaultRepeat);
void sendOff(const uint16_t repeat = kSamsungAcDefaultRepeat);
/// Run the calibration to calculate uSec timing offsets for this platform.
@@ -201,6 +211,8 @@ class IRSamsungAc {
uint8_t getMode(void) const;
void setSwing(const bool on);
bool getSwing(void) const;
+ void setSwingH(const bool on);
+ bool getSwingH(void) const;
void setBeep(const bool on);
bool getBeep(void) const;
void setClean(const bool on);
@@ -211,10 +223,18 @@ class IRSamsungAc {
bool getPowerful(void) const;
void setBreeze(const bool on);
bool getBreeze(void) const;
+ void setEcono(const bool on);
+ bool getEcono(void) const;
void setDisplay(const bool on);
bool getDisplay(void) const;
void setIon(const bool on);
bool getIon(void) const;
+ uint16_t getOnTimer(void) const;
+ void setOnTimer(const uint16_t nr_of_mins);
+ uint16_t getOffTimer(void) const;
+ void setOffTimer(const uint16_t nr_of_mins);
+ uint16_t getSleepTimer(void) const;
+ void setSleepTimer(const uint16_t nr_of_mins);
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kSamsungAcStateLength);
@@ -238,9 +258,22 @@ class IRSamsungAc {
/// @endcond
#endif // UNIT_TEST
SamsungProtocol _;
- bool _forcepower; ///< Hack to know when we need to send a special power mesg
+ bool _forceextended; ///< Flag to know when we need to send an extended mesg.
bool _lastsentpowerstate;
+ bool _OnTimerEnable;
+ bool _OffTimerEnable;
+ bool _Sleep;
+ bool _lastSleep;
+ uint16_t _OnTimer;
+ uint16_t _OffTimer;
+ uint16_t _lastOnTimer;
+ uint16_t _lastOffTimer;
void checksum(void);
+ uint16_t _getOnTimer(void) const;
+ uint16_t _getOffTimer(void) const;
+ void _setOnTimer(void);
+ void _setOffTimer(void);
+ void _setSleepTimer(void);
};
#endif // IR_SAMSUNG_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.cpp
index 8cbace41e..38f0ac32c 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.cpp
@@ -45,7 +45,9 @@ using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addModelToString;
+using irutils::addSwingVToString;
using irutils::addTempToString;
+using irutils::addToggleToString;
using irutils::minsToString;
// Also used by Denon protocol
@@ -544,24 +546,73 @@ void IRSharpAc::setTurbo(const bool on) {
_.Special = kSharpAcSpecialTurbo;
}
+/// Get the Vertical Swing setting of the A/C.
+/// @return The position of the Vertical Swing setting.
+uint8_t IRSharpAc::getSwingV(void) const { return _.Swing; }
+
+/// Set the Vertical Swing setting of the A/C.
+/// @note Some positions may not work on all models.
+/// @param[in] position The desired position/setting.
+/// @note `setSwingV(kSharpAcSwingVLowest)` will only allow the Lowest setting
+/// in Heat mode, it will default to `kSharpAcSwingVLow` otherwise.
+/// If you want to set this value in other modes e.g. Cool, you must
+/// use `setSwingV`s optional `force` parameter.
+/// @param[in] force Do we override the safety checks and just do it?
+void IRSharpAc::setSwingV(const uint8_t position, const bool force) {
+ switch (position) {
+ case kSharpAcSwingVCoanda:
+ // Only allowed in Heat mode.
+ if (!force && getMode() != kSharpAcHeat) {
+ setSwingV(kSharpAcSwingVLow); // Use the next lowest setting.
+ return;
+ }
+ // FALLTHRU
+ case kSharpAcSwingVHigh:
+ case kSharpAcSwingVMid:
+ case kSharpAcSwingVLow:
+ case kSharpAcSwingVToggle:
+ case kSharpAcSwingVOff:
+ case kSharpAcSwingVLast: // Technically valid, but we don't use it.
+ // All expected non-positions set the special bits.
+ _.Special = kSharpAcSpecialSwing;
+ // FALLTHRU
+ case kSharpAcSwingVIgnore:
+ _.Swing = position;
+ }
+}
+
+/// Convert a standard A/C vertical swing into its native setting.
+/// @param[in] position A stdAc::swingv_t position to convert.
+/// @return The equivalent native horizontal swing position.
+uint8_t IRSharpAc::convertSwingV(const stdAc::swingv_t position) {
+ switch (position) {
+ case stdAc::swingv_t::kHighest:
+ case stdAc::swingv_t::kHigh: return kSharpAcSwingVHigh;
+ case stdAc::swingv_t::kMiddle: return kSharpAcSwingVMid;
+ case stdAc::swingv_t::kLow: return kSharpAcSwingVLow;
+ case stdAc::swingv_t::kLowest: return kSharpAcSwingVCoanda;
+ case stdAc::swingv_t::kAuto: return kSharpAcSwingVToggle;
+ case stdAc::swingv_t::kOff: return kSharpAcSwingVOff;
+ default: return kSharpAcSwingVIgnore;
+ }
+}
+
/// Get the (vertical) Swing Toggle setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
bool IRSharpAc::getSwingToggle(void) const {
- return _.Swing == kSharpAcSwingToggle;
+ return getSwingV() == kSharpAcSwingVToggle;
}
/// Set the (vertical) Swing Toggle setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
void IRSharpAc::setSwingToggle(const bool on) {
- _.Swing = (on ? kSharpAcSwingToggle : kSharpAcSwingNoToggle);
+ setSwingV(on ? kSharpAcSwingVToggle : kSharpAcSwingVIgnore);
if (on) _.Special = kSharpAcSpecialSwing;
}
/// Get the Ion (Filter) setting of the A/C.
/// @return true, the setting is on. false, the setting is off.
-bool IRSharpAc::getIon(void) const {
- return _.Ion;
-}
+bool IRSharpAc::getIon(void) const { return _.Ion; }
/// Set the Ion (Filter) setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
@@ -628,15 +679,11 @@ uint16_t IRSharpAc::getTimerTime(void) const {
/// Is the Timer enabled?
/// @return true, the setting is on. false, the setting is off.
-bool IRSharpAc::getTimerEnabled(void) const {
- return _.TimerEnabled;
-}
+bool IRSharpAc::getTimerEnabled(void) const { return _.TimerEnabled; }
/// Get the current timer type.
/// @return true, It's an "On" timer. false, It's an "Off" timer.
-bool IRSharpAc::getTimerType(void) const {
- return _.TimerType;
-}
+bool IRSharpAc::getTimerType(void) const { return _.TimerType; }
/// Set or cancel the timer function.
/// @param[in] enable Is the timer to be enabled (true) or canceled(false)?
@@ -765,10 +812,34 @@ stdAc::fanspeed_t IRSharpAc::toCommonFanSpeed(const uint8_t speed) const {
}
}
+/// Convert a native vertical swing postion to it's common equivalent.
+/// @param[in] pos A native position to convert.
+/// @param[in] mode What operating mode are we in?
+/// @return The common vertical swing position.
+stdAc::swingv_t IRSharpAc::toCommonSwingV(const uint8_t pos,
+ const stdAc::opmode_t mode) const {
+ switch (pos) {
+ case kSharpAcSwingVHigh: return stdAc::swingv_t::kHighest;
+ case kSharpAcSwingVMid: return stdAc::swingv_t::kMiddle;
+ case kSharpAcSwingVLow: return stdAc::swingv_t::kLow;
+ case kSharpAcSwingVCoanda: // Coanda has mode dependent positionss
+ switch (mode) {
+ case stdAc::opmode_t::kCool: return stdAc::swingv_t::kHighest;
+ case stdAc::opmode_t::kHeat: return stdAc::swingv_t::kLowest;
+ default: return stdAc::swingv_t::kOff;
+ }
+ case kSharpAcSwingVToggle: return stdAc::swingv_t::kAuto;
+ default: return stdAc::swingv_t::kOff;
+ }
+}
+
/// Convert the current internal state into its stdAc::state_t equivalent.
+/// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings.
-stdAc::state_t IRSharpAc::toCommon(void) const {
+stdAc::state_t IRSharpAc::toCommon(const stdAc::state_t *prev) const {
stdAc::state_t result;
+ // Start with the previous state if given it.
+ if (prev != NULL) result = *prev;
result.protocol = decode_type_t::SHARP_AC;
result.model = getModel();
result.power = getPower();
@@ -777,8 +848,8 @@ stdAc::state_t IRSharpAc::toCommon(void) const {
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
result.turbo = getTurbo();
- result.swingv = getSwingToggle() ? stdAc::swingv_t::kAuto
- : stdAc::swingv_t::kOff;
+ if (getSwingV() != kSharpAcSwingVIgnore)
+ result.swingv = toCommonSwingV(getSwingV(), result.mode);
result.filter = _.Ion;
result.econo = getEconoToggle();
result.light = getLightToggle();
@@ -797,14 +868,16 @@ stdAc::state_t IRSharpAc::toCommon(void) const {
String IRSharpAc::toString(void) const {
String result = "";
const sharp_ac_remote_model_t model = getModel();
- result.reserve(160); // Reserve some heap for the string to reduce fragging.
+ result.reserve(170); // Reserve some heap for the string to reduce fragging.
result += addModelToString(decode_type_t::SHARP_AC, getModel(), false);
- result += addLabeledString(isPowerSpecial() ? "-"
- : (getPower() ? kOnStr : kOffStr),
+ result += addLabeledString(isPowerSpecial() ? String("-")
+ : String(getPower() ? kOnStr
+ : kOffStr),
kPowerStr);
+ const uint8_t mode = _.Mode;
result += addModeToString(
- _.Mode,
+ mode,
// Make the value invalid if the model doesn't support an Auto mode.
(model == sharp_ac_remote_model_t::A907) ? kSharpAcAuto : 255,
kSharpAcCool, kSharpAcHeat, kSharpAcDry, kSharpAcFan);
@@ -821,18 +894,37 @@ String IRSharpAc::toString(void) const {
kSharpAcFanAuto, kSharpAcFanAuto,
kSharpAcFanMed);
}
+ if (getSwingV() == kSharpAcSwingVIgnore) {
+ result += addIntToString(kSharpAcSwingVIgnore, kSwingVStr);
+ result += kSpaceLBraceStr;
+ result += kNAStr;
+ result += ')';
+ } else {
+ result += addSwingVToString(
+ getSwingV(), 0xFF,
+ // Coanda means Highest when in Cool mode.
+ (mode == kSharpAcCool) ? kSharpAcSwingVCoanda : kSharpAcSwingVToggle,
+ kSharpAcSwingVHigh,
+ 0xFF, // Upper Middle is unused
+ kSharpAcSwingVMid,
+ 0xFF, // Lower Middle is unused
+ kSharpAcSwingVLow,
+ kSharpAcSwingVCoanda,
+ kSharpAcSwingVOff,
+ // Below are unused.
+ kSharpAcSwingVToggle,
+ 0xFF,
+ 0xFF);
+ }
result += addBoolToString(getTurbo(), kTurboStr);
- result += addBoolToString(getSwingToggle(), kSwingVToggleStr);
result += addBoolToString(_.Ion, kIonStr);
switch (model) {
case sharp_ac_remote_model_t::A705:
case sharp_ac_remote_model_t::A903:
- result += addLabeledString(getLightToggle() ? kToggleStr : "-",
- kLightStr);
+ result += addToggleToString(getLightToggle(), kLightStr);
break;
default:
- result += addLabeledString(getEconoToggle() ? kToggleStr : "-",
- kEconoStr);
+ result += addToggleToString(getEconoToggle(), kEconoStr);
}
result += addBoolToString(_.Clean, kCleanStr);
if (_.TimerEnabled)
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.h
index dd6d826ac..b3be534e7 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Sharp.h
@@ -17,6 +17,7 @@
// Brand: Sharp, Model: AY-ZP40KR A/C (A907)
// Brand: Sharp, Model: AH-AxSAY A/C (A907)
// Brand: Sharp, Model: CRMC-A907 JBEZ remote (A907)
+// Brand: Sharp, Model: CRMC-A950 JBEZ (A907)
// Brand: Sharp, Model: AH-PR13-GL A/C (A903)
// Brand: Sharp, Model: CRMC-A903JBEZ remote (A903)
// Brand: Sharp, Model: AH-XP10NRY A/C (A903)
@@ -121,8 +122,23 @@ const uint8_t kSharpAcTimerHoursMax = 0b1100; // 12
const uint8_t kSharpAcOffTimerType = 0b0;
const uint8_t kSharpAcOnTimerType = 0b1;
-const uint8_t kSharpAcSwingToggle = 0b111;
-const uint8_t kSharpAcSwingNoToggle = 0b000;
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/discussions/1590#discussioncomment-1260213
+const uint8_t kSharpAcSwingVIgnore = 0b000; // Don't change the swing setting.
+const uint8_t kSharpAcSwingVHigh = 0b001; // 0° down. Similar to Cool Coanda.
+const uint8_t kSharpAcSwingVOff = 0b010; // Stop & Go to last fixed pos.
+const uint8_t kSharpAcSwingVMid = 0b011; // 30° down
+const uint8_t kSharpAcSwingVLow = 0b100; // 45° down
+const uint8_t kSharpAcSwingVLast = 0b101; // Same as kSharpAcSwingVOff.
+// Toggles between last fixed pos & either 75° down (Heat) or 0° down (Cool)
+// i.e. alternate between last pos <-> 75° down if in Heat mode, AND
+// alternate between last pos <-> 0° down if in Cool mode.
+// Note: `setSwingV(kSharpAcSwingVLowest)` will only allow the Lowest setting in
+// Heat mode, it will default to `kSharpAcSwingVLow` otherwise.
+// If you want to set this value in other modes e.g. Cool, you must
+// use `setSwingV`s optional `force` parameter.
+const uint8_t kSharpAcSwingVLowest = 0b110;
+const uint8_t kSharpAcSwingVCoanda = kSharpAcSwingVLowest;
+const uint8_t kSharpAcSwingVToggle = 0b111; // Toggle Constant swinging on/off.
const uint8_t kSharpAcSpecialPower = 0x00;
const uint8_t kSharpAcSpecialTurbo = 0x01;
@@ -166,6 +182,8 @@ class IRSharpAc {
void setTurbo(const bool on);
bool getSwingToggle(void) const;
void setSwingToggle(const bool on);
+ uint8_t getSwingV(void) const;
+ void setSwingV(const uint8_t position, const bool force = false);
bool getIon(void) const;
void setIon(const bool on);
bool getEconoToggle(void) const;
@@ -187,9 +205,13 @@ class IRSharpAc {
static uint8_t convertFan(const stdAc::fanspeed_t speed,
const sharp_ac_remote_model_t model =
sharp_ac_remote_model_t::A907);
+ static uint8_t convertSwingV(const stdAc::swingv_t position);
stdAc::opmode_t toCommonMode(const uint8_t mode) const;
stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed) const;
- stdAc::state_t toCommon(void) const;
+ stdAc::swingv_t toCommonSwingV(
+ const uint8_t pos,
+ const stdAc::opmode_t mode = stdAc::opmode_t::kHeat) const;
+ stdAc::state_t toCommon(const stdAc::state_t *prev = NULL) const;
String toString(void) const;
#ifndef UNIT_TEST
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Symphony.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Symphony.cpp
index d5fedb29b..b629ef72d 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Symphony.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Symphony.cpp
@@ -18,6 +18,15 @@
// Brand: Satellite Electronic, Model: ID6 Remote
// Brand: Satellite Electronic, Model: JY199I Fan driver
// Brand: Satellite Electronic, Model: JY199I-L Fan driver
+// Brand: SilverCrest, Model: SSVS 85 A1 Fan
+
+// Known Codes:
+// SilverCrest SSVS 85 A1 Fan:
+// 0x581 - On/Off
+// 0x582 - Speed
+// 0x584 - Mist
+// 0x588 - Timer
+// 0x590 - OSC
#include
#include "IRrecv.h"
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.cpp
index cce9d1f4c..a9e8784a3 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.cpp
@@ -15,12 +15,18 @@
// Constants
+const uint8_t kTcl112AcTimerResolution = 20; // Minutes
+const uint16_t kTcl112AcTimerMax = 720; // Minutes (12 hrs)
+
using irutils::addBoolToString;
using irutils::addFanToString;
using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
+using irutils::addModelToString;
+using irutils::addSwingVToString;
using irutils::addTempFloatToString;
+using irutils::minsToString;
#if SEND_TCL112AC
/// Send a TCL 112-bit A/C message.
@@ -71,6 +77,8 @@ void IRTcl112Ac::send(const uint16_t repeat) {
_quiet_prev = _quiet;
// Restore the old state.
setRaw(save);
+ // Make sure it looks like a normal TCL mesg if needed.
+ if (_.MsgType == kTcl112AcNormal) _.isTcl = true;
}
// Send the normal (type 1) state.
_irsend.sendTcl112Ac(getRaw(), kTcl112AcStateLength, repeat);
@@ -109,6 +117,17 @@ bool IRTcl112Ac::validChecksum(uint8_t state[], const uint16_t length) {
return (length > 1 && state[length - 1] == calcChecksum(state, length));
}
+/// Check the supplied state looks like a TCL112AC message.
+/// @param[in] state The array to verify the checksum of.
+/// @note Assumes the state is the correct size.
+/// @return true, if the state looks like a TCL112AC message. Otherwise, false.
+/// @warning This is just a guess.
+bool IRTcl112Ac::isTcl(const uint8_t state[]) {
+ Tcl112Protocol mesg;
+ std::memcpy(mesg.raw, state, kTcl112AcStateLength);
+ return (mesg.MsgType != kTcl112AcNormal) || mesg.isTcl;
+}
+
/// Reset the internal state of the emulation. (On, Cool, 24C)
void IRTcl112Ac::stateReset(void) {
// A known good state. (On, Cool, 24C)
@@ -121,6 +140,19 @@ void IRTcl112Ac::stateReset(void) {
_quiet_explictly_set = false;
}
+/// Get/Detect the model of the A/C.
+/// @return The enum of the compatible model.
+tcl_ac_remote_model_t IRTcl112Ac::getModel(void) const {
+ return isTcl(_.raw) ? tcl_ac_remote_model_t::TAC09CHSD
+ : tcl_ac_remote_model_t::GZ055BE1;
+}
+
+/// Set the model of the A/C to emulate.
+/// @param[in] model The enum of the appropriate model.
+void IRTcl112Ac::setModel(const tcl_ac_remote_model_t model) {
+ _.isTcl = (model != tcl_ac_remote_model_t::GZ055BE1);
+}
+
/// Get a PTR to the internal state/code for this protocol.
/// @return PTR to a code for this protocol based on the current internal state.
uint8_t* IRTcl112Ac::getRaw(void) {
@@ -203,6 +235,7 @@ float IRTcl112Ac::getTemp(void) const {
void IRTcl112Ac::setFan(const uint8_t speed) {
switch (speed) {
case kTcl112AcFanAuto:
+ case kTcl112AcFanMin:
case kTcl112AcFanLow:
case kTcl112AcFanMed:
case kTcl112AcFanHigh:
@@ -250,14 +283,23 @@ void IRTcl112Ac::setSwingHorizontal(const bool on) { _.SwingH = on; }
bool IRTcl112Ac::getSwingHorizontal(void) const { return _.SwingH; }
/// Set the vertical swing setting of the A/C.
-/// @param[in] on true, the setting is on. false, the setting is off.
-void IRTcl112Ac::setSwingVertical(const bool on) {
- _.SwingV = (on ? kTcl112AcSwingVOn : kTcl112AcSwingVOff);
+/// @param[in] setting The value of the desired setting.
+void IRTcl112Ac::setSwingVertical(const uint8_t setting) {
+ switch (setting) {
+ case kTcl112AcSwingVOff:
+ case kTcl112AcSwingVHighest:
+ case kTcl112AcSwingVHigh:
+ case kTcl112AcSwingVMiddle:
+ case kTcl112AcSwingVLow:
+ case kTcl112AcSwingVLowest:
+ case kTcl112AcSwingVOn:
+ _.SwingV = setting;
+ }
}
/// Get the vertical swing setting of the A/C.
-/// @return true, the setting is on. false, the setting is off.
-bool IRTcl112Ac::getSwingVertical(void) const { return _.SwingV; }
+/// @return The current setting.
+uint8_t IRTcl112Ac::getSwingVertical(void) const { return _.SwingV; }
/// Set the Turbo setting of the A/C.
/// @param[in] on true, the setting is on. false, the setting is off.
@@ -291,6 +333,36 @@ bool IRTcl112Ac::getQuiet(const bool def) const {
return _quiet_explictly_set ? _quiet : def;
}
+/// Get how long the On Timer is set for, in minutes.
+/// @return The time in nr of minutes.
+uint16_t IRTcl112Ac::getOnTimer(void) const {
+ return _.OnTimer * kTcl112AcTimerResolution;
+}
+
+/// Set or cancel the On Timer function.
+/// @param[in] mins Nr. of minutes the timer is to be set to.
+/// @note Rounds down to 20 min increments. (max: 720 mins (12h), 0 is Off)
+void IRTcl112Ac::setOnTimer(const uint16_t mins) {
+ _.OnTimer = std::min(mins, kTcl112AcTimerMax) / kTcl112AcTimerResolution;
+ _.OnTimerEnabled = _.OnTimer > 0;
+ _.TimerIndicator = _.OnTimerEnabled || _.OffTimerEnabled;
+}
+
+/// Get how long the Off Timer is set for, in minutes.
+/// @return The time in nr of minutes.
+uint16_t IRTcl112Ac::getOffTimer(void) const {
+ return _.OffTimer * kTcl112AcTimerResolution;
+}
+
+/// Set or cancel the Off Timer function.
+/// @param[in] mins Nr. of minutes the timer is to be set to.
+/// @note Rounds down to 20 min increments. (max: 720 mins (12h), 0 is Off)
+void IRTcl112Ac::setOffTimer(const uint16_t mins) {
+ _.OffTimer = std::min(mins, kTcl112AcTimerMax) / kTcl112AcTimerResolution;
+ _.OffTimerEnabled = _.OffTimer > 0;
+ _.TimerIndicator = _.OnTimerEnabled || _.OffTimerEnabled;
+}
+
/// Convert a stdAc::opmode_t enum into its native mode.
/// @param[in] mode The enum to be converted.
/// @return The native equivalent of the enum.
@@ -309,7 +381,7 @@ uint8_t IRTcl112Ac::convertMode(const stdAc::opmode_t mode) {
/// @return The native equivalent of the enum.
uint8_t IRTcl112Ac::convertFan(const stdAc::fanspeed_t speed) {
switch (speed) {
- case stdAc::fanspeed_t::kMin:
+ case stdAc::fanspeed_t::kMin: return kTcl112AcFanMin;
case stdAc::fanspeed_t::kLow: return kTcl112AcFanLow;
case stdAc::fanspeed_t::kMedium: return kTcl112AcFanMed;
case stdAc::fanspeed_t::kHigh:
@@ -331,6 +403,21 @@ stdAc::opmode_t IRTcl112Ac::toCommonMode(const uint8_t mode) {
}
}
+/// Convert a stdAc::swingv_t enum into it's native setting.
+/// @param[in] position The enum to be converted.
+/// @return The native equivalent of the enum.
+uint8_t IRTcl112Ac::convertSwingV(const stdAc::swingv_t position) {
+ switch (position) {
+ case stdAc::swingv_t::kOff: return kTcl112AcSwingVOff;
+ case stdAc::swingv_t::kHighest: return kTcl112AcSwingVHighest;
+ case stdAc::swingv_t::kHigh: return kTcl112AcSwingVHigh;
+ case stdAc::swingv_t::kMiddle: return kTcl112AcSwingVMiddle;
+ case stdAc::swingv_t::kLow: return kTcl112AcSwingVLow;
+ case stdAc::swingv_t::kLowest: return kTcl112AcSwingVLowest;
+ default: return kTcl112AcSwingVOn;
+ }
+}
+
/// Convert a native fan speed into its stdAc equivalent.
/// @param[in] spd The native setting to be converted.
/// @return The stdAc equivalent of the native setting.
@@ -338,11 +425,21 @@ stdAc::fanspeed_t IRTcl112Ac::toCommonFanSpeed(const uint8_t spd) {
switch (spd) {
case kTcl112AcFanHigh: return stdAc::fanspeed_t::kMax;
case kTcl112AcFanMed: return stdAc::fanspeed_t::kMedium;
- case kTcl112AcFanLow: return stdAc::fanspeed_t::kMin;
+ case kTcl112AcFanLow: return stdAc::fanspeed_t::kLow;
+ case kTcl112AcFanMin: return stdAc::fanspeed_t::kMin;
default: return stdAc::fanspeed_t::kAuto;
}
}
+/// Convert a native vertical swing postion to it's common equivalent.
+/// @param[in] setting A native position to convert.
+/// @return The common vertical swing position.
+stdAc::swingv_t IRTcl112Ac::toCommonSwingV(const uint8_t setting) {
+ switch (setting) {
+ case kTcl112AcSwingVOff: return stdAc::swingv_t::kOff;
+ default: return stdAc::swingv_t::kAuto;
+ }
+}
/// Convert the current internal state into its stdAc::state_t equivalent.
/// @param[in] prev Ptr to the previous state if required.
/// @return The stdAc equivalent of the native settings.
@@ -351,7 +448,7 @@ stdAc::state_t IRTcl112Ac::toCommon(const stdAc::state_t *prev) const {
// Start with the previous state if given it.
if (prev != NULL) result = *prev;
result.protocol = decode_type_t::TCL112AC;
- result.model = -1; // Not supported.
+ result.model = getModel();
result.quiet = getQuiet(result.quiet);
// The rest only get updated if it is a "normal" message.
if (_.MsgType == kTcl112AcNormal) {
@@ -360,7 +457,7 @@ stdAc::state_t IRTcl112Ac::toCommon(const stdAc::state_t *prev) const {
result.celsius = true;
result.degrees = getTemp();
result.fanspeed = toCommonFanSpeed(_.Fan);
- result.swingv = _.SwingV ? stdAc::swingv_t::kAuto : stdAc::swingv_t::kOff;
+ result.swingv = toCommonSwingV(_.SwingV);
result.swingh = _.SwingH ? stdAc::swingh_t::kAuto : stdAc::swingh_t::kOff;
result.turbo = _.Turbo;
result.filter = _.Health;
@@ -379,8 +476,10 @@ stdAc::state_t IRTcl112Ac::toCommon(const stdAc::state_t *prev) const {
/// @return A human readable string.
String IRTcl112Ac::toString(void) const {
String result = "";
- result.reserve(150); // Reserve some heap for the string to reduce fragging.
- result += addIntToString(_.MsgType, D_STR_TYPE, false);
+ result.reserve(220); // Reserve some heap for the string to reduce fragging.
+ tcl_ac_remote_model_t model = getModel();
+ result += addModelToString(decode_type_t::TCL112AC, model, false);
+ result += addIntToString(_.MsgType, D_STR_TYPE);
switch (_.MsgType) {
case kTcl112AcNormal:
result += addBoolToString(_.Power, kPowerStr);
@@ -388,14 +487,32 @@ String IRTcl112Ac::toString(void) const {
kTcl112AcHeat, kTcl112AcDry, kTcl112AcFan);
result += addTempFloatToString(getTemp());
result += addFanToString(_.Fan, kTcl112AcFanHigh, kTcl112AcFanLow,
- kTcl112AcFanAuto, kTcl112AcFanAuto,
+ kTcl112AcFanAuto, kTcl112AcFanMin,
kTcl112AcFanMed);
- result += addBoolToString(_.Econo, kEconoStr);
- result += addBoolToString(_.Health, kHealthStr);
- result += addBoolToString(_.Turbo, kTurboStr);
- result += addBoolToString(_.SwingH, kSwingHStr);
- result += addBoolToString(_.SwingV, kSwingVStr);
- result += addBoolToString(getLight(), kLightStr);
+ result += addSwingVToString(_.SwingV, kTcl112AcSwingVOff,
+ kTcl112AcSwingVHighest,
+ kTcl112AcSwingVHigh,
+ 0xFF, // unused
+ kTcl112AcSwingVMiddle,
+ 0xFF, // unused
+ kTcl112AcSwingVLow,
+ kTcl112AcSwingVLowest,
+ kTcl112AcSwingVOff,
+ kTcl112AcSwingVOn, // Swing
+ 0xFF, 0xFF); // Both Unused
+ if (model != tcl_ac_remote_model_t::GZ055BE1) {
+ result += addBoolToString(_.SwingH, kSwingHStr);
+ result += addBoolToString(_.Econo, kEconoStr);
+ result += addBoolToString(_.Health, kHealthStr);
+ result += addBoolToString(_.Turbo, kTurboStr);
+ result += addBoolToString(getLight(), kLightStr);
+ }
+ result += addLabeledString(
+ _.OnTimerEnabled ? minsToString(getOnTimer()) : kOffStr,
+ kOnTimerStr);
+ result += addLabeledString(
+ _.OffTimerEnabled ? minsToString(getOffTimer()) : kOffStr,
+ kOffTimerStr);
break;
case kTcl112AcSpecial:
result += addBoolToString(_.Quiet, kQuietStr);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.h
index b9f059627..e1696c42a 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Tcl.h
@@ -4,8 +4,10 @@
/// @brief Support for TCL protocols.
// Supports:
-// Brand: Leberg, Model: LBS-TOR07 A/C
-// Brand: TCL, Model: TAC-09CHSD/XA31I A/C
+// Brand: Leberg, Model: LBS-TOR07 A/C (TAC09CHSD)
+// Brand: TCL, Model: TAC-09CHSD/XA31I A/C (TAC09CHSD)
+// Brand: Teknopoint, Model: Allegro SSA-09H A/C (GZ055BE1)
+// Brand: Teknopoint, Model: GZ-055B-E1 remote (GZ055BE1)
#ifndef IR_TCL_H_
#define IR_TCL_H_
@@ -25,41 +27,54 @@ union Tcl112Protocol{
uint8_t raw[kTcl112AcStateLength]; ///< The State in IR code form.
struct {
// Byte 0~2
- uint8_t pad0[3];
+ uint8_t :8;
+ uint8_t :8;
+ uint8_t :8;
// Byte 3
- uint8_t MsgType :2;
- uint8_t :6;
+ uint8_t MsgType :2;
+ uint8_t :6;
// Byte 4
- uint8_t :8;
+ uint8_t :8;
// Byte 5
- uint8_t :2;
- uint8_t Power :1;
- uint8_t :2;
- uint8_t Quiet :1;
- uint8_t Light :1;
- uint8_t Econo :1;
+ uint8_t :2;
+ uint8_t Power :1;
+ uint8_t OffTimerEnabled :1;
+ uint8_t OnTimerEnabled :1;
+ uint8_t Quiet :1;
+ uint8_t Light :1;
+ uint8_t Econo :1;
// Byte 6
- uint8_t Mode :4;
- uint8_t Health :1;
- uint8_t Turbo :1;
- uint8_t :2;
+ uint8_t Mode :4;
+ uint8_t Health :1;
+ uint8_t Turbo :1;
+ uint8_t :2;
// Byte 7
- uint8_t Temp :4;
- uint8_t :4;
+ uint8_t Temp :4;
+ uint8_t :4;
// Byte 8
- uint8_t Fan :3;
- uint8_t SwingV :3;
- uint8_t :2;
- // Byte 9~11
- uint8_t pad1[3];
+ uint8_t Fan :3;
+ uint8_t SwingV :3;
+ uint8_t TimerIndicator :1;
+ uint8_t :1;
+ // Byte 9
+ uint8_t :1; // 0
+ uint8_t OffTimer :6;
+ uint8_t :1; // 0
+ // Byte 10
+ uint8_t :1; // 0
+ uint8_t OnTimer :6;
+ uint8_t :1; // 0
+ // Byte 11
+ uint8_t :8; // 00000000
// Byte 12
- uint8_t :3;
- uint8_t SwingH :1;
- uint8_t :1;
- uint8_t HalfDegree :1;
- uint8_t :2;
+ uint8_t :3;
+ uint8_t SwingH :1;
+ uint8_t :1;
+ uint8_t HalfDegree :1;
+ uint8_t :1;
+ uint8_t isTcl :1;
// Byte 13
- uint8_t Sum :8;
+ uint8_t Sum :8;
};
};
@@ -81,15 +96,23 @@ const uint8_t kTcl112AcFan = 7;
const uint8_t kTcl112AcAuto = 8;
const uint8_t kTcl112AcFanAuto = 0b000;
+const uint8_t kTcl112AcFanMin = 0b001; // Aka. "Night"
const uint8_t kTcl112AcFanLow = 0b010;
const uint8_t kTcl112AcFanMed = 0b011;
const uint8_t kTcl112AcFanHigh = 0b101;
+const uint8_t kTcl112AcFanNight = kTcl112AcFanMin;
+const uint8_t kTcl112AcFanQuiet = kTcl112AcFanMin;
const float kTcl112AcTempMax = 31.0;
const float kTcl112AcTempMin = 16.0;
-const uint8_t kTcl112AcSwingVOn = 0b111;
-const uint8_t kTcl112AcSwingVOff = 0b000;
+const uint8_t kTcl112AcSwingVOff = 0b000;
+const uint8_t kTcl112AcSwingVHighest = 0b001;
+const uint8_t kTcl112AcSwingVHigh = 0b010;
+const uint8_t kTcl112AcSwingVMiddle = 0b011;
+const uint8_t kTcl112AcSwingVLow = 0b100;
+const uint8_t kTcl112AcSwingVLowest = 0b101;
+const uint8_t kTcl112AcSwingVOn = 0b111;
// MsgType
const uint8_t kTcl112AcNormal = 0b01;
const uint8_t kTcl112AcSpecial = 0b10;
@@ -113,6 +136,8 @@ class IRTcl112Ac {
uint8_t* getRaw(void);
void setRaw(const uint8_t new_code[],
const uint16_t length = kTcl112AcStateLength);
+ tcl_ac_remote_model_t getModel(void) const;
+ void setModel(const tcl_ac_remote_model_t model);
void on(void);
void off(void);
void setPower(const bool on);
@@ -135,16 +160,23 @@ class IRTcl112Ac {
bool getLight(void) const;
void setSwingHorizontal(const bool on);
bool getSwingHorizontal(void) const;
- void setSwingVertical(const bool on);
- bool getSwingVertical(void) const;
+ void setSwingVertical(const uint8_t setting);
+ uint8_t getSwingVertical(void) const;
void setTurbo(const bool on);
bool getTurbo(void) const;
void setQuiet(const bool on);
bool getQuiet(const bool def = false) const;
+ uint16_t getOnTimer(void) const;
+ void setOnTimer(const uint16_t mins);
+ uint16_t getOffTimer(void) const;
+ void setOffTimer(const uint16_t mins);
+ static bool isTcl(const uint8_t state[]);
static uint8_t convertMode(const stdAc::opmode_t mode);
static uint8_t convertFan(const stdAc::fanspeed_t speed);
+ static uint8_t convertSwingV(const stdAc::swingv_t position);
static stdAc::opmode_t toCommonMode(const uint8_t mode);
static stdAc::fanspeed_t toCommonFanSpeed(const uint8_t speed);
+ static stdAc::swingv_t toCommonSwingV(const uint8_t setting);
stdAc::state_t toCommon(const stdAc::state_t *prev = NULL) const;
String toString(void) const;
#ifndef UNIT_TEST
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Transcold.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Transcold.cpp
index 066196073..14cc7f8bd 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Transcold.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/ir_Transcold.cpp
@@ -29,7 +29,7 @@ using irutils::addIntToString;
using irutils::addLabeledString;
using irutils::addModeToString;
using irutils::addTempToString;
-
+using irutils::addToggleToString;
#if SEND_TRANSCOLD
/// Send a Transcold message
@@ -391,13 +391,7 @@ String IRTranscoldAc::toString(void) const {
result += addBoolToString(getPower(), kPowerStr, false);
if (!getPower()) return result; // If it's off, there is no other info.
// Special modes.
- if (getSwing()) {
- result += kCommaSpaceStr;
- result += kSwingStr;
- result += kColonSpaceStr;
- result += kToggleStr;
- return result;
- }
+ if (getSwing()) return result + addToggleToString(true, kSwingStr);
result += addModeToString(getMode(), kTranscoldAuto, kTranscoldCool,
kTranscoldHeat, kTranscoldDry, kTranscoldFan);
result += addIntToString(_.Fan, kFanStr);
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/defaults.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/defaults.h
index b55b87abc..0fcc04791 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/defaults.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/defaults.h
@@ -30,9 +30,15 @@
#ifndef D_STR_ON
#define D_STR_ON "On"
#endif // D_STR_ON
+#ifndef D_STR_1
+#define D_STR_1 "1"
+#endif // D_STR_1
#ifndef D_STR_OFF
#define D_STR_OFF "Off"
#endif // D_STR_OFF
+#ifndef D_STR_0
+#define D_STR_0 "0"
+#endif // D_STR_0
#ifndef D_STR_MODE
#define D_STR_MODE "Mode"
#endif // D_STR_MODE
@@ -285,6 +291,9 @@
#ifndef D_STR_VANE
#define D_STR_VANE "Vane"
#endif // D_STR_VANE
+#ifndef D_STR_LOCK
+#define D_STR_LOCK "Lock"
+#endif // D_STR_LOCK
#ifndef D_STR_AUTO
#define D_STR_AUTO "Auto"
@@ -298,18 +307,42 @@
#ifndef D_STR_COOL
#define D_STR_COOL "Cool"
#endif // D_STR_COOL
+#ifndef D_STR_COOLING
+#define D_STR_COOLING "Cooling"
+#endif // D_STR_COOLING
#ifndef D_STR_HEAT
#define D_STR_HEAT "Heat"
#endif // D_STR_HEAT
+#ifndef D_STR_HEATING
+#define D_STR_HEATING "Heating"
+#endif // D_STR_HEATING
#ifndef D_STR_FAN
#define D_STR_FAN "Fan"
#endif // D_STR_FAN
#ifndef D_STR_FANONLY
-#define D_STR_FANONLY "fan_only"
+#define D_STR_FANONLY "fan-only"
#endif // D_STR_FANONLY
+#ifndef D_STR_FAN_ONLY
+#define D_STR_FAN_ONLY "fan_only"
+#endif // D_STR_FAN_ONLY
+#ifndef D_STR_ONLY
+#define D_STR_ONLY "Only"
+#endif // D_STR_ONLY
+#ifndef D_STR_FANSPACEONLY
+#define D_STR_FANSPACEONLY D_STR_FAN " " D_STR_ONLY
+#endif // D_STR_FANSPACEONLY
+#ifndef D_STR_FANONLYNOSPACE
+#define D_STR_FANONLYNOSPACE D_STR_FAN D_STR_ONLY
+#endif // D_STR_FANONLYNOSPACE
#ifndef D_STR_DRY
#define D_STR_DRY "Dry"
#endif // D_STR_DRY
+#ifndef D_STR_DRYING
+#define D_STR_DRYING "Drying"
+#endif // D_STR_DRYING
+#ifndef D_STR_DEHUMIDIFY
+#define D_STR_DEHUMIDIFY "Dehumidify"
+#endif // D_STR_DEHUMIDIFY
#ifndef D_STR_MAX
#define D_STR_MAX "Max"
@@ -360,6 +393,12 @@
#ifndef D_STR_MAXRIGHT
#define D_STR_MAXRIGHT D_STR_MAX " " D_STR_RIGHT // Set `D_STR_MAX` first!
#endif // D_STR_MAXRIGHT
+#ifndef D_STR_MAXRIGHT_NOSPACE
+#define D_STR_MAXRIGHT_NOSPACE D_STR_MAX D_STR_RIGHT // Set `D_STR_MAX` first!
+#endif // D_STR_MAXRIGHT_NOSPACE
+#ifndef D_STR_RIGHTMAX
+#define D_STR_RIGHTMAX D_STR_RIGHT " " D_STR_MAX // Set `D_STR_MAX` first!
+#endif // D_STR_RIGHTMAX
#ifndef D_STR_RIGHTMAX_NOSPACE
#define D_STR_RIGHTMAX_NOSPACE D_STR_RIGHT D_STR_MAX // Set `D_STR_MAX` first!
#endif // D_STR_RIGHTMAX_NOSPACE
@@ -369,6 +408,12 @@
#ifndef D_STR_MAXLEFT
#define D_STR_MAXLEFT D_STR_MAX " " D_STR_LEFT // Set `D_STR_MAX` first!
#endif // D_STR_MAXLEFT
+#ifndef D_STR_MAXLEFT_NOSPACE
+#define D_STR_MAXLEFT_NOSPACE D_STR_MAX D_STR_LEFT // Set `D_STR_MAX` first!
+#endif // D_STR_MAXLEFT_NOSPACE
+#ifndef D_STR_LEFTMAX
+#define D_STR_LEFTMAX D_STR_LEFT " " D_STR_MAX // Set `D_STR_MAX` first!
+#endif // D_STR_LEFTMAX
#ifndef D_STR_LEFTMAX_NOSPACE
#define D_STR_LEFTMAX_NOSPACE D_STR_LEFT D_STR_MAX // Set `D_STR_MAX` first!
#endif // D_STR_LEFTMAX_NOSPACE
@@ -440,6 +485,9 @@
#ifndef D_STR_COLONSPACE
#define D_STR_COLONSPACE ": "
#endif // D_STR_COLONSPACE
+#ifndef D_STR_DASH
+#define D_STR_DASH "-"
+#endif // D_STR_DASH
#ifndef D_STR_DAY
#define D_STR_DAY "Day"
@@ -495,7 +543,135 @@
#define D_STR_BITS "Bits"
#endif // D_STR_BITS
+// Model Names
+#ifndef D_STR_YAW1F
+#define D_STR_YAW1F "YAW1F"
+#endif // D_STR_YAW1F
+#ifndef D_STR_YBOFB
+#define D_STR_YBOFB "YBOFB"
+#endif // D_STR_YBOFB
+#ifndef D_STR_V9014557_A
+#define D_STR_V9014557_A "V9014557-A"
+#endif // D_STR_V9014557_A
+#ifndef D_STR_V9014557_B
+#define D_STR_V9014557_B "V9014557-B"
+#endif // D_STR_V9014557_B
+#ifndef D_STR_RLT0541HTA_A
+#define D_STR_RLT0541HTA_A "R-LT0541-HTA-A"
+#endif // D_STR_RLT0541HTA_A
+#ifndef D_STR_RLT0541HTA_B
+#define D_STR_RLT0541HTA_B "R-LT0541-HTA-B"
+#endif // D_STR_RLT0541HTA_B
+#ifndef D_STR_ARRAH2E
+#define D_STR_ARRAH2E "ARRAH2E"
+#endif // D_STR_ARRAH2E
+#ifndef D_STR_ARDB1
+#define D_STR_ARDB1 "ARDB1"
+#endif // D_STR_ARDB1
+#ifndef D_STR_ARREB1E
+#define D_STR_ARREB1E "ARREB1E"
+#endif // D_STR_ARREB1E
+#ifndef D_STR_ARJW2
+#define D_STR_ARJW2 "ARJW2"
+#endif // D_STR_ARJW2
+#ifndef D_STR_ARRY4
+#define D_STR_ARRY4 "ARRY4"
+#endif // D_STR_ARRY4
+#ifndef D_STR_ARREW4E
+#define D_STR_ARREW4E "ARREW4E"
+#endif // D_STR_ARREW4E
+#ifndef D_STR_GE6711AR2853M
+#define D_STR_GE6711AR2853M "GE6711AR2853M"
+#endif // D_STR_GE6711AR2853M
+#ifndef D_STR_AKB75215403
+#define D_STR_AKB75215403 "AKB75215403"
+#endif // D_STR_AKB75215403
+#ifndef D_STR_AKB74955603
+#define D_STR_AKB74955603 "AKB74955603"
+#endif // D_STR_AKB74955603
+#ifndef D_STR_AKB73757604
+#define D_STR_AKB73757604 "AKB73757604"
+#endif // D_STR_AKB73757604
+#ifndef D_STR_KKG9AC1
+#define D_STR_KKG9AC1 "KKG9AC1"
+#endif // D_STR_KKG9AC1
+#ifndef D_STR_KKG29AC1
+#define D_STR_KKG29AC1 "KKG29AC1"
+#endif // D_STR_KKG9AC1
+#ifndef D_STR_LKE
+#define D_STR_LKE "LKE"
+#endif // D_STR_LKE
+#ifndef D_STR_NKE
+#define D_STR_NKE "NKE"
+#endif // D_STR_NKE
+#ifndef D_STR_DKE
+#define D_STR_DKE "DKE"
+#endif // D_STR_DKE
+#ifndef D_STR_PKR
+#define D_STR_PKR "PKR"
+#endif // D_STR_PKR
+#ifndef D_STR_JKE
+#define D_STR_JKE "JKE"
+#endif // D_STR_JKE
+#ifndef D_STR_CKP
+#define D_STR_CKP "CKP"
+#endif // D_STR_CKP
+#ifndef D_STR_RKR
+#define D_STR_RKR "RKR"
+#endif // D_STR_RKR
+#ifndef D_STR_PANASONICLKE
+#define D_STR_PANASONICLKE "PANASONICLKE"
+#endif // D_STR_PANASONICLKE
+#ifndef D_STR_PANASONICNKE
+#define D_STR_PANASONICNKE "PANASONICNKE"
+#endif // D_STR_PANASONICNKE
+#ifndef D_STR_PANASONICDKE
+#define D_STR_PANASONICDKE "PANASONICDKE"
+#endif // D_STR_PANASONICDKE
+#ifndef D_STR_PANASONICPKR
+#define D_STR_PANASONICPKR "PANASONICPKR"
+#endif // D_STR_PANASONICPKR
+#ifndef D_STR_PANASONICJKE
+#define D_STR_PANASONICJKE "PANASONICJKE"
+#endif // D_STR_PANASONICJKE
+#ifndef D_STR_PANASONICCKP
+#define D_STR_PANASONICCKP "PANASONICCKP"
+#endif // D_STR_PANASONICCKP
+#ifndef D_STR_PANASONICRKR
+#define D_STR_PANASONICRKR "PANASONICRKR"
+#endif // D_STR_PANASONICRKR
+#ifndef D_STR_A907
+#define D_STR_A907 "A907"
+#endif // D_STR_A907
+#ifndef D_STR_A705
+#define D_STR_A705 "A705"
+#endif // D_STR_A705
+#ifndef D_STR_A903
+#define D_STR_A903 "A903"
+#endif // D_STR_A903
+#ifndef D_STR_TAC09CHSD
+#define D_STR_TAC09CHSD "TAC09CHSD"
+#endif // D_STR_TAC09CHSD
+#ifndef D_STR_GZ055BE1
+#define D_STR_GZ055BE1 "GZ055BE1"
+#endif // D_STR_GZ055BE1
+#ifndef D_STR_122LZF
+#define D_STR_122LZF "122LZF"
+#endif // D_STR_122LZF
+#ifndef D_STR_DG11J13A
+#define D_STR_DG11J13A "DG11J13A"
+#endif // D_STR_DG11J13A
+#ifndef D_STR_DG11J104
+#define D_STR_DG11J104 "DG11J104"
+#endif // D_STR_DG11J104
+#ifndef D_STR_DG11J191
+#define D_STR_DG11J191 "DG11J191"
+#endif // D_STR_DG11J191
+
// Protocols Names
+#ifndef D_STR_AIRTON
+#define D_STR_AIRTON "AIRTON"
+#endif // D_STR_AIRTON
#ifndef D_STR_AIRWELL
#define D_STR_AIRWELL "AIRWELL"
#endif // D_STR_AIRWELL
@@ -508,6 +684,9 @@
#ifndef D_STR_ARGO
#define D_STR_ARGO "ARGO"
#endif // D_STR_ARGO
+#ifndef D_STR_ARRIS
+#define D_STR_ARRIS "ARRIS"
+#endif // D_STR_ARRIS
#ifndef D_STR_BOSE
#define D_STR_BOSE "BOSE"
#endif // D_STR_BOSE
@@ -733,6 +912,9 @@
#ifndef D_STR_RCMM
#define D_STR_RCMM "RCMM"
#endif // D_STR_RCMM
+#ifndef D_STR_RHOSS
+#define D_STR_RHOSS "RHOSS"
+#endif // D_STR_RHOSS
#ifndef D_STR_SAMSUNG
#define D_STR_SAMSUNG "SAMSUNG"
#endif // D_STR_SAMSUNG
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/pt-BR.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/pt-BR.h
index 4875dda0d..4b2c929e0 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/pt-BR.h
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/pt-BR.h
@@ -29,6 +29,7 @@
#define D_STR_TIMER "Timer"
#define D_STR_ONTIMER D_STR_TIMER " " D_STR_ON
#define D_STR_OFFTIMER D_STR_TIMER " " D_STR_OFF
+#define D_STR_TIMERMODE D_STR_MODE " " D_STR_TIMER
#define D_STR_CLOCK "Relógio"
#define D_STR_COMMAND "Comando"
#define D_STR_HEALTH "Saúde"
@@ -84,6 +85,11 @@
#define D_STR_6THSENSE "Sexto sentido"
#define D_STR_ZONEFOLLOW "Acompanhar ambiente"
#define D_STR_FIXED "Fixo"
+#define D_STR_TYPE "Tipo"
+#define D_STR_SPECIAL "Especial"
+#define D_STR_RECYCLE "Reciclar"
+#define D_STR_ID "Id"
+#define D_STR_VANE "Vane"
#define D_STR_AUTO "Auto"
#define D_STR_AUTOMATIC "Automático"
@@ -91,7 +97,11 @@
#define D_STR_COOL "Esfriar"
#define D_STR_HEAT "Aquecer"
#define D_STR_FAN "Ventilar"
-#define D_STR_FANONLY "Apenas ventilar"
+#define D_STR_FANONLY "Apenas-ventilar"
+#define D_STR_FAN_ONLY "Apenas_ventilar"
+#define D_STR_ONLY "Apenas"
+#define D_STR_FANSPACEONLY D_STR_ONLY " " D_STR_FAN
+#define D_STR_FANONLYNOSPACE D_STR_ONLY D_STR_FAN
#define D_STR_DRY "Secar"
#define D_STR_8C_HEAT D_STR_HEAT " 8C"
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/ru-RU.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/ru-RU.h
new file mode 100644
index 000000000..02a892403
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/ru-RU.h
@@ -0,0 +1,152 @@
+// Copyright 2021 - PtilopsisLeucotis (@PtilopsisLeucotis)
+// Locale/language file for Russian / Russia.
+// This file will override the default values located in `defaults.h`.
+#ifndef LOCALE_RU_RU_H_
+#define LOCALE_RU_RU_H_
+
+#define D_STR_UNKNOWN "НЕИЗВЕСТНО"
+#define D_STR_PROTOCOL "Протокол"
+#define D_STR_POWER "Питание"
+#define D_STR_PREVIOUS "Предыдущий"
+#define D_STR_ON "Вкл"
+#define D_STR_OFF "Выкл"
+#define D_STR_MODE "Режим"
+#define D_STR_TOGGLE "Переключить"
+#define D_STR_TURBO "Турбо"
+#define D_STR_SUPER "Супер"
+#define D_STR_SLEEP "Сон"
+#define D_STR_LIGHT "Свет"
+#define D_STR_POWERFUL "Мощный"
+#define D_STR_QUIET "Тихий"
+#define D_STR_ECONO "Экономичный"
+#define D_STR_SWING "Качание"
+#define D_STR_SWINGH D_STR_SWING"(Г)"
+#define D_STR_SWINGV D_STR_SWING"(В)"
+#define D_STR_BEEP "Звук"
+#define D_STR_MOULD "Плесень"
+#define D_STR_CLEAN "Чистый"
+#define D_STR_PURIFY "Очистка"
+#define D_STR_TIMER "Таймер"
+#define D_STR_ONTIMER "Таймер Включения"
+#define D_STR_OFFTIMER "Таймер Выключения"
+#define D_STR_TIMERMODE "Режим Таймера"
+#define D_STR_CLOCK "Часы"
+#define D_STR_COMMAND "Команда"
+#define D_STR_HEALTH "Здоровье"
+#define D_STR_MODEL "Модель"
+#define D_STR_TEMP "Температура"
+#define D_STR_HUMID "Влажность"
+#define D_STR_SAVE "Сохранить"
+#define D_STR_EYE "Глаз"
+#define D_STR_FOLLOW "Следовать"
+#define D_STR_ION "Ион"
+#define D_STR_FRESH "Свежесть"
+#define D_STR_HOLD "Удержать"
+#define D_STR_BUTTON "Кнопка"
+#define D_STR_NIGHT "Ночь"
+#define D_STR_SILENT "Тихий"
+#define D_STR_FILTER "Фильтр"
+#define D_STR_CELSIUS "Цельсий"
+#define D_STR_FAHRENHEIT "Фаренгейт"
+#define D_STR_UP "Выше"
+#define D_STR_TEMPUP D_STR_TEMP " " D_STR_UP
+#define D_STR_DOWN "Ниже"
+#define D_STR_TEMPDOWN D_STR_TEMP " " D_STR_DOWN
+#define D_STR_CHANGE "Изменение"
+#define D_STR_START "Запуск"
+#define D_STR_STOP "Остановка"
+#define D_STR_MOVE "Перемещение"
+#define D_STR_SET "Установка"
+#define D_STR_CANCEL "Отмена"
+#define D_STR_COMFORT "Комфорт"
+#define D_STR_SENSOR "Сенсор"
+#define D_STR_DISPLAY "Дисплей"
+#define D_STR_WEEKLY "Недельный"
+#define D_STR_LAST "Последний"
+#define D_STR_FAST "Быстро"
+#define D_STR_SLOW "Медленно"
+#define D_STR_AIRFLOW "Воздушный Поток"
+#define D_STR_STEP "Шаг"
+#define D_STR_NA "Н/Д"
+#define D_STR_INSIDE "Внутри"
+#define D_STR_OUTSIDE "Снаружи"
+#define D_STR_LOUD "Громко"
+#define D_STR_UPPER "Верхнее"
+#define D_STR_LOWER "Нижнее"
+#define D_STR_BREEZE "Бриз"
+#define D_STR_CIRCULATE "Циркуляция"
+#define D_STR_CEILING "Потолок"
+#define D_STR_WALL "Стена"
+#define D_STR_ROOM "Комната"
+#define D_STR_6THSENSE "6-ое чувство"
+#define D_STR_FIXED "Фиксированный"
+#define D_STR_TYPE "Тип"
+#define D_STR_SPECIAL "Специальный"
+#define D_STR_RECYCLE "Рециркуляция"
+#define D_STR_VANE "Жалюзи"
+#define D_STR_LOCK "Блокировка"
+#define D_STR_AUTO "Авто"
+#define D_STR_AUTOMATIC "Автоматический"
+#define D_STR_MANUAL "Ручной"
+#define D_STR_COOL "Охл"
+#define D_STR_COOLING "Охлаждение"
+#define D_STR_HEAT "Нагр"
+#define D_STR_HEATING "Обогрев"
+#define D_STR_FAN "Вентиляция"
+#define D_STR_ONLY "Только"
+#define D_STR_FANSPACEONLY D_STR_ONLY " " D_STR_FAN
+#define D_STR_FANONLYNOSPACE D_STR_ONLY D_STR_FAN
+#define D_STR_DRY "Сухо"
+#define D_STR_DRYING "Сушка"
+#define D_STR_DEHUMIDIFY "Осушение"
+#define D_STR_MAX "Макс"
+#define D_STR_MAXIMUM "Максимум"
+#define D_STR_MIN "Мин"
+#define D_STR_MINIMUM "Минимум"
+#define D_STR_MED "Сред"
+#define D_STR_MEDIUM "Среднее"
+#define D_STR_HIGHEST "Верхнее"
+#define D_STR_HIGH "Верх"
+#define D_STR_HI "Верх"
+#define D_STR_MID "Сред"
+#define D_STR_MIDDLE "Середина"
+#define D_STR_LOW "Низ"
+#define D_STR_LO "Низ"
+#define D_STR_LOWEST "Нижнее"
+#define D_STR_RIGHT "Право"
+#define D_STR_LEFT "Лево"
+#define D_STR_WIDE "Широкий"
+#define D_STR_CENTRE "Центр"
+#define D_STR_TOP "Наивысший"
+#define D_STR_BOTTOM "Наинизший"
+#define D_STR_DAY "День"
+#define D_STR_DAYS "Дней"
+#define D_STR_HOUR "Час"
+#define D_STR_HOURS "Часов"
+#define D_STR_MINUTE "Минута"
+#define D_STR_MINUTES "Минут"
+#define D_STR_SECOND "Секунда"
+#define D_STR_SECONDS "Секунд"
+#define D_STR_NOW "Сейчас"
+#define D_STR_THREELETTERDAYS "ВскПндВтрСреЧтвПтнСуб"
+#define D_STR_YES "Да"
+#define D_STR_NO "Нет"
+#define D_STR_TRUE "Истина"
+#define D_STR_FALSE "Ложь"
+#define D_STR_REPEAT "Повтор"
+#define D_STR_CODE "Код"
+#define D_STR_BITS "Бит"
+
+// IRrecvDumpV2+
+#define D_STR_TIMESTAMP "Метка Времени"
+#define D_STR_LIBRARY "Библиотека"
+#define D_STR_MESGDESC "Описание Сообщения."
+#define D_STR_TOLERANCE "Допуск"
+#define D_STR_IRRECVDUMP_STARTUP \
+ "IRrecvDump запущен и ождает ИК команды на Входе %d"
+#define D_WARN_BUFFERFULL \
+ "ПРЕДУПРЕЖДЕНИЕ: ИК код слишком велик для буфера (>= %d). " \
+ "Этому результату не следует доверять, пока это не будет исправлено. " \
+ "Исправьте и увеличьте `kCaptureBufferSize`."
+
+#endif // LOCALE_RU_RU_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/sv-SE.h b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/sv-SE.h
new file mode 100644
index 000000000..b82ec42bc
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/src/locale/sv-SE.h
@@ -0,0 +1,189 @@
+// Copyright 2021 - Tom Rosenback (@tomrosenback)
+// Locale/language file for swedish / Sweden.
+// This file will override the default values located in `defaults.h`.
+#ifndef LOCALE_SV_SE_H_
+#define LOCALE_SV_SE_H_
+
+#define D_STR_UNKNOWN "OKÄND"
+#define D_STR_PROTOCOL "Protokoll"
+#define D_STR_POWER "Strömläge"
+#define D_STR_PREVIOUS "Föregående"
+#define D_STR_ON "På"
+#define D_STR_OFF "Av"
+#define D_STR_MODE "Läge"
+#define D_STR_TOGGLE "Växla"
+#define D_STR_TURBO "Turbo"
+#define D_STR_SUPER "Super"
+#define D_STR_SLEEP "Sova"
+#define D_STR_LIGHT "Svag"
+#define D_STR_POWERFUL "Kraftig"
+#define D_STR_QUIET "Tyst"
+#define D_STR_ECONO "Eko"
+#define D_STR_SWING "Sving"
+#define D_STR_SWINGH D_STR_SWING"(H)"
+#define D_STR_SWINGV D_STR_SWING"(V)"
+#define D_STR_BEEP "Pip"
+#define D_STR_MOULD "Forma"
+#define D_STR_CLEAN "Rengör"
+#define D_STR_PURIFY "Rena"
+#define D_STR_TIMER "Timer"
+#define D_STR_ONTIMER "På timer"
+#define D_STR_OFFTIMER "Av timer"
+#define D_STR_TIMERMODE "Timerläge"
+#define D_STR_CLOCK "Klocka"
+#define D_STR_COMMAND "Kommando"
+#define D_STR_XFAN "XFan"
+#define D_STR_HEALTH "Hälsa"
+#define D_STR_MODEL "Modell"
+#define D_STR_TEMP "Temp"
+#define D_STR_IFEEL "Känns som"
+#define D_STR_HUMID "Humid"
+#define D_STR_SAVE "Save"
+#define D_STR_EYE "Öga"
+#define D_STR_FOLLOW "Följ"
+#define D_STR_ION "Ion"
+#define D_STR_FRESH "Frisk"
+#define D_STR_HOLD "Håll"
+#define D_STR_8C_HEAT "8C " D_STR_HEAT
+#define D_STR_10C_HEAT "10C " D_STR_HEAT
+#define D_STR_BUTTON "Knapp"
+#define D_STR_NIGHT "Natt"
+#define D_STR_SILENT "Tyst"
+#define D_STR_FILTER "Filter"
+#define D_STR_3D "3D"
+#define D_STR_CELSIUS "Celsius"
+#define D_STR_FAHRENHEIT "Fahrenheit"
+#define D_STR_CELSIUS_FAHRENHEIT D_STR_CELSIUS "/" D_STR_FAHRENHEIT
+#define D_STR_UP "Upp"
+#define D_STR_TEMPUP D_STR_TEMP " upp"
+#define D_STR_DOWN "Ner"
+#define D_STR_TEMPDOWN D_STR_TEMP " ner"
+#define D_STR_CHANGE "Ändra"
+#define D_STR_START "Starta"
+#define D_STR_STOP "Stoppa"
+#define D_STR_MOVE "Flytta"
+#define D_STR_SET "Ställ in"
+#define D_STR_CANCEL "Avbryt"
+#define D_STR_COMFORT "Komfort"
+#define D_STR_SENSOR "Sensor"
+#define D_STR_DISPLAY "Display"
+#define D_STR_WEEKLY "Veckovis"
+#define D_STR_WEEKLYTIMER D_STR_WEEKLY " timer"
+#define D_STR_WIFI "WiFi"
+#define D_STR_LAST "Senast"
+#define D_STR_FAST "Snabb"
+#define D_STR_SLOW "Sakta"
+#define D_STR_AIRFLOW "Luftflöde"
+#define D_STR_STEP "Steppa"
+#define D_STR_NA "N/A"
+#define D_STR_INSIDE "Inne"
+#define D_STR_OUTSIDE "Ute"
+#define D_STR_LOUD "Hög"
+#define D_STR_UPPER "Övre"
+#define D_STR_LOWER "Nedre"
+#define D_STR_BREEZE "Bris"
+#define D_STR_CIRCULATE "Cirkulera"
+#define D_STR_CEILING "Tak"
+#define D_STR_WALL "Vägg"
+#define D_STR_ROOM "Rum"
+#define D_STR_6THSENSE "6e sinne"
+#define D_STR_ZONEFOLLOW "Följ zon"
+#define D_STR_FIXED "Fast"
+#define D_STR_TYPE "Typ"
+#define D_STR_SPECIAL "Speciell"
+#define D_STR_RECYCLE "Återvinn"
+#define D_STR_ID "Id"
+#define D_STR_VANE "Vindflöjel"
+
+#define D_STR_AUTO "Auto"
+#define D_STR_AUTOMATIC "Automatisk"
+#define D_STR_MANUAL "Manuell"
+#define D_STR_COOL "Kyla"
+#define D_STR_HEAT "Värme"
+#define D_STR_FAN "Fläkt"
+#define D_STR_FANONLY "fläkt-enbart"
+#define D_STR_FAN_ONLY "fläkt_enbart"
+#define D_STR_ONLY "Enbart"
+#define D_STR_FANSPACEONLY D_STR_FAN " " D_STR_ONLY
+#define D_STR_FANONLYNOSPACE D_STR_FAN D_STR_ONLY
+#define D_STR_DRY "Torka"
+
+#define D_STR_MAX "Max"
+#define D_STR_MAXIMUM "Maximum"
+#define D_STR_MIN "Min"
+#define D_STR_MINIMUM "Minimum"
+#define D_STR_MED "Med"
+#define D_STR_MEDIUM "Medium"
+
+#define D_STR_HIGHEST "Högsta"
+#define D_STR_HIGH "Hög"
+#define D_STR_HI "Hög"
+#define D_STR_MID "Mellan"
+#define D_STR_MIDDLE "Mellan"
+#define D_STR_LOW "Låg"
+#define D_STR_LO "Låg"
+#define D_STR_LOWEST "Lägsta"
+#define D_STR_RIGHT "Höger"
+#define D_STR_MAXRIGHT D_STR_MAX " höger"
+#define D_STR_RIGHTMAX_NOSPACE D_STR_MAX D_STR_RIGHT
+#define D_STR_LEFT "Vänster"
+#define D_STR_MAXLEFT D_STR_MAX " vänster"
+#define D_STR_LEFTMAX_NOSPACE D_STR_MAX D_STR_LEFT
+#define D_STR_WIDE "Vid"
+#define D_STR_CENTRE "Mitten"
+#define D_STR_TOP "Topp"
+#define D_STR_BOTTOM "Botten"
+
+#define D_STR_ECONOTOGGLE D_STR_TOGGLE " eko"
+#define D_STR_EYEAUTO D_STR_AUTO " öga"
+#define D_STR_LIGHTTOGGLE D_STR_TOGGLE " svag"
+#define D_STR_OUTSIDEQUIET D_STR_QUIET " ute"
+#define D_STR_POWERTOGGLE D_STR_TOGGLE " strömläge"
+#define D_STR_POWERBUTTON "Strömknapp"
+#define D_STR_PREVIOUSPOWER "Föregående strömläge"
+#define D_STR_DISPLAYTEMP "Displaytemp"
+#define D_STR_SENSORTEMP "Sensortemp"
+#define D_STR_SLEEP_TIMER "Sovtimer"
+#define D_STR_SWINGVMODE D_STR_SWINGV " läge"
+#define D_STR_SWINGVTOGGLE D_STR_TOGGLE " sving(v)"
+#define D_STR_TURBOTOGGLE D_STR_TOGGLE " turbo"
+
+// Separatorer
+#define D_CHR_TIME_SEP ':'
+#define D_STR_SPACELBRACE " ("
+#define D_STR_COMMASPACE ", "
+#define D_STR_COLONSPACE ": "
+
+#define D_STR_DAY "Dag"
+#define D_STR_DAYS D_STR_DAY "ar"
+#define D_STR_HOUR "Timme"
+#define D_STR_HOURS "Timmar"
+#define D_STR_MINUTE "Minut"
+#define D_STR_MINUTES D_STR_MINUTE "er"
+#define D_STR_SECOND "Sekund"
+#define D_STR_SECONDS D_STR_MINUTE "er"
+#define D_STR_NOW "Nu"
+#define D_STR_THREELETTERDAYS "SönMånTisOnsTorFreLör"
+
+#define D_STR_YES "Ja"
+#define D_STR_NO "Nej"
+#define D_STR_TRUE "Sant"
+#define D_STR_FALSE "Falskt"
+
+#define D_STR_REPEAT "Upprepa"
+#define D_STR_CODE "Kod"
+#define D_STR_BITS "Bitar"
+
+// IRrecvDumpV2+
+#define D_STR_TIMESTAMP "Tidskod"
+#define D_STR_LIBRARY "Bibliotek"
+#define D_STR_MESGDESC "Meddelande beskr."
+#define D_STR_TOLERANCE "Tolerans"
+#define D_STR_IRRECVDUMP_STARTUP \
+ "IRrecvDump har nu startats och väntar på IR signaler på PIN %d"
+#define D_WARN_BUFFERFULL \
+ "VARNING: IR koden är för stor för att rymmas i bufferminnet (>= %d). " \
+ "Detta resultat är inte pålitligt innan problemet är åtgärdat. " \
+ "Redigera och öka `kCaptureBufferSize`."
+
+#endif // LOCALE_SV_SE_H_
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp
index 140e50137..d43cfcd9d 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/IRac_test.cpp
@@ -19,6 +19,7 @@
#include "ir_Kelvinator.h"
#include "ir_LG.h"
#include "ir_Midea.h"
+#include "ir_Mirage.h"
#include "ir_Mitsubishi.h"
#include "ir_MitsubishiHeavy.h"
#include "ir_Neoclima.h"
@@ -560,7 +561,8 @@ TEST(TestIRac, Electra) {
IRrecv capture(kGpioUnused);
char expected[] =
"Power: On, Mode: 6 (Fan), Temp: 26C, Fan: 1 (High), "
- "Swing(V): On, Swing(H): On, Light: Toggle, Clean: On, Turbo: On";
+ "Swing(V): On, Swing(H): On, Light: Toggle, Clean: On, Turbo: On, "
+ "IFeel: Off";
ac.begin();
irac.electra(&ac,
@@ -727,9 +729,10 @@ TEST(TestIRac, Gree) {
IRrecv capture(kGpioUnused);
char expected[] =
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 71F, "
- "Fan: 2 (Medium), Turbo: Off, IFeel: Off, WiFi: Off, XFan: On, "
- "Light: On, Sleep: On, Swing(V) Mode: Manual, "
- "Swing(V): 3 (UNKNOWN), Timer: Off, Display Temp: 0 (Off)";
+ "Fan: 2 (Medium), Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, "
+ "XFan: On, Light: On, Sleep: On, Swing(V) Mode: Manual, "
+ "Swing(V): 3 (UNKNOWN), Swing(H): 5 (Right), Timer: Off, "
+ "Display Temp: 0 (Off)";
ac.begin();
irac.gree(&ac,
@@ -740,7 +743,9 @@ TEST(TestIRac, Gree) {
71, // Degrees (F)
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kHigh, // Vertical swing
+ stdAc::swingh_t::kRight, // Horizontal swing
false, // Turbo
+ false, // Econo
true, // Light
true, // Clean (aka Mold/XFan)
8 * 60 + 0); // Sleep time
@@ -760,7 +765,7 @@ TEST(TestIRac, Haier) {
IRrecv capture(kGpioUnused);
char expected[] =
"Command: 1 (On), Mode: 1 (Cool), Temp: 24C, Fan: 2 (Medium), "
- "Swing: 1 (Up), Sleep: On, Health: On, Clock: 13:45, "
+ "Swing(V): 1 (Up), Sleep: On, Health: On, Clock: 13:45, "
"On Timer: Off, Off Timer: Off";
ac.begin();
@@ -788,19 +793,24 @@ TEST(TestIRac, Haier176) {
IRac irac(kGpioUnused);
IRrecv capture(kGpioUnused);
const char expected[] =
- "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 23C, "
- "Fan: 2 (Medium), Turbo: 1 (High), Swing: 1 (Highest), Sleep: On, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off";
+ "Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
+ "Mode: 1 (Cool), Temp: 23C, Fan: 2 (Medium), Turbo: On, Quiet: Off, "
+ "Swing(V): 1 (Highest), Swing(H): 0 (Middle), Sleep: On, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off";
ac.begin();
irac.haier176(&ac,
- true, // Power
- stdAc::opmode_t::kCool, // Mode
- 23, // Celsius
- stdAc::fanspeed_t::kMedium, // Fan speed
- stdAc::swingv_t::kHigh, // Vertical swing
- true, // Turbo
- true, // Filter
- 8 * 60 + 0); // Sleep time
+ haier_ac176_remote_model_t::V9014557_A, // Model
+ true, // Power
+ stdAc::opmode_t::kCool, // Mode
+ true, // Celsius
+ 23, // Degrees
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kHigh, // Vertical swing
+ stdAc::swingh_t::kOff, // Horizontal swing
+ true, // Turbo
+ false, // Quiet
+ true, // Filter
+ 8 * 60 + 0); // Sleep time
ASSERT_EQ(expected, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
@@ -816,20 +826,24 @@ TEST(TestIRac, HaierYrwo2) {
IRac irac(kGpioUnused);
IRrecv capture(kGpioUnused);
char expected[] =
- "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 23C, "
- "Fan: 2 (Medium), Turbo: 1 (High), Swing: 1 (Highest), Sleep: On, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off";
+ "Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
+ "Mode: 1 (Cool), Temp: 23C, Fan: 2 (Medium), Turbo: Off, Quiet: On, "
+ "Swing(V): 1 (Highest), Swing(H): 7 (Auto), Sleep: On, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off";
ac.begin();
irac.haierYrwo2(&ac,
- true, // Power
- stdAc::opmode_t::kCool, // Mode
- 23, // Celsius
- stdAc::fanspeed_t::kMedium, // Fan speed
- stdAc::swingv_t::kHigh, // Vertical swing
- true, // Turbo
- true, // Filter
- 8 * 60 + 0); // Sleep time
+ true, // Power
+ stdAc::opmode_t::kCool, // Mode
+ true, // Celsius
+ 23, // Degrees
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kHigh, // Vertical swing
+ stdAc::swingh_t::kAuto, // Vertical swing
+ false, // Turbo
+ true, // Quiet
+ true, // Filter
+ 8 * 60 + 0); // Sleep time
ASSERT_EQ(expected, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
@@ -1125,7 +1139,22 @@ TEST(TestIRac, Issue1513) {
stdAc::swingh_t::kOff, // Horizontal swing
true); // Light
ac._irsend.makeDecodeResult();
- // All sent, we assume the above works. Just need to switch to swing off now.
+ EXPECT_EQ(121, ac._irsend.capture.rawlen);
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
+ ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
+ ASSERT_EQ(
+ "Model: 2 (AKB75215403), Power: On, Mode: 4 (Heat), Temp: 26C, "
+ "Fan: 0 (Quiet)",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+
+ // The next should be a SwingV On.
+ EXPECT_TRUE(capture.decodeLG(&ac._irsend.capture, 61));
+ ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
+ ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
+ EXPECT_EQ(kLgAcSwingVSwing, ac._irsend.capture.value);
+ ASSERT_EQ("Model: 3 (AKB74955603), Swing(V): 20 (Swing)",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
ac._irsend.reset();
ac.stateReset();
ac.send();
@@ -1163,6 +1192,79 @@ TEST(TestIRac, Issue1513) {
IRAcUtils::resultAcToString(&ac._irsend.capture));
}
+// Ref:
+// https://github.com/crankyoldgit/IRremoteESP8266/issues/1651#issuecomment-952811720
+TEST(TestIRac, Issue1651) {
+ // Simulate sending a state with a SwingV off, then followed by a SwingV Auto.
+ IRLgAc ac(kGpioUnused);
+ IRac irac(kGpioUnused);
+ IRrecv capture(kGpioUnused);
+ ac.begin();
+ // IRhvac {"Vendor":"LG2","Model":3,"Mode":"Auto","Power":"On","Celsius":"On",
+ // "Temp":15,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off",
+ // "Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"On",
+ // "Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
+ ac._irsend.reset();
+ irac.lg(&ac,
+ lg_ac_remote_model_t::AKB74955603, // Model
+ true, // Power
+ stdAc::opmode_t::kAuto, // Mode
+ 15, // Degrees C (Note: 16C is min)
+ stdAc::fanspeed_t::kAuto, // Fan speed
+ stdAc::swingv_t::kOff, // Vertical swing
+ stdAc::swingv_t::kOff, // Vertical swing (previous)
+ stdAc::swingh_t::kOff, // Horizontal swing
+ true); // Light
+ ac._irsend.makeDecodeResult();
+ // As we are not making a change of the SwingV state, there should only be
+ // one message. (i.e. 60 + 1)
+ EXPECT_EQ(61, ac._irsend.capture.rawlen);
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
+ ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
+ ASSERT_EQ(
+ "Model: 2 (AKB75215403), Power: On, Mode: 3 (Auto), Temp: 16C, "
+ "Fan: 5 (Auto)",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ac._irsend.reset();
+ ac.stateReset();
+ ac.send();
+ // IRhvac {"Vendor":"LG2","Model":3,"Mode":"Auto","Power":"On","Celsius":"On",
+ // "Temp":15,"FanSpeed":"Max","SwingV":"Auto","SwingH":"Off",
+ // "Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"On",
+ // "Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
+ ac._irsend.makeDecodeResult();
+ ac._irsend.reset();
+ irac.lg(&ac,
+ lg_ac_remote_model_t::AKB74955603, // Model
+ true, // Power
+ stdAc::opmode_t::kAuto, // Mode
+ 15, // Degrees C (Note: 16C is min)
+ stdAc::fanspeed_t::kMax, // Fan speed
+ stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingv_t::kOff, // Vertical swing (previous)
+ stdAc::swingh_t::kOff, // Horizontal swing
+ true); // Light
+ ac._irsend.makeDecodeResult();
+ // There should only be two messages.
+ EXPECT_EQ(121, ac._irsend.capture.rawlen);
+ // First message should be normal.
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
+ ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
+ ASSERT_EQ(
+ "Model: 2 (AKB75215403), Power: On, Mode: 3 (Auto), Temp: 16C, "
+ "Fan: 4 (Maximum)",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+ // The next should be a SwingV Off.
+ EXPECT_TRUE(capture.decodeLG(&ac._irsend.capture, 61));
+ ASSERT_EQ(LG2, ac._irsend.capture.decode_type); // Not "LG"
+ ASSERT_EQ(kLgBits, ac._irsend.capture.bits);
+ EXPECT_EQ(kLgAcSwingVSwing, ac._irsend.capture.value);
+ ASSERT_EQ("Model: 3 (AKB74955603), Swing(V): 20 (Swing)",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+}
+
TEST(TestIRac, LG2_AKB73757604) {
IRLgAc ac(kGpioUnused);
IRac irac(kGpioUnused);
@@ -1252,6 +1354,62 @@ TEST(TestIRac, Midea) {
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
+TEST(TestIRac, Mirage) {
+ IRMirageAc ac(kGpioUnused);
+ IRac irac(kGpioUnused);
+ IRrecv capture(kGpioUnused);
+ stdAc::state_t state, r, p;
+ const char expected_KKG9AC1[] =
+ "Model: 1 (KKG9AC1), Power: On, Mode: 3 (Dry), Temp: 27C, "
+ "Fan: 2 (Medium), Turbo: Off, Sleep: On, Light: Off, "
+ "Swing(V): 9 (High), Clock: 17:31";
+
+ ac.begin();
+
+ state.model = mirage_ac_remote_model_t::KKG9AC1;
+ state.power = true;
+ state.mode = stdAc::opmode_t::kDry;
+ state.celsius = true;
+ state.degrees = 27;
+ state.fanspeed = stdAc::fanspeed_t::kMedium;
+ state.swingv = stdAc::swingv_t::kHigh;
+ state.swingh = stdAc::swingh_t::kLeft;
+ state.turbo = false;
+ state.quiet = true;
+ state.light = false;
+ state.filter = true;
+ state.clean = false;
+ state.sleep = 8 * 60 + 0;
+ state.clock = 17 * 60 + 31;
+ state.beep = false;
+ irac.mirage(&ac, state);
+
+ ASSERT_EQ(expected_KKG9AC1, ac.toString());
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(MIRAGE, ac._irsend.capture.decode_type);
+ ASSERT_EQ(kMirageBits, ac._irsend.capture.bits);
+ ASSERT_EQ(expected_KKG9AC1, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
+
+ const char expected_KKG29AC1[] =
+ "Model: 2 (KKG29AC1), Power: On, Mode: 3 (Dry), Temp: 27C, "
+ "Fan: 3 (Medium), Turbo: Off, Sleep: On, Quiet: On, Light: -, "
+ "Swing(V): On, Swing(H): On, Filter: On, Clean: -, "
+ "On Timer: Off, Off Timer: Off, IFeel: Off";
+ ac._irsend.reset();
+ state.model = mirage_ac_remote_model_t::KKG29AC1;
+ irac.mirage(&ac, state);
+ ASSERT_EQ(expected_KKG29AC1, ac.toString());
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(MIRAGE, ac._irsend.capture.decode_type);
+ ASSERT_EQ(kMirageBits, ac._irsend.capture.bits);
+ ASSERT_EQ(expected_KKG29AC1,
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
+}
+
TEST(TestIRac, Mitsubishi) {
IRMitsubishiAC ac(kGpioUnused);
IRac irac(kGpioUnused);
@@ -1493,9 +1651,10 @@ TEST(TestIRac, Samsung) {
IRSamsungAc ac(kGpioUnused);
IRac irac(kGpioUnused);
IRrecv capture(kGpioUnused);
- char expected[] =
- "Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), Swing: On, "
- "Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, "
+ const char expected[] =
+ "Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), "
+ "Swing(V): On, Swing(H): On, Beep: Toggle, "
+ "Clean: Toggle, Quiet: On, Powerful: Off, ""Econo: Off, Breeze: Off, "
"Light: On, Ion: Off";
ac.begin();
@@ -1505,14 +1664,18 @@ TEST(TestIRac, Samsung) {
28, // Celsius
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingh_t::kAuto, // Horizontal swing
true, // Quiet
false, // Turbo
+ false, // Econo
true, // Light (Display)
false, // Filter (Ion)
- true, // Clean
+ true, // Clean (Toggle)
true, // Beep
+ -1, // Sleep
true, // Previous power state
- false); // with dopower Off
+ -1, // Previous Sleep
+ false); // Force Extended
ASSERT_EQ(expected, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
@@ -1529,22 +1692,59 @@ TEST(TestIRac, Samsung) {
28, // Celsius
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingh_t::kAuto, // Horizontal swing
true, // Quiet
false, // Turbo
+ false, // Econo
true, // Light (Display)
false, // Filter (Ion)
- true, // Clean
+ true, // Clean (Toggle)
true, // Beep
+ -1, // Sleep
true, // Previous power state
- true); // with dopower On
+ -1, // Previous Sleep
+ true); // Force Extended
ASSERT_EQ(expected, ac.toString()); // Class should be in the desired mode.
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
- // We expect an extended state because of `dopower`.
+ // We expect an extended state because of `Force Extended`.
ASSERT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
ASSERT_EQ(expected, IRAcUtils::resultAcToString(&ac._irsend.capture));
ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
+
+ ac._irsend.reset();
+ const char sleep[] =
+ "Power: On, Mode: 0 (Auto), Temp: 28C, Fan: 6 (Auto), "
+ "Swing(V): On, Swing(H): Off, Beep: -, Clean: Toggle, "
+ "Quiet: On, Powerful: Off, Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, Sleep Timer: 08:00";
+ irac.samsung(&ac,
+ true, // Power
+ stdAc::opmode_t::kAuto, // Mode
+ 28, // Celsius
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingh_t::kOff, // Horizontal swing
+ true, // Quiet
+ false, // Turbo
+ false, // Econo
+ true, // Light (Display)
+ false, // Filter (Ion)
+ true, // Clean (Toggle)
+ false, // Beep
+ 8 * 60, // Sleep
+ true, // Previous power state
+ -1, // Previous Sleep
+ false); // Force Extended
+ ASSERT_EQ(sleep, ac.toString());
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(capture.decode(&ac._irsend.capture));
+ ASSERT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ // We expect an extended state because of the change in `sleep`.
+ ASSERT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
+ ASSERT_EQ(sleep, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ASSERT_TRUE(IRAcUtils::decodeToState(&ac._irsend.capture, &r, &p));
}
TEST(TestIRac, Sanyo) {
@@ -1610,7 +1810,7 @@ TEST(TestIRac, Sharp) {
IRrecv capture(kGpioUnused);
char expected[] =
"Model: 1 (A907), Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), "
- "Turbo: Off, Swing(V) Toggle: On, Ion: On, Econo: -, Clean: Off";
+ "Swing(V): 7 (Swing), Turbo: Off, Ion: On, Econo: -, Clean: Off";
ac.begin();
irac.sharp(&ac,
@@ -1621,6 +1821,7 @@ TEST(TestIRac, Sharp) {
28, // Celsius
stdAc::fanspeed_t::kMedium, // Fan speed
stdAc::swingv_t::kAuto, // Vertical swing
+ stdAc::swingv_t::kOff, // Previous Vertical swing
false, // Turbo
false, // Light
true, // Filter (Ion)
@@ -1640,23 +1841,25 @@ TEST(TestIRac, Tcl112) {
IRac irac(kGpioUnused);
IRrecv capture(kGpioUnused);
char expected[] =
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 20C, Fan: 3 (Medium), "
- "Econo: On, Health: On, Turbo: Off, Swing(H): On, Swing(V): Off, "
- "Light: On";
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 20C, "
+ "Fan: 3 (Medium), Swing(V): 0 (Auto), Swing(H): On, "
+ "Econo: On, Health: On, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off";
ac.begin();
irac.tcl112(&ac,
- true, // Power
- stdAc::opmode_t::kCool, // Mode
- 20, // Celsius
- stdAc::fanspeed_t::kMedium, // Fan speed
- stdAc::swingv_t::kOff, // Vertical swing
- stdAc::swingh_t::kAuto, // Horizontal swing
- false, // Quiet (aka. Mute)
- false, // Turbo
- true, // Light
- true, // Econo
- true); // Filter (aka. Health)
+ tcl_ac_remote_model_t::TAC09CHSD, // Model
+ true, // Power
+ stdAc::opmode_t::kCool, // Mode
+ 20, // Celsius
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kOff, // Vertical swing
+ stdAc::swingh_t::kAuto, // Horizontal swing
+ false, // Quiet (aka. Mute)
+ false, // Turbo
+ true, // Light
+ true, // Econo
+ true); // Filter (aka. Health)
ASSERT_EQ(expected, ac.toString());
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
@@ -1668,23 +1871,24 @@ TEST(TestIRac, Tcl112) {
// Test the quiet mode, which should generate two messages.
ac._irsend.reset();
irac.tcl112(&ac,
- true, // Power
- stdAc::opmode_t::kCool, // Mode
- 20, // Celsius
- stdAc::fanspeed_t::kMedium, // Fan speed
- stdAc::swingv_t::kOff, // Vertical swing
- stdAc::swingh_t::kAuto, // Horizontal swing
- true, // Quiet (aka. Mute)
- false, // Turbo
- true, // Light
- true, // Econo
- true); // Filter (aka. Health)
+ tcl_ac_remote_model_t::TAC09CHSD, // Model
+ true, // Power
+ stdAc::opmode_t::kCool, // Mode
+ 20, // Celsius
+ stdAc::fanspeed_t::kMedium, // Fan speed
+ stdAc::swingv_t::kOff, // Vertical swing
+ stdAc::swingh_t::kAuto, // Horizontal swing
+ true, // Quiet (aka. Mute)
+ false, // Turbo
+ true, // Light
+ true, // Econo
+ true); // Filter (aka. Health)
ac._irsend.makeDecodeResult();
EXPECT_TRUE(capture.decode(&ac._irsend.capture));
ASSERT_EQ(TCL112AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kTcl112AcBits, ac._irsend.capture.bits);
ASSERT_EQ(
- "Type: 2, Quiet: On",
+ "Model: 1 (TAC09CHSD), Type: 2, Quiet: On",
IRAcUtils::resultAcToString(&ac._irsend.capture));
// TCL112 uses the Mitsubishi112 decoder.
// Skip first message.
@@ -2335,6 +2539,10 @@ TEST(TestIRac, opmodeToString) {
EXPECT_EQ("Auto", IRac::opmodeToString(stdAc::opmode_t::kAuto));
EXPECT_EQ("Cool", IRac::opmodeToString(stdAc::opmode_t::kCool));
EXPECT_EQ("UNKNOWN", IRac::opmodeToString((stdAc::opmode_t)500));
+ // Home Assistant/Google Home differences.
+ EXPECT_EQ("Fan", IRac::opmodeToString(stdAc::opmode_t::kFan, false));
+ EXPECT_EQ("fan_only", IRac::opmodeToString(stdAc::opmode_t::kFan, true));
+ EXPECT_EQ("Fan", IRac::opmodeToString(stdAc::opmode_t::kFan)); // Default
}
TEST(TestIRac, fanspeedToString) {
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/Makefile b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/Makefile
index 132350803..7a193e813 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/Makefile
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/Makefile
@@ -3,6 +3,9 @@
# make [all] - makes everything.
# make TARGET - makes the given target.
# make run - makes everything and runs all the tests.
+# make run_tests - run all tests
+# make run-% - run specific test file (exclude _test.cpp)
+# replace % with given test file, eg run-IRsend
# make clean - removes all files generated by make.
# make install-googletest - install the googletest code suite
@@ -45,6 +48,7 @@ clean :
run : all
failed=""; \
for unittest in $(TESTS); do \
+ echo "RUNNING: $${unittest}"; \
./$${unittest} || failed="$${failed} $${unittest}"; \
done; \
if [ -n "$${failed}" ]; then \
@@ -55,6 +59,10 @@ run : all
run_tests : run
+run-% : %_test
+ echo "RUNNING: $*"; \
+ ./$*_test
+
install-googletest :
rm -rf ../lib/googletest
git clone -b v1.8.x https://github.com/google/googletest.git ../lib/googletest
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Airton_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Airton_test.cpp
new file mode 100644
index 000000000..e4e66ee13
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Airton_test.cpp
@@ -0,0 +1,62 @@
+// Copyright 2021 crankyoldgit
+
+#include "IRac.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// Tests for decodeAirton().
+
+TEST(TestDecodeAirton, RealExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ const uint16_t rawData[115] = {
+ 6632, 3352,
+ 404, 1266, 404, 1264, 406, 430, 406, 430, 400, 1264, 406, 430, 402, 1264,
+ 408, 1262, 406, 1264, 404, 430, 402, 434, 402, 432, 402, 1264, 406, 430,
+ 404, 432, 400, 456, 376, 432, 402, 430, 402, 1264, 404, 1264, 404, 432,
+ 402, 434, 398, 434, 402, 430, 404, 1264, 404, 432, 402, 430, 404, 1264,
+ 406, 430, 402, 432, 400, 434, 402, 430, 402, 430, 404, 432, 402, 430,
+ 402, 432, 402, 432, 402, 430, 402, 432, 402, 430, 402, 434, 400, 432,
+ 402, 1264, 404, 430, 404, 1264, 404, 432, 402, 454, 378, 432, 402, 430,
+ 404, 1264, 404, 1264, 404, 1264, 378, 1292, 404, 432, 402, 1264, 404, 432,
+ 402};
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData, 115, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRTON, irsend.capture.decode_type);
+ ASSERT_EQ(kAirtonBits, irsend.capture.bits);
+ EXPECT_EQ(0x5E1400090C11D3, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+}
+
+TEST(TestDecodeAirton, SyntheticExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+ irsend.reset();
+ irsend.sendAirton(0x5E1400090C11D3);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::AIRTON, irsend.capture.decode_type);
+ ASSERT_EQ(kAirtonBits, irsend.capture.bits);
+ EXPECT_EQ(0x5E1400090C11D3, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x0, irsend.capture.command);
+}
+
+TEST(TestUtils, Housekeeping) {
+ ASSERT_EQ("AIRTON", typeToString(decode_type_t::AIRTON));
+ ASSERT_EQ(decode_type_t::AIRTON, strToDecodeType("AIRTON"));
+ ASSERT_FALSE(hasACState(decode_type_t::AIRTON));
+ ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::AIRTON));
+ ASSERT_EQ(kAirtonBits, IRsend::defaultBits(decode_type_t::AIRTON));
+ ASSERT_EQ(kAirtonDefaultRepeat, IRsend::minRepeats(decode_type_t::AIRTON));
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Arris_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Arris_test.cpp
new file mode 100644
index 000000000..2a219b6b2
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Arris_test.cpp
@@ -0,0 +1,189 @@
+// Copyright 2021 David Conran
+
+#include "IRac.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "gtest/gtest.h"
+
+// Tests for decodeArris().
+
+// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1595
+// Data from:
+// https://github.com/crankyoldgit/IRremoteESP8266/files/7100289/raw_data.txt
+TEST(TestDecodeArris, RealExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+
+ const uint16_t rawData_1[59] = {
+ 2584, 1896, 666, 306, 338, 300, 336, 304, 668, 610, 332, 306, 338, 300,
+ 334, 304, 332, 312, 332, 306, 340, 300, 334, 304, 330, 308, 338, 302, 334,
+ 304, 330, 308, 336, 308, 336, 302, 332, 306, 330, 310, 674, 606, 336, 302,
+ 332, 306, 338, 306, 668, 612, 668, 306, 338, 304, 332, 308, 336, 608,
+ 334}; // UNKNOWN EDF1C0D0
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRaw(rawData_1, 59, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::ARRIS, irsend.capture.decode_type);
+ EXPECT_EQ(kArrisBits, irsend.capture.bits);
+ EXPECT_EQ(0x1000085E, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x85, irsend.capture.command);
+
+ irsend.reset();
+ const uint16_t rawData_2[115] = {
+ 2584, 1898, 664, 308, 338, 302, 332, 306, 668, 614, 330, 308, 336, 302,
+ 332, 306, 340, 304, 330, 310, 336, 304, 332, 306, 338, 300, 334, 304, 330,
+ 308, 336, 302, 332, 312, 334, 306, 330, 308, 336, 302, 670, 610, 332, 306,
+ 330, 310, 336, 308, 674, 606, 664, 312, 334, 306, 338, 302, 334, 612, 330,
+ 5930,
+ 2584, 1898, 664, 308, 336, 302, 332, 306, 666, 614, 338, 300, 336, 304,
+ 332, 310, 674, 610, 332, 334, 312, 328, 308, 332, 304, 336, 310, 330, 306,
+ 332, 302, 314, 330, 336, 308, 330, 306, 334, 640, 612, 330, 308, 336, 302,
+ 332, 312, 672, 608, 672, 608, 672, 304, 330, 614, 330
+ }; // UNKNOWN E6A77D83
+ irsend.sendRaw(rawData_2, 115, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::ARRIS, irsend.capture.decode_type);
+ EXPECT_EQ(kArrisBits, irsend.capture.bits);
+ EXPECT_EQ(0x1000085E, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x85, irsend.capture.command);
+
+ const uint16_t rawData_3[51] = {
+ 2584, 1896, 666, 308, 338, 328, 306, 332, 640, 612, 332, 336, 310, 300,
+ 334, 304, 678, 606, 336, 330, 306, 334, 310, 300, 334, 304, 332, 308, 338,
+ 302, 334, 310, 672, 304, 332, 614, 668, 612, 330, 336, 638, 620, 670, 610,
+ 670, 304, 330, 310, 336, 610, 672}; // UNKNOWN 4CA048A1
+ irsend.reset();
+ irsend.sendRaw(rawData_3, 51, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(decode_type_t::ARRIS, irsend.capture.decode_type);
+ EXPECT_EQ(kArrisBits, irsend.capture.bits);
+ EXPECT_EQ(0x1080695D, irsend.capture.value);
+ EXPECT_EQ(0x1, irsend.capture.address);
+ EXPECT_EQ(0x695, irsend.capture.command);
+}
+
+TEST(TestDecodeArris, SyntheticExample) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+ irsend.reset();
+ irsend.sendArris(0x1000085E);
+ irsend.makeDecodeResult();
+
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::ARRIS, irsend.capture.decode_type);
+ EXPECT_EQ(kArrisBits, irsend.capture.bits);
+ EXPECT_EQ(0x1000085E, irsend.capture.value);
+ EXPECT_EQ(0x0, irsend.capture.address);
+ EXPECT_EQ(0x85, irsend.capture.command);
+
+ EXPECT_EQ(
+ "f38000d50"
+// const uint16_t rawData_1[59] = {
+// 2584, 1896,
+ "m2560s1920"
+// 666, 306,
+ "m640s320"
+// 338, 300,
+ "m320s320"
+// 336, 304,
+ "m320s320"
+// 668, 610,
+ "m640s640"
+// 332, 306,
+ "m320s320"
+// 338, 300,
+ "m320s320"
+// 334, 304,
+ "m320s320"
+// 332, 312,
+ "m320s320"
+// 332, 306,
+ "m320s320"
+// 340, 300,
+ "m320s320"
+// 334, 304,
+ "m320s320"
+// 330, 308,
+ "m320s320"
+// 338, 302,
+ "m320s320"
+// 334, 304,
+ "m320s320"
+// 330, 308,
+ "m320s320"
+// 336, 308,
+ "m320s320"
+// 336, 302,
+ "m320s320"
+// 332, 306,
+ "m320s320"
+// 330, 310,
+ "m320s320"
+// 674, 606,
+ "m640s640"
+// 336, 302,
+ "m320s320"
+// 332, 306,
+ "m320s320"
+// 338, 306,
+ "m320s320"
+// 668, 612,
+ "m640s640"
+// 668, 306,
+ "m640s320"
+// 338, 304,
+ "m320s320"
+// 332, 308,
+ "m320s320"
+// 336, 608,
+ "m320s640"
+// 334}; // UNKNOWN EDF1C0D0
+ "m320s77184", irsend.outputStr());
+
+ irsend.reset();
+ irsend.sendArris(0x1080695D);
+ irsend.makeDecodeResult();
+
+ EXPECT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(decode_type_t::ARRIS, irsend.capture.decode_type);
+ EXPECT_EQ(kArrisBits, irsend.capture.bits);
+ EXPECT_EQ(0x1080695D, irsend.capture.value);
+ EXPECT_EQ(0x1, irsend.capture.address);
+ EXPECT_EQ(0x695, irsend.capture.command);
+}
+
+TEST(TestUtils, Housekeeping) {
+ ASSERT_EQ("ARRIS", typeToString(decode_type_t::ARRIS));
+ ASSERT_EQ(decode_type_t::ARRIS, strToDecodeType("ARRIS"));
+ ASSERT_FALSE(hasACState(decode_type_t::ARRIS));
+ ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::ARRIS));
+ ASSERT_EQ(kArrisBits, IRsend::defaultBits(decode_type_t::ARRIS));
+ ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::ARRIS));
+}
+
+TEST(TestSendArris, ReleaseToggle) {
+ EXPECT_EQ(0x10800F5D, IRsend::toggleArrisRelease(0x10000F55));
+ EXPECT_EQ(0x10000F55, IRsend::toggleArrisRelease(0x10800F5D));
+ EXPECT_EQ(
+ 0x10800F5D,
+ IRsend::toggleArrisRelease(IRsend::toggleArrisRelease(0x10800F5D)));
+}
+
+TEST(TestSendArris, encodeArris) {
+ EXPECT_EQ(0x10800F5D, IRsend::encodeArris(0xF5, true));
+ EXPECT_EQ(0x10000F55, IRsend::encodeArris(0xF5, false));
+ EXPECT_EQ(0x1080695D, IRsend::encodeArris(0x695, true));
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Electra_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Electra_test.cpp
index 1fddf537b..9c1dedd09 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Electra_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Electra_test.cpp
@@ -101,7 +101,8 @@ TEST(TestDecodeElectraAC, RealExampleDecode) {
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
@@ -235,7 +236,8 @@ TEST(TestIRElectraAcClass, HumanReadable) {
ac.setRaw(on_cool_32C_auto_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 32C, Fan: 5 (Auto), "
- "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
uint8_t on_cool_16C_auto_voff[13] = {
0xC3, 0x47, 0xE0, 0x00, 0xA0, 0x00, 0x20,
@@ -243,7 +245,8 @@ TEST(TestIRElectraAcClass, HumanReadable) {
ac.setRaw(on_cool_16C_auto_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 5 (Auto), "
- "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
uint8_t on_cool_16C_low_voff[13] = {
0xC3, 0x47, 0xE0, 0x00, 0x60, 0x00, 0x20,
@@ -251,7 +254,8 @@ TEST(TestIRElectraAcClass, HumanReadable) {
ac.setRaw(on_cool_16C_low_voff);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
}
@@ -275,7 +279,8 @@ TEST(TestIRElectraAcClass, Clean) {
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
}
@@ -301,7 +306,8 @@ TEST(TestIRElectraAcClass, Turbo) {
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: On",
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: On, "
+ "IFeel: Off",
ac.toString());
}
@@ -325,7 +331,8 @@ TEST(TestIRElectraAcClass, LightToggle) {
ac.setRaw(on);
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
}
@@ -352,8 +359,76 @@ TEST(TestIRElectraAcClass, ConstructKnownState) {
EXPECT_EQ(
"Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 3 (Low), "
- "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off",
+ "Swing(V): Off, Swing(H): Off, Light: Toggle, Clean: On, Turbo: Off, "
+ "IFeel: Off",
ac.toString());
EXPECT_STATE_EQ(on_cool_24C_fan1_swing_off_turbo_off_clean_on,
ac.getRaw(), kElectraAcBits);
}
+
+TEST(TestIRElectraAcClass, IFeelAndSensor) {
+ IRElectraAc ac(kGpioUnused);
+ ac.stateReset();
+ // Test a real example.
+ const uint8_t ifeel_on[kElectraAcStateLength] = {
+ 0xC3, 0x6F, 0xE0, 0x00, 0xA0, 0x00, 0x28,
+ 0x64, 0x00, 0x20, 0x00, 0x1E, 0x7C};
+ ac.setRaw(ifeel_on);
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(26, ac.getSensorTemp());
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (Cool), Temp: 21C, Fan: 5 (Auto), "
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: On, Sensor Temp: 26C",
+ ac.toString());
+
+ ac.stateReset();
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp());
+
+ ac.setIFeel(true);
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp());
+
+ ac.setSensorTemp(kElectraAcSensorMaxTemp);
+ EXPECT_EQ(kElectraAcSensorMaxTemp, ac.getSensorTemp());
+
+ ac.setSensorTemp(kElectraAcSensorMaxTemp + 1);
+ EXPECT_EQ(kElectraAcSensorMaxTemp, ac.getSensorTemp());
+
+ ac.setIFeel(false);
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp());
+ EXPECT_EQ(0, ac._.SensorTemp);
+
+ ac.setIFeel(true);
+ ac.setSensorTemp(kElectraAcSensorMinTemp);
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(kElectraAcSensorMinTemp, ac.getSensorTemp());
+
+ ac.setSensorTemp(26); // Celsius
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(26, ac.getSensorTemp());
+
+ EXPECT_FALSE(ac.getSensorUpdate());
+ ac.setSensorUpdate(true);
+ EXPECT_TRUE(ac.getSensorUpdate());
+ EXPECT_EQ("Sensor Temp: 26C", ac.toString());
+ ac.setSensorUpdate(false);
+ EXPECT_FALSE(ac.getSensorUpdate());
+
+ const uint8_t sensor_update_28C[kElectraAcStateLength] = {
+ 0xC3, 0x9F, 0xE0, 0x40, 0xA0, 0x00, 0x88,
+ 0x66, 0x00, 0x30, 0x00, 0x1E, 0x5E};
+ ac.setRaw(sensor_update_28C);
+ EXPECT_TRUE(ac.getSensorUpdate());
+ EXPECT_EQ(28, ac.getSensorTemp());
+ EXPECT_EQ("Sensor Temp: 28C", ac.toString());
+ ac.setSensorUpdate(false);
+ EXPECT_FALSE(ac.getSensorUpdate());
+ EXPECT_EQ(
+ "Power: On, Mode: 4 (Heat), Temp: 27C, Fan: 5 (Auto), "
+ "Swing(V): Off, Swing(H): Off, Light: -, Clean: Off, Turbo: Off, "
+ "IFeel: On, Sensor Temp: 28C",
+ ac.toString());
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Gree_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Gree_test.cpp
index 597fd3c09..cb1832f61 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Gree_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Gree_test.cpp
@@ -303,9 +303,10 @@ TEST(TestGreeClass, Temperature) {
EXPECT_EQ(63, ac.getTemp());
EXPECT_EQ(
"Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 63F, Fan: 0 (Auto), "
- "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
- "Swing(V) Mode: Manual, Swing(V): 0 (Last), Timer: Off, "
- "Display Temp: 0 (Off)", ac.toString());
+ "Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, "
+ "Sleep: Off, "
+ "Swing(V) Mode: Manual, Swing(V): 0 (Last), Swing(H): 0 (Off), "
+ "Timer: Off, Display Temp: 0 (Off)", ac.toString());
}
TEST(TestGreeClass, OperatingMode) {
@@ -385,6 +386,20 @@ TEST(TestGreeClass, Turbo) {
EXPECT_TRUE(ac.getTurbo());
}
+TEST(TestGreeClass, Econo) {
+ IRGreeAC ac(kGpioUnused);
+ ac.begin();
+
+ ac.setEcono(true);
+ EXPECT_TRUE(ac.getEcono());
+
+ ac.setEcono(false);
+ EXPECT_FALSE(ac.getEcono());
+
+ ac.setEcono(true);
+ EXPECT_TRUE(ac.getEcono());
+}
+
TEST(TestGreeClass, IFeel) {
IRGreeAC ac(kGpioUnused);
ac.begin();
@@ -506,6 +521,24 @@ TEST(TestGreeClass, VerticalSwing) {
EXPECT_EQ(kGreeSwingAuto, ac.getSwingVerticalPosition());
}
+TEST(TestGreeClass, HorizontalSwing) {
+ IRGreeAC ac(kGpioUnused);
+ ac.begin();
+
+ ac.setSwingHorizontal(kGreeSwingHAuto);
+ EXPECT_EQ(kGreeSwingHAuto, ac.getSwingHorizontal());
+
+ ac.setSwingHorizontal(kGreeSwingHMiddle);
+ EXPECT_EQ(kGreeSwingHMiddle, ac.getSwingHorizontal());
+
+ ac.setSwingHorizontal(kGreeSwingHMaxRight);
+ EXPECT_EQ(kGreeSwingHMaxRight, ac.getSwingHorizontal());
+
+ // Out of bounds.
+ ac.setSwingHorizontal(kGreeSwingHMaxRight + 1);
+ EXPECT_EQ(kGreeSwingHOff, ac.getSwingHorizontal());
+}
+
TEST(TestGreeClass, SetAndGetRaw) {
IRGreeAC ac(kGpioUnused);
uint8_t initialState[kGreeStateLength] = {0x00, 0x09, 0x20, 0x50,
@@ -543,8 +576,9 @@ TEST(TestGreeClass, HumanReadable) {
EXPECT_EQ(
"Model: 1 (YAW1F), Power: Off, Mode: 0 (Auto), Temp: 25C, Fan: 0 (Auto), "
- "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
- "Swing(V) Mode: Manual, Swing(V): 0 (Last), "
+ "Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, "
+ "Sleep: Off, "
+ "Swing(V) Mode: Manual, Swing(V): 0 (Last), Swing(H): 0 (Off), "
"Timer: Off, Display Temp: 0 (Off)",
ac.toString());
ac.on();
@@ -562,9 +596,10 @@ TEST(TestGreeClass, HumanReadable) {
ac.setDisplayTempSource(3);
EXPECT_EQ(
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 3 (High), "
- "Turbo: On, IFeel: On, WiFi: On, XFan: On, Light: Off, Sleep: On, "
- "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: 12:30, "
- "Display Temp: 3 (Outside)",
+ "Turbo: On, Econo: Off, IFeel: On, WiFi: On, XFan: On, Light: Off, "
+ "Sleep: On, "
+ "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Swing(H): 0 (Off), "
+ "Timer: 12:30, Display Temp: 3 (Outside)",
ac.toString());
}
@@ -623,9 +658,10 @@ TEST(TestDecodeGree, NormalRealExample) {
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Model: 1 (YAW1F), Power: On, Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), "
- "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
- "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Timer: Off, "
- "Display Temp: 3 (Outside)",
+ "Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, "
+ "Sleep: Off, "
+ "Swing(V) Mode: Manual, Swing(V): 2 (UNKNOWN), Swing(H): 0 (Off), "
+ "Timer: Off, Display Temp: 3 (Outside)",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
@@ -681,8 +717,9 @@ TEST(TestGreeClass, Issue814Power) {
EXPECT_EQ(gree_ac_remote_model_t::YBOFB, ac.getModel());
EXPECT_EQ(
"Model: 2 (YBOFB), Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 1 (Low), "
- "Turbo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, Sleep: Off, "
- "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Timer: Off, "
+ "Turbo: Off, Econo: Off, IFeel: Off, WiFi: Off, XFan: Off, Light: On, "
+ "Sleep: Off, "
+ "Swing(V) Mode: Auto, Swing(V): 1 (Auto), Swing(H): 0 (Off), Timer: Off, "
"Display Temp: 0 (Off)",
ac.toString());
ac.off();
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Haier_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Haier_test.cpp
index 8b89b1098..b60a08f23 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Haier_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Haier_test.cpp
@@ -105,597 +105,711 @@ TEST(TestSendHaierAC, SendWithRepeats) {
// Tests for IRHaierAC class.
TEST(TestHaierACClass, Command) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
- haier.setCommand(kHaierAcCmdOff);
- EXPECT_EQ(kHaierAcCmdOff, haier.getCommand());
- haier.setCommand(kHaierAcCmdOn);
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
- haier.setCommand(kHaierAcCmdMode);
- EXPECT_EQ(kHaierAcCmdMode, haier.getCommand());
- haier.setCommand(kHaierAcCmdFan);
- EXPECT_EQ(kHaierAcCmdFan, haier.getCommand());
- haier.setCommand(kHaierAcCmdTempUp);
- EXPECT_EQ(kHaierAcCmdTempUp, haier.getCommand());
- haier.setCommand(kHaierAcCmdTempDown);
- EXPECT_EQ(kHaierAcCmdTempDown, haier.getCommand());
- haier.setCommand(kHaierAcCmdSleep);
- EXPECT_EQ(kHaierAcCmdSleep, haier.getCommand());
- haier.setCommand(kHaierAcCmdTimerSet);
- EXPECT_EQ(kHaierAcCmdTimerSet, haier.getCommand());
- haier.setCommand(kHaierAcCmdTimerCancel);
- EXPECT_EQ(kHaierAcCmdTimerCancel, haier.getCommand());
- haier.setCommand(kHaierAcCmdHealth);
- EXPECT_EQ(kHaierAcCmdHealth, haier.getCommand());
- haier.setCommand(kHaierAcCmdSwing);
- EXPECT_EQ(kHaierAcCmdSwing, haier.getCommand());
- haier.setCommand(kHaierAcCmdOn);
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
- haier.setCommand(kHaierAcCmdOff);
- EXPECT_EQ(kHaierAcCmdOff, haier.getCommand());
+ ac.setCommand(kHaierAcCmdOff);
+ EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
+ ac.setCommand(kHaierAcCmdMode);
+ EXPECT_EQ(kHaierAcCmdMode, ac.getCommand());
+ ac.setCommand(kHaierAcCmdFan);
+ EXPECT_EQ(kHaierAcCmdFan, ac.getCommand());
+ ac.setCommand(kHaierAcCmdTempUp);
+ EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
+ ac.setCommand(kHaierAcCmdTempDown);
+ EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
+ ac.setCommand(kHaierAcCmdSleep);
+ EXPECT_EQ(kHaierAcCmdSleep, ac.getCommand());
+ ac.setCommand(kHaierAcCmdTimerSet);
+ EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
+ ac.setCommand(kHaierAcCmdTimerCancel);
+ EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
+ ac.setCommand(kHaierAcCmdHealth);
+ EXPECT_EQ(kHaierAcCmdHealth, ac.getCommand());
+ ac.setCommand(kHaierAcCmdSwing);
+ EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
+ ac.setCommand(kHaierAcCmdOff);
+ EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
// Test unexpected values.
- haier.setCommand(0b00001110);
- EXPECT_EQ(kHaierAcCmdOff, haier.getCommand());
- haier.setCommand(0b00001111);
- EXPECT_EQ(kHaierAcCmdOff, haier.getCommand());
- haier.setCommand(0b00000100);
- EXPECT_EQ(kHaierAcCmdOff, haier.getCommand());
+ ac.setCommand(0b00001110);
+ EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
+ ac.setCommand(0b00001111);
+ EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
+ ac.setCommand(0b00000100);
+ EXPECT_EQ(kHaierAcCmdOff, ac.getCommand());
}
TEST(TestHaierACClass, OperatingMode) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
- haier.setMode(kHaierAcAuto);
- EXPECT_EQ(kHaierAcAuto, haier.getMode());
+ ac.setMode(kHaierAcAuto);
+ EXPECT_EQ(kHaierAcAuto, ac.getMode());
- haier.setMode(kHaierAcCool);
- EXPECT_EQ(kHaierAcCool, haier.getMode());
+ ac.setMode(kHaierAcCool);
+ EXPECT_EQ(kHaierAcCool, ac.getMode());
- haier.setMode(kHaierAcHeat);
- EXPECT_EQ(kHaierAcHeat, haier.getMode());
+ ac.setMode(kHaierAcHeat);
+ EXPECT_EQ(kHaierAcHeat, ac.getMode());
- haier.setMode(kHaierAcFan);
- EXPECT_EQ(kHaierAcFan, haier.getMode());
+ ac.setMode(kHaierAcFan);
+ EXPECT_EQ(kHaierAcFan, ac.getMode());
- haier.setMode(kHaierAcDry);
- EXPECT_EQ(kHaierAcDry, haier.getMode());
+ ac.setMode(kHaierAcDry);
+ EXPECT_EQ(kHaierAcDry, ac.getMode());
- haier.setMode(kHaierAcAuto - 1);
- EXPECT_EQ(kHaierAcAuto, haier.getMode());
+ ac.setMode(kHaierAcAuto - 1);
+ EXPECT_EQ(kHaierAcAuto, ac.getMode());
- haier.setMode(kHaierAcCool);
- EXPECT_EQ(kHaierAcCool, haier.getMode());
+ ac.setMode(kHaierAcCool);
+ EXPECT_EQ(kHaierAcCool, ac.getMode());
- haier.setMode(kHaierAcFan + 1);
- EXPECT_EQ(kHaierAcAuto, haier.getMode());
+ ac.setMode(kHaierAcFan + 1);
+ EXPECT_EQ(kHaierAcAuto, ac.getMode());
- haier.setMode(255);
- EXPECT_EQ(kHaierAcAuto, haier.getMode());
+ ac.setMode(255);
+ EXPECT_EQ(kHaierAcAuto, ac.getMode());
}
TEST(TestHaierACClass, Temperature) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
- haier.setTemp(kHaierAcMinTemp);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
+ ac.setTemp(kHaierAcMinTemp);
+ EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
- haier.setCommand(kHaierAcCmdOn);
- haier.setTemp(kHaierAcMinTemp + 1);
- EXPECT_EQ(kHaierAcMinTemp + 1, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempUp, haier.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ ac.setTemp(kHaierAcMinTemp + 1);
+ EXPECT_EQ(kHaierAcMinTemp + 1, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
- haier.setTemp(kHaierAcMaxTemp);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempUp, haier.getCommand());
+ ac.setTemp(kHaierAcMaxTemp);
+ EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
- haier.setTemp(kHaierAcMinTemp - 1);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempDown, haier.getCommand());
+ ac.setTemp(kHaierAcMinTemp - 1);
+ EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
- haier.setTemp(kHaierAcMaxTemp + 1);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempUp, haier.getCommand());
+ ac.setTemp(kHaierAcMaxTemp + 1);
+ EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
- haier.setTemp(23);
- EXPECT_EQ(23, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempDown, haier.getCommand());
- haier.setCommand(kHaierAcCmdOn);
- haier.setTemp(23);
- EXPECT_EQ(23, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
- haier.setTemp(0);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempDown, haier.getCommand());
+ ac.setTemp(0);
+ EXPECT_EQ(kHaierAcMinTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempDown, ac.getCommand());
- haier.setTemp(255);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcCmdTempUp, haier.getCommand());
+ ac.setTemp(255);
+ EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcCmdTempUp, ac.getCommand());
}
TEST(TestHaierACClass, FanSpeed) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
- haier.setFan(kHaierAcFanLow);
- haier.setCommand(kHaierAcCmdOn);
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
+ ac.setFan(kHaierAcFanLow);
+ ac.setCommand(kHaierAcCmdOn);
- haier.setFan(kHaierAcFanAuto);
- EXPECT_EQ(kHaierAcFanAuto, haier.getFan());
- EXPECT_EQ(kHaierAcCmdFan, haier.getCommand());
+ ac.setFan(kHaierAcFanAuto);
+ EXPECT_EQ(kHaierAcFanAuto, ac.getFan());
+ EXPECT_EQ(kHaierAcCmdFan, ac.getCommand());
- haier.setFan(kHaierAcFanLow);
- EXPECT_EQ(kHaierAcFanLow, haier.getFan());
- haier.setFan(kHaierAcFanMed);
- EXPECT_EQ(kHaierAcFanMed, haier.getFan());
- haier.setFan(kHaierAcFanHigh);
- EXPECT_EQ(kHaierAcFanHigh, haier.getFan());
+ ac.setFan(kHaierAcFanLow);
+ EXPECT_EQ(kHaierAcFanLow, ac.getFan());
+ ac.setFan(kHaierAcFanMed);
+ EXPECT_EQ(kHaierAcFanMed, ac.getFan());
+ ac.setFan(kHaierAcFanHigh);
+ EXPECT_EQ(kHaierAcFanHigh, ac.getFan());
- haier.setCommand(kHaierAcCmdOn);
- haier.setFan(kHaierAcFanHigh);
- EXPECT_EQ(kHaierAcFanHigh, haier.getFan());
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ ac.setFan(kHaierAcFanHigh);
+ EXPECT_EQ(kHaierAcFanHigh, ac.getFan());
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
}
-TEST(TestHaierACClass, Swing) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
- haier.setFan(kHaierAcFanLow);
- haier.setCommand(kHaierAcCmdOn);
+TEST(TestHaierACClass, SwingV) {
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
+ ac.setFan(kHaierAcFanLow);
+ ac.setCommand(kHaierAcCmdOn);
- haier.setSwing(kHaierAcSwingOff);
- EXPECT_EQ(kHaierAcSwingOff, haier.getSwing());
+ ac.setSwingV(kHaierAcSwingVOff);
+ EXPECT_EQ(kHaierAcSwingVOff, ac.getSwingV());
- haier.setSwing(kHaierAcSwingUp);
- EXPECT_EQ(kHaierAcSwingUp, haier.getSwing());
- EXPECT_EQ(kHaierAcCmdSwing, haier.getCommand());
+ ac.setSwingV(kHaierAcSwingVUp);
+ EXPECT_EQ(kHaierAcSwingVUp, ac.getSwingV());
+ EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
- haier.setSwing(kHaierAcSwingDown);
- EXPECT_EQ(kHaierAcSwingDown, haier.getSwing());
- EXPECT_EQ(kHaierAcCmdSwing, haier.getCommand());
+ ac.setSwingV(kHaierAcSwingVDown);
+ EXPECT_EQ(kHaierAcSwingVDown, ac.getSwingV());
+ EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
- haier.setSwing(kHaierAcSwingChg);
- EXPECT_EQ(kHaierAcSwingChg, haier.getSwing());
- EXPECT_EQ(kHaierAcCmdSwing, haier.getCommand());
+ ac.setSwingV(kHaierAcSwingVChg);
+ EXPECT_EQ(kHaierAcSwingVChg, ac.getSwingV());
+ EXPECT_EQ(kHaierAcCmdSwing, ac.getCommand());
}
TEST(TestHaierACClass, CurrentTime) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
- EXPECT_EQ(0, haier.getCurrTime());
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
+ EXPECT_EQ(0, ac.getCurrTime());
- haier.setCurrTime(1);
- EXPECT_EQ(1, haier.getCurrTime());
+ ac.setCurrTime(1);
+ EXPECT_EQ(1, ac.getCurrTime());
- haier.setCurrTime(60);
- EXPECT_EQ(60, haier.getCurrTime());
+ ac.setCurrTime(60);
+ EXPECT_EQ(60, ac.getCurrTime());
- haier.setCurrTime(61);
- EXPECT_EQ(61, haier.getCurrTime());
+ ac.setCurrTime(61);
+ EXPECT_EQ(61, ac.getCurrTime());
- haier.setCurrTime(18 * 60 + 34); // 18:34
- EXPECT_EQ(1114, haier.getCurrTime());
+ ac.setCurrTime(18 * 60 + 34); // 18:34
+ EXPECT_EQ(1114, ac.getCurrTime());
- haier.setCurrTime(23 * 60 + 59); // 23:59
- EXPECT_EQ(kHaierAcMaxTime, haier.getCurrTime()); // 23:59
+ ac.setCurrTime(23 * 60 + 59); // 23:59
+ EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
- haier.setCurrTime(23 * 60 + 59 + 1); // 24:00
- EXPECT_EQ(kHaierAcMaxTime, haier.getCurrTime()); // 23:59
+ ac.setCurrTime(23 * 60 + 59 + 1); // 24:00
+ EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
- haier.setCurrTime(UINT16_MAX);
- EXPECT_EQ(kHaierAcMaxTime, haier.getCurrTime()); // 23:59
+ ac.setCurrTime(UINT16_MAX);
+ EXPECT_EQ(kHaierAcMaxTime, ac.getCurrTime()); // 23:59
}
TEST(TestHaierACClass, Timers) {
- IRHaierAC haier(kGpioUnused);
- haier.begin();
+ IRHaierAC ac(kGpioUnused);
+ ac.begin();
- haier.setCommand(kHaierAcCmdOn);
+ ac.setCommand(kHaierAcCmdOn);
// Off by default.
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
// On Timer.
- haier.setOnTimer(6 * 60); // 6am
- EXPECT_EQ(6 * 60, haier.getOnTimer()); // 6am
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdTimerSet, haier.getCommand());
+ ac.setOnTimer(6 * 60); // 6am
+ EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
- haier.setCommand(kHaierAcCmdOn);
- EXPECT_EQ(6 * 60, haier.getOnTimer()); // 6am
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
- haier.cancelTimers();
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdTimerCancel, haier.getCommand());
+ ac.cancelTimers();
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
// Off Timer.
- haier.setOffTimer(18 * 60 + 30); // 6:30pm
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_EQ(18 * 60 + 30, haier.getOffTimer()); // 6:30pm
- EXPECT_EQ(kHaierAcCmdTimerSet, haier.getCommand());
+ ac.setOffTimer(18 * 60 + 30); // 6:30pm
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
+ EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
- haier.setCommand(kHaierAcCmdOn);
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_EQ(18 * 60 + 30, haier.getOffTimer()); // 6:30pm
- EXPECT_EQ(kHaierAcCmdOn, haier.getCommand());
+ ac.setCommand(kHaierAcCmdOn);
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
+ EXPECT_EQ(kHaierAcCmdOn, ac.getCommand());
- haier.cancelTimers();
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdTimerCancel, haier.getCommand());
+ ac.cancelTimers();
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
// Both Timers.
- haier.setOnTimer(6 * 60); // 6am
- EXPECT_EQ(kHaierAcCmdTimerSet, haier.getCommand());
- haier.setOffTimer(18 * 60 + 30); // 6:30pm
- EXPECT_EQ(kHaierAcCmdTimerSet, haier.getCommand());
- EXPECT_EQ(6 * 60, haier.getOnTimer()); // 6am
- EXPECT_EQ(18 * 60 + 30, haier.getOffTimer()); // 6:30pm
+ ac.setOnTimer(6 * 60); // 6am
+ EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
+ ac.setOffTimer(18 * 60 + 30); // 6:30pm
+ EXPECT_EQ(kHaierAcCmdTimerSet, ac.getCommand());
+ EXPECT_EQ(6 * 60, ac.getOnTimer()); // 6am
+ EXPECT_EQ(18 * 60 + 30, ac.getOffTimer()); // 6:30pm
- haier.cancelTimers();
- EXPECT_GT(0, haier.getOnTimer());
- EXPECT_GT(0, haier.getOffTimer());
- EXPECT_EQ(kHaierAcCmdTimerCancel, haier.getCommand());
+ ac.cancelTimers();
+ EXPECT_GT(0, ac.getOnTimer());
+ EXPECT_GT(0, ac.getOffTimer());
+ EXPECT_EQ(kHaierAcCmdTimerCancel, ac.getCommand());
}
TEST(TestHaierACClass, MessageConstuction) {
- IRHaierAC haier(kGpioUnused);
+ IRHaierAC ac(kGpioUnused);
EXPECT_EQ(
"Command: 1 (On), Mode: 0 (Auto), Temp: 25C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:00, On Timer: Off, Off Timer: Off",
- haier.toString());
- haier.setMode(kHaierAcCool);
- haier.setTemp(21);
- haier.setFan(kHaierAcFanHigh);
+ ac.toString());
+ ac.setMode(kHaierAcCool);
+ ac.setTemp(21);
+ ac.setFan(kHaierAcFanHigh);
EXPECT_EQ(
"Command: 3 (Fan), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:00, On Timer: Off, Off Timer: Off",
- haier.toString());
- haier.setSwing(kHaierAcSwingChg);
- haier.setHealth(true);
- haier.setSleep(true);
- haier.setCurrTime(615); // 10:15am
+ ac.toString());
+ ac.setSwingV(kHaierAcSwingVChg);
+ ac.setHealth(true);
+ ac.setSleep(true);
+ ac.setCurrTime(615); // 10:15am
EXPECT_EQ(
"Command: 8 (Sleep), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
- "Swing: 3 (Change), Sleep: On, Health: On, "
+ "Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: Off, Off Timer: Off",
- haier.toString());
- haier.setOnTimer(800); // 1:20pm
- haier.setOffTimer(1125); // 6:45pm
- haier.setCommand(kHaierAcCmdOn);
+ ac.toString());
+ ac.setOnTimer(800); // 1:20pm
+ ac.setOffTimer(1125); // 6:45pm
+ ac.setCommand(kHaierAcCmdOn);
EXPECT_EQ(
"Command: 1 (On), Mode: 1 (Cool), Temp: 21C, Fan: 3 (High), "
- "Swing: 3 (Change), Sleep: On, Health: On, "
+ "Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
- haier.toString());
+ ac.toString());
// Now change a few already set things.
- haier.setMode(kHaierAcHeat);
+ ac.setMode(kHaierAcHeat);
EXPECT_EQ(
"Command: 2 (Mode), Mode: 3 (Heat), Temp: 21C, Fan: 3 (High), "
- "Swing: 3 (Change), Sleep: On, Health: On, "
+ "Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
- haier.toString());
+ ac.toString());
- haier.setTemp(25);
+ ac.setTemp(25);
EXPECT_EQ(
"Command: 6 (Temp Up), Mode: 3 (Heat), Temp: 25C, Fan: 3 (High), "
- "Swing: 3 (Change), Sleep: On, Health: On, "
+ "Swing(V): 3 (Change), Sleep: On, Health: On, "
"Clock: 10:15, On Timer: 13:20, Off Timer: 18:45",
- haier.toString());
+ ac.toString());
uint8_t expectedState[kHaierACStateLength] = {0xA5, 0x96, 0xEA, 0xCF, 0x32,
0x6D, 0x6D, 0x54, 0x54};
- EXPECT_STATE_EQ(expectedState, haier.getRaw(), kHaierACBits);
+ EXPECT_STATE_EQ(expectedState, ac.getRaw(), kHaierACBits);
// Check that the checksum is valid.
- EXPECT_TRUE(IRHaierAC::validChecksum(haier.getRaw()));
+ EXPECT_TRUE(IRHaierAC::validChecksum(ac.getRaw()));
// Now load up some random data.
uint8_t randomState[kHaierACStateLength] = {0x52, 0x49, 0x50, 0x20, 0x54,
0x61, 0x6C, 0x69, 0x61};
EXPECT_FALSE(IRHaierAC::validChecksum(randomState));
- haier.setRaw(randomState);
+ ac.setRaw(randomState);
EXPECT_EQ(
"Command: 9 (Timer Set), Mode: 3 (Heat), Temp: 20C, Fan: 3 (High), "
- "Swing: 1 (Up), Sleep: On, Health: Off, "
+ "Swing(V): 1 (Up), Sleep: On, Health: Off, "
"Clock: 16:32, On Timer: Off, Off Timer: Off",
- haier.toString());
+ ac.toString());
// getRaw() should correct the checksum.
- EXPECT_TRUE(IRHaierAC::validChecksum(haier.getRaw()));
+ EXPECT_TRUE(IRHaierAC::validChecksum(ac.getRaw()));
}
// Tests for the IRHaierACYRW02 class.
TEST(TestHaierACYRW02Class, Button) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setButton(kHaierAcYrw02ButtonPower);
- EXPECT_EQ(kHaierAcYrw02ButtonPower, haier.getButton());
- haier.setButton(kHaierAcYrw02ButtonMode);
- EXPECT_EQ(kHaierAcYrw02ButtonMode, haier.getButton());
- haier.setButton(kHaierAcYrw02ButtonSleep);
- EXPECT_EQ(kHaierAcYrw02ButtonSleep, haier.getButton());
- haier.setButton(kHaierAcYrw02ButtonFan);
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
+ ac.setButton(kHaierAcYrw02ButtonMode);
+ EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
+ ac.setButton(kHaierAcYrw02ButtonSleep);
+ EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
+ ac.setButton(kHaierAcYrw02ButtonFan);
// Test unexpected values.
- haier.setButton(0xFF);
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
- haier.setButton(0x10);
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
+ ac.setButton(0xFF);
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
+ ac.setButton(0x10);
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
}
TEST(TestHaierACYRW02Class, OperatingMode) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setButton(kHaierAcYrw02ButtonPower);
- haier.setMode(kHaierAcYrw02Auto);
- EXPECT_EQ(kHaierAcYrw02Auto, haier.getMode());
- EXPECT_EQ(kHaierAcYrw02ButtonMode, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ ac.setMode(kHaierAcYrw02Auto);
+ EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
+ EXPECT_EQ(kHaierAcYrw02ButtonMode, ac.getButton());
- haier.setMode(kHaierAcYrw02Cool);
- EXPECT_EQ(kHaierAcYrw02Cool, haier.getMode());
+ ac.setMode(kHaierAcYrw02Cool);
+ EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
- haier.setMode(kHaierAcYrw02Heat);
- EXPECT_EQ(kHaierAcYrw02Heat, haier.getMode());
+ ac.setMode(kHaierAcYrw02Heat);
+ EXPECT_EQ(kHaierAcYrw02Heat, ac.getMode());
- haier.setMode(kHaierAcYrw02Fan);
- EXPECT_EQ(kHaierAcYrw02Fan, haier.getMode());
+ ac.setMode(kHaierAcYrw02Fan);
+ EXPECT_EQ(kHaierAcYrw02Fan, ac.getMode());
- haier.setMode(kHaierAcYrw02Dry);
- EXPECT_EQ(kHaierAcYrw02Dry, haier.getMode());
+ ac.setMode(kHaierAcYrw02Dry);
+ EXPECT_EQ(kHaierAcYrw02Dry, ac.getMode());
- haier.setMode(kHaierAcYrw02Auto - 1);
- EXPECT_EQ(kHaierAcYrw02Auto, haier.getMode());
+ ac.setMode(kHaierAcYrw02Auto - 1);
+ EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
- haier.setMode(kHaierAcYrw02Cool);
- EXPECT_EQ(kHaierAcYrw02Cool, haier.getMode());
+ ac.setMode(kHaierAcYrw02Cool);
+ EXPECT_EQ(kHaierAcYrw02Cool, ac.getMode());
- haier.setMode(kHaierAcYrw02Fan + 1);
- EXPECT_EQ(kHaierAcYrw02Auto, haier.getMode());
+ ac.setMode(kHaierAcYrw02Fan + 1);
+ EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
- haier.setMode(255);
- EXPECT_EQ(kHaierAcYrw02Auto, haier.getMode());
+ ac.setMode(255);
+ EXPECT_EQ(kHaierAcYrw02Auto, ac.getMode());
}
TEST(TestHaierACYRW02Class, Temperature) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setTemp(kHaierAcMinTemp);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
+ ac.setTemp(kHaierAcYrw02MinTempC);
+ EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
- haier.setButton(kHaierAcYrw02ButtonPower);
- haier.setTemp(kHaierAcMinTemp + 1);
- EXPECT_EQ(kHaierAcMinTemp + 1, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ ac.setTemp(kHaierAcYrw02MinTempC + 1);
+ EXPECT_EQ(kHaierAcYrw02MinTempC + 1, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
- haier.setTemp(kHaierAcMaxTemp);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setTemp(kHaierAcYrw02MaxTempC);
+ EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
- haier.setTemp(kHaierAcMinTemp - 1);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempDown, haier.getButton());
+ ac.setTemp(kHaierAcYrw02MinTempC - 1);
+ EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
- haier.setTemp(kHaierAcMaxTemp + 1);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setTemp(kHaierAcYrw02MaxTempC + 1);
+ EXPECT_EQ(kHaierAcYrw02MaxTempC, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
- haier.setTemp(23);
- EXPECT_EQ(23, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempDown, haier.getButton());
- haier.setButton(kHaierAcYrw02ButtonPower);
- haier.setTemp(23);
- EXPECT_EQ(23, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonPower, haier.getButton());
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ ac.setTemp(23);
+ EXPECT_EQ(23, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
- haier.setTemp(0);
- EXPECT_EQ(kHaierAcMinTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempDown, haier.getButton());
+ ac.setTemp(kHaierAcYrw02MinTempF, true);
+ EXPECT_EQ(kHaierAcYrw02MinTempF, ac.getTemp());
- haier.setTemp(255);
- EXPECT_EQ(kHaierAcMaxTemp, haier.getTemp());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ ac.setTemp(kHaierAcYrw02MinTempF + 1, true);
+ EXPECT_EQ(kHaierAcYrw02MinTempF + 1, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
+
+ ac.setTemp(kHaierAcYrw02MaxTempF, true);
+ EXPECT_EQ(kHaierAcYrw02MaxTempF, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
+
+ ac.setTemp(kHaierAcYrw02MinTempF - 1, true);
+ EXPECT_EQ(kHaierAcYrw02MinTempF, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
+
+ ac.setTemp(kHaierAcYrw02MaxTempF + 1, true);
+ EXPECT_EQ(kHaierAcYrw02MaxTempF, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
+
+ ac.setTemp(66, true);
+ EXPECT_EQ(66, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
+ ac.setButton(kHaierAcYrw02ButtonPower);
+ ac.setTemp(66, true);
+ EXPECT_EQ(66, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
+
+ // Test specific cases for converting to Fahrenheit
+ ac.setTemp(76, true);
+ EXPECT_EQ(76, ac.getTemp());
+ ac.setTemp(77, true);
+ EXPECT_EQ(77, ac.getTemp());
+ ac.setTemp(78, true);
+ EXPECT_EQ(78, ac.getTemp());
+
+ ac.setTemp(24);
+ EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
+
+ ac.setTemp(0);
+ EXPECT_EQ(kHaierAcYrw02MinTempC, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempDown, ac.getButton());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kHaierAcMaxTemp, ac.getTemp());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
TEST(TestHaierACYRW02Class, HealthMode) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setHealth(true);
- EXPECT_TRUE(haier.getHealth());
- EXPECT_EQ(kHaierAcYrw02ButtonHealth, haier.getButton());
+ ac.setHealth(true);
+ EXPECT_TRUE(ac.getHealth());
+ EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setHealth(false);
- EXPECT_FALSE(haier.getHealth());
- EXPECT_EQ(kHaierAcYrw02ButtonHealth, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setHealth(false);
+ EXPECT_FALSE(ac.getHealth());
+ EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
- haier.setHealth(true);
- EXPECT_TRUE(haier.getHealth());
- EXPECT_EQ(kHaierAcYrw02ButtonHealth, haier.getButton());
+ ac.setHealth(true);
+ EXPECT_TRUE(ac.getHealth());
+ EXPECT_EQ(kHaierAcYrw02ButtonHealth, ac.getButton());
}
TEST(TestHaierACYRW02Class, Power) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setPower(true);
- EXPECT_TRUE(haier.getPower());
- EXPECT_EQ(kHaierAcYrw02ButtonPower, haier.getButton());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setPower(false);
- EXPECT_FALSE(haier.getPower());
- EXPECT_EQ(kHaierAcYrw02ButtonPower, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
- haier.setPower(true);
- EXPECT_TRUE(haier.getPower());
- EXPECT_EQ(kHaierAcYrw02ButtonPower, haier.getButton());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ EXPECT_EQ(kHaierAcYrw02ButtonPower, ac.getButton());
- haier.off();
- EXPECT_FALSE(haier.getPower());
- haier.on();
- EXPECT_TRUE(haier.getPower());
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
}
TEST(TestHaierACYRW02Class, SleepMode) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setSleep(true);
- EXPECT_TRUE(haier.getSleep());
- EXPECT_EQ(kHaierAcYrw02ButtonSleep, haier.getButton());
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+ EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setSleep(false);
- EXPECT_FALSE(haier.getSleep());
- EXPECT_EQ(kHaierAcYrw02ButtonSleep, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setSleep(false);
+ EXPECT_FALSE(ac.getSleep());
+ EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
- haier.setSleep(true);
- EXPECT_TRUE(haier.getSleep());
- EXPECT_EQ(kHaierAcYrw02ButtonSleep, haier.getButton());
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+ EXPECT_EQ(kHaierAcYrw02ButtonSleep, ac.getButton());
}
-TEST(TestHaierACYRW02Class, TurboMode) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+TEST(TestHaierACYRW02Class, TurboAndQuiet) {
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setTurbo(kHaierAcYrw02TurboOff);
- EXPECT_EQ(kHaierAcYrw02TurboOff, haier.getTurbo());
- EXPECT_EQ(kHaierAcYrw02ButtonTurbo, haier.getButton());
+ ac.setMode(kHaierAcYrw02Cool); // Turbo & Quiet is allowed in this mode.
+ ac.setTurbo(false);
+ ac.setQuiet(false);
+ EXPECT_FALSE(ac.getTurbo());
+ EXPECT_FALSE(ac.getQuiet());
+ EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setTurbo(kHaierAcYrw02TurboLow);
- EXPECT_EQ(kHaierAcYrw02TurboLow, haier.getTurbo());
- EXPECT_EQ(kHaierAcYrw02ButtonTurbo, haier.getButton());
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+ EXPECT_FALSE(ac.getQuiet());
+ EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
- haier.setTurbo(kHaierAcYrw02TurboHigh);
- EXPECT_EQ(kHaierAcYrw02TurboHigh, haier.getTurbo());
- EXPECT_EQ(kHaierAcYrw02ButtonTurbo, haier.getButton());
+ ac.setQuiet(true);
+ EXPECT_FALSE(ac.getTurbo());
+ EXPECT_TRUE(ac.getQuiet());
+ EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
- haier.setTurbo(kHaierAcYrw02TurboOff);
- EXPECT_EQ(kHaierAcYrw02TurboOff, haier.getTurbo());
- EXPECT_EQ(kHaierAcYrw02ButtonTurbo, haier.getButton());
+ ac.setTurbo(false);
+ ac.setQuiet(false);
+ EXPECT_FALSE(ac.getTurbo());
+ EXPECT_FALSE(ac.getQuiet());
+ EXPECT_EQ(kHaierAcYrw02ButtonTurbo, ac.getButton());
+
+ ac.setMode(kHaierAcYrw02Auto); // Turbo & Quiet is not allowed in this mode.
+ EXPECT_FALSE(ac.getTurbo());
+ EXPECT_FALSE(ac.getQuiet());
+ ac.setTurbo(true);
+ EXPECT_FALSE(ac.getTurbo());
+ EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
+ ac.setQuiet(true);
+ EXPECT_FALSE(ac.getQuiet());
+ EXPECT_NE(kHaierAcYrw02ButtonTurbo, ac.getButton());
}
TEST(TestHaierACYRW02Class, Fan) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setFan(kHaierAcYrw02FanAuto);
- EXPECT_EQ(kHaierAcYrw02FanAuto, haier.getFan());
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
+ ac.setFan(kHaierAcYrw02FanAuto);
+ EXPECT_EQ(kHaierAcYrw02FanAuto, ac.getFan());
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setFan(kHaierAcYrw02FanLow);
- EXPECT_EQ(kHaierAcYrw02FanLow, haier.getFan());
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
+ ac.setFan(kHaierAcYrw02FanLow);
+ EXPECT_EQ(kHaierAcYrw02FanLow, ac.getFan());
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
- haier.setFan(kHaierAcYrw02FanHigh);
- EXPECT_EQ(kHaierAcYrw02FanHigh, haier.getFan());
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
+ ac.setFan(kHaierAcYrw02FanHigh);
+ EXPECT_EQ(kHaierAcYrw02FanHigh, ac.getFan());
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
- haier.setFan(kHaierAcYrw02FanMed);
- EXPECT_EQ(kHaierAcYrw02FanMed, haier.getFan());
- EXPECT_EQ(kHaierAcYrw02ButtonFan, haier.getButton());
+ ac.setFan(kHaierAcYrw02FanMed);
+ EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
+ EXPECT_EQ(kHaierAcYrw02ButtonFan, ac.getButton());
// Test unexpected values.
- haier.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setFan(0x00);
- EXPECT_EQ(kHaierAcYrw02FanMed, haier.getFan());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setFan(0x00);
+ EXPECT_EQ(kHaierAcYrw02FanMed, ac.getFan());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
}
-TEST(TestHaierACYRW02Class, Swing) {
- IRHaierACYRW02 haier(kGpioUnused);
- haier.begin();
+TEST(TestHaierACYRW02Class, SwingV) {
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
- haier.setSwing(kHaierAcYrw02SwingOff);
- EXPECT_EQ(kHaierAcYrw02SwingOff, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonSwing, haier.getButton());
+ ac.setSwingV(kHaierAcYrw02SwingVOff);
+ EXPECT_EQ(kHaierAcYrw02SwingVOff, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
- haier.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setSwing(kHaierAcYrw02SwingAuto);
- EXPECT_EQ(kHaierAcYrw02SwingAuto, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonSwing, haier.getButton());
+ ac.setSwingV(kHaierAcYrw02SwingVAuto);
+ EXPECT_EQ(kHaierAcYrw02SwingVAuto, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
- haier.setSwing(kHaierAcYrw02SwingTop);
- EXPECT_EQ(kHaierAcYrw02SwingTop, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonSwing, haier.getButton());
+ ac.setSwingV(kHaierAcYrw02SwingVTop);
+ EXPECT_EQ(kHaierAcYrw02SwingVTop, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
- haier.setSwing(kHaierAcYrw02SwingDown);
- EXPECT_EQ(kHaierAcYrw02SwingDown, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonSwing, haier.getButton());
+ ac.setSwingV(kHaierAcYrw02SwingVDown);
+ EXPECT_EQ(kHaierAcYrw02SwingVDown, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
// Test unexpected values.
- haier.setButton(kHaierAcYrw02ButtonTempUp);
- haier.setSwing(0xFF);
- EXPECT_EQ(kHaierAcYrw02SwingDown, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonTempUp, haier.getButton());
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setSwingV(0xFF);
+ EXPECT_EQ(kHaierAcYrw02SwingVDown, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
// Test the mode-dependant positions.
- haier.setMode(kHaierAcYrw02Auto);
- haier.setSwing(kHaierAcYrw02SwingMiddle);
- EXPECT_EQ(kHaierAcYrw02SwingMiddle, haier.getSwing());
- EXPECT_EQ(kHaierAcYrw02ButtonSwing, haier.getButton());
- haier.setMode(kHaierAcYrw02Heat);
- haier.setSwing(kHaierAcYrw02SwingMiddle);
- EXPECT_EQ(kHaierAcYrw02SwingBottom, haier.getSwing());
- haier.setSwing(kHaierAcYrw02SwingAuto);
- EXPECT_EQ(kHaierAcYrw02SwingAuto, haier.getSwing());
- haier.setSwing(kHaierAcYrw02SwingBottom);
- EXPECT_EQ(kHaierAcYrw02SwingBottom, haier.getSwing());
- haier.setMode(kHaierAcYrw02Cool);
- haier.setSwing(kHaierAcYrw02SwingBottom);
- EXPECT_EQ(kHaierAcYrw02SwingMiddle, haier.getSwing());
+ ac.setMode(kHaierAcYrw02Auto);
+ ac.setSwingV(kHaierAcYrw02SwingVMiddle);
+ EXPECT_EQ(kHaierAcYrw02SwingVMiddle, ac.getSwingV());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingV, ac.getButton());
+ ac.setMode(kHaierAcYrw02Heat);
+ ac.setSwingV(kHaierAcYrw02SwingVMiddle);
+ EXPECT_EQ(kHaierAcYrw02SwingVBottom, ac.getSwingV());
+ ac.setSwingV(kHaierAcYrw02SwingVAuto);
+ EXPECT_EQ(kHaierAcYrw02SwingVAuto, ac.getSwingV());
+ ac.setSwingV(kHaierAcYrw02SwingVBottom);
+ EXPECT_EQ(kHaierAcYrw02SwingVBottom, ac.getSwingV());
+ ac.setMode(kHaierAcYrw02Cool);
+ ac.setSwingV(kHaierAcYrw02SwingVBottom);
+ EXPECT_EQ(kHaierAcYrw02SwingVMiddle, ac.getSwingV());
+}
+
+TEST(TestHaierACYRW02Class, SwingH) {
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
+
+ ac.setSwingH(kHaierAcYrw02SwingVOff);
+ EXPECT_EQ(kHaierAcYrw02SwingHMiddle, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+
+ ac.setSwingH(kHaierAcYrw02SwingHLeftMax);
+ EXPECT_EQ(kHaierAcYrw02SwingHLeftMax, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ ac.setSwingH(kHaierAcYrw02SwingHLeft);
+ EXPECT_EQ(kHaierAcYrw02SwingHLeft, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ ac.setSwingH(kHaierAcYrw02SwingHRight);
+ EXPECT_EQ(kHaierAcYrw02SwingHRight, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ ac.setSwingH(kHaierAcYrw02SwingHRightMax);
+ EXPECT_EQ(kHaierAcYrw02SwingHRightMax, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ ac.setSwingH(kHaierAcYrw02SwingHAuto);
+ EXPECT_EQ(kHaierAcYrw02SwingHAuto, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonSwingH, ac.getButton());
+
+ // Test unexpected values.
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setSwingH(0xFF);
+ EXPECT_EQ(kHaierAcYrw02SwingHAuto, ac.getSwingH());
+ EXPECT_EQ(kHaierAcYrw02ButtonTempUp, ac.getButton());
+}
+
+TEST(TestHaierACYRW02Class, Lock) {
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.begin();
+
+ ac.setLock(true);
+ EXPECT_TRUE(ac.getLock());
+ EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
+
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setLock(false);
+ EXPECT_FALSE(ac.getLock());
+ EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
+
+ ac.setLock(true);
+ EXPECT_TRUE(ac.getLock());
+ EXPECT_EQ(kHaierAcYrw02ButtonLock, ac.getButton());
}
TEST(TestHaierACYRW02Class, MessageConstuction) {
- IRHaierACYRW02 haier(kGpioUnused);
+ IRHaierACYRW02 ac(kGpioUnused);
EXPECT_EQ(
- "Power: On, Button: 5 (Power), Mode: 0 (Auto), Temp: 25C,"
- " Fan: 5 (Auto), Turbo: 0 (Off), Swing: 0 (Off), Sleep: Off,"
- " Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
- haier.setMode(kHaierAcYrw02Cool);
- haier.setTemp(21);
- haier.setFan(kHaierAcYrw02FanHigh);
+ "Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
+ "Mode: 0 (Auto), Temp: 25C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
+ ac.setMode(kHaierAcYrw02Cool);
+ ac.setTemp(21);
+ ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_EQ(
- "Power: On, Button: 4 (Fan), Mode: 1 (Cool), Temp: 21C,"
- " Fan: 1 (High), Turbo: 0 (Off), Swing: 0 (Off), Sleep: Off,"
- " Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
+ "Mode: 1 (Cool), Temp: 21C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
- haier.setSwing(kHaierAcYrw02SwingMiddle);
- haier.setHealth(false);
- haier.setSleep(true);
- haier.setTurbo(kHaierAcYrw02TurboHigh);
+ ac.setTemp(75, true);
+ ac.setSwingV(kHaierAcYrw02SwingVMiddle);
+ ac.setHealth(false);
+ ac.setSleep(true);
+ ac.setTurbo(true);
EXPECT_EQ(
- "Power: On, Button: 8 (Turbo), Mode: 1 (Cool), Temp: 21C, "
- "Fan: 1 (High), Turbo: 1 (High), Swing: 2 (Middle), "
- "Sleep: On, Health: Off, "
- "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 8 (Turbo), "
+ "Mode: 1 (Cool), Temp: 75F, Fan: 1 (High), Turbo: On, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: On, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
}
// Decode "real" state messages.
@@ -704,55 +818,60 @@ TEST(TestHaierACYRW02Class, RealStates) {
0xA6, 0xE1, 0x00, 0x00, 0x40, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x07, 0x6E};
- IRHaierACYRW02 haier(kGpioUnused);
- haier.setRaw(expectedState1);
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.setRaw(expectedState1);
EXPECT_EQ(
- "Power: On, Button: 7 (Health), Mode: 4 (Heat), Temp: 30C, "
- "Fan: 1 (High), Turbo: 0 (Off), Swing: 1 (Highest), Sleep: Off, "
- "Health: Off, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 7 (Health), "
+ "Mode: 4 (Heat), Temp: 30C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 1 (Highest), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
uint8_t expectedState2[kHaierACYRW02StateLength] = {
0xA6, 0xE0, 0x00, 0x00, 0x00, 0x20, 0x00,
0x80, 0x00, 0x00, 0x00, 0x00, 0x05, 0x75};
- haier.setRaw(expectedState2);
+ ac.setRaw(expectedState2);
EXPECT_EQ(
- "Power: Off, Button: 5 (Power), Mode: 4 (Heat), Temp: 30C, "
- "Fan: 1 (High), Turbo: 0 (Off), Swing: 0 (Off), Sleep: Off, "
- "Health: Off, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: Off, Button: 5 (Power), "
+ "Mode: 4 (Heat), Temp: 30C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
uint8_t expectedState3[kHaierACYRW02StateLength] = {
0xA6, 0x02, 0x00, 0x02, 0x40, 0x20, 0x00,
0x20, 0x00, 0x00, 0x00, 0x00, 0x01, 0x2B};
- haier.setRaw(expectedState3);
+ ac.setRaw(expectedState3);
EXPECT_EQ(
- "Power: On, Button: 1 (Temp Down), Mode: 1 (Cool), Temp: 16C, "
- "Fan: 1 (High), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 1 (Temp Down), "
+ "Mode: 1 (Cool), Temp: 16C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
- // cool 25, health, fan auto, swing auto, sleep on
+ // cool 25, health, fan auto, vertical swing auto, sleep on
uint8_t expectedState4[kHaierACYRW02StateLength] = {
0xA6, 0x9C, 0x00, 0x02, 0x40, 0xA8, 0x00,
0x20, 0x80, 0x00, 0x00, 0x00, 0x0B, 0xD7};
- haier.setRaw(expectedState4);
+ ac.setRaw(expectedState4);
EXPECT_EQ(
- "Power: On, Button: 11 (Sleep), Mode: 1 (Cool), Temp: 25C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 12 (Auto), Sleep: On, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 11 (Sleep), "
+ "Mode: 1 (Cool), Temp: 25C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 12 (Auto), Swing(H): 0 (Middle), Sleep: On, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
- // cool 25, health, fan 3, swing auto, sleep on
+ // cool 25, health, fan 3, vertical swing auto, sleep on
uint8_t expectedState5[kHaierACYRW02StateLength] = {
0xA6, 0x9C, 0x00, 0x02, 0x40, 0x27, 0x36,
0x20, 0x80, 0x00, 0x00, 0x00, 0x04, 0x85};
- haier.setRaw(expectedState5);
+ ac.setRaw(expectedState5);
EXPECT_EQ(
- "Power: On, Button: 4 (Fan), Mode: 1 (Cool), Temp: 25C, "
- "Fan: 1 (High), Turbo: 0 (Off), Swing: 12 (Auto), Sleep: On, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
+ "Mode: 1 (Cool), Temp: 25C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 12 (Auto), Swing(H): 0 (Middle), Sleep: On, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
}
// Tests for decodeHaierAC().
@@ -823,7 +942,7 @@ TEST(TestDecodeHaierAC, RealExample1) {
EXPECT_EQ(
"Command: 1 (On), Mode: 1 (Cool), Temp: 16C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:01, On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
@@ -864,13 +983,13 @@ TEST(TestDecodeHaierAC, RealExample2) {
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRHaierAC haier(kGpioUnused);
- haier.setRaw(irsend.capture.state);
+ IRHaierAC ac(kGpioUnused);
+ ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Command: 6 (Temp Up), Mode: 1 (Cool), Temp: 22C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, "
"Clock: 00:01, On Timer: Off, Off Timer: Off",
- haier.toString());
+ ac.toString());
}
// Decode a "real" example message.
@@ -907,13 +1026,13 @@ TEST(TestDecodeHaierAC, RealExample3) {
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRHaierAC haier(kGpioUnused);
- haier.setRaw(irsend.capture.state);
+ IRHaierAC ac(kGpioUnused);
+ ac.setRaw(irsend.capture.state);
EXPECT_EQ(
"Command: 12 (Health), Mode: 1 (Cool), Temp: 30C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: On, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: On, "
"Clock: 00:09, On Timer: Off, Off Timer: Off",
- haier.toString());
+ ac.toString());
}
// Decode normal "synthetic" messages.
@@ -977,13 +1096,14 @@ TEST(TestDecodeHaierAC_YRW02, RealExample) {
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
- IRHaierACYRW02 haier(kGpioUnused);
- haier.setRaw(irsend.capture.state);
+ IRHaierACYRW02 ac(kGpioUnused);
+ ac.setRaw(irsend.capture.state);
EXPECT_EQ(
- "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 17C, "
- "Fan: 1 (High), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: On, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
- haier.toString());
+ "Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
+ "Mode: 1 (Cool), Temp: 17C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
}
// Default state of the remote needed to include hidden data.
@@ -998,7 +1118,7 @@ TEST(TestHaierAcIssues, Issue668) {
ac._irsend.reset();
char expected_on[] =
"Command: 1 (On), Mode: 1 (Cool), Temp: 25C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
// State taken from real capture:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/668#issuecomment-483531895
@@ -1036,7 +1156,7 @@ TEST(TestHaierAcIssues, Issue668) {
ac._irsend.reset();
char expected_temp_plus_one[] =
"Command: 6 (Temp Up), Mode: 1 (Cool), Temp: 26C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
// State taken from real capture:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/668#issuecomment-483531895
@@ -1060,7 +1180,7 @@ TEST(TestHaierAcIssues, Issue668) {
ac._irsend.reset();
char expected_temp_minus_one[] =
"Command: 7 (Temp Down), Mode: 1 (Cool), Temp: 25C, Fan: 1 (Low), "
- "Swing: 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
+ "Swing(V): 0 (Off), Sleep: Off, Health: Off, Clock: 00:00, "
"On Timer: Off, Off Timer: Off";
ASSERT_EQ(26, ac.getTemp());
ac.setTemp(ac.getTemp() - 1);
@@ -1081,7 +1201,7 @@ TEST(TestHaierACClass, toCommon) {
ac.setMode(kHaierAcCool);
ac.setTemp(20);
ac.setFan(kHaierAcFanHigh);
- ac.setSwing(kHaierAcSwingChg);
+ ac.setSwingV(kHaierAcSwingVChg);
ac.setHealth(true);
ac.setSleep(true);
// Now test it.
@@ -1102,7 +1222,7 @@ TEST(TestHaierACClass, toCommon) {
ASSERT_FALSE(ac.toCommon().quiet);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().clean);
- ASSERT_FALSE(ac.toCommon().beep);
+ ASSERT_TRUE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
@@ -1112,12 +1232,14 @@ TEST(TestHaierACYRW02Class, toCommon) {
ac.setMode(kHaierAcYrw02Cool);
ac.setTemp(20);
ac.setFan(kHaierAcYrw02FanHigh);
- ac.setSwing(kHaierAcYrw02SwingTop);
+ ac.setSwingV(kHaierAcYrw02SwingVTop);
+ ac.setSwingH(kHaierAcYrw02SwingHRightMax);
ac.setHealth(true);
ac.setSleep(true);
+ ac.setTurbo(true);
// Now test it.
ASSERT_EQ(decode_type_t::HAIER_AC_YRW02, ac.toCommon().protocol);
- ASSERT_EQ(-1, ac.toCommon().model);
+ ASSERT_EQ(1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
@@ -1125,15 +1247,15 @@ TEST(TestHaierACYRW02Class, toCommon) {
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(stdAc::swingv_t::kHighest, ac.toCommon().swingv);
+ ASSERT_EQ(stdAc::swingh_t::kRightMax, ac.toCommon().swingh);
ASSERT_EQ(0, ac.toCommon().sleep);
- // Unsupported.
- ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
- ASSERT_FALSE(ac.toCommon().turbo);
- ASSERT_FALSE(ac.toCommon().light);
+ ASSERT_TRUE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().quiet);
+ // Unsupported.
+ ASSERT_FALSE(ac.toCommon().light);
ASSERT_FALSE(ac.toCommon().econo);
ASSERT_FALSE(ac.toCommon().clean);
- ASSERT_FALSE(ac.toCommon().beep);
+ ASSERT_TRUE(ac.toCommon().beep);
ASSERT_EQ(-1, ac.toCommon().clock);
}
@@ -1204,9 +1326,10 @@ TEST(TestDecodeHaierAC176, SyntheticDecode) {
EXPECT_FALSE(irsend.capture.repeat);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "Power: On, Button: 5 (Power), Mode: 1 (Cool), Temp: 24C, Fan: 5 (Auto), "
- "Turbo: 0 (Off), Swing: 6 (UNKNOWN), Sleep: Off, Health: Off, "
- "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
+ "Model: 1 (V9014557-A), Power: On, Button: 5 (Power), "
+ "Mode: 1 (Cool), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 6 (UNKNOWN), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t result, prev;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &result, &prev));
@@ -1245,9 +1368,10 @@ TEST(TestHaierAC176Class, BuildKnownState) {
ac.setFan(kHaierAcYrw02FanHigh);
EXPECT_TRUE(ac.validChecksum(ac.getRaw()));
EXPECT_EQ(
- "Power: On, Button: 4 (Fan), Mode: 4 (Heat), Temp: 24C, Fan: 1 (High), "
- "Turbo: 0 (Off), Swing: 0 (Off), Sleep: Off, Health: On, "
- "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
+ "Model: 1 (V9014557-A), Power: On, Button: 4 (Fan), "
+ "Mode: 4 (Heat), Temp: 24C, Fan: 1 (High), Turbo: Off, Quiet: Off, "
+ "Swing(V): 0 (Off), Swing(H): 0 (Middle), Sleep: Off, Health: On, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
/* Disabled pending:
https://github.com/crankyoldgit/IRremoteESP8266/issues/1480#issuecomment-885636790
@@ -1323,56 +1447,91 @@ TEST(TestHaierAC176Class, Timers) {
// Real data.
// Ref: https://github.com/crankyoldgit/IRremoteESP8266/issues/1480#issuecomment-894804106
- const uint8_t timer30m[22] = {
+ const uint8_t timer30m[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0x40, 0x00, 0xA0, 0x00, 0x00, 0x1E, 0x00, 0x00,
0x00, 0x10, 0x36, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
- const uint8_t timeroff[22] = {
+ const uint8_t timeroff[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0x00, 0x40, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x10, 0x18, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
// https://docs.google.com/spreadsheets/d/1wdOVS08wgK2pEP7hTZLYMmrQ9FZVmLpZF2HjNQaVxlU/edit#gid=0&range=A65
- const uint8_t timeroffthenon[22] = {
+ const uint8_t timeroffthenon[kHaierAC176StateLength] = {
0xA6, 0x82, 0x00, 0xA0, 0x40, 0xA0, 0x1E, 0x08, 0x00, 0x00, 0x00,
0x00, 0x10, 0xDE, 0xB7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB7};
ac.setRaw(timer30m);
EXPECT_EQ(kHaierAcYrw02OnTimer, ac.getTimerMode());
EXPECT_EQ(
- "Power: Off, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 2 (On), On Timer: 00:30, Off Timer: Off",
+ "Model: 1 (V9014557-A), Power: Off, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 2 (On), On Timer: 00:30, Off Timer: Off, Lock: Off",
ac.toString());
ac.setRaw(timeroff);
EXPECT_EQ(kHaierAcYrw02NoTimers, ac.getTimerMode());
EXPECT_EQ(
- "Power: On, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
+ "Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
ac.setRaw(timeroffthenon);
EXPECT_EQ(
- "Power: On, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 5 (Off-On), On Timer: 08:00, Off Timer: 00:30",
+ "Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 5 (Off-On), On Timer: 08:00, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02OnThenOffTimer);
EXPECT_EQ(
- "Power: On, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 4 (On-Off), On Timer: 08:00, Off Timer: 00:30",
+ "Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 4 (On-Off), On Timer: 08:00, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02OffTimer);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(30, ac.getOffTimer());
EXPECT_EQ(
- "Power: On, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 1 (Off), On Timer: Off, Off Timer: 00:30",
+ "Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 1 (Off), On Timer: Off, Off Timer: 00:30, Lock: Off",
ac.toString());
ac.setTimerMode(kHaierAcYrw02NoTimers);
EXPECT_EQ(0, ac.getOnTimer());
EXPECT_EQ(0, ac.getOffTimer());
EXPECT_EQ(
- "Power: On, Button: 0 (Temp Up), Mode: 0 (Auto), Temp: 24C, "
- "Fan: 5 (Auto), Turbo: 0 (Off), Swing: 2 (Middle), Sleep: Off, "
- "Health: Off, Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off",
+ "Model: 1 (V9014557-A), Power: On, Button: 16 (Timer), "
+ "Mode: 0 (Auto), Temp: 24C, Fan: 5 (Auto), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
+ ac.toString());
+}
+
+TEST(TestHaierAC176Class, Models) {
+ IRHaierAC176 ac(kGpioUnused);
+ ac.begin();
+ EXPECT_EQ(haier_ac176_remote_model_t::V9014557_A, ac.getModel());
+
+ ac.setButton(kHaierAcYrw02ButtonTempUp);
+ ac.setModel(haier_ac176_remote_model_t::V9014557_B);
+ EXPECT_EQ(haier_ac176_remote_model_t::V9014557_B, ac.getModel());
+ EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
+
+ ac.setButton(kHaierAcYrw02ButtonTempDown);
+ ac.setModel(haier_ac176_remote_model_t::V9014557_A);
+ EXPECT_EQ(haier_ac176_remote_model_t::V9014557_A, ac.getModel());
+ EXPECT_EQ(kHaierAcYrw02ButtonCFAB, ac.getButton());
+
+ // Real data.
+ const uint8_t setmodelb[kHaierAC176StateLength] = {
+ 0x59, 0x82, 0x00, 0x00, 0x40, 0x60, 0x00, 0xC0, 0x00, 0x00, 0x00,
+ 0x00, 0x1A, 0x55, 0xB7, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x77};
+ ac.setRaw(setmodelb);
+ EXPECT_EQ(haier_ac176_remote_model_t::V9014557_B, ac.getModel());
+ EXPECT_EQ(
+ "Model: 2 (V9014557-B), Power: On, Button: 26 (Celsius/Fahrenheit), "
+ "Mode: 6 (Fan), Temp: 24C, Fan: 3 (Low), Turbo: Off, Quiet: Off, "
+ "Swing(V): 2 (Middle), Swing(H): 0 (Middle), Sleep: Off, Health: Off, "
+ "Timer Mode: 0 (N/A), On Timer: Off, Off Timer: Off, Lock: Off",
ac.toString());
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Mirage_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Mirage_test.cpp
index 2530afc5c..ad08918e2 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Mirage_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Mirage_test.cpp
@@ -1,5 +1,6 @@
-// Copyright 2020 David Conran
+// Copyright 2020-2021 David Conran
+#include "ir_Mirage.h"
#include "IRac.h"
#include "IRrecv.h"
#include "IRrecv_test.h"
@@ -11,7 +12,7 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ("MIRAGE", typeToString(decode_type_t::MIRAGE));
ASSERT_EQ(decode_type_t::MIRAGE, strToDecodeType("MIRAGE"));
ASSERT_TRUE(hasACState(decode_type_t::MIRAGE));
- ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::MIRAGE));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::MIRAGE));
ASSERT_EQ(kMirageBits, IRsend::defaultBits(decode_type_t::MIRAGE));
ASSERT_EQ(kMirageMinRepeat, IRsend::minRepeats(decode_type_t::MIRAGE));
}
@@ -55,7 +56,9 @@ TEST(TestDecodeMirage, RealExample) {
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "",
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
@@ -70,13 +73,14 @@ TEST(TestDecodeMirage, SyntheticExample) {
irsend.sendMirage(expected);
irsend.makeDecodeResult();
- ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_TRUE(irrecv.decode(&irsend.capture));
ASSERT_EQ(decode_type_t::MIRAGE, irsend.capture.decode_type);
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "",
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
@@ -119,6 +123,469 @@ TEST(TestDecodeMirage, RealExampleWithDodgyHardwareCapture) {
ASSERT_EQ(kMirageBits, irsend.capture.bits);
EXPECT_STATE_EQ(expected, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "",
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 0 (Off), Clock: 14:16",
IRAcUtils::resultAcToString(&irsend.capture));
}
+
+TEST(TestMirageAcClass, Power) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+
+ const uint8_t on[kMirageStateLength] = {
+ 0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x16, 0x14, 0x26};
+ ac.setRaw(on);
+ EXPECT_TRUE(ac.getPower());
+ const uint8_t off[kMirageStateLength] = {
+ 0x56, 0x6C, 0x00, 0x00, 0x21, 0xD8, 0x00, 0x00,
+ 0x0C, 0x00, 0x0C, 0x2C, 0x23, 0x01, 0x61};
+ ac.setRaw(off);
+ EXPECT_FALSE(ac.getPower());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+}
+
+TEST(TestMirageAcClass, OperatingMode) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setMode(kMirageAcCool);
+ EXPECT_EQ(kMirageAcCool, ac.getMode());
+ ac.setMode(kMirageAcHeat);
+ EXPECT_EQ(kMirageAcHeat, ac.getMode());
+ ac.setMode(kMirageAcDry);
+ EXPECT_EQ(kMirageAcDry, ac.getMode());
+ ac.setMode(kMirageAcFan);
+ EXPECT_EQ(kMirageAcFan, ac.getMode());
+ ac.setMode(kMirageAcRecycle);
+ EXPECT_EQ(kMirageAcRecycle, ac.getMode());
+ ac.setMode(255);
+ EXPECT_EQ(kMirageAcCool, ac.getMode());
+}
+
+TEST(TestMirageAcClass, HumanReadable) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ // Tests for the KKG9AC1 model.
+ EXPECT_EQ(
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 13 (Auto), Clock: 00:00",
+ ac.toString());
+ // Ref: https://docs.google.com/spreadsheets/d/1Ucu9mOOIIJoWQjUJq_VCvwgV3EwKaRk8K2AuZgccYEk/edit#gid=0&range=C7
+ // 0x56710000201A00000C000C26010041
+ const uint8_t cool_21c_auto[kMirageStateLength] = {
+ 0x56, 0x71, 0x00, 0x00, 0x20, 0x1A, 0x00, 0x00,
+ 0x0C, 0x00, 0x0C, 0x26, 0x01, 0x00, 0x41};
+ ac.setRaw(cool_21c_auto);
+ EXPECT_EQ(
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 21C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 13 (Auto), Clock: 00:01",
+ ac.toString());
+
+ const uint8_t SyntheticExample[kMirageStateLength] = {
+ 0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0x14, 0x26};
+ ac.setRaw(SyntheticExample);
+ EXPECT_EQ(
+ "Model: 1 (KKG9AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Light: Off, "
+ "Swing(V): 0 (Off), Clock: 14:16",
+ ac.toString());
+
+ // Tests for the KKG29AC1 model.
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ EXPECT_EQ(
+ "Model: 2 (KKG29AC1), Power: On, Mode: 2 (Cool), Temp: 25C, "
+ "Fan: 0 (Auto), Turbo: Off, Sleep: Off, Quiet: Off, Light: -, "
+ "Swing(V): Off, Swing(H): Off, "
+ "Filter: Off, Clean: -, On Timer: Off, Off Timer: Off, "
+ "IFeel: Off",
+ ac.toString());
+}
+
+TEST(TestMirageAcClass, Temperature) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setTemp(0);
+ EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
+
+ ac.setTemp(kMirageAcMinTemp);
+ EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
+
+ ac.setTemp(kMirageAcMaxTemp);
+ EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
+
+ ac.setTemp(kMirageAcMinTemp - 1);
+ EXPECT_EQ(kMirageAcMinTemp, ac.getTemp());
+
+ ac.setTemp(kMirageAcMaxTemp + 1);
+ EXPECT_EQ(kMirageAcMaxTemp, ac.getTemp());
+
+ ac.setTemp(17);
+ EXPECT_EQ(17, ac.getTemp());
+
+ ac.setTemp(21);
+ EXPECT_EQ(21, ac.getTemp());
+
+ ac.setTemp(25);
+ EXPECT_EQ(25, ac.getTemp());
+
+ ac.setTemp(30);
+ EXPECT_EQ(30, ac.getTemp());
+}
+
+TEST(TestMirageAcClass, FanSpeed) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setFan(kMirageAcFanAuto);
+ EXPECT_EQ(kMirageAcFanAuto, ac.getFan());
+ ac.setFan(kMirageAcFanLow);
+ EXPECT_EQ(kMirageAcFanLow, ac.getFan());
+ ac.setFan(kMirageAcFanMed);
+ EXPECT_EQ(kMirageAcFanMed, ac.getFan());
+ ac.setFan(kMirageAcFanHigh);
+ EXPECT_EQ(kMirageAcFanHigh, ac.getFan());
+
+ ac.setFan(255);
+ EXPECT_EQ(kMirageAcFanAuto, ac.getFan());
+}
+
+TEST(TestMirageAcClass, Turbo) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+ ac.setTurbo(false);
+ EXPECT_FALSE(ac.getTurbo());
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+ ac.setTurbo(false);
+ EXPECT_FALSE(ac.getTurbo());
+ ac.setTurbo(true);
+ EXPECT_TRUE(ac.getTurbo());
+}
+
+TEST(TestMirageAcClass, Light) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.setLight(true);
+ EXPECT_TRUE(ac.getLight());
+ ac.setLight(false);
+ EXPECT_FALSE(ac.getLight());
+ ac.setLight(true);
+ EXPECT_TRUE(ac.getLight());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.setLight(true);
+ EXPECT_TRUE(ac.getLight());
+ ac.setLight(false);
+ EXPECT_FALSE(ac.getLight());
+ ac.setLight(true);
+ EXPECT_TRUE(ac.getLight());
+}
+
+TEST(TestMirageAcClass, Sleep) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+ ac.setSleep(false);
+ EXPECT_FALSE(ac.getSleep());
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+ ac.setSleep(false);
+ EXPECT_FALSE(ac.getSleep());
+ ac.setSleep(true);
+ EXPECT_TRUE(ac.getSleep());
+}
+
+TEST(TestMirageAcClass, Clock) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // This model supports time.
+ ac.setClock(0);
+ EXPECT_EQ(0, ac.getClock());
+ ac.setClock(12 * 60 * 60 + 30 * 60 + 59); // aka. 12:30:59
+ EXPECT_EQ(12 * 60 * 60 + 30 * 60 + 59, ac.getClock());
+ ac.setClock(23 * 60 * 60 + 59 * 60 + 59); // aka. 23:59:59
+ EXPECT_EQ(23 * 60 * 60 + 59 * 60 + 59, ac.getClock());
+ ac.setClock(24 * 60 * 60); // aka. 24:00:00
+ EXPECT_EQ(23 * 60 * 60 + 59 * 60 + 59, ac.getClock()); // aka. 23:59:59
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // This model has no clock.
+ EXPECT_EQ(0, ac.getClock());
+ ac.setClock(12 * 60 * 60 + 30 * 60 + 59); // aka. 12:30:59
+ EXPECT_EQ(0, ac.getClock());
+}
+
+TEST(TestMirageAcClass, Checksums) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ const uint8_t SyntheticExample[kMirageStateLength] = {
+ 0x56, 0x75, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x16, 0x14, 0x26};
+ EXPECT_TRUE(IRMirageAc::validChecksum(SyntheticExample));
+ EXPECT_EQ(0x26, IRMirageAc::calculateChecksum(SyntheticExample));
+}
+
+TEST(TestMirageAcClass, SwingV) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ // Set the model to one with full swingv support.
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+
+ ac.setSwingV(kMirageAcSwingVAuto);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+
+ ac.setSwingV(kMirageAcSwingVHigh);
+ EXPECT_EQ(kMirageAcSwingVHigh, ac.getSwingV());
+
+ ac.setSwingV(0xFF);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+
+ ac.setSwingV(kMirageAcSwingVLowest);
+ EXPECT_EQ(kMirageAcSwingVLowest, ac.getSwingV());
+
+ ac.setSwingV(kMirageAcSwingVLowest - 1);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+
+ // Set the model to one with limited swingv support.
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+
+ ac.setSwingV(kMirageAcSwingVAuto);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+ ac.setSwingV(kMirageAcSwingVOff);
+ EXPECT_EQ(kMirageAcSwingVOff, ac.getSwingV());
+ ac.setSwingV(kMirageAcSwingVHigh);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+ ac.setSwingV(0xFF);
+ EXPECT_EQ(kMirageAcSwingVAuto, ac.getSwingV());
+ ac.setSwingV(kMirageAcSwingVOff);
+ EXPECT_EQ(kMirageAcSwingVOff, ac.getSwingV());
+}
+
+TEST(TestMirageAcClass, SwingH) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.setSwingH(true);
+ EXPECT_FALSE(ac.getSwingH());
+ ac.setSwingH(false);
+ EXPECT_FALSE(ac.getSwingH());
+ ac.setSwingH(true);
+ EXPECT_FALSE(ac.getSwingH());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.setSwingH(true);
+ EXPECT_TRUE(ac.getSwingH());
+ ac.setSwingH(false);
+ EXPECT_FALSE(ac.getSwingH());
+ ac.setSwingH(true);
+ EXPECT_TRUE(ac.getSwingH());
+}
+
+TEST(TestMirageAcClass, Filter) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No Support
+ ac.setFilter(true);
+ EXPECT_FALSE(ac.getFilter());
+ ac.setFilter(false);
+ EXPECT_FALSE(ac.getFilter());
+ ac.setFilter(true);
+ EXPECT_FALSE(ac.getFilter());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
+ ac.setFilter(true);
+ EXPECT_TRUE(ac.getFilter());
+ ac.setFilter(false);
+ EXPECT_FALSE(ac.getFilter());
+ ac.setFilter(true);
+ EXPECT_TRUE(ac.getFilter());
+}
+
+TEST(TestMirageAcClass, Quiet) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No Support
+ ac.setQuiet(true);
+ EXPECT_FALSE(ac.getQuiet());
+ ac.setQuiet(false);
+ EXPECT_FALSE(ac.getQuiet());
+ ac.setQuiet(true);
+ EXPECT_FALSE(ac.getQuiet());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
+ ac.setQuiet(true);
+ EXPECT_TRUE(ac.getQuiet());
+ ac.setQuiet(false);
+ EXPECT_FALSE(ac.getQuiet());
+ ac.setQuiet(true);
+ EXPECT_TRUE(ac.getQuiet());
+}
+
+TEST(TestMirageAcClass, CleanToggle) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1);
+ ac.setCleanToggle(true);
+ EXPECT_FALSE(ac.getCleanToggle());
+ ac.setCleanToggle(false);
+ EXPECT_FALSE(ac.getCleanToggle());
+ ac.setCleanToggle(true);
+ EXPECT_FALSE(ac.getCleanToggle());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1);
+ ac.setCleanToggle(true);
+ EXPECT_TRUE(ac.getCleanToggle());
+ ac.setCleanToggle(false);
+ EXPECT_FALSE(ac.getCleanToggle());
+ ac.setCleanToggle(true);
+ EXPECT_TRUE(ac.getCleanToggle());
+ ac.send(); // Should be reset when sent.
+ EXPECT_FALSE(ac.getCleanToggle());
+}
+
+TEST(TestMirageAcClass, Timers) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No timer support
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+ ac.setOnTimer(12 * 60 + 37); // 12:37
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+ ac.setOffTimer(17 * 60 + 5); // 17:05
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Timer supported
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(12 * 60 + 37); // 12:37
+ EXPECT_EQ(12 * 60 + 37, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOffTimer(17 * 60 + 5); // 17:05
+ EXPECT_EQ(17 * 60 + 5, ac.getOffTimer());
+ EXPECT_EQ(12 * 60 + 37, ac.getOnTimer());
+ ac.setOnTimer(0); // Off/Disabled
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(17 * 60 + 5, ac.getOffTimer());
+ ac.setOffTimer(0); // Off/Disabled
+ EXPECT_EQ(0, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ ac.setOnTimer(12 * 60 + 37); // 12:37
+ ac.setOffTimer(17 * 60 + 5); // 17:05
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No timer support
+ EXPECT_EQ(0, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+}
+
+TEST(TestMirageAcClass, IFeelAndSensorTemp) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+
+ ac.setModel(mirage_ac_remote_model_t::KKG9AC1); // No support
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(0, ac.getSensorTemp());
+ ac.setIFeel(true);
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(0, ac.getSensorTemp());
+ ac.setSensorTemp(20); // 20C
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(0, ac.getSensorTemp());
+
+ ac.setModel(mirage_ac_remote_model_t::KKG29AC1); // Supported
+ EXPECT_FALSE(ac.getIFeel());
+ EXPECT_EQ(0, ac.getSensorTemp());
+ ac.setIFeel(true);
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(0, ac.getSensorTemp());
+ ac.setSensorTemp(25); // 25C
+ EXPECT_TRUE(ac.getIFeel());
+ EXPECT_EQ(25, ac.getSensorTemp());
+ ac.setIFeel(false);
+ EXPECT_FALSE(ac.getIFeel());
+}
+
+TEST(TestMirageAcClass, getModel) {
+ IRMirageAc ac(kGpioUnused);
+ ac.begin();
+ const uint8_t KKG9AC1[kMirageStateLength] = {
+ 0x56, 0x6C, 0x00, 0x00, 0x20, 0xD8, 0x00, 0x00,
+ 0x0C, 0x32, 0x0B, 0x00, 0x32, 0x0F, 0x64};
+ EXPECT_EQ(mirage_ac_remote_model_t::KKG9AC1, IRMirageAc::getModel(KKG9AC1));
+
+ // https://github.com/crankyoldgit/IRremoteESP8266/issues/1573#issuecomment-955722044
+ const uint8_t KKG29AC1[kMirageStateLength] = {
+ 0x56, 0x74, 0x00, 0x00, 0x12, 0x00, 0x40, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D};
+ EXPECT_EQ(mirage_ac_remote_model_t::KKG29AC1, IRMirageAc::getModel(KKG29AC1));
+
+ // https://github.com/crankyoldgit/IRremoteESP8266/issues/1573#issuecomment-962362540
+ const uint8_t KKG29AC1_2[kMirageStateLength] = {
+ 0x56, 0x72, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x19};
+ EXPECT_EQ(mirage_ac_remote_model_t::KKG29AC1,
+ IRMirageAc::getModel(KKG29AC1_2));
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Rhoss_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Rhoss_test.cpp
new file mode 100644
index 000000000..855b9a48c
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Rhoss_test.cpp
@@ -0,0 +1,396 @@
+// Copyright 2021 Tom Rosenback
+
+#include "IRac.h"
+#include "ir_Rhoss.h"
+#include "IRrecv.h"
+#include "IRrecv_test.h"
+#include "IRsend.h"
+#include "IRsend_test.h"
+#include "IRutils.h"
+#include "gtest/gtest.h"
+
+TEST(TestUtils, Housekeeping) {
+ ASSERT_EQ("RHOSS", typeToString(decode_type_t::RHOSS));
+ ASSERT_EQ(decode_type_t::RHOSS, strToDecodeType("RHOSS"));
+ ASSERT_TRUE(hasACState(decode_type_t::RHOSS));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::RHOSS));
+}
+
+// Test sending typical data only.
+TEST(TestSendRhoss, SendDataOnly) {
+ IRsendTest irsend(kGpioUnused);
+ irsend.begin();
+
+ uint8_t expectedState[kRhossStateLength] = {
+ 0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
+
+ irsend.reset();
+ irsend.sendRhoss(expectedState);
+
+ EXPECT_EQ(
+ "f38000d50"
+ "m3042s4248"
+ "m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
+ "m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
+ "m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
+ "m648s457m648"
+ "s100000",
+ irsend.outputStr());
+}
+
+// Test send typical data with repeats
+TEST(TestSendRhoss, SendWithRepeats) {
+ IRsendTest irsend(kGpioUnused);
+ irsend.begin();
+
+ irsend.reset();
+
+uint8_t expectedState[kRhossStateLength] = {
+ 0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
+
+ irsend.sendRhoss(expectedState, kRhossStateLength, 0); // 0 repeats.
+ EXPECT_EQ(
+ "f38000d50"
+ "m3042s4248"
+ "m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
+ "m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
+ "m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
+ "m648s457m648"
+ "s100000",
+ irsend.outputStr());
+
+ irsend.sendRhoss(expectedState, kRhossStateLength, 2); // 2 repeats.
+ EXPECT_EQ(
+ "f38000d50"
+ "m3042s4248"
+ "m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
+ "m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
+ "m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
+ "m648s457m648"
+ "s100000"
+ "m3042s4248"
+ "m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
+ "m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
+ "m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
+ "m648s457m648"
+ "s100000"
+ "m3042s4248"
+ "m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457m648s1545"
+ "m648s1545m648s457m648s1545m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s1545m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s1545"
+ "m648s457m648s457m648s1545m648s457m648s1545m648s457m648s1545m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s457m648s457m648s457m648s457m648s457m648s457m648s457m648s457"
+ "m648s1545m648s1545m648s457m648s457m648s1545m648s1545m648s457m648s457"
+ "m648s457m648"
+ "s100000",
+ irsend.outputStr());
+}
+
+// Test send raw data
+TEST(TestSendRhoss, RawData) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ irsend.begin();
+ irsend.reset();
+
+ // Power on, mode cool, temp 20, fan auto, swing off
+ const uint16_t rawData[197] = {
+ 3044, 4248,
+ 648, 458, 650, 1540, 646, 458, 650, 1538,
+ 650, 458, 650, 1538, 650, 458, 650, 1540, // byte 0
+ 648, 458, 650, 458, 650, 1540, 646, 484,
+ 624, 456, 650, 456, 650, 456, 650, 456, // byte 1
+ 650, 456, 650, 456, 650, 456, 650, 456,
+ 650, 458, 650, 1540, 650, 1538, 650, 456, // byte 2
+ 650, 456, 650, 456, 650, 456, 650, 458,
+ 650, 456, 650, 456, 650, 456, 650, 458, // byte 3
+ 650, 458, 650, 456, 650, 458, 650, 458,
+ 650, 458, 650, 1538, 650, 458, 650, 458, // byte 4
+ 650, 458, 648, 458, 674, 434, 648, 458,
+ 672, 434, 648, 458, 650, 458, 648, 1540, // byte 5
+ 672, 434, 650, 458, 672, 1518, 644, 488,
+ 622, 1540, 644, 464, 672, 1516, 672, 434, // byte 6
+ 672, 434, 672, 434, 650, 458, 648, 458,
+ 672, 434, 674, 434, 672, 434, 650, 458, // byte 7
+ 672, 434, 648, 458, 650, 458, 672, 434,
+ 672, 436, 648, 458, 648, 456, 650, 458, // byte 8
+ 650, 458, 650, 456, 674, 434, 650, 458,
+ 650, 456, 650, 458, 674, 432, 650, 458, // byte 9
+ 650, 456, 650, 456, 650, 458, 648, 458,
+ 674, 432, 650, 456, 674, 434, 650, 458, // byte 10
+ 650, 458, 650, 1538, 650, 458, 650, 458,
+ 650, 456, 650, 458, 650, 456, 650, 458, // byte 11
+ 650, 456,
+ 650 }; // UNKNOWN 93E7BDB2
+
+ irsend.sendRaw(rawData, 197, 38);
+ irsend.makeDecodeResult();
+
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ ASSERT_EQ(RHOSS, irsend.capture.decode_type);
+ EXPECT_EQ(kRhossBits, irsend.capture.bits);
+
+ uint8_t expected[kRhossStateLength] = {
+ 0xAA, 0x04, 0x60, 0x00, 0x20, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x02 };
+ EXPECT_STATE_EQ(expected, irsend.capture.state, kRhossBits);
+
+ EXPECT_EQ(
+ "Power: On, Mode: 2 (Cool), Temp: 20C, Fan: 0 (Auto), Swing(V): Off",
+ IRAcUtils::resultAcToString(&irsend.capture));
+
+ stdAc::state_t r, p;
+ ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
+}
+
+// Test synthetic decode
+TEST(TestDecodeRhoss, SyntheticSelfDecode) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(0);
+ IRRhossAc ac(0);
+
+ uint8_t expectedState[kRhossStateLength] = {
+ 0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRhoss(expectedState);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(irrecv.decode(&irsend.capture));
+ EXPECT_EQ(RHOSS, irsend.capture.decode_type);
+ EXPECT_EQ(kRhossBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+ ac.setRaw(irsend.capture.state);
+ EXPECT_EQ(
+ "Power: On, Mode: 5 (Auto), Temp: 21C, Fan: 0 (Auto), Swing(V): Off",
+ ac.toString());
+}
+
+// Test strict decoding
+TEST(TestDecodeRhoss, StrictDecode) {
+ IRsendTest irsend(kGpioUnused);
+ IRrecv irrecv(0);
+ IRRhossAc ac(0);
+
+ uint8_t expectedState[kRhossStateLength] = {
+ 0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
+
+ irsend.begin();
+ irsend.reset();
+ irsend.sendRhoss(expectedState);
+ irsend.makeDecodeResult();
+ ASSERT_TRUE(
+ irrecv.decodeRhoss(&irsend.capture,
+ kStartOffset, kRhossBits, true));
+ EXPECT_EQ(RHOSS, irsend.capture.decode_type);
+ EXPECT_EQ(kRhossBits, irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
+ ac.setRaw(irsend.capture.state);
+ EXPECT_EQ(
+ "Power: On, Mode: 5 (Auto), Temp: 21C, Fan: 0 (Auto), Swing(V): Off",
+ ac.toString());
+}
+
+// Tests for IRRhossAc class.
+
+TEST(TestRhossAcClass, Power) {
+ IRRhossAc ac(0);
+ ac.begin();
+
+ ac.on();
+ EXPECT_TRUE(ac.getPower());
+
+ ac.off();
+ EXPECT_FALSE(ac.getPower());
+
+ ac.setPower(true);
+ EXPECT_TRUE(ac.getPower());
+
+ ac.setPower(false);
+ EXPECT_FALSE(ac.getPower());
+}
+
+TEST(TestRhossAcClass, Temperature) {
+ IRRhossAc ac(0);
+ ac.begin();
+
+ ac.setTemp(0);
+ EXPECT_EQ(kRhossTempMin, ac.getTemp());
+
+ ac.setTemp(255);
+ EXPECT_EQ(kRhossTempMax, ac.getTemp());
+
+ ac.setTemp(kRhossTempMin);
+ EXPECT_EQ(kRhossTempMin, ac.getTemp());
+
+ ac.setTemp(kRhossTempMax);
+ EXPECT_EQ(kRhossTempMax, ac.getTemp());
+
+ ac.setTemp(kRhossTempMin - 1);
+ EXPECT_EQ(kRhossTempMin, ac.getTemp());
+
+ ac.setTemp(kRhossTempMax + 1);
+ EXPECT_EQ(kRhossTempMax, ac.getTemp());
+
+ ac.setTemp(17);
+ EXPECT_EQ(17, ac.getTemp());
+
+ ac.setTemp(21);
+ EXPECT_EQ(21, ac.getTemp());
+
+ ac.setTemp(25);
+ EXPECT_EQ(25, ac.getTemp());
+
+ ac.setTemp(29);
+ EXPECT_EQ(29, ac.getTemp());
+}
+
+
+TEST(TestRhossAcClass, OperatingMode) {
+ IRRhossAc ac(0);
+ ac.begin();
+
+ ac.setMode(kRhossModeAuto);
+ EXPECT_EQ(kRhossModeAuto, ac.getMode());
+
+ ac.setMode(kRhossModeCool);
+ EXPECT_EQ(kRhossModeCool, ac.getMode());
+
+ ac.setMode(kRhossModeHeat);
+ EXPECT_EQ(kRhossModeHeat, ac.getMode());
+
+ ac.setMode(kRhossModeDry);
+ EXPECT_EQ(kRhossModeDry, ac.getMode());
+
+ ac.setMode(kRhossModeFan);
+ EXPECT_EQ(kRhossModeFan, ac.getMode());
+
+ ac.setMode(kRhossModeAuto + 1);
+ EXPECT_EQ(kRhossDefaultMode, ac.getMode());
+
+ ac.setMode(255);
+ EXPECT_EQ(kRhossDefaultMode, ac.getMode());
+}
+
+TEST(TestRhossAcClass, FanSpeed) {
+ IRRhossAc ac(0);
+ ac.begin();
+
+ ac.setFan(0);
+ EXPECT_EQ(kRhossFanAuto, ac.getFan());
+
+ ac.setFan(255);
+ EXPECT_EQ(kRhossFanAuto, ac.getFan());
+
+ ac.setFan(kRhossFanMax);
+ EXPECT_EQ(kRhossFanMax, ac.getFan());
+
+ ac.setFan(kRhossFanMax + 1);
+ EXPECT_EQ(kRhossFanAuto, ac.getFan());
+
+ ac.setFan(kRhossFanMax - 1);
+ EXPECT_EQ(kRhossFanMax - 1, ac.getFan());
+
+ ac.setFan(1);
+ EXPECT_EQ(1, ac.getFan());
+
+ ac.setFan(1);
+ EXPECT_EQ(1, ac.getFan());
+
+ ac.setFan(3);
+ EXPECT_EQ(3, ac.getFan());
+}
+
+TEST(TestRhossAcClass, Swing) {
+ IRRhossAc ac(0);
+ ac.begin();
+
+ ac.setSwing(false);
+ EXPECT_FALSE(ac.getSwing());
+
+ ac.setSwing(true);
+ EXPECT_TRUE(ac.getSwing());
+}
+
+TEST(TestRhossAcClass, Checksums) {
+ uint8_t state[kRhossStateLength] = {
+ 0xAA, 0x05, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x33 };
+
+ ASSERT_EQ(0x33, IRRhossAc::calcChecksum(state));
+ EXPECT_TRUE(IRRhossAc::validChecksum(state));
+ // Change the array so the checksum is invalid.
+ state[0] ^= 0xFF;
+ EXPECT_FALSE(IRRhossAc::validChecksum(state));
+ // Restore the previous change, and change another byte.
+ state[0] ^= 0xFF;
+ state[4] ^= 0xFF;
+ EXPECT_FALSE(IRRhossAc::validChecksum(state));
+ state[4] ^= 0xFF;
+ EXPECT_TRUE(IRRhossAc::validChecksum(state));
+
+ // Additional known good states.
+ uint8_t knownGood1[kRhossStateLength] = {
+ 0xAA, 0x06, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x34 };
+ EXPECT_TRUE(IRRhossAc::validChecksum(knownGood1));
+ ASSERT_EQ(0x34, IRRhossAc::calcChecksum(knownGood1));
+
+ uint8_t knownGood2[kRhossStateLength] = {
+ 0xAA, 0x07, 0x60, 0x00, 0x50, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x35 };
+ EXPECT_TRUE(IRRhossAc::validChecksum(knownGood2));
+ ASSERT_EQ(0x35, IRRhossAc::calcChecksum(knownGood2));
+
+ uint8_t knownGood3[kRhossStateLength] = {
+ 0xAA, 0x07, 0x60, 0x00, 0x53, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x38 };
+ EXPECT_TRUE(IRRhossAc::validChecksum(knownGood3));
+ ASSERT_EQ(0x38, IRRhossAc::calcChecksum(knownGood3));
+
+ // Validate calculation of checksum,
+ // same as knownGood3 except for the checksum.
+ uint8_t knownBad[kRhossStateLength] = {
+ 0xAA, 0x07, 0x60, 0x00, 0x53, 0x80, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00 };
+ EXPECT_FALSE(IRRhossAc::validChecksum(knownBad));
+ IRRhossAc ac(0);
+ ac.setRaw(knownBad);
+ EXPECT_STATE_EQ(knownGood3, ac.getRaw(), kRhossBits);
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Samsung_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Samsung_test.cpp
index a4e0503cd..061067421 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Samsung_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Samsung_test.cpp
@@ -426,16 +426,37 @@ TEST(TestIRSamsungAcClass, SetAndGetPower) {
TEST(TestIRSamsungAcClass, SetAndGetSwing) {
IRSamsungAc ac(kGpioUnused);
+
+ // Vertical
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
+ EXPECT_FALSE(ac.getSwingH());
ac.setSwing(false);
EXPECT_FALSE(ac.getSwing());
+ EXPECT_FALSE(ac.getSwingH());
ac.setSwing(true);
EXPECT_TRUE(ac.getSwing());
+ EXPECT_FALSE(ac.getSwingH());
+ // Horizontal
+ ac.setSwingH(true);
+ EXPECT_TRUE(ac.getSwing());
+ EXPECT_TRUE(ac.getSwingH());
+ ac.setSwingH(false);
+ EXPECT_TRUE(ac.getSwing());
+ EXPECT_FALSE(ac.getSwingH());
+ ac.setSwingH(true);
+ EXPECT_TRUE(ac.getSwing());
+ EXPECT_TRUE(ac.getSwingH());
+
+ ac.setSwing(false);
+ EXPECT_FALSE(ac.getSwing());
+ EXPECT_TRUE(ac.getSwingH());
+ ac.setSwingH(false);
+ EXPECT_FALSE(ac.getSwing());
+ EXPECT_FALSE(ac.getSwingH());
// Real examples from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/505#issuecomment-424036602
- // TODO(Hollako): Explain why state[9] lowest bit changes between on and off.
const uint8_t expected_off[kSamsungAcStateLength] = {
0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
0x01, 0xE2, 0xFE, 0x71, 0x80, 0x11, 0xF0};
@@ -576,14 +597,24 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_EQ(kSamsungAcFanTurbo, ac.getFan());
ac.setPowerful(false);
EXPECT_FALSE(ac.getPowerful());
- EXPECT_EQ(kSamsungAcFanAuto, ac.getFan());
- // Breeze and Powerful/Turbo are mutually exclusive.
+ // Breeze, Econo, and Powerful/Turbo are mutually exclusive.
ac.setPowerful(true);
EXPECT_TRUE(ac.getPowerful());
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_FALSE(ac.getEcono());
ac.setBreeze(true);
EXPECT_TRUE(ac.getBreeze());
EXPECT_FALSE(ac.getPowerful());
+ EXPECT_FALSE(ac.getEcono());
+ ac.setEcono(true);
+ EXPECT_TRUE(ac.getEcono());
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_FALSE(ac.getPowerful());
+ ac.setPowerful(true);
+ EXPECT_TRUE(ac.getPowerful());
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_FALSE(ac.getEcono());
// Actual powerful on & off states from:
// https://github.com/crankyoldgit/IRremoteESP8266/issues/734#issuecomment-500120270
@@ -594,9 +625,10 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_TRUE(ac.getPowerful());
EXPECT_EQ(kSamsungAcFanTurbo, ac.getFan());
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: On, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 7 (Turbo), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: On, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
uint8_t off[kSamsungAcStateLength] = {
@@ -606,9 +638,10 @@ TEST(TestIRSamsungAcClass, SetAndGetPowerful) {
EXPECT_FALSE(ac.getPowerful());
EXPECT_NE(kSamsungAcFanTurbo, ac.getFan());
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -633,6 +666,44 @@ TEST(TestIRSamsungAcClass, QuietAndPowerfulAreMutuallyExclusive) {
EXPECT_NE(kSamsungAcFanTurbo, ac.getFan());
}
+TEST(TestIRSamsungAcClass, SetAndGetEcono) {
+ IRSamsungAc ac(kGpioUnused);
+ ac.begin();
+ EXPECT_FALSE(ac.getEcono());
+ ac.setFan(kSamsungAcFanMed);
+ ac.setSwing(false);
+ ac.setEcono(true);
+ EXPECT_TRUE(ac.getEcono());
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_FALSE(ac.getPowerful());
+ EXPECT_TRUE(ac.getSwing()); // Econo turns on swingv.
+ EXPECT_EQ(kSamsungAcFanAuto, ac.getFan()); // And sets the fan to Auto.
+ ac.setEcono(false);
+ EXPECT_FALSE(ac.getEcono());
+ EXPECT_FALSE(ac.getBreeze());
+ EXPECT_FALSE(ac.getPowerful());
+
+ // Breeze, Econo, and Powerful/Turbo are mutually exclusive.
+ // But that is tested in `SetAndGetPowerful`
+
+ // Actual econo on state from:
+ // https://cryptpad.fr/sheet/#/2/sheet/view/r9k8pmELYEjLyC71cD7EsThEYgKGLJygREZ5pVfNkS8/
+ // Row: 33
+ uint8_t on[kSamsungAcStateLength] = {
+ 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
+ 0x01, 0xD2, 0xAE, 0x7F, 0x80, 0x11, 0xF0};
+ ac.setRaw(on, kSamsungAcStateLength);
+ EXPECT_TRUE(ac.getEcono());
+ EXPECT_TRUE(ac.getSwing());
+ EXPECT_EQ(kSamsungAcFanAuto, ac.getFan());
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), "
+ "Swing(V): On, Swing(H): Off, Beep: -, Clean: -, "
+ "Quiet: Off, Powerful: Off, Econo: On, Breeze: Off, "
+ "Light: On, Ion: Off",
+ ac.toString());
+}
+
TEST(TestIRSamsungAcClass, ChecksumCalculation) {
IRSamsungAc ac(kGpioUnused);
@@ -668,9 +739,10 @@ TEST(TestIRSamsungAcClass, ChecksumCalculation) {
TEST(TestIRSamsungAcClass, HumanReadable) {
IRSamsungAc ac(kGpioUnused);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), "
+ "Swing(V): On, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, Econo: Off, "
+ "Breeze: Off, Light: On, Ion: Off",
ac.toString());
ac.setTemp(kSamsungAcMaxTemp);
ac.setMode(kSamsungAcHeat);
@@ -680,28 +752,32 @@ TEST(TestIRSamsungAcClass, HumanReadable) {
ac.setBeep(true);
ac.setClean(true);
EXPECT_EQ(
- "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 5 (High), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 5 (High), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: Toggle, Clean: Toggle, Quiet: Off, Powerful: Off, Econo: Off, "
+ "Breeze: Off, Light: On, Ion: Off",
ac.toString());
ac.setQuiet(true);
EXPECT_EQ(
- "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), Swing: Off, "
- "Beep: On, Clean: On, Quiet: On, Powerful: Off, Breeze: Off, "
+ "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, Beep: Toggle, "
+ "Clean: Toggle, Quiet: On, Powerful: Off, Econo: Off, Breeze: Off, "
"Light: On, Ion: Off",
ac.toString());
ac.setQuiet(false);
ac.setPowerful(true);
EXPECT_EQ(
- "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: On, Breeze: Off, "
+ "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), "
+ "Swing(V): Off, Swing(H): Off, Beep: Toggle, "
+ "Clean: Toggle, Quiet: Off, Powerful: On, Econo: Off, Breeze: Off, "
"Light: On, Ion: Off",
ac.toString());
ac.setIon(true);
ac.setDisplay(false);
EXPECT_EQ(
- "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), Swing: Off, "
- "Beep: On, Clean: On, Quiet: Off, Powerful: On, Breeze: Off, "
+ "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 7 (Turbo), "
+ "Swing(V): Off, Swing(H): Off, Beep: Toggle, "
+ "Clean: Toggle, Quiet: Off, Powerful: On, Econo: Off, Breeze: Off, "
"Light: Off, Ion: On",
ac.toString());
}
@@ -802,9 +878,10 @@ TEST(TestDecodeSamsungAC, DecodeRealExample) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 2 (Low), "
+ "Swing(V): On, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -852,9 +929,10 @@ TEST(TestDecodeSamsungAC, DecodeRealExample2) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -912,9 +990,10 @@ TEST(TestDecodeSamsungAC, DecodePowerOnSample) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state, kSamsungAcExtendedStateLength);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -973,9 +1052,10 @@ TEST(TestDecodeSamsungAC, DecodePowerOffSample) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state, kSamsungAcExtendedStateLength);
EXPECT_EQ(
- "Power: Off, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: Off, Mode: 1 (Cool), Temp: 24C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -1021,9 +1101,10 @@ TEST(TestDecodeSamsungAC, DecodeHeatSample) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
- "Power: On, Mode: 4 (Heat), Temp: 17C, Fan: 0 (Auto), Swing: On, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 4 (Heat), Temp: 17C, Fan: 0 (Auto), "
+ "Swing(V): On, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -1066,9 +1147,10 @@ TEST(TestDecodeSamsungAC, DecodeCoolSample) {
EXPECT_EQ(kSamsungAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
@@ -1127,9 +1209,10 @@ TEST(TestDecodeSamsungAC, Issue604DecodeExtended) {
IRSamsungAc ac(kGpioUnused);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
- "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: Off, Mode: 4 (Heat), Temp: 30C, Fan: 0 (Auto), "
+ "Swing(V): On, Swing(H): On, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -1311,8 +1394,10 @@ TEST(TestIRSamsungAcClass, Issue604SendPowerHack) {
"m586s436m586s436m586s436m586s436m586s436m586s436m586s436m586s436"
"m586s2886";
std::string text = "Power: On, Mode: 1 (Cool), Temp: 23C, Fan: 4 (Med), "
- "Swing: On, Beep: Off, Clean: Off, Quiet: Off, "
- "Powerful: Off, Breeze: Off, Light: On, Ion: Off";
+ "Swing(V): On, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, "
+ "Powerful: Off, Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off";
// Don't do a setPower()/on()/off() as that will trigger the special message.
// So it should only be the normal "settings" message.
ac.setTemp(23);
@@ -1445,9 +1530,10 @@ TEST(TestDecodeSamsungAC, Issue734QuietSetting) {
IRSamsungAc ac(0);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: On, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
// Make sure the ac class state is in something wildly different first.
@@ -1468,9 +1554,10 @@ TEST(TestDecodeSamsungAC, Issue734QuietSetting) {
ac.setClean(false);
ac.setQuiet(true);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: On, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: On, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
// Check it matches the known good/expected state.
EXPECT_STATE_EQ(expectedState, ac.getRaw(), kSamsungAcBits);
@@ -1519,9 +1606,10 @@ TEST(TestDecodeSamsungAC, Issue734PowerfulOff) {
IRSamsungAc ac(0);
ac.setRaw(irsend.capture.state, irsend.capture.bits / 8);
EXPECT_EQ(
- "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 1 (Cool), Temp: 16C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -1553,9 +1641,10 @@ TEST(TestIRSamsungAcClass, SetAndGetBreeze) {
ac.setRaw(on);
ASSERT_TRUE(ac.getBreeze());
EXPECT_EQ(
- "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: On, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: On, Light: On, Ion: Off",
ac.toString());
// MODE FAN, 24C WINDFREE OFF, FAN = LOW
const uint8_t off[14] = {
@@ -1564,9 +1653,10 @@ TEST(TestIRSamsungAcClass, SetAndGetBreeze) {
ac.setRaw(off);
ASSERT_FALSE(ac.getBreeze());
EXPECT_EQ(
- "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 2 (Low), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: On, Ion: Off",
+ "Power: On, Mode: 3 (Fan), Temp: 24C, Fan: 2 (Low), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off",
ac.toString());
}
@@ -1614,9 +1704,10 @@ TEST(TestDecodeSamsungAC, Issue1227VeryPoorSignal) {
EXPECT_EQ(kSamsungAcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto), Swing: Off, "
- "Beep: Off, Clean: Off, Quiet: Off, Powerful: Off, Breeze: Off, "
- "Light: Off, Ion: Off",
+ "Power: On, Mode: 0 (Auto), Temp: 17C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: Off, Ion: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
@@ -1671,3 +1762,362 @@ TEST(TestIRSamsungAcClass, SectionChecksums) {
EXPECT_EQ(IRSamsungAc::getSectionChecksum(extended_off + 14),
IRSamsungAc::calcSectionChecksum(extended_off + 14));
}
+
+TEST(TestIRSamsungAcClass, Issue1648) {
+ IRSamsungAc ac(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ const uint8_t onState[kSamsungAcExtendedStateLength] = {
+ 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
+ 0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xC2, 0xFE, 0x71, 0x90, 0x15, 0xF0};
+ const String onText = "Power: On, Mode: 1 (Cool), Temp: 25C, Fan: 2 (Low), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, "
+ "Powerful: Off, Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off";
+ const uint8_t extended_offState[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0xE2, 0xFE, 0x71, 0x90, 0x15, 0xC0};
+ const uint8_t short_offState[kSamsungAcStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0xE2, 0xFE, 0x71, 0x90, 0x15, 0xC0};
+ const String offText = "Power: Off, Mode: 1 (Cool), Temp: 25C, Fan: 2 (Low), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, "
+ "Powerful: Off, Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off";
+ const uint8_t coolState[kSamsungAcStateLength] = {
+ 0x02, 0x92, 0x0F, 0x00, 0x00, 0x00, 0xF0,
+ 0x01, 0xC2, 0xFE, 0x71, 0x90, 0x15, 0xF0};
+
+ // "setup()"" from provided code.
+ ac.begin(); // User code
+ ac.off(); // User code
+ ac.setFan(kSamsungAcFanLow); // User code
+ ac.setMode(kSamsungAcCool); // User code
+ ac.setTemp(25); // User code
+ ac.setSwing(false); // User code
+
+ // Go through "loop()" from provided code.
+ for (uint8_t i = 0; i < 2; i++) {
+ ac.on(); // User code
+ ac.send(); // User code
+
+ // Verify what was sent.
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(onState, ac._irsend.capture.state, ac._irsend.capture.bits);
+ EXPECT_EQ(onText, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ EXPECT_TRUE(ac._lastsentpowerstate);
+ ac._irsend.reset();
+
+ ac.setMode(kSamsungAcCool); // User code
+ ac.send(); // User code
+
+ // Verify what was sent.
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(coolState, ac._irsend.capture.state,
+ ac._irsend.capture.bits);
+ EXPECT_EQ(onText, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ac._irsend.reset();
+ EXPECT_TRUE(ac._lastsentpowerstate);
+ EXPECT_FALSE(ac._forceextended);
+
+ ac.off(); // User code
+ ac.send(); // User code
+
+ // Verify what was sent.
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(extended_offState, ac._irsend.capture.state,
+ ac._irsend.capture.bits);
+ EXPECT_EQ(offText, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ EXPECT_FALSE(ac._lastsentpowerstate);
+ ac._irsend.reset();
+
+ ac.off(); // User code
+ ac.send(); // User code
+
+ // Verify what was sent.
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(short_offState, ac._irsend.capture.state,
+ ac._irsend.capture.bits);
+ EXPECT_EQ(offText, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ EXPECT_FALSE(ac._lastsentpowerstate);
+ ac._irsend.reset();
+ // End of "loop()" code.
+ }
+
+ // Data from https://github.com/crankyoldgit/IRremoteESP8266/issues/1648#issuecomment-950822399
+ const uint8_t expectedState[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0xD2, 0x0F, 0x00, 0x00, 0x00, 0x00,
+ 0x01, 0x12, 0xAF, 0x71, 0x80, 0x15, 0xC0};
+ const String expectedText = "Power: Off, Mode: 1 (Cool), Temp: 24C, "
+ "Fan: 2 (Low), Swing(V): On, Swing(H): Off, "
+ "Beep: -, Clean: -, "
+ "Quiet: Off, Powerful: Off, Econo: Off, "
+ "Breeze: Off, Light: On, Ion: Off";
+
+ ac.stateReset();
+ ac.setRaw(expectedState, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(expectedText, ac.toString());
+
+ // Try to generate the same message.
+ ac.stateReset();
+ ac.off();
+ ac.setMode(kSamsungAcCool);
+ ac.setTemp(24);
+ ac.setFan(kSamsungAcFanLow);
+ ac.setSwing(true);
+ ac.setBeep(false);
+ ac.setClean(false);
+ ac.setQuiet(false);
+ ac.setPowerful(false);
+ ac.setBreeze(false);
+ ac.setDisplay(true);
+ ac.setIon(false);
+ EXPECT_EQ(expectedText, ac.toString());
+
+ ac.send();
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, ac._irsend.capture.state,
+ ac._irsend.capture.bits);
+ EXPECT_EQ(expectedText, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ac._irsend.reset();
+}
+
+TEST(TestIRSamsungAcClass, Timers) {
+ IRSamsungAc ac(kGpioUnused);
+ ac.begin();
+
+ // https://github.com/crankyoldgit/IRremoteESP8266/issues/1277#issuecomment-961836703
+ const uint8_t on_timer_30m[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0xA2, 0x0F, 0x30, 0x00, 0x02, 0x00,
+ 0x01, 0x02, 0xFF, 0x71, 0x40, 0x11, 0xC0};
+ const uint8_t off_timer_1h_on_timer_10m[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0x92, 0x8F, 0x10, 0x00, 0x06, 0x00,
+ 0x01, 0x02, 0xFF, 0x71, 0x40, 0x11, 0xC0};
+ const uint8_t off_timer_1h_on_timer_0m[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0xA2, 0x8F, 0x00, 0x00, 0x06, 0x00,
+ 0x01, 0x02, 0xFF, 0x71, 0x40, 0x11, 0xC0};
+
+ ac.setRaw(on_timer_30m, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(
+ "Power: Off, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, Light: On, Ion: Off, On Timer: 00:30",
+ ac.toString());
+ ac.setRaw(off_timer_1h_on_timer_10m, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(
+ "Power: Off, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, On Timer: 00:10, Off Timer: 01:00",
+ ac.toString());
+ ac.setRaw(off_timer_1h_on_timer_0m, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(
+ "Power: Off, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, On Timer: 00:00, Off Timer: 01:00",
+ ac.toString());
+
+ // https://cryptpad.fr/sheet/#/2/sheet/view/r9k8pmELYEjLyC71cD7EsThEYgKGLJygREZ5pVfNkS8/
+ // Row 155
+ const uint8_t off_timer_11h_on_timer_6h[kSamsungAcExtendedStateLength] = {
+ 0x02, 0xB2, 0x0F, 0x00, 0x00, 0x00, 0xC0,
+ 0x01, 0x62, 0x8F, 0x05, 0x03, 0x06, 0x00,
+ 0x01, 0x02, 0xFF, 0x71, 0x40, 0x11, 0xC0};
+ ac.setRaw(off_timer_11h_on_timer_6h, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(
+ "Power: Off, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, On Timer: 06:00, Off Timer: 11:00",
+ ac.toString());
+
+ ac.stateReset(false);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(0);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOffTimer(0);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ // On Timer only
+ ac.setOnTimer(30);
+ EXPECT_EQ(30, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(90); // 1h30m
+ EXPECT_EQ(90, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(85); // 1h25m -> 1h20m
+ EXPECT_EQ(80, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(23 * 60 + 59); // 23:59
+ EXPECT_EQ(23 * 60 + 50, ac.getOnTimer()); // 23:50
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(24 * 60 + 30); // 24:30
+ EXPECT_EQ(24 * 60, ac.getOnTimer()); // 24:00 (Max)
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ // Off Timer only
+ ac.setOnTimer(0);
+ ac.setOffTimer(0);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOffTimer(30);
+ EXPECT_EQ(30, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ ac.setOffTimer(90); // 1h30m
+ EXPECT_EQ(90, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ ac.setOffTimer(85); // 1h25m -> 1h20m
+ EXPECT_EQ(80, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ ac.setOffTimer(23 * 60 + 59); // 23:59
+ EXPECT_EQ(23 * 60 + 50, ac.getOffTimer()); // 23:50
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ ac.setOffTimer(24 * 60 + 30); // 24:30
+ EXPECT_EQ(24 * 60, ac.getOffTimer()); // 24:00 (Max)
+ EXPECT_EQ(0, ac.getOnTimer());
+
+ // Both Timers
+ ac.setOnTimer(24 * 60); // 24:00
+ EXPECT_EQ(24 * 60, ac.getOnTimer()); // 24:00 (Max)
+ EXPECT_EQ(24 * 60, ac.getOffTimer()); // 24:00 (Max)
+
+ ac.setOnTimer(1 * 60 + 30); // 1:30
+ ac.setOffTimer(11 * 60); // 11:00
+ EXPECT_EQ(1 * 60 + 30, ac.getOnTimer());
+ EXPECT_EQ(11 * 60, ac.getOffTimer());
+}
+
+TEST(TestIRSamsungAcClass, Sleep) {
+ IRSamsungAc ac(kGpioUnused);
+ ac.begin();
+
+ // https://cryptpad.fr/sheet/#/2/sheet/view/r9k8pmELYEjLyC71cD7EsThEYgKGLJygREZ5pVfNkS8/
+ const uint8_t sleep_8h[kSamsungAcExtendedStateLength] = {
+ 0x02, 0x82, 0x0F, 0x00, 0x00, 0x10, 0xF0,
+ 0x01, 0xA2, 0x0F, 0x04, 0x00, 0x0C, 0x00,
+ 0x01, 0xE2, 0xFE, 0x71, 0x40, 0x11, 0xF0};
+ ac.setRaw(sleep_8h, kSamsungAcExtendedStateLength);
+ EXPECT_EQ(8 * 60, ac.getSleepTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(
+ "Power: On, Mode: 1 (Cool), Temp: 20C, Fan: 0 (Auto), "
+ "Swing(V): Off, Swing(H): Off, "
+ "Beep: -, Clean: -, Quiet: Off, Powerful: Off, "
+ "Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, Sleep Timer: 08:00",
+ ac.toString());
+
+ ac.stateReset(false);
+ EXPECT_EQ(0, ac.getSleepTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setOnTimer(60);
+ ac.setOffTimer(90);
+ EXPECT_EQ(0, ac.getSleepTimer());
+ EXPECT_EQ(60, ac.getOnTimer());
+ EXPECT_EQ(90, ac.getOffTimer());
+
+ ac.setSleepTimer(120);
+ EXPECT_EQ(120, ac.getSleepTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+
+ ac.setSleepTimer(24 * 60 + 31); // 24h31m
+ EXPECT_EQ(24 * 60, ac.getSleepTimer()); // 24h (Max)
+
+ ac.setSleepTimer(35); // 45m
+ EXPECT_EQ(30, ac.getSleepTimer()); // 30m (Only stored in 10m increments).
+
+ ac.setOnTimer(60); // Seting an On Timer should clear the sleep setting.
+ EXPECT_EQ(0, ac.getSleepTimer());
+ EXPECT_EQ(60, ac.getOnTimer());
+
+ ac.setSleepTimer(120);
+ ac.setOffTimer(90); // Setting an Off Timer will clear the sleep setting.
+ EXPECT_EQ(0, ac.getSleepTimer());
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(90, ac.getOffTimer());
+}
+
+TEST(TestIRSamsungAcClass, BuildKnownSleepSate) {
+ // For https://github.com/crankyoldgit/IRremoteESP8266/issues/1277#issuecomment-965047193
+ IRSamsungAc ac(kGpioUnused);
+ IRrecv irrecv(kGpioUnused);
+ ac.begin();
+ const uint8_t expectedState[kSamsungAcExtendedStateLength] = {
+ 0x02, 0x82, 0x0F, 0x00, 0x00, 0x10, 0xF0,
+ 0x01, 0xA2, 0x0F, 0x04, 0x00, 0x0C, 0x00,
+ 0x01, 0xD2, 0xFE, 0x71, 0x50, 0x41, 0xF0};
+ const char expectedStr[] = "Power: On, Mode: 4 (Heat), Temp: 21C, "
+ "Fan: 0 (Auto), Swing(V): Off, Swing(H): Off, Beep: -, Clean: -, "
+ "Quiet: Off, Powerful: Off, Econo: Off, Breeze: Off, "
+ "Light: On, Ion: Off, Sleep Timer: 08:00";
+ ac.setPower(true);
+ ac.setMode(kSamsungAcHeat);
+ ac.setTemp(21);
+ ac.setFan(kSamsungAcFanAuto);
+ ac.setSwing(false);
+ ac.setSwingH(false);
+ ac.setBeep(false);
+ ac.setClean(false);
+ ac.setQuiet(false);
+ ac.setPowerful(false);
+ ac.setEcono(false);
+ ac.setBreeze(false);
+ ac.setDisplay(true);
+ ac.setIon(false);
+ ac.setSleepTimer(8 * 60);
+ EXPECT_EQ(expectedStr, ac.toString());
+ ac.send();
+ ac._irsend.makeDecodeResult();
+ EXPECT_TRUE(irrecv.decode(&ac._irsend.capture));
+ EXPECT_EQ(SAMSUNG_AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kSamsungAcExtendedBits, ac._irsend.capture.bits);
+ EXPECT_STATE_EQ(expectedState, ac._irsend.capture.state,
+ ac._irsend.capture.bits);
+ EXPECT_EQ(expectedStr, IRAcUtils::resultAcToString(&ac._irsend.capture));
+ ac._irsend.reset();
+}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Sharp_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Sharp_test.cpp
index bf08c644a..a2acafb9c 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Sharp_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Sharp_test.cpp
@@ -410,8 +410,8 @@ TEST(TestDecodeSharpAc, RealExample) {
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 2 (Auto), "
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
IRAcUtils::resultAcToString(&irsend.capture));
stdAc::state_t r, p;
ASSERT_TRUE(IRAcUtils::decodeToState(&irsend.capture, &r, &p));
@@ -561,7 +561,7 @@ TEST(TestSharpAcClass, OperatingMode) {
// Check toString() says Fan rather than Auto.
EXPECT_EQ(
"Model: 2 (A705), Power: Off, Mode: 0 (Fan), Temp: 15C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Light: -, Clean: Off",
ac.toString());
}
@@ -615,8 +615,8 @@ TEST(TestSharpAcClass, ReconstructKnownState) {
EXPECT_STATE_EQ(on_auto_auto, ac.getRaw(), kSharpAcBits);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_auto_28[kSharpAcStateLength] = {
@@ -629,8 +629,8 @@ TEST(TestSharpAcClass, ReconstructKnownState) {
ac.setTemp(28);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
EXPECT_STATE_EQ(cool_auto_28, ac.getRaw(), kSharpAcBits);
}
@@ -647,8 +647,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(off_auto_auto);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), "
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t on_auto_auto[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0x00, 0x11, 0x20, 0x00, 0x08, 0x80, 0x00, 0xE0,
@@ -657,8 +657,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(on_auto_auto);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 0 (Auto), Temp: 15C, Fan: 2 (Auto), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_auto_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x22, 0x00, 0x08, 0x80, 0x04, 0xE0,
@@ -667,8 +667,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(cool_auto_28);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 2 (Auto), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_fan1_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x42, 0x00, 0x08, 0x80, 0x05, 0xE0,
@@ -677,8 +677,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(cool_fan1_28);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 4 (Low), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 4 (Low), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_fan2_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x32, 0x00, 0x08, 0x80, 0x05, 0xE0,
@@ -688,7 +688,7 @@ TEST(TestSharpAcClass, KnownStates) {
EXPECT_EQ(
"Model: 1 (A907), "
"Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 3 (Medium), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_fan3_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x52, 0x00, 0x08, 0x80, 0x05, 0xE0,
@@ -698,7 +698,7 @@ TEST(TestSharpAcClass, KnownStates) {
EXPECT_EQ(
"Model: 1 (A907), "
"Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 5 (UNKNOWN), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_fan4_28[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x31, 0x72, 0x00, 0x08, 0x80, 0x05, 0xE0,
@@ -707,8 +707,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(cool_fan4_28);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
uint8_t cool_fan4_28_ion_on[kSharpAcStateLength] = {
0xAA, 0x5A, 0xCF, 0x10, 0xCD, 0x61, 0x72, 0x08, 0x08, 0x80, 0x00, 0xE4,
@@ -717,8 +717,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(cool_fan4_28_ion_on);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: -, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: On, Econo: -, Clean: Off",
+ "Power: -, Mode: 2 (Cool), Temp: 28C, Fan: 7 (High), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: On, Econo: -, Clean: Off",
ac.toString());
/* Unsupported / Not yet reverse engineered.
uint8_t cool_fan4_28_eco1[kSharpAcStateLength] = {
@@ -735,8 +735,8 @@ TEST(TestSharpAcClass, KnownStates) {
ac.setRaw(dry_auto);
EXPECT_EQ(
"Model: 1 (A907), "
- "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
}
@@ -747,6 +747,7 @@ TEST(TestSharpAcClass, toCommon) {
ac.setMode(kSharpAcCool);
ac.setTemp(20);
ac.setFan(kSharpAcFanMax);
+ ac.setSwingV(kSharpAcSwingVOff);
// Now test it.
ASSERT_EQ(decode_type_t::SHARP_AC, ac.toCommon().protocol);
ASSERT_TRUE(ac.toCommon().power);
@@ -755,8 +756,8 @@ TEST(TestSharpAcClass, toCommon) {
ASSERT_EQ(stdAc::opmode_t::kCool, ac.toCommon().mode);
ASSERT_EQ(stdAc::fanspeed_t::kMax, ac.toCommon().fanspeed);
ASSERT_EQ(sharp_ac_remote_model_t::A705, ac.toCommon().model);
- // Unsupported.
ASSERT_EQ(stdAc::swingv_t::kOff, ac.toCommon().swingv);
+ // Unsupported.
ASSERT_EQ(stdAc::swingh_t::kOff, ac.toCommon().swingh);
ASSERT_FALSE(ac.toCommon().turbo);
ASSERT_FALSE(ac.toCommon().quiet);
@@ -868,20 +869,20 @@ TEST(TestSharpAcClass, Turbo) {
EXPECT_EQ(kSharpAcFanMax, ac.getFan());
EXPECT_EQ(
"Model: 3 (A903), "
- "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: On, "
- "Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off",
+ "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), "
+ "Swing(V): 0 (N/A), Turbo: On, Ion: On, Light: -, Clean: Off",
ac.toString());
ac.setRaw(off_state);
EXPECT_FALSE(ac.getTurbo());
EXPECT_EQ(
"Model: 3 (A903), "
- "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off",
+ "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), "
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: On, Light: -, Clean: Off",
ac.toString());
}
-TEST(TestSharpAcClass, SwingToggle) {
+TEST(TestSharpAcClass, Swings) {
IRSharpAc ac(kGpioUnused);
ac.begin();
@@ -906,6 +907,70 @@ TEST(TestSharpAcClass, SwingToggle) {
ac.setRaw(off_state);
EXPECT_FALSE(ac.getSwingToggle());
+
+ // Vertical
+ ac.setSwingV(kSharpAcSwingVToggle);
+ EXPECT_EQ(kSharpAcSwingVToggle, ac.getSwingV());
+ EXPECT_TRUE(ac.getSwingToggle());
+
+ ac.setSwingV(kSharpAcSwingVHigh);
+ EXPECT_EQ(kSharpAcSwingVHigh, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ ac.setSwingV(0xFF); // Doesn't change if invalid position given.
+ EXPECT_EQ(kSharpAcSwingVHigh, ac.getSwingV());
+
+ ac.setSwingV(kSharpAcSwingVMid);
+ EXPECT_EQ(kSharpAcSwingVMid, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ ac.setSwingV(kSharpAcSwingVLow);
+ EXPECT_EQ(kSharpAcSwingVLow, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ ac.setSwingV(kSharpAcSwingVIgnore);
+ EXPECT_EQ(kSharpAcSwingVIgnore, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+
+ // Lowest/Coanda only works in Heat mode.
+ ac.setMode(kSharpAcCool);
+ ac.setSwingV(kSharpAcSwingVLowest);
+ EXPECT_EQ(kSharpAcSwingVLow, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+ ac.setModel(sharp_ac_remote_model_t::A907); // Model A907 has heat mode.
+ ac.setMode(kSharpAcHeat);
+ EXPECT_EQ(kSharpAcHeat, ac.getMode());
+ ac.setSwingV(kSharpAcSwingVLowest);
+ EXPECT_EQ(kSharpAcSwingVLowest, ac.getSwingV());
+
+ // Check we can force Coanda in Cool mode.
+ ac.setMode(kSharpAcCool);
+ ASSERT_EQ(kSharpAcSwingVCoanda, kSharpAcSwingVLowest);
+ ac.setSwingV(kSharpAcSwingVCoanda, true);
+ EXPECT_EQ(kSharpAcSwingVCoanda, ac.getSwingV());
+ EXPECT_FALSE(ac.getSwingToggle());
+ EXPECT_EQ(kSharpAcCool, ac.getMode());
+
+ // Real messages/states
+ // ref: https://github.com/crankyoldgit/IRremoteESP8266/discussions/1590#discussioncomment-1254748
+ ac.stateReset();
+ const uint8_t coanda_heat_on[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC8, 0x31, 0x21,
+ 0x0A, 0x0E, 0x80, 0x06, 0xF4, 0x81};
+ ac.setRaw(coanda_heat_on);
+ EXPECT_EQ(
+ "Model: 3 (A903), Power: On, Mode: 1 (Heat), Temp: 23C, Fan: 2 (Auto), "
+ "Swing(V): 6 (Lowest), Turbo: Off, Ion: On, Light: -, Clean: Off",
+ ac.toString());
+
+ const uint8_t coanda_cool_on[13] = {
+ 0xAA, 0x5A, 0xCF, 0x10, 0xC7, 0x31, 0x22,
+ 0x0A, 0x0E, 0x80, 0x06, 0xF4, 0x41};
+ ac.setRaw(coanda_cool_on);
+ EXPECT_EQ(
+ "Model: 3 (A903), Power: On, Mode: 2 (Cool), Temp: 22C, Fan: 2 (Auto), "
+ "Swing(V): 6 (Highest), Turbo: Off, Ion: On, Light: -, Clean: Off",
+ ac.toString());
}
TEST(TestSharpAcClass, Ion) {
@@ -1005,8 +1070,8 @@ TEST(TestSharpAcClass, Timers) {
EXPECT_TRUE(ac.isPowerSpecial());
EXPECT_EQ(
"Model: 3 (A903), "
- "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Turbo: Off, "
- "Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off, Off Timer: 08:30",
+ "Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), Swing(V): 0 (N/A), "
+ "Turbo: Off, Ion: On, Light: -, Clean: Off, Off Timer: 08:30",
ac.toString());
// ref: https://docs.google.com/spreadsheets/d/1otzVFM5_tegrZ4ROCLgQ_jvJaWCDlZs1vC-YuR1FFXM/edit#gid=0&range=E80
@@ -1020,7 +1085,7 @@ TEST(TestSharpAcClass, Timers) {
EXPECT_TRUE(ac.isPowerSpecial());
EXPECT_EQ(
"Model: 3 (A903), Power: -, Mode: 2 (Cool), Temp: 21C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off, "
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: On, Light: -, Clean: Off, "
"On Timer: 12:00",
ac.toString());
}
@@ -1058,13 +1123,13 @@ TEST(TestSharpAcClass, Clean) {
EXPECT_TRUE(ac.getClean());
EXPECT_EQ(
"Model: 3 (A903), Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Light: -, Clean: On",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Light: -, Clean: On",
ac.toString());
ac.setRaw(clean_off_state);
EXPECT_FALSE(ac.getClean());
EXPECT_EQ(
"Model: 3 (A903), Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Light: -, Clean: Off",
ac.toString());
// Try constructing the clean on state.
@@ -1084,13 +1149,13 @@ TEST(TestSharpAcClass, Clean) {
ac.setPower(false);
EXPECT_EQ(
"Model: 1 (A907), Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
// Clean ON
ac.setClean(true);
EXPECT_EQ(
"Model: 1 (A907), Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: On",
ac.toString());
// Clean OFF (state is identical to `off_msg`).
// i.e. It just clears the clean settings & turns off the device.
@@ -1098,25 +1163,25 @@ TEST(TestSharpAcClass, Clean) {
ac.setPower(false, true);
EXPECT_EQ(
"Model: 1 (A907), Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
// Clean ON
ac.setClean(true);
EXPECT_EQ(
"Model: 1 (A907), Power: On, Mode: 3 (Dry), Temp: 15C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: On",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: On",
ac.toString());
// AC OFF
ac.off();
EXPECT_EQ(
"Model: 1 (A907), Power: Off, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
// AC ON (Mode Cool, Temp 25, Ion OFF, Fan 7)
ac.on();
EXPECT_EQ(
"Model: 1 (A907), Power: On, Mode: 2 (Cool), Temp: 25C, Fan: 7 (High), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
}
@@ -1126,7 +1191,7 @@ TEST(TestSharpAcClass, Issue1309) {
ac.stateReset();
EXPECT_EQ(
"Model: 1 (A907), Power: Off, Mode: 0 (Auto), Temp: 15C, Fan: 0 (UNKNOWN), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Econo: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Econo: -, Clean: Off",
ac.toString());
const uint8_t issue1309_on[13] = {
@@ -1135,7 +1200,7 @@ TEST(TestSharpAcClass, Issue1309) {
ac.setRaw(issue1309_on);
EXPECT_EQ(
"Model: 2 (A705), Power: On, Mode: 2 (Cool), Temp: 16C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Light: -, Clean: Off",
ac.toString());
EXPECT_STATE_EQ(issue1309_on, ac.getRaw(), kSharpAcBits);
@@ -1147,7 +1212,7 @@ TEST(TestSharpAcClass, Issue1309) {
ac.on();
EXPECT_EQ(
"Model: 2 (A705), Power: On, Mode: 2 (Cool), Temp: 16C, Fan: 2 (Auto), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: Off, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: Off, Light: -, Clean: Off",
ac.toString());
}
@@ -1200,13 +1265,13 @@ TEST(TestSharpAcClass, Issue1387Power) {
EXPECT_STATE_EQ(real_off, ac.getRaw(), kSharpAcBits);
EXPECT_EQ(
"Model: 3 (A903), Power: Off, Mode: 2 (Cool), Temp: 27C, Fan: 3 (Low), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: On, Light: -, Clean: Off",
ac.toString());
// Create the same off state.
ac.setPower(true, ac.getPower());
EXPECT_STATE_EQ(real_on, ac.getRaw(), kSharpAcBits);
EXPECT_EQ(
"Model: 3 (A903), Power: On, Mode: 2 (Cool), Temp: 27C, Fan: 3 (Low), "
- "Turbo: Off, Swing(V) Toggle: Off, Ion: On, Light: -, Clean: Off",
+ "Swing(V): 0 (N/A), Turbo: Off, Ion: On, Light: -, Clean: Off",
ac.toString());
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Tcl_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Tcl_test.cpp
index da3fefc8c..b7ab5301f 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Tcl_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Tcl_test.cpp
@@ -10,8 +10,18 @@
// General housekeeping
TEST(TestTcl112Ac, Housekeeping) {
- ASSERT_EQ("TCL112AC", typeToString(TCL112AC));
- ASSERT_TRUE(hasACState(TCL112AC));
+ ASSERT_EQ("TCL112AC", typeToString(decode_type_t::TCL112AC));
+ ASSERT_EQ(decode_type_t::TCL112AC, strToDecodeType("TCL112AC"));
+ ASSERT_TRUE(hasACState(decode_type_t::TCL112AC));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::TCL112AC));
+ ASSERT_EQ(kTcl112AcBits, IRsend::defaultBits(decode_type_t::TCL112AC));
+ ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::TCL112AC));
+ ASSERT_EQ(tcl_ac_remote_model_t::TAC09CHSD, IRac::strToModel("TAC09CHSD"));
+ ASSERT_EQ(irutils::modelToStr(decode_type_t::TCL112AC,
+ tcl_ac_remote_model_t::TAC09CHSD), "TAC09CHSD");
+ ASSERT_EQ(tcl_ac_remote_model_t::GZ055BE1, IRac::strToModel("GZ055BE1"));
+ ASSERT_EQ(irutils::modelToStr(decode_type_t::TCL112AC,
+ tcl_ac_remote_model_t::GZ055BE1), "GZ055BE1");
}
// Tests for decodeTcl112Ac().
@@ -63,9 +73,10 @@ TEST(TestDecodeTcl112Ac, DecodeRealExample) {
EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 24C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
}
@@ -106,27 +117,31 @@ TEST(TestTcl112AcClass, Temperature) {
IRTcl112Ac ac(kGpioUnused);
ac.setRaw(temp16C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
ac.setRaw(temp16point5C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 16.5C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16.5C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
ac.setRaw(temp19point5C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 19.5C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 19.5C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
ac.setRaw(temp31C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 31C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 31C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
ac.setTemp(kTcl112AcTempMin);
@@ -206,9 +221,10 @@ TEST(TestTcl112AcClass, OperatingMode) {
0x07, 0x00, 0x00, 0x00, 0x00, 0x80, 0x48};
ac.setRaw(automode);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 8 (Auto), Temp: 24C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 8 (Auto), Temp: 24C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
}
@@ -236,9 +252,10 @@ TEST(TestTcl112AcClass, Power) {
0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
ac.setRaw(on);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
const uint8_t off[kTcl112AcStateLength] = {
@@ -246,9 +263,10 @@ TEST(TestTcl112AcClass, Power) {
0x07, 0x40, 0x00, 0x00, 0x00, 0x80, 0xCB};
ac.setRaw(off);
EXPECT_EQ(
- "Type: 1, Power: Off, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: Off, Mode: 3 (Cool), Temp: 24C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
}
@@ -263,15 +281,17 @@ TEST(TestTcl112AcClass, Checksum) {
EXPECT_EQ(0xCB, ac.calcChecksum(temp16C));
ac.setRaw(temp16C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
ac.setRaw(temp31C);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 31C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 31C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
EXPECT_EQ(0xBC, ac.calcChecksum(temp31C));
@@ -337,12 +357,22 @@ TEST(TestTcl112AcClass, SwingVertical) {
IRTcl112Ac ac(kGpioUnused);
ac.begin();
- ac.setSwingVertical(true);
- EXPECT_TRUE(ac.getSwingVertical());
- ac.setSwingVertical(false);
- EXPECT_EQ(false, ac.getSwingVertical());
- ac.setSwingVertical(true);
- EXPECT_TRUE(ac.getSwingVertical());
+ ac.setSwingVertical(kTcl112AcSwingVOff);
+ EXPECT_EQ(kTcl112AcSwingVOff, ac.getSwingVertical());
+ ac.setSwingVertical(kTcl112AcSwingVOn);
+ EXPECT_EQ(kTcl112AcSwingVOn, ac.getSwingVertical());
+ ac.setSwingVertical(kTcl112AcSwingVHigh);
+ EXPECT_EQ(kTcl112AcSwingVHigh, ac.getSwingVertical());
+ ac.setSwingVertical(kTcl112AcSwingVOff);
+ EXPECT_EQ(kTcl112AcSwingVOff, ac.getSwingVertical());
+ ac.setSwingVertical(0xFF); // Unused value so shouldn't change from previous.
+ EXPECT_EQ(kTcl112AcSwingVOff, ac.getSwingVertical());
+
+ const uint8_t highest[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x08, 0x00, 0x00, 0x00, 0x00, 0x53};
+ ac.setRaw(highest);
+ EXPECT_EQ(kTcl112AcSwingVHighest, ac.getSwingVertical());
}
TEST(TestTcl112AcClass, Turbo) {
@@ -405,6 +435,7 @@ TEST(TestTcl112AcClass, Quiet_Mute) {
TEST(TestTcl112AcClass, toCommon) {
IRTcl112Ac ac(kGpioUnused);
+ ac.setModel(tcl_ac_remote_model_t::TAC09CHSD);
ac.setPower(true);
ac.setMode(kTcl112AcCool);
ac.setTemp(20);
@@ -418,7 +449,7 @@ TEST(TestTcl112AcClass, toCommon) {
ac.setQuiet(false);
// Now test it.
ASSERT_EQ(decode_type_t::TCL112AC, ac.toCommon().protocol);
- ASSERT_EQ(-1, ac.toCommon().model);
+ ASSERT_EQ(1, ac.toCommon().model);
ASSERT_TRUE(ac.toCommon().power);
ASSERT_TRUE(ac.toCommon().celsius);
ASSERT_EQ(20, ac.toCommon().degrees);
@@ -485,9 +516,10 @@ TEST(TestDecodeTcl112Ac, Issue744) {
IRTcl112Ac ac(kGpioUnused);
ac.setRaw(irsend.capture.state);
EXPECT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 23C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: On",
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 23C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: On, "
+ "On Timer: Off, Off Timer: Off",
ac.toString());
}
@@ -527,7 +559,7 @@ TEST(TestDecodeTcl112Ac, Issue1528) {
EXPECT_EQ(kTcl112AcBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "Type: 2, Quiet: On",
+ "Model: 1 (TAC09CHSD), Type: 2, Quiet: On",
IRAcUtils::resultAcToString(&irsend.capture));
}
@@ -536,7 +568,6 @@ TEST(TestTcl112AcClass, SendingQuiet) {
IRTcl112Ac ac(kGpioUnused);
IRrecv capture(kGpioUnused);
-
ac.begin();
ac.on();
ac.setTemp(24);
@@ -559,16 +590,116 @@ TEST(TestTcl112AcClass, SendingQuiet) {
ASSERT_EQ(TCL112AC, ac._irsend.capture.decode_type);
ASSERT_EQ(kTcl112AcBits, ac._irsend.capture.bits);
ASSERT_EQ(
- "Type: 2, Quiet: On",
+ "Model: 1 (TAC09CHSD), Type: 2, Quiet: On",
IRAcUtils::resultAcToString(&ac._irsend.capture));
// Second message.
// TCL112 uses the Mitsubishi112 decoder.
// Skip first message.
EXPECT_TRUE(capture.decodeMitsubishi112(&ac._irsend.capture, 229));
- ASSERT_EQ(TCL112AC, ac._irsend.capture.decode_type);
- ASSERT_EQ(kTcl112AcBits, ac._irsend.capture.bits);
+ EXPECT_EQ(TCL112AC, ac._irsend.capture.decode_type);
+ EXPECT_EQ(kTcl112AcBits, ac._irsend.capture.bits);
ASSERT_EQ(
- "Type: 1, Power: On, Mode: 3 (Cool), Temp: 24C, Fan: 0 (Auto), "
- "Econo: Off, Health: Off, Turbo: Off, Swing(H): Off, Swing(V): Off, "
- "Light: Off", IRAcUtils::resultAcToString(&ac._irsend.capture));
+ "Model: 1 (TAC09CHSD), Type: 1, Power: On, Mode: 3 (Cool), Temp: 24C, "
+ "Fan: 0 (Auto), Swing(V): 0 (Auto), Swing(H): Off, "
+ "Econo: Off, Health: Off, Turbo: Off, Light: Off, "
+ "On Timer: Off, Off Timer: Off",
+ IRAcUtils::resultAcToString(&ac._irsend.capture));
+}
+
+TEST(TestTcl112AcClass, isTcl) {
+ const uint8_t tcl_temp16C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x00, 0x00, 0x00, 0x00, 0x80, 0xCB};
+ EXPECT_TRUE(IRTcl112Ac::isTcl(tcl_temp16C));
+ const uint8_t tcl_temp31C[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xBC};
+ EXPECT_TRUE(IRTcl112Ac::isTcl(tcl_temp31C));
+ const uint8_t issue1528[kTcl112AcStateLength] = {
+ 0x23, 0xCB, 0x26, 0x02, 0x00, 0x60, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85};
+ EXPECT_TRUE(IRTcl112Ac::isTcl(issue1528));
+ // Ref: https://cociweb.info/container/hvac_ir_recapture_2719.log
+ const uint8_t teknopoint[14] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x24, 0x03,
+ 0x0F, 0x38, 0x00, 0x00, 0x00, 0x00, 0x83};
+ EXPECT_FALSE(IRTcl112Ac::isTcl(teknopoint));
+}
+
+TEST(TestTcl112AcClass, Timers) {
+ IRTcl112Ac ac(kGpioUnused);
+
+ ac.stateReset();
+ ac.setOnTimer(0);
+ ac.setOffTimer(0);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_EQ(0, ac.getOffTimer());
+ EXPECT_FALSE(ac._.TimerIndicator);
+ EXPECT_FALSE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+
+ ac.setOnTimer(7 * 60);
+ EXPECT_EQ(7 * 60, ac.getOnTimer());
+ EXPECT_TRUE(ac._.TimerIndicator);
+ EXPECT_TRUE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+
+ ac.setOnTimer(0);
+ EXPECT_EQ(0, ac.getOnTimer());
+ EXPECT_FALSE(ac._.TimerIndicator);
+ EXPECT_FALSE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+
+ ac.setOffTimer(13 * 60); // Beyond max.
+ EXPECT_EQ(12 * 60, ac.getOffTimer());
+ EXPECT_TRUE(ac._.TimerIndicator);
+ EXPECT_FALSE(ac._.OnTimerEnabled);
+ EXPECT_TRUE(ac._.OffTimerEnabled);
+
+ ac.setOffTimer(0);
+ EXPECT_EQ(0, ac.getOffTimer());
+ EXPECT_FALSE(ac._.TimerIndicator);
+ EXPECT_FALSE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+
+ // Real messages/states
+ // Per https://github.com/crankyoldgit/IRremoteESP8266/issues/1486#issuecomment-917545485
+
+ const uint8_t ontimer_1h[14] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x34, 0x03,
+ 0x00, 0x78, 0x00, 0x06, 0x00, 0x00, 0xCA};
+ ac.setRaw(ontimer_1h);
+ EXPECT_EQ(60, ac.getOnTimer());
+ EXPECT_TRUE(ac._.TimerIndicator);
+ EXPECT_TRUE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+
+ const uint8_t ontimer_4h[14] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x34, 0x03,
+ 0x00, 0x78, 0x00, 0x18, 0x00, 0x00, 0xDC};
+ ac.setRaw(ontimer_4h);
+ EXPECT_EQ(240, ac.getOnTimer());
+ EXPECT_TRUE(ac._.TimerIndicator);
+ EXPECT_TRUE(ac._.OnTimerEnabled);
+ EXPECT_FALSE(ac._.OffTimerEnabled);
+ EXPECT_EQ(
+ "Model: 2 (GZ055BE1), Type: 1, Power: On, Mode: 3 (Cool), Temp: 31C, "
+ "Fan: 0 (Auto), Swing(V): 7 (Swing), "
+ "On Timer: 04:00, Off Timer: Off",
+ ac.toString());
+
+ const uint8_t offtimer_2h[14] = {
+ 0x23, 0xCB, 0x26, 0x01, 0x00, 0x2C, 0x08,
+ 0x07, 0x78, 0x0C, 0x00, 0x00, 0x00, 0xD4};
+
+ ac.setRaw(offtimer_2h);
+ EXPECT_EQ(120, ac.getOffTimer());
+ EXPECT_TRUE(ac._.TimerIndicator);
+ EXPECT_FALSE(ac._.OnTimerEnabled);
+ EXPECT_TRUE(ac._.OffTimerEnabled);
+ EXPECT_EQ(
+ "Model: 2 (GZ055BE1), Type: 1, Power: On, Mode: 8 (Auto), Temp: 24C, "
+ "Fan: 0 (Auto), Swing(V): 7 (Swing), "
+ "On Timer: Off, Off Timer: 02:00",
+ ac.toString());
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Teknopoint_test.cpp b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Teknopoint_test.cpp
index 009b2a41b..74f29d146 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Teknopoint_test.cpp
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/test/ir_Teknopoint_test.cpp
@@ -44,7 +44,9 @@ TEST(TestDecodeTeknopoint, RealExample) {
ASSERT_EQ(kTeknopointBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "",
+ "Model: 2 (GZ055BE1), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Swing(V): 1 (Highest), "
+ "On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
}
@@ -67,7 +69,9 @@ TEST(TestDecodeTeknopoint, SyntheticExample) {
ASSERT_EQ(kTeknopointBits, irsend.capture.bits);
EXPECT_STATE_EQ(expectedState, irsend.capture.state, irsend.capture.bits);
EXPECT_EQ(
- "",
+ "Model: 2 (GZ055BE1), Type: 1, Power: On, Mode: 3 (Cool), Temp: 16C, "
+ "Fan: 0 (Auto), Swing(V): 1 (Highest), "
+ "On Timer: Off, Off Timer: Off",
IRAcUtils::resultAcToString(&irsend.capture));
EXPECT_EQ(
@@ -95,7 +99,7 @@ TEST(TestUtils, Housekeeping) {
ASSERT_EQ("TEKNOPOINT", typeToString(decode_type_t::TEKNOPOINT));
ASSERT_EQ(decode_type_t::TEKNOPOINT, strToDecodeType("TEKNOPOINT"));
ASSERT_TRUE(hasACState(decode_type_t::TEKNOPOINT));
- ASSERT_FALSE(IRac::isProtocolSupported(decode_type_t::TEKNOPOINT));
+ ASSERT_TRUE(IRac::isProtocolSupported(decode_type_t::TEKNOPOINT));
ASSERT_EQ(kTeknopointBits, IRsend::defaultBits(decode_type_t::TEKNOPOINT));
ASSERT_EQ(kNoRepeat, IRsend::minRepeats(decode_type_t::TEKNOPOINT));
}
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/Makefile b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/Makefile
index b30d1207c..15f192efd 100644
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/Makefile
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/Makefile
@@ -1,7 +1,11 @@
# SYNOPSIS:
#
-# make [all] - makes everything.
-# make clean - removes all files generated by make.
+# make [all] - makes everything.
+# make TARGET - makes the given target.
+# make run_tests - makes everything and runs all test
+# make run-% - run specific test file (exclude .py)
+# replace % with given test file
+# make clean - removes all files generated by make.
# Please tweak the following variable definitions as needed by your
# project, except GTEST_HEADERS, which you can use in your own targets
@@ -37,6 +41,10 @@ run_tests : all
echo "PASS: \o/ \o/ All unit tests passed. \o/ \o/"; \
fi
+run-% : all
+ echo "RUNNING: $*"; \
+ python3 ./$*.py;
+
clean :
rm -f *.o *.pyc gc_decode mode2_decode
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/auto_analyse_raw_data.py b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/auto_analyse_raw_data.py
index aa5c990a9..e061d3c42 100755
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/auto_analyse_raw_data.py
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/auto_analyse_raw_data.py
@@ -85,6 +85,7 @@ class RawIRMessage():
bits = len(binary_str)
rev_binary_str = binary_str[::-1]
rev_num = int(rev_binary_str, 2)
+ # pylint: disable=C0209
self.output.write("\n Bits: %d\n"
" Hex: %s (MSB first)\n"
" %s (LSB first)\n"
@@ -95,22 +96,21 @@ class RawIRMessage():
(bits, ("0x{0:0%dX}" % (bits / 4)).format(num),
("0x{0:0%dX}" % (bits / 4)).format(rev_num), num,
rev_num, binary_str, rev_binary_str))
+ # pylint: enable=C0209
def add_data_code(self, bin_str, name="", footer=True):
"""Add the common "data" sequence of code to send the bulk of a message."""
# pylint: disable=no-self-use
code = []
nbits = len(bin_str)
- code.append(" // Data Section #%d" % self.section_count)
- code.append(" // e.g. data = 0x%X, nbits = %d" % (int(bin_str, 2),
- nbits))
- code.append(" sendData(k%sBitMark, k%sOneSpace, k%sBitMark, "
- "k%sZeroSpace, send_data, %d, true);" %
- (name, name, name, name, nbits))
- code.append(" send_data >>= %d;" % nbits)
+ code.append(f" // Data Section #{self.section_count}")
+ code.append(f" // e.g. data = 0x{int(bin_str, 2):X}, nbits = {nbits}")
+ code.append(f" sendData(k{name}BitMark, k{name}OneSpace, k{name}BitMark,"
+ f" k{name}ZeroSpace, send_data, {nbits}, true);")
+ code.append(f" send_data >>= {nbits};")
if footer:
code.append(" // Footer")
- code.append(" mark(k%sBitMark);" % name)
+ code.append(f" mark(k{name}BitMark);")
return code
def add_data_decode_code(self, bin_str, name="", footer=True):
@@ -120,21 +120,20 @@ class RawIRMessage():
nbits = len(bin_str)
code.extend([
"",
- " // Data Section #%d" % self.section_count,
- " // e.g. data_result.data = 0x%X, nbits = %d" % (int(bin_str, 2),
- nbits),
- " data_result = matchData(&(results->rawbuf[offset]), %s," % nbits,
- " k%sBitMark, k%sOneSpace," % (name, name),
- " k%sBitMark, k%sZeroSpace);" % (name, name),
+ f" // Data Section #{self.section_count}",
+ f" // e.g. data_result.data = 0x{int(bin_str, 2):X}, nbits = {nbits}",
+ f" data_result = matchData(&(results->rawbuf[offset]), {nbits},",
+ f" k{name}BitMark, k{name}OneSpace,",
+ f" k{name}BitMark, k{name}ZeroSpace);",
" offset += data_result.used;",
" if (data_result.success == false) return false; // Fail",
- " data <<= %s; // Make room for the new bits of data." % nbits,
+ f" data <<= {nbits}; // Make room for the new bits of data.",
" data |= data_result.data;"])
if footer:
code.extend([
"",
" // Footer",
- " if (!matchMark(results->rawbuf[offset++], k%sBitMark))" % name,
+ f" if (!matchMark(results->rawbuf[offset++], k{name}BitMark))",
" return false;"])
return code
@@ -148,26 +147,28 @@ class RawIRMessage():
ambles = {}
firstmark = ambles.get("firstmark", 0)
firstspace = ambles.get("firstspace", 0)
- lastmark = ambles.get("lastmark", "k%sBitMark" % name)
+ lastmark = ambles.get("lastmark", f"k{name}BitMark")
lastspace = ambles.get("lastspace", "kDefaultMessageGap")
- code.append(
- " // Data Section #%d" % self.section_count)
+ code.append(f" // Data Section #{self.section_count}")
if nbits % 8:
code.append(" // DANGER: Nr. of bits is not a multiple of 8. "
"This section won't work!")
code.extend([
" // e.g.",
- " // bits = %d; bytes = %d;" % (nbits, nbytes),
+ f" // bits = {nbits}; bytes = {int(nbytes)};",
+ # pylint: disable=C0209
" // *(data + pos) = {0x%s};" % (
", 0x".join("%02X" % int(bin_str[i:i + 8], 2)
for i in range(0, len(bin_str), 8))),
- " sendGeneric(%s, %s," % (firstmark, firstspace),
- " k%sBitMark, k%sOneSpace," % (name, name),
- " k%sBitMark, k%sZeroSpace," % (name, name),
- " %s, %s," % (lastmark, lastspace),
- " data + pos, %d, // Bytes" % nbytes,
- " k%sFreq, true, kNoRepeat, kDutyDefault);" % name,
- " pos += %d; // Adjust by how many bytes of data we sent" % nbytes])
+ # pylint: enable=C0209
+ f" sendGeneric({firstmark}, {firstspace},",
+ f" k{name}BitMark, k{name}OneSpace,",
+ f" k{name}BitMark, k{name}ZeroSpace,",
+ f" {lastmark}, {lastspace},",
+ f" data + pos, {int(nbytes)}, // Bytes",
+ f" k{name}Freq, true, kNoRepeat, kDutyDefault);",
+ f" pos += {int(nbytes)};"
+ f" // Adjust by how many bytes of data we sent"])
return code
def add_data_byte_decode_code(self, bin_str, name="", ambles=None):
@@ -183,36 +184,37 @@ class RawIRMessage():
ambles = {}
firstmark = ambles.get("firstmark", 0)
firstspace = ambles.get("firstspace", 0)
- lastmark = ambles.get("lastmark", "k%sBitMark" % name)
+ lastmark = ambles.get("lastmark", f"k{name}BitMark")
lastspace = ambles.get("lastspace", "kDefaultMessageGap")
code.extend([
"",
- " // Data Section #%d" % self.section_count,
+ f" // Data Section #{self.section_count}",
" // e.g.",
- " // bits = %d; bytes = %d;" % (nbits, nbytes),
+ f" // bits = {nbits}; bytes = {int(nbytes)};",
+ # pylint: disable=C0209
" // *(results->state + pos) = {0x%s};" % (
", 0x".join("%02X" % int(bin_str[i:i + 8], 2)
for i in range(0, len(bin_str), 8))),
+ # pylint: enable=C0209
" used = matchGeneric(results->rawbuf + offset, results->state + pos,",
- " results->rawlen - offset, %d," % nbits,
- " %s, %s," % (firstmark, firstspace),
- " k%sBitMark, k%sOneSpace," % (name, name),
- " k%sBitMark, k%sZeroSpace," % (name, name),
- " %s, %s, true);" % (lastmark, lastspace),
+ f" results->rawlen - offset, {nbits},",
+ f" {firstmark}, {firstspace},",
+ f" k{name}BitMark, k{name}OneSpace,",
+ f" k{name}BitMark, k{name}ZeroSpace,",
+ f" {lastmark}, {lastspace}, true);",
" if (used == 0) return false; // We failed to find any data.",
" offset += used; // Adjust for how much of the message we read.",
- " pos += %d; // Adjust by how many bytes of data we read" % nbytes])
+ f" pos += {int(nbytes)};"
+ " // Adjust by how many bytes of data we read"])
return code
def _calc_values(self):
"""Calculate the values which describe the standard timings
for the protocol."""
if self.verbose:
- self.output.write("Potential Mark Candidates:\n"
- "%s\n"
- "Potential Space Candidates:\n"
- "%s\n" % (str(self.marks), str(self.spaces)))
+ self.output.write(f"Potential Mark Candidates:\n{self.marks}\n"
+ f"Potential Space Candidates:\n{self.spaces}\n")
# The bit mark is likely to be the smallest mark.
self.bit_mark = self.marks[-1]
if len(self.marks) > 2: # Possible leader mark?
@@ -305,8 +307,8 @@ def convert_rawdata(data_str):
results.append(int(timing))
except ValueError as non_numeric:
raise ValueError(
- "Raw Data contains a non-numeric value of '%s'." %
- timing) from non_numeric
+ f"Raw Data contains a non-numeric value of '{timing}'."
+ ) from non_numeric
return results
@@ -326,35 +328,33 @@ def dump_constants(message, defines, name="", output=sys.stdout):
zero_space = avg_list(message.space_buckets[message.zero_space])
output.write("Guessing key value:\n"
- "k%sHdrMark = %d\n"
- "k%sHdrSpace = %d\n"
- "k%sBitMark = %d\n"
- "k%sOneSpace = %d\n"
- "k%sZeroSpace = %d\n" % (name, hdr_mark, name, hdr_space,
- name, bit_mark, name, one_space,
- name, zero_space))
- defines.append("const uint16_t k%sHdrMark = %d;" % (name, hdr_mark))
- defines.append("const uint16_t k%sBitMark = %d;" % (name, bit_mark))
- defines.append("const uint16_t k%sHdrSpace = %d;" % (name, hdr_space))
- defines.append("const uint16_t k%sOneSpace = %d;" % (name, one_space))
- defines.append("const uint16_t k%sZeroSpace = %d;" % (name, zero_space))
+ f"k{name}HdrMark = {hdr_mark}\n"
+ f"k{name}HdrSpace = {hdr_space}\n"
+ f"k{name}BitMark = {bit_mark}\n"
+ f"k{name}OneSpace = {one_space}\n"
+ f"k{name}ZeroSpace = {zero_space}\n")
+ defines.append(f"const uint16_t k{name}HdrMark = {hdr_mark};")
+ defines.append(f"const uint16_t k{name}BitMark = {bit_mark};")
+ defines.append(f"const uint16_t k{name}HdrSpace = {hdr_space};")
+ defines.append(f"const uint16_t k{name}OneSpace = {one_space};")
+ defines.append(f"const uint16_t k{name}ZeroSpace = {zero_space};")
if ldr_mark:
- output.write("k%sLdrMark = %d\n" % (name, ldr_mark))
- defines.append("const uint16_t k%sLdrMark = %d;" % (name, ldr_mark))
+ output.write(f"k{name}LdrMark = {ldr_mark}\n")
+ defines.append(f"const uint16_t k{name}LdrMark = {ldr_mark};")
avg_gaps = [avg_list(message.space_buckets[x]) for x in message.gaps]
if len(message.gaps) == 1:
- output.write("k%sSpaceGap = %d\n" % (name, avg_gaps[0]))
- defines.append("const uint16_t k%sSpaceGap = %d;" % (name, avg_gaps[0]))
+ output.write(f"k{name}SpaceGap = {avg_gaps[0]}\n")
+ defines.append(f"const uint16_t k{name}SpaceGap = {avg_gaps[0]};")
else:
count = 0
for gap in avg_gaps:
# We probably (still) have a gap in the protocol.
count = count + 1
- output.write("k%sSpaceGap%d = %d\n" % (name, count, gap))
- defines.append("const uint16_t k%sSpaceGap%d = %d;" % (name, count, gap))
- defines.append("const uint16_t k%sFreq = 38000; "
- "// Hz. (Guessing the most common frequency.)" % name)
+ output.write(f"k{name}SpaceGap{count} = {gap}\n")
+ defines.append(f"const uint16_t k{name}SpaceGap{count} = {gap};")
+ defines.append(f"const uint16_t k{name}Freq = 38000; "
+ "// Hz. (Guessing the most common frequency.)")
def parse_and_report(rawdata_str, margin, gen_code=False, name="",
@@ -374,7 +374,7 @@ def parse_and_report(rawdata_str, margin, gen_code=False, name="",
# Parse the input.
rawdata = convert_rawdata(rawdata_str)
- output.write("Found %d timing entries.\n" % len(rawdata))
+ output.write(f"Found {len(rawdata)} timing entries.\n")
message = RawIRMessage(margin, rawdata, output)
output.write("\nGuessing encoding type:\n")
@@ -410,17 +410,17 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
code["sendcomhead"].extend([
"",
- "#if SEND_%s" % def_name.upper(),
+ f"#if SEND_{def_name.upper()}",
SAFE64NOTE,
- "/// Send a %s formatted message." % name,
+ f"/// Send a {name} formatted message.",
"/// Status: ALPHA / Untested."])
code["send"].extend([
"/// @param[in] data containing the IR command.",
- "/// @param[in] nbits Nr. of bits to send. usually k%sBits" % name,
+ f"/// @param[in] nbits Nr. of bits to send. usually k{name}Bits",
"/// @param[in] repeat Nr. of times the message is to be repeated.",
- "void IRsend::send%s(const uint64_t data, const uint16_t"
- " nbits, const uint16_t repeat) {" % def_name,
- " enableIROut(k%sFreq);" % name,
+ f"void IRsend::send{def_name}(const uint64_t data, const uint16_t"
+ " nbits, const uint16_t repeat) {",
+ f" enableIROut(k{name}Freq);",
" for (uint16_t r = 0; r <= repeat; r++) {",
" uint64_t send_data = data;"])
code["send64+"].extend([
@@ -431,21 +431,21 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
CODEGEN,
"/// @endcode",
"/// @param[in] nbytes Nr. of bytes of data in the array."
- " (>=k%sStateLength)" % name,
+ f" (>=k{name}StateLength)",
"/// @param[in] repeat Nr. of times the message is to be repeated.",
- "void IRsend::send%s(const uint8_t data[], const uint16_t nbytes,"
- " const uint16_t repeat) {" % def_name,
+ f"void IRsend::send{def_name}(const uint8_t data[],"
+ " const uint16_t nbytes, const uint16_t repeat) {",
" for (uint16_t r = 0; r <= repeat; r++) {",
" uint16_t pos = 0;"])
code["sendcomfoot"].extend([
" }",
"}",
- "#endif // SEND_%s" % def_name.upper()])
+ f"#endif // SEND_{def_name.upper()}"])
code["recvcomhead"].extend([
"",
- "#if DECODE_%s" % def_name.upper(),
+ f"#if DECODE_{def_name.upper()}",
SAFE64NOTE,
- "/// Decode the supplied %s message." % name,
+ f"/// Decode the supplied {name} message.",
"/// Status: ALPHA / Untested.",
"/// @param[in,out] results Ptr to the data to decode &"
" where to store the decode",
@@ -456,11 +456,11 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
"/// @param[in] strict Flag indicating if we should perform strict"
" matching.",
"/// @return A boolean. True if it can decode it, false if it can't.",
- "bool IRrecv::decode%s(decode_results *results, uint16_t offset,"
- " const uint16_t nbits, const bool strict) {" % def_name,
- " if (results->rawlen < 2 * nbits + k%sOverhead - offset)" % name,
+ f"bool IRrecv::decode{def_name}(decode_results *results, uint16_t offset,"
+ " const uint16_t nbits, const bool strict) {",
+ f" if (results->rawlen < 2 * nbits + k{name}Overhead - offset)",
" return false; // Too short a message to match.",
- " if (strict && nbits != k%sBits)" % name,
+ f" if (strict && nbits != k{name}Bits)",
" return false;",
""])
code["recv"].extend([
@@ -472,7 +472,7 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
code["recvcomfoot"].extend([
" return true;",
"}",
- "#endif // DECODE_%s" % def_name.upper()])
+ f"#endif // DECODE_{def_name.upper()}"])
# states are:
# HM: Header/Leader mark
@@ -496,24 +496,24 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
code["recv"].extend(message.add_data_decode_code(binary_value, name,
False))
message.section_count = message.section_count + 1
- code_info["lastmark"] = "k%s%sdrMark" % (name, mark_type)
+ code_info["lastmark"] = f"k{name}{mark_type}drMark"
total_bits = total_bits + binary_value
- code_info["firstmark"] = "k%s%sdrMark" % (name, mark_type)
+ code_info["firstmark"] = f"k{name}{mark_type}drMark"
binary_value = add_bit(binary_value, "reset")
- output.write("k%s%sdrMark+" % (name, mark_type))
- code["send"].extend([" // %seader" % mark_type,
- " mark(k%s%sdrMark);" % (name, mark_type)])
+ output.write(f"k{name}{mark_type}drMark+")
+ code["send"].extend([f" // {mark_type}eader",
+ f" mark(k{name}{mark_type}drMark);"])
code["recv"].extend([
"",
- " // %seader" % mark_type,
- " if (!matchMark(results->rawbuf[offset++], k%s%sdrMark))" % (
- name, mark_type),
+ f" // {mark_type}eader",
+ " if (!matchMark(results->rawbuf[offset++],"
+ f" k{name}{mark_type}drMark))",
" return false;"])
# Handle header spaces.
elif message.is_hdr_space(usec) and not message.is_one_space(usec):
if binary64_value:
- code_info["lastspace"] = "k%sHdrSpace" % name
+ code_info["lastspace"] = f"k{name}HdrSpace"
message.section_count = message.section_count - 1
code["send64+"].extend(message.add_data_byte_code(binary64_value, name,
code_info))
@@ -529,39 +529,39 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
total_bits = total_bits + binary_value
code["send"].extend(message.add_data_code(binary_value, name))
code["recv"].extend(message.add_data_decode_code(binary_value, name))
- code_info["lastspace"] = "k%sHdrSpace" % name
+ code_info["lastspace"] = f"k{name}HdrSpace"
message.section_count = message.section_count + 1
binary_value = binary64_value = add_bit(binary_value, "reset")
output.write("UNEXPECTED->")
state = "HS"
- output.write("k%sHdrSpace+" % name)
- code["send"].append(" space(k%sHdrSpace);" % name)
+ output.write(f"k{name}HdrSpace+")
+ code["send"].append(f" space(k{name}HdrSpace);")
code["recv"].extend([
- " if (!matchSpace(results->rawbuf[offset++], k%sHdrSpace))" % name,
+ f" if (!matchSpace(results->rawbuf[offset++], k{name}HdrSpace))",
" return false;"])
- code_info["firstspace"] = "k%sHdrSpace" % name
+ code_info["firstspace"] = f"k{name}HdrSpace"
# Handle bit marks.
elif message.is_bit_mark(usec) and count % 2:
if state not in ("HS", "BS"):
- output.write("k%sBitMark(UNEXPECTED)" % name)
+ output.write(f"k{name}BitMark(UNEXPECTED)")
state = "BM"
# Handle "zero" spaces
elif message.is_zero_space(usec):
if state != "BM":
- output.write("k%sZeroSpace(UNEXPECTED)" % name)
+ output.write(f"k{name}ZeroSpace(UNEXPECTED)")
state = "BS"
binary_value = binary64_value = add_bit(binary_value, 0, output)
# Handle "one" spaces
elif message.is_one_space(usec):
if state != "BM":
- output.write("k%sOneSpace(UNEXPECTED)" % name)
+ output.write(f"k{name}OneSpace(UNEXPECTED)")
state = "BS"
binary_value = binary64_value = add_bit(binary_value, 1, output)
elif message.is_gap(usec):
if state != "BM":
output.write("UNEXPECTED->")
- output.write("GAP(%d)" % usec)
- code_info["lastspace"] = "k%sSpaceGap" % name
+ output.write(f"GAP({usec})")
+ code_info["lastspace"] = f"k{name}SpaceGap"
if binary64_value:
code["send64+"].extend(message.add_data_byte_code(binary64_value, name,
code_info))
@@ -579,19 +579,19 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
" // Gap"])
code["send"].extend([" // Gap"])
if state == "BM":
- code["send"].extend([" mark(k%sBitMark);" % name])
+ code["send"].extend([f" mark(k{name}BitMark);"])
code["recv"].extend([
- " if (!matchMark(results->rawbuf[offset++], k%sBitMark))" % name,
+ f" if (!matchMark(results->rawbuf[offset++], k{name}BitMark))",
" return false;"])
- code["send"].append(" space(k%sSpaceGap);" % name)
+ code["send"].append(f" space(k{name}SpaceGap);")
code["recv"].extend([
- " if (!matchSpace(results->rawbuf[offset++], k%sSpaceGap))" % name,
+ f" if (!matchSpace(results->rawbuf[offset++], k{name}SpaceGap))",
" return false;"])
total_bits = total_bits + binary_value
binary_value = binary64_value = add_bit(binary_value, "reset")
state = "GS"
else:
- output.write("UNKNOWN(%d)" % usec)
+ output.write(f"UNKNOWN({usec})")
state = "UNK"
count = count + 1
if binary64_value:
@@ -611,7 +611,7 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
code["recv"].extend([
"",
" // Success",
- " results->decode_type = decode_type_t::%s;" % def_name.upper(),
+ f" results->decode_type = decode_type_t::{def_name.upper()};",
" results->bits = nbits;",
" results->value = data;",
" results->command = 0;",
@@ -619,19 +619,18 @@ def decode_data(message, defines, code, name="", output=sys.stdout):
code["recv64+"].extend([
"",
" // Success",
- " results->decode_type = decode_type_t::%s;" % def_name.upper(),
+ f" results->decode_type = decode_type_t::{def_name.upper()};",
" results->bits = nbits;"])
total_bits = total_bits + binary_value
- output.write("\nTotal Nr. of suspected bits: %d\n" % len(total_bits))
- defines.append("const uint16_t k%sBits = %d;"
- " // Move to IRremoteESP8266.h" % (name, len(total_bits)))
+ output.write(f"\nTotal Nr. of suspected bits: {len(total_bits)}\n")
+ defines.append(f"const uint16_t k{name}Bits = {len(total_bits)};"
+ " // Move to IRremoteESP8266.h")
if len(total_bits) > 64:
- defines.append("const uint16_t k%sStateLength = %d;"
- " // Move to IRremoteESP8266.h" %
- (name, len(total_bits) / 8))
- defines.append("const uint16_t k%sOverhead = %d;" %
- (name, message.rawlen - 2 * len(total_bits)))
+ defines.append(f"const uint16_t k{name}StateLength = "
+ f"{int(len(total_bits) / 8)}; // Move to IRremoteESP8266.h")
+ defines.append(f"const uint16_t k{name}Overhead = "
+ f"{message.rawlen - 2 * len(total_bits)};")
return total_bits
@@ -645,9 +644,9 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout):
output.write("\nGenerating a VERY rough code outline:\n\n"
"// Copyright 2020 David Conran (crankyoldgit)\n"
"/// @file\n"
- "/// @brief Support for %s protocol\n\n"
+ f"/// @brief Support for {def_name} protocol\n\n"
"// Supports:\n"
- "// Brand: %s, Model: TODO add device and remote\n\n"
+ f"// Brand: {def_name}, Model: TODO add device and remote\n\n"
'#include "IRrecv.h"\n'
'#include "IRsend.h"\n'
'#include "IRutils.h"\n\n'
@@ -656,9 +655,9 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout):
"// See https://github.com/crankyoldgit/IRremoteESP8266/wiki/"
"Adding-support-for-a-new-IR-protocol\n"
"// for details of how to include this in the library."
- "\n" % (def_name, def_name))
+ "\n")
for line in defines:
- output.write("%s\n" % line)
+ output.write(f"{line}\n")
if len(bits_str) > 64: # Will it fit in a uint64_t?
output.write("// DANGER: More than 64 bits detected. A uint64_t for "
@@ -668,18 +667,21 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout):
for line in code["sendcomhead"] + code["send"] + code["sendcomfoot"]:
if line == SAFE64NOTE:
line = "// Function should be safe up to 64 bits."
- output.write("%s\n" % line)
+ output.write(f"{line}\n")
if len(bits_str) > 64: # Will it fit in a uint64_t?
for line in code["sendcomhead"] + code["send64+"] + code["sendcomfoot"]:
if line == SAFE64NOTE:
- line = "// Alternative >64bit function to send %s messages\n" % \
- def_name.upper() + "// Function should be safe over 64 bits."
+ line = (f"// Alternative >64bit function to send {def_name.upper()}"
+ " messages\n"
+ "// Function should be safe over 64 bits.")
elif line == CODEGEN:
+ # pylint: disable=C0209
line = "/// uint8_t data[k%sStateLength] = {0x%s};" % (
name, ", 0x".join("%02X" % int(bits_str[i:i + 8], 2)
for i in range(0, len(bits_str), 8)))
- output.write("%s\n" % line)
+ # pylint: enable=C0209
+ output.write(f"{line}\n")
if len(bits_str) > 64: # Will it fit in a uint64_t?
output.write("\n// DANGER: More than 64 bits detected. A uint64_t for "
"'data' won't work!")
@@ -689,7 +691,7 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout):
for line in code["recvcomhead"] + code["recv"] + code["recvcomfoot"]:
if line == SAFE64NOTE:
line = "// Function should be safe up to 64 bits."
- output.write("%s\n" % line)
+ output.write(f"{line}\n")
# Display the > 64bit version's decode code
if len(bits_str) > 64: # Is it too big for a uint64_t?
@@ -699,7 +701,7 @@ def generate_code(defines, code, bits_str, name="", output=sys.stdout):
for line in code["recvcomhead"] + code["recv64+"] + code["recvcomfoot"]:
if line == SAFE64NOTE:
line = "// Function should be safe over 64 bits."
- output.write("%s\n" % line)
+ output.write(f"{line}\n")
def add_rawdata_args(parser):
"""Add the arguments for feeding in the rawdata string(s)."""
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/generate_irtext_h.sh b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/generate_irtext_h.sh
index df2baee06..b0d9855c4 100755
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/generate_irtext_h.sh
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/generate_irtext_h.sh
@@ -24,12 +24,26 @@ cat >${OUTPUT} << EOF
// Constant text to be shared across all object files.
// This means there is only one copy of the character/string/text etc.
+#ifdef ESP8266
+class __FlashStringHelper;
+#define IRTEXT_CONST_PTR_CAST(PTR)\\
+ reinterpret_cast(PTR)
+#define IRTEXT_CONST_PTR(NAME) const __FlashStringHelper* const NAME
+#else // ESP8266
+#define IRTEXT_CONST_PTR_CAST(PTR) PTR
+#define IRTEXT_CONST_PTR(NAME) const char* const NAME
+#endif // ESP8266
+
EOF
# Parse and output contents of INPUT file.
sed 's/ PROGMEM//' ${INPUT} | egrep "^(const )?char" | cut -f1 -d= |
sed 's/ $/;/;s/^/extern /' | sort -u >> ${OUTPUT}
-
+egrep '^\s{,10}IRTEXT_CONST_STRING\(' ${INPUT} | cut -f2 -d\( | cut -f1 -d, |
+ sed 's/^/extern IRTEXT_CONST_PTR\(/;s/$/\);/' | sort -u >> ${OUTPUT}
+egrep '^\s{,10}IRTEXT_CONST_BLOB_DECL\(' ${INPUT} |
+ cut -f2 -d\( | cut -f1 -d\) |
+ sed 's/^/extern IRTEXT_CONST_PTR\(/;s/$/\);/' | sort -u >> ${OUTPUT}
# Footer
cat >> ${OUTPUT} << EOF
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/mkkeywords b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/mkkeywords
index 84f2a46fd..e050e4964 100755
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/mkkeywords
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/mkkeywords
@@ -31,7 +31,8 @@ cat << EndOfTextEndOfTextEndOfText
EndOfTextEndOfTextEndOfText
CLASSES=$(egrep -h "^ *((enum|class) |} [a-zA-Z0-9_]+_t;$)" src/*.h |
- sed 's/^ *//;s/enum class//;s/\;$//' | cut -d' ' -f2 | sort -u)
+ sed 's/^ *//;s/enum class//;s/\;$//' | cut -d' ' -f2 | sort -u |
+ grep -v "^__")
for i in ${CLASSES}; do
echo -e "${i}\tKEYWORD1"
done | sort -du
@@ -59,13 +60,15 @@ cat << EndOfTextEndOfTextEndOfText
#######################################
EndOfTextEndOfTextEndOfText
-LITERALS=$(grep "^#define [A-Z]" src/*.cpp src/*.h |
+LITERALS=$(grep -h "^#define [A-Z]" src/*.cpp src/*.h |
while read ignore define ignore; do
echo ${define};
done | sort -u |
grep -v [\(\)] | grep -v ^_ | grep -v _\$ | grep -v VIRTUAL)
-CONSTS=$(grep "^const " src/*.cpp src/*.h |
- sed -E 's/\[.*\] =.*//;s/ =.*//;s/^.* \*?k/k/')
+CONSTS=$(grep -h "^const " src/*.cpp src/*.h |
+ sed -E 's/\[.*\] =.*//;s/ =.*//;s/^.* \*?k/k/';
+ grep -h "^IRTEXT_CONST_" src/*.cpp src/*.h |
+ sed -E 's/IRTEXT_CONST_\S+\(//;s/,.*//;s/\).*//')
ENUMS=$(cat src/*.h | while read a b; do
if [[ ${a} == "};" ]]; then
ENUM=0;
@@ -76,7 +79,7 @@ ENUMS=$(cat src/*.h | while read a b; do
if [[ ${a} == "enum" ]]; then
ENUM=1;
fi;
- done)
+ done | grep -v "^//")
for i in ${LITERALS} ${CONSTS} ${ENUMS}; do
echo -e "${i}\tLITERAL1"
done | sort -u
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/raw_to_pronto_code.py b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/raw_to_pronto_code.py
index 307ae7121..8d8fc815c 100755
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/raw_to_pronto_code.py
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/raw_to_pronto_code.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+ #!/usr/bin/python
"""Convert IRremoteESP8266's Raw data output into Pronto Code."""
#
# Copyright 2020 David Conran
@@ -16,7 +16,7 @@ def parse_and_report(rawdata_str, hertz=38000, end_usecs=100000,
# Parse the input.
rawdata = convert_rawdata(rawdata_str)
if verbose:
- output.write("Found %d timing entries.\n" % len(rawdata))
+ output.write(f"Found {len(rawdata)} timing entries.\n")
# Do we need to pad out the rawdata to make it even in length?
if end_usecs > 0 and len(rawdata) % 2 == 1:
@@ -26,29 +26,29 @@ def parse_and_report(rawdata_str, hertz=38000, end_usecs=100000,
# Work out the frequency code.
pronto_freq = int(1000000.0 / (hertz * 0.241246))
if verbose:
- output.write("Pronto frequency is %X (%d Hz).\n" % (pronto_freq, hertz))
- result.append("%04X" % pronto_freq)
+ output.write(f"Pronto frequency is {pronto_freq:X} ({hertz} Hz).\n")
+ result.append(f"{pronto_freq:04X}")
period = 1000000.0 / max(1, hertz)
if verbose:
- output.write("Pronto period is %f uSecs.\n" % period)
+ output.write(f"Pronto period is {period} uSecs.\n")
# Add the lengths to the code.
if use_initial:
- result.append("%04x" % int(len(rawdata) / 2)) # Initial burst code length
- result.append("%04x" % 0) # No Repeat code length
+ result.append(f"{int(len(rawdata) / 2):04x}") # Initial burst code length
+ result.append("0000") # No Repeat code length
else:
- result.append("%04x" % 0) # No Initial burst code length
- result.append("%04x" % int(len(rawdata) / 2)) # Repeat code length
+ result.append("0000") # No Initial burst code length
+ result.append(f"{int(len(rawdata) / 2):04x}") # Repeat code length
# Add the data.
if verbose:
- output.write("Raw data: %s " % rawdata)
+ output.write(f"Raw data: {rawdata} ")
for i in rawdata:
- result.append("%04x" % int(i / period))
+ result.append(f"{int(i / period):04x}")
if generate_code:
- output.write("uint16_t pronto[%d] = {0x%s};\n" % (len(result),
- ", 0x".join(result)))
+ output.write(f"uint16_t pronto[{len(result)}] = "
+ f"{{0x{', 0x'.join(result)}}};\n")
else:
- output.write("Pronto code = '%s'\n" % " ".join(result))
+ output.write(f"Pronto code = '{' '.join(result)}'\n")
# pylint: enable=too-many-arguments
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py
new file mode 100755
index 000000000..f40b3e959
--- /dev/null
+++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py
@@ -0,0 +1,426 @@
+#!/usr/bin/env python3
+"""Generate SupportedProtocols.md by scraping source code files"""
+import pathlib
+import argparse
+import subprocess
+from io import StringIO
+import sys
+import re
+import time
+
+CODE_URL = "https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_"
+
+BRAND_MODEL = re.compile(r"""
+ Brand:\s{1,20} # "Brand:" label followd by between 1 and 20 whitespace chars.
+ \b(?P.{1,40})\b # The actual brand of the device, max 40 chars.
+ \s{0,10}, # Followed by at most 10 whitespace chars, then a comma.
+ \s{1,20} # The between 1 and 20 whitespace chars.
+ Model:\s{1,20} # "Model:" label followd by between 1 and 20 whitespace chars.
+ \b(?P.{1,80}) # The model info of the device, max 80 chars.
+ \s{0,5}$ # Followed by at most 5 whitespaces before the end of line.
+ """, re.VERBOSE)
+ENUMS = re.compile(r"enum (\w{1,60}) {(.{1,5000}?)};", re.DOTALL)
+ENUM_ENTRY = re.compile(r"^\s{1,80}(\w{1,80})", re.MULTILINE)
+DECODED_PROTOCOLS = re.compile(r"""
+ .{0,80} # Ignore upto an 80 char line of whitespace/code etc.
+ # Now look for code that looks like we are assigning the Protocol type.
+ # There are two typical styles used:
+ (?:results->decode_type # The first style.
+ | # Or
+ typeguess) # The second style
+ \s{0,5}=\s{0,5} # The assignment operator and potential whitespace
+ (?:decode_type_t::)? # The protocol could have an optional type prefix.
+ (\w{1,40}); # Finally, the last word of code should be the Protocol.
+ """, re.VERBOSE)
+AC_FN = re.compile(r"ir_(.{1,80})\.h")
+AC_MODEL_ENUM_RE = re.compile(r"(.{1,40})_ac_remote_model_t")
+IRSEND_FN_RE = re.compile(r"IRsend\.h")
+ALL_FN = re.compile(r"ir_(.{1,80})\.(h|cpp)")
+
+EXCLUDED_PROTOCOLS = ["UNKNOWN", "UNUSED", "kLastDecodeType", "typeguess"]
+EXCLUDED_ACS = ["Magiquest", "NEC"]
+
+def getgitcommittime():
+ """Call git to get time of last commit
+ """
+ try:
+ label = subprocess.check_output(\
+ ["git", "show", "-s", "--format=%ct", "HEAD"]).strip()
+ return int(label)
+ except FileNotFoundError as err:
+ print("Git failed, which is ok, no git binary found?:", err)
+ return None
+ except subprocess.SubprocessError as err:
+ print("Git failed, which is ok, see output, maybe no git checkout?:", err)
+ return None
+
+def getmarkdownheader():
+ """Get the generated header
+ """
+ srctime = getgitcommittime()
+ # pylint: disable=C0209
+ return """""".format(
+ time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime(srctime)))
+ # pylint: enable=C0209
+
+
+
+def getallprotocols():
+ """Return all protocls configured in IRremoteESP8266.h
+ """
+ irremote = ARGS.directory / "IRremoteESP8266.h"
+ enums = getenums(irremote)["decode_type_t"]
+ if not enums:
+ errorexit("Error getting ENUMS from IRremoteESP8266.h")
+ return enums
+
+
+def getdecodedprotocols():
+ """All protocols that include decoding support"""
+ ret = set()
+ for path in ARGS.directory.iterdir():
+ if path.suffix != ".cpp":
+ continue
+ matches = DECODED_PROTOCOLS.finditer(path.open(encoding="utf-8").read())
+ for match in matches:
+ protocol = match.group(1)
+ if protocol not in EXCLUDED_PROTOCOLS:
+ ret.add(protocol)
+ return ret
+
+
+def getallacs():
+ """All supported A/C codes"""
+ ret = {}
+ for path in ARGS.directory.iterdir():
+ match = AC_FN.match(path.name)
+ if match:
+ acprotocol = match.group(1)
+ rawmodels = getenums(path)
+ models = set()
+ for model in rawmodels:
+ model = model.upper()
+ model = model.replace(f"K{acprotocol.upper()}", "")
+ if model and model not in EXCLUDED_PROTOCOLS:
+ models.add(model)
+ if acprotocol in ret:
+ ret[acprotocol].update(models)
+ else:
+ ret[acprotocol] = models
+ # Parse IRsend.h's enums
+ match = IRSEND_FN_RE.match(path.name)
+ if match:
+ rawmodels = getenums(path)
+ for acprotocol, acmodels in rawmodels.items():
+ models = set()
+ for model in acmodels:
+ model = model.upper()
+ model = model.replace(f"K{acprotocol.upper()}", "")
+ if model and model not in EXCLUDED_PROTOCOLS:
+ models.add(model)
+ if acprotocol in ret:
+ ret[acprotocol].update(models)
+ else:
+ ret[acprotocol] = models
+ return ret
+
+class FnSets():
+ """Container for getalldevices"""
+ def __init__(self):
+ self.allcodes = {}
+ self.fnnomatch = set()
+ self.allhfileprotos = set()
+ self.fnhmatch = set()
+ self.fncppmatch = set()
+
+ def add(self, supports, path):
+ """add the path to correct set based on supports"""
+ if path.suffix == ".h":
+ self.allhfileprotos.add(path.stem)
+ if supports:
+ if path.suffix == ".h":
+ self.fnhmatch.add(path.stem)
+ elif path.suffix == ".cpp":
+ self.fncppmatch.add(path.stem)
+ else:
+ self.fnnomatch.add(path.stem)
+
+ def printwarnings(self):
+ """print warnings"""
+ # all protos with support in .cpp file, when there is a .h file
+ # meaning that the documentation should probably be moved to .h
+ # in the future, with doxygen, that might change
+ protosincppwithh = list(self.fncppmatch & self.allhfileprotos)
+ if protosincppwithh:
+ protosincppwithh.sort()
+ print("The following files has supports section in .cpp, expected in .h")
+ for path in protosincppwithh:
+ print(f"\t{path}")
+
+ protosincppandh = list(self.fncppmatch & self.fnhmatch)
+ if protosincppandh:
+ protosincppandh.sort()
+ print("The following files has supports section in both .h and .cpp")
+ for path in protosincppandh:
+ print(f"\t{path}")
+
+ nosupports = self.getnosupports()
+ if nosupports:
+ nosupports.sort()
+ print("The following files had no supports section:")
+ for path in nosupports:
+ print(f"\t{path}")
+
+ return protosincppwithh or protosincppandh or nosupports
+
+ def getnosupports(self):
+ """get protos without supports sections"""
+ return list(self.fnnomatch - self.fnhmatch - self.fncppmatch)
+
+
+def getalldevices():
+ """All devices and associated branding and model information (if available)
+ """
+ sets = FnSets()
+ for path in ARGS.directory.iterdir():
+ match = ALL_FN.match(path.name)
+ if not match:
+ continue
+ supports = extractsupports(path)
+ sets.add(supports, path)
+ protocol = match.group(1)
+ for brand, model in supports:
+ protocolbrand = (protocol, brand)
+ pbset = sets.allcodes.get(protocolbrand, [])
+ if model in pbset:
+ print(f"Model {model} is duplicated for {protocol}, {brand}")
+ sets.allcodes[protocolbrand] = pbset + [model]
+
+ for fnprotocol in sets.getnosupports():
+ sets.allcodes[(fnprotocol[3:], "Unknown")] = []
+ return sets
+
+
+def getenums(path):
+ """Returns the keys for the first enum type in path
+ """
+ ret = {}
+ for enums in ENUMS.finditer(path.open(encoding="utf-8").read()):
+ if enums:
+ enum_name = AC_MODEL_ENUM_RE.search(enums.group(1))
+ if enum_name:
+ enum_name = enum_name.group(1).capitalize()
+ else:
+ enum_name = enums.group(1)
+ ret[enum_name] = set()
+ for enum in ENUM_ENTRY.finditer(enums.group(2)):
+ enum = enum.group(1)
+ if enum in EXCLUDED_PROTOCOLS:
+ continue
+ ret[enum_name].add(enum)
+ return ret
+
+
+ARGS = None
+
+
+def initargs():
+ """Init the command line arguments"""
+ global ARGS # pylint: disable=global-statement
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ "-n",
+ "--noout",
+ help="generate no output data, combine with --alert to only check",
+ action="store_true",
+ )
+ parser.add_argument(
+ "-s",
+ "--stdout",
+ help="output to stdout rather than SupportedProtocols.md",
+ action="store_true",
+ )
+ parser.add_argument("-v",
+ "--verbose",
+ help="increase output verbosity",
+ action="store_true")
+ parser.add_argument(
+ "-a",
+ "--alert",
+ help="alert if a file does not have a supports section, "
+ "non zero exit code if issues where found",
+ action="store_true",
+ )
+ parser.add_argument(
+ "directory",
+ nargs="?",
+ help="directory of the source git checkout",
+ default=None,
+ )
+ ARGS = parser.parse_args()
+ if ARGS.directory is None:
+ src = pathlib.Path("../src")
+ if not src.is_dir():
+ src = pathlib.Path("./src")
+ else:
+ src = pathlib.Path(ARGS.directory) / "src"
+ if not src.is_dir():
+ errorexit(f"Directory not valid: {src!s}")
+ ARGS.directory = src
+ return ARGS
+
+def getmdfile():
+ """Resolves SupportedProtocols.md path"""
+ foutpath = ARGS.directory / "../SupportedProtocols.md"
+ return foutpath.resolve()
+
+def errorexit(msg):
+ """Print an error and exit on critical error"""
+ sys.stderr.write(f"{msg}\n")
+ sys.exit(1)
+
+def extractsupports(path):
+ """Extract all of the Supports: sections and associated brands and models
+ """
+ supports = []
+ insupports = False
+ for line in path.open(encoding="utf-8"):
+ if not line.startswith("//"):
+ continue
+ line = line[2:].strip()
+ if line == "Supports:":
+ insupports = True
+ continue
+ if insupports:
+ match = BRAND_MODEL.match(line)
+ if match:
+ supports.append((match.group("brand"), match.group("model")))
+ else:
+ insupports = False
+ continue
+ # search and inform about any legacy formated supports data
+ elif any(x in line for x in [ \
+ "seems compatible with",
+ "be compatible with",
+ "it working with here"]):
+ print(f"\t{path.name} Legacy supports format found\n\t\t{line}")
+ return supports
+
+
+def makeurl(txt, path):
+ """Make a Markup URL from given filename"""
+ return f"[{txt}]({CODE_URL + path})"
+
+
+def outputprotocols(fout, protocols):
+ """For a given protocol set, sort and output the markdown"""
+ protocols = list(protocols)
+ protocols.sort()
+ for protocol in protocols:
+ fout.write(f"- {protocol}\n")
+
+
+def generate(fout):
+ """Generate data to fout
+ return True on any issues (when alert is active)"""
+ decodedprotocols = getdecodedprotocols()
+ sendonly = getallprotocols() - decodedprotocols
+ allacs = getallacs()
+
+ sets = getalldevices()
+ allcodes = sets.allcodes
+ allbrands = list(allcodes.keys())
+ allbrands.sort()
+
+ fout.write("\n# IR Protocols supported by this library\n\n")
+ fout.write(
+ "| Protocol | Brand | Model | A/C Model | Detailed A/C Support |\n")
+ fout.write("| --- | --- | --- | --- | --- |\n")
+
+ for protocolbrand in allbrands:
+ protocol, brand = protocolbrand
+ codes = allcodes[protocolbrand]
+ codes.sort()
+ acmodels = []
+ acsupport = "-"
+ if protocol in allacs:
+ acmodels = list(allacs[protocol])
+ acmodels.sort()
+ brand = makeurl(brand, protocol + ".h")
+ if protocol not in EXCLUDED_ACS:
+ acsupport = "Yes"
+ # pylint: disable=C0209
+ fout.write("| {} | **{}** | {} | {} | {} |\n".format(
+ makeurl(protocol, protocol + ".cpp"),
+ brand,
+ " ".join(codes).replace("|", "\\|"),
+ " ".join(acmodels),
+ acsupport,
+ ))
+ # pylint: enable=C0209
+
+ fout.write("\n\n## Send only protocols:\n\n")
+ outputprotocols(fout, sendonly)
+
+ fout.write("\n\n## Send & decodable protocols:\n\n")
+ outputprotocols(fout, decodedprotocols)
+
+ return ARGS.alert and sets.printwarnings()
+
+def generatenone():
+ """No out write
+ return True on any issues"""
+ return generate(StringIO())
+
+def generatestdout():
+ """Standard out write
+ return True on any issues"""
+ fout = sys.stdout
+ fout.write(getmarkdownheader())
+ return generate(fout)
+
+def generatefile():
+ """File write, extra detection of changes in existing file
+ return True on any issues, but only if there is changes"""
+ # get file path
+ foutpath = getmdfile()
+ if ARGS.verbose:
+ print(f"Output path: {foutpath!s}")
+ # write data to temp memorystream
+ ftemp = StringIO()
+ ret = generate(ftemp)
+ # get old filedata, skipping header
+ with getmdfile().open("r", encoding="utf-8") as forg:
+ olddata = forg.readlines()[3:]
+ # get new data, skip first empty line
+ ftemp.seek(0)
+ newdata = ftemp.readlines()[1:]
+ # if new data is same as old we don't need to write anything
+ if newdata == olddata:
+ print("No changes, exit without write")
+ return False
+ # write output
+ with foutpath.open("w", encoding="utf-8") as fout:
+ fout.write(getmarkdownheader())
+ fout.write(ftemp.getvalue())
+
+ return ret
+
+def main():
+ """Default main function
+ return True on any issues"""
+ initargs()
+ if ARGS.verbose:
+ print(f"Looking for files in: {ARGS.directory.resolve()!s}")
+ if ARGS.noout:
+ return generatenone()
+ if ARGS.stdout:
+ return generatestdout()
+ # default file
+ return generatefile()
+
+
+if __name__ == "__main__":
+ sys.exit(1 if main() else 0)
diff --git a/lib/lib_basic/IRremoteESP8266/library.json b/lib/lib_basic/IRremoteESP8266/library.json
index f905e1c2f..6ac0ca58a 100644
--- a/lib/lib_basic/IRremoteESP8266/library.json
+++ b/lib/lib_basic/IRremoteESP8266/library.json
@@ -1,6 +1,6 @@
{
"name": "IRremoteESP8266",
- "version": "2.7.19",
+ "version": "2.8.0",
"keywords": "infrared, ir, remote, esp8266, esp32",
"description": "Send and receive infrared signals with multiple protocols (ESP8266/ESP32)",
"repository":
@@ -48,8 +48,6 @@
"frameworks": "arduino",
"platforms": ["espressif8266", "espressif32"],
-
-
"build": {
"srcDir": "IRremoteESP8266/src",
"flags": [ "-I$PROJECT_DIR/include", "-includetasmota_options.h" ]
From ca85acb687837ea25b13bc4286d56b81b69d9482 Mon Sep 17 00:00:00 2001
From: mikep1998 <44448320+mikep1998@users.noreply.github.com>
Date: Fri, 19 Nov 2021 16:56:15 -0800
Subject: [PATCH 102/174] Update xdrv_54_lvgl.ino
If using lvgl and universal display and NOT berry then Init_uDisplay declaration needed.
---
tasmota/xdrv_54_lvgl.ino | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tasmota/xdrv_54_lvgl.ino b/tasmota/xdrv_54_lvgl.ino
index c8f533310..b0987f6dd 100644
--- a/tasmota/xdrv_54_lvgl.ino
+++ b/tasmota/xdrv_54_lvgl.ino
@@ -363,6 +363,8 @@ extern "C" {
* We use Adafruit_LvGL_Glue to leverage the Adafruit
* display ecosystem.
************************************************************/
+extern Renderer *Init_uDisplay(const char *desc);
+
void start_lvgl(const char * uconfig);
void start_lvgl(const char * uconfig) {
From cad8c179b5f30c25dba6f45b87f23ff00544b2d2 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sat, 20 Nov 2021 09:49:23 +0100
Subject: [PATCH 103/174] Berry add gc objects metrics
---
lib/libesp32/Berry/src/be_debuglib.c | 1 +
lib/libesp32/Berry/src/be_gc.c | 9 ++++++++-
lib/libesp32/Berry/src/be_gc.h | 6 +++++-
lib/libesp32/Berry/src/be_vm.c | 2 ++
lib/libesp32/Berry/src/be_vm.h | 2 ++
tasmota/xdrv_52_9_berry.ino | 5 ++++-
6 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/lib/libesp32/Berry/src/be_debuglib.c b/lib/libesp32/Berry/src/be_debuglib.c
index 13c15f50e..aa6e8df3a 100644
--- a/lib/libesp32/Berry/src/be_debuglib.c
+++ b/lib/libesp32/Berry/src/be_debuglib.c
@@ -169,6 +169,7 @@ static int m_counters(bvm *vm)
map_insert(vm, "set", vm->counter_set);
map_insert(vm, "try", vm->counter_try);
map_insert(vm, "raise", vm->counter_exc);
+ map_insert(vm, "objects", vm->counter_gc_scanned);
be_pop(vm, 1);
be_return(vm);
}
diff --git a/lib/libesp32/Berry/src/be_gc.c b/lib/libesp32/Berry/src/be_gc.c
index 0475de7b3..8fa560b73 100644
--- a/lib/libesp32/Berry/src/be_gc.c
+++ b/lib/libesp32/Berry/src/be_gc.c
@@ -497,6 +497,9 @@ static void delete_white(bvm *vm)
prev->next = next;
}
free_object(vm, node);
+#if BE_USE_PERF_COUNTERS
+ vm->counter_gc_freed++;
+#endif
} else {
gc_setwhite(node);
prev = node;
@@ -537,6 +540,10 @@ void be_gc_collect(bvm *vm)
if (vm->gc.status & GC_HALT) {
return; /* the GC cannot run for some reason */
}
+#if BE_USE_PERF_COUNTERS
+ vm->counter_gc_scanned = 0;
+ vm->counter_gc_freed = 0;
+#endif
#if BE_USE_OBSERVABILITY_HOOK
if (vm->obshook != NULL)
(*vm->obshook)(vm, BE_OBS_GC_START, vm->gc.usage);
@@ -559,6 +566,6 @@ void be_gc_collect(bvm *vm)
vm->gc.threshold = next_threshold(vm->gc);
#if BE_USE_OBSERVABILITY_HOOK
if (vm->obshook != NULL)
- (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage);
+ (*vm->obshook)(vm, BE_OBS_GC_END, vm->gc.usage, vm->counter_gc_scanned, vm->counter_gc_freed);
#endif
}
diff --git a/lib/libesp32/Berry/src/be_gc.h b/lib/libesp32/Berry/src/be_gc.h
index b1b204c13..acefc3c06 100644
--- a/lib/libesp32/Berry/src/be_gc.h
+++ b/lib/libesp32/Berry/src/be_gc.h
@@ -37,7 +37,11 @@ if (!gc_isconst(o)) { \
#define gc_setwhite(o) gc_setmark((o), GC_WHITE)
#define gc_setgray(o) gc_setmark((o), GC_GRAY)
-#define gc_setdark(o) gc_setmark((o), GC_DARK)
+#if BE_USE_PERF_COUNTERS
+ #define gc_setdark(o) { vm->counter_gc_scanned++; gc_setmark((o), GC_DARK); }
+#else
+ #define gc_setdark(o) gc_setmark((o), GC_DARK)
+#endif
#define gc_isfixed(o) (((o)->marked & GC_FIXED) != 0)
#define gc_setfixed(o) ((o)->marked |= GC_FIXED)
#define gc_clearfixed(o) ((o)->marked &= ~GC_FIXED)
diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c
index 48834910e..fabba9220 100644
--- a/lib/libesp32/Berry/src/be_vm.c
+++ b/lib/libesp32/Berry/src/be_vm.c
@@ -472,6 +472,8 @@ BERRY_API bvm* be_vm_new(void)
vm->counter_set = 0;
vm->counter_try = 0;
vm->counter_exc = 0;
+ vm->counter_gc_scanned = 0;
+ vm->counter_gc_freed = 0;
#endif
return vm;
}
diff --git a/lib/libesp32/Berry/src/be_vm.h b/lib/libesp32/Berry/src/be_vm.h
index 5890ecd41..0a512210b 100644
--- a/lib/libesp32/Berry/src/be_vm.h
+++ b/lib/libesp32/Berry/src/be_vm.h
@@ -112,6 +112,8 @@ struct bvm {
uint32_t counter_set; /* counter for SETMBR */
uint32_t counter_try; /* counter for `try` statement */
uint32_t counter_exc; /* counter for raised exceptions */
+ uint32_t counter_gc_scanned; /* counter for objects scanned by last gc */
+ uint32_t counter_gc_freed; /* counter for objects freed by last gc */
#endif
#if BE_USE_DEBUG_HOOK
bvalue hook;
diff --git a/tasmota/xdrv_52_9_berry.ino b/tasmota/xdrv_52_9_berry.ino
index c2ed977be..ff74ba950 100644
--- a/tasmota/xdrv_52_9_berry.ino
+++ b/tasmota/xdrv_52_9_berry.ino
@@ -262,7 +262,10 @@ void BerryObservability(bvm *vm, int event...) {
{
int32_t vm_usage2 = va_arg(param, int32_t);
uint32_t gc_elapsed = millis() - gc_time;
- AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_BERRY "GC from %i to %i bytes (in %d ms)"), vm_usage, vm_usage2, gc_elapsed);
+ uint32_t vm_scanned = va_arg(param, uint32_t);
+ uint32_t vm_freed = va_arg(param, uint32_t);
+ AddLog(LOG_LEVEL_DEBUG, D_LOG_BERRY "GC from %i to %i bytes, objects freed %i/%i (in %d ms)",
+ vm_usage, vm_usage2, vm_freed, vm_scanned, gc_elapsed);
// make new threshold tighter when we reach high memory usage
if (!UsePSRAM() && vm->gc.threshold > 20*1024) {
vm->gc.threshold = vm->gc.usage + 10*1024; // increase by only 10 KB
From 56f5584a46007bd03d1c8ae690c418df1275e995 Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Sat, 20 Nov 2021 11:29:04 +0100
Subject: [PATCH 104/174] Berry allow import in tapp (#13743)
* Berry allow import in tapp
* Avoid patching Berry
---
lib/libesp32/Berry/default/berry_conf.h | 2 +-
lib/libesp32/Berry/generate/be_const_strtab.h | 681 ++++++------
.../Berry/generate/be_const_strtab_def.h | 990 +++++++++---------
lib/libesp32/Berry/generate/be_fixed_sys.h | 15 +
.../Zip-readonly-FS/src/ZipReadFS.cpp | 2 +
5 files changed, 855 insertions(+), 835 deletions(-)
diff --git a/lib/libesp32/Berry/default/berry_conf.h b/lib/libesp32/Berry/default/berry_conf.h
index 597c3d65b..d2284ac31 100644
--- a/lib/libesp32/Berry/default/berry_conf.h
+++ b/lib/libesp32/Berry/default/berry_conf.h
@@ -193,7 +193,7 @@
#define BE_USE_TIME_MODULE 0
#define BE_USE_OS_MODULE 0
#define BE_USE_GLOBAL_MODULE 1
-#define BE_USE_SYS_MODULE 0
+#define BE_USE_SYS_MODULE 1
#define BE_USE_DEBUG_MODULE 0
#define BE_USE_GC_MODULE 1
#define BE_USE_SOLIDIFY_MODULE 0
diff --git a/lib/libesp32/Berry/generate/be_const_strtab.h b/lib/libesp32/Berry/generate/be_const_strtab.h
index 718eac65c..12a0ebefc 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab.h
@@ -1,347 +1,348 @@
-extern const bcstring be_const_str_setmember;
-extern const bcstring be_const_str_hex;
-extern const bcstring be_const_str_arch;
-extern const bcstring be_const_str_resolvecmnd;
-extern const bcstring be_const_str_resp_cmnd_done;
-extern const bcstring be_const_str_top;
-extern const bcstring be_const_str_content_start;
-extern const bcstring be_const_str_deg;
-extern const bcstring be_const_str_fromptr;
-extern const bcstring be_const_str_time_dump;
-extern const bcstring be_const_str_compile;
-extern const bcstring be_const_str_members;
-extern const bcstring be_const_str_arg_name;
-extern const bcstring be_const_str_real;
-extern const bcstring be_const_str_insert;
-extern const bcstring be_const_str_open;
-extern const bcstring be_const_str_ctypes_bytes;
-extern const bcstring be_const_str_tag;
-extern const bcstring be_const_str_reset;
-extern const bcstring be_const_str_toupper;
-extern const bcstring be_const_str_POST;
-extern const bcstring be_const_str_SERIAL_6O2;
-extern const bcstring be_const_str_iter;
-extern const bcstring be_const_str_load;
-extern const bcstring be_const_str_available;
-extern const bcstring be_const_str_ceil;
-extern const bcstring be_const_str_clear;
-extern const bcstring be_const_str_digital_read;
-extern const bcstring be_const_str__get_cb;
-extern const bcstring be_const_str_bytes;
-extern const bcstring be_const_str_settings;
-extern const bcstring be_const_str_get_string;
-extern const bcstring be_const_str_asstring;
-extern const bcstring be_const_str_pin_used;
-extern const bcstring be_const_str_pop;
-extern const bcstring be_const_str_static;
-extern const bcstring be_const_str_AES_GCM;
-extern const bcstring be_const_str_SERIAL_8N2;
-extern const bcstring be_const_str_close;
-extern const bcstring be_const_str_set_power;
-extern const bcstring be_const_str_find_op;
-extern const bcstring be_const_str_get;
-extern const bcstring be_const_str_print;
-extern const bcstring be_const_str_publish_result;
-extern const bcstring be_const_str_target_search;
-extern const bcstring be_const_str__ccmd;
-extern const bcstring be_const_str_fromb64;
-extern const bcstring be_const_str_module;
-extern const bcstring be_const_str_allocated;
-extern const bcstring be_const_str_GET;
-extern const bcstring be_const_str_SERIAL_8E1;
-extern const bcstring be_const_str_classof;
-extern const bcstring be_const_str_cos;
-extern const bcstring be_const_str_assert;
-extern const bcstring be_const_str_content_send;
-extern const bcstring be_const_str_read13;
-extern const bcstring be_const_str_reverse;
-extern const bcstring be_const_str_set_timer;
-extern const bcstring be_const_str_class;
-extern const bcstring be_const_str_codedump;
-extern const bcstring be_const_str_isrunning;
-extern const bcstring be_const_str_publish;
-extern const bcstring be_const_str_range;
-extern const bcstring be_const_str_write;
-extern const bcstring be_const_str_opt_connect;
-extern const bcstring be_const_str_SERIAL_7O1;
-extern const bcstring be_const_str_update;
-extern const bcstring be_const_str__cmd;
-extern const bcstring be_const_str_isnan;
-extern const bcstring be_const_str_resp_cmnd_failed;
-extern const bcstring be_const_str_SERIAL_5O1;
-extern const bcstring be_const_str_abs;
-extern const bcstring be_const_str_SERIAL_7E2;
-extern const bcstring be_const_str_SERIAL_6N1;
-extern const bcstring be_const_str__cb;
-extern const bcstring be_const_str_depower;
-extern const bcstring be_const_str_Tasmota;
-extern const bcstring be_const_str_item;
-extern const bcstring be_const_str_set_useragent;
-extern const bcstring be_const_str_wire2;
-extern const bcstring be_const_str_time_reached;
-extern const bcstring be_const_str_chars_in_string;
-extern const bcstring be_const_str_false;
-extern const bcstring be_const_str_add_rule;
-extern const bcstring be_const_str_setbits;
-extern const bcstring be_const_str_write_file;
-extern const bcstring be_const_str_hs2rgb;
-extern const bcstring be_const_str_SERIAL_8O1;
-extern const bcstring be_const_str_wd;
-extern const bcstring be_const_str_wire_scan;
-extern const bcstring be_const_str_AudioFileSourceFS;
-extern const bcstring be_const_str_get_free_heap;
-extern const bcstring be_const_str_AudioGenerator;
-extern const bcstring be_const_str_SERIAL_5E2;
-extern const bcstring be_const_str__global_addr;
-extern const bcstring be_const_str_content_send_style;
-extern const bcstring be_const_str_remove_timer;
-extern const bcstring be_const_str_tr;
-extern const bcstring be_const_str_dot_w;
-extern const bcstring be_const_str_MD5;
-extern const bcstring be_const_str_break;
-extern const bcstring be_const_str_digital_write;
-extern const bcstring be_const_str_asin;
-extern const bcstring be_const_str__def;
-extern const bcstring be_const_str_exec_cmd;
-extern const bcstring be_const_str_exists;
-extern const bcstring be_const_str_flush;
-extern const bcstring be_const_str_as;
-extern const bcstring be_const_str_set_light;
-extern const bcstring be_const_str_time_str;
-extern const bcstring be_const_str_arg_size;
-extern const bcstring be_const_str_bus;
-extern const bcstring be_const_str_opt_eq;
-extern const bcstring be_const_str_try_rule;
-extern const bcstring be_const_str_kv;
-extern const bcstring be_const_str_reverse_gamma10;
-extern const bcstring be_const_str_tostring;
-extern const bcstring be_const_str_format;
-extern const bcstring be_const_str_tob64;
-extern const bcstring be_const_str_continue;
-extern const bcstring be_const_str_log;
-extern const bcstring be_const_str_SERIAL_7N1;
-extern const bcstring be_const_str_lower;
-extern const bcstring be_const_str_stop;
-extern const bcstring be_const_str_count;
-extern const bcstring be_const_str_encrypt;
-extern const bcstring be_const_str_resp_cmnd_str;
-extern const bcstring be_const_str_byte;
-extern const bcstring be_const_str_fromstring;
-extern const bcstring be_const_str_run_deferred;
-extern const bcstring be_const_str_setitem;
-extern const bcstring be_const_str_cmd;
-extern const bcstring be_const_str_event;
-extern const bcstring be_const_str_SERIAL_6E1;
-extern const bcstring be_const_str_SERIAL_6O1;
-extern const bcstring be_const_str_remove_driver;
-extern const bcstring be_const_str_EC_C25519;
-extern const bcstring be_const_str_read12;
-extern const bcstring be_const_str__write;
-extern const bcstring be_const_str_opt_call;
-extern const bcstring be_const_str_AudioOutput;
-extern const bcstring be_const_str_attrdump;
-extern const bcstring be_const_str_int;
-extern const bcstring be_const_str_AudioGeneratorMP3;
-extern const bcstring be_const_str_add_header;
-extern const bcstring be_const_str_ctypes_bytes_dyn;
-extern const bcstring be_const_str_keys;
-extern const bcstring be_const_str_set_auth;
-extern const bcstring be_const_str_def;
-extern const bcstring be_const_str_;
-extern const bcstring be_const_str_SERIAL_5N2;
-extern const bcstring be_const_str__rules;
-extern const bcstring be_const_str_has;
-extern const bcstring be_const_str_set;
-extern const bcstring be_const_str_public_key;
-extern const bcstring be_const_str_get_power;
-extern const bcstring be_const_str_type;
-extern const bcstring be_const_str_opt_add;
-extern const bcstring be_const_str_dot_size;
-extern const bcstring be_const_str_set_timeouts;
-extern const bcstring be_const_str_tomap;
-extern const bcstring be_const_str_getbits;
-extern const bcstring be_const_str_sinh;
-extern const bcstring be_const_str_sqrt;
-extern const bcstring be_const_str_dot_p1;
-extern const bcstring be_const_str_begin;
-extern const bcstring be_const_str_delay;
-extern const bcstring be_const_str_scan;
-extern const bcstring be_const_str_for;
-extern const bcstring be_const_str_read8;
-extern const bcstring be_const_str_AudioGeneratorWAV;
-extern const bcstring be_const_str_get_light;
-extern const bcstring be_const_str__global_def;
-extern const bcstring be_const_str_map;
-extern const bcstring be_const_str_redirect;
-extern const bcstring be_const_str__ptr;
-extern const bcstring be_const_str_isinstance;
-extern const bcstring be_const_str_pin;
-extern const bcstring be_const_str_size;
-extern const bcstring be_const_str_state;
-extern const bcstring be_const_str_dot_p;
-extern const bcstring be_const_str__drivers;
-extern const bcstring be_const_str_erase;
-extern const bcstring be_const_str_I2C_Driver;
-extern const bcstring be_const_str_addr;
-extern const bcstring be_const_str_copy;
-extern const bcstring be_const_str_find_key_i;
-extern const bcstring be_const_str_pin_mode;
-extern const bcstring be_const_str_setrange;
-extern const bcstring be_const_str_SERIAL_8N1;
-extern const bcstring be_const_str_char;
-extern const bcstring be_const_str_concat;
+extern const bcstring be_const_str_pow;
extern const bcstring be_const_str_remove;
-extern const bcstring be_const_str_serial;
-extern const bcstring be_const_str_SERIAL_5O2;
-extern const bcstring be_const_str__read;
-extern const bcstring be_const_str_cmd_res;
-extern const bcstring be_const_str_contains;
-extern const bcstring be_const_str_imax;
-extern const bcstring be_const_str_super;
-extern const bcstring be_const_str_try;
-extern const bcstring be_const_str_last_modified;
-extern const bcstring be_const_str_return;
-extern const bcstring be_const_str_SERIAL_6N2;
-extern const bcstring be_const_str_call;
-extern const bcstring be_const_str_resize;
-extern const bcstring be_const_str_escape;
-extern const bcstring be_const_str_upper;
-extern const bcstring be_const_str_end;
-extern const bcstring be_const_str_gamma8;
-extern const bcstring be_const_str_memory;
-extern const bcstring be_const_str_wifi;
-extern const bcstring be_const_str_yield;
-extern const bcstring be_const_str_get_option;
-extern const bcstring be_const_str_init;
-extern const bcstring be_const_str_read;
-extern const bcstring be_const_str__settings_ptr;
-extern const bcstring be_const_str__timers;
-extern const bcstring be_const_str_finish;
-extern const bcstring be_const_str___upper__;
-extern const bcstring be_const_str_dump;
-extern const bcstring be_const_str_save;
-extern const bcstring be_const_str___lower__;
-extern const bcstring be_const_str_listdir;
-extern const bcstring be_const_str_check_privileged_access;
-extern const bcstring be_const_str_rand;
-extern const bcstring be_const_str_web_send;
-extern const bcstring be_const_str_i2c_enabled;
-extern const bcstring be_const_str_wire1;
-extern const bcstring be_const_str_dac_voltage;
-extern const bcstring be_const_str_imin;
-extern const bcstring be_const_str_log10;
-extern const bcstring be_const_str_skip;
-extern const bcstring be_const_str_else;
-extern const bcstring be_const_str_except;
-extern const bcstring be_const_str_nil;
-extern const bcstring be_const_str_resp_cmnd_error;
-extern const bcstring be_const_str_calldepth;
-extern const bcstring be_const_str_do;
-extern const bcstring be_const_str___iterator__;
-extern const bcstring be_const_str_true;
-extern const bcstring be_const_str_rad;
+extern const bcstring be_const_str_remove_timer;
+extern const bcstring be_const_str_MD5;
+extern const bcstring be_const_str__ccmd;
+extern const bcstring be_const_str_digital_write;
+extern const bcstring be_const_str_dot_p2;
+extern const bcstring be_const_str_floor;
+extern const bcstring be_const_str_input;
+extern const bcstring be_const_str_range;
+extern const bcstring be_const_str_atan;
+extern const bcstring be_const_str_find_op;
+extern const bcstring be_const_str_SERIAL_6N1;
+extern const bcstring be_const_str_classname;
+extern const bcstring be_const_str_content_start;
extern const bcstring be_const_str_import;
-extern const bcstring be_const_str_SERIAL_8O2;
-extern const bcstring be_const_str_gamma10;
-extern const bcstring be_const_str_elif;
-extern const bcstring be_const_str_resp_cmnd;
-extern const bcstring be_const_str_shared_key;
-extern const bcstring be_const_str_web_send_decimal;
-extern const bcstring be_const_str_write8;
-extern const bcstring be_const_str_SERIAL_5E1;
-extern const bcstring be_const_str_member;
-extern const bcstring be_const_str_sin;
-extern const bcstring be_const_str_OneWire;
-extern const bcstring be_const_str_SERIAL_7O2;
+extern const bcstring be_const_str_raise;
+extern const bcstring be_const_str_SERIAL_8N2;
+extern const bcstring be_const_str_keys;
+extern const bcstring be_const_str_content_send_style;
+extern const bcstring be_const_str_static;
extern const bcstring be_const_str__begin_transmission;
-extern const bcstring be_const_str_get_switch;
-extern const bcstring be_const_str_name;
-extern const bcstring be_const_str_nan;
+extern const bcstring be_const_str__request_from;
+extern const bcstring be_const_str_isnan;
+extern const bcstring be_const_str_reverse_gamma10;
+extern const bcstring be_const_str_number;
+extern const bcstring be_const_str_resp_cmnd_str;
+extern const bcstring be_const_str_run_deferred;
+extern const bcstring be_const_str_exec_rules;
+extern const bcstring be_const_str_web_send;
+extern const bcstring be_const_str_GET;
+extern const bcstring be_const_str__rules;
+extern const bcstring be_const_str_begin;
+extern const bcstring be_const_str_escape;
+extern const bcstring be_const_str_I2C_Driver;
+extern const bcstring be_const_str_char;
+extern const bcstring be_const_str_opt_neq;
+extern const bcstring be_const_str_Wire;
+extern const bcstring be_const_str_asstring;
+extern const bcstring be_const_str_strftime;
+extern const bcstring be_const_str_last_modified;
+extern const bcstring be_const_str_set;
extern const bcstring be_const_str_add;
extern const bcstring be_const_str_eth;
-extern const bcstring be_const_str_find;
-extern const bcstring be_const_str_read32;
-extern const bcstring be_const_str_remove_cmd;
-extern const bcstring be_const_str_gc;
-extern const bcstring be_const_str_reset_search;
-extern const bcstring be_const_str_content_stop;
-extern const bcstring be_const_str_counters;
-extern const bcstring be_const_str_detect;
-extern const bcstring be_const_str_exp;
-extern const bcstring be_const_str_on;
-extern const bcstring be_const_str_arg;
-extern const bcstring be_const_str_reduce;
-extern const bcstring be_const_str_split;
-extern const bcstring be_const_str_strftime;
-extern const bcstring be_const_str_raise;
-extern const bcstring be_const_str_AudioOutputI2S;
-extern const bcstring be_const_str_if;
-extern const bcstring be_const_str_cb_dispatch;
-extern const bcstring be_const_str_exec_tele;
-extern const bcstring be_const_str_srand;
-extern const bcstring be_const_str_write_bytes;
-extern const bcstring be_const_str__settings_def;
-extern const bcstring be_const_str_cosh;
-extern const bcstring be_const_str_pi;
-extern const bcstring be_const_str_remove_rule;
-extern const bcstring be_const_str_scale_uint;
-extern const bcstring be_const_str_var;
-extern const bcstring be_const_str_SERIAL_8E2;
-extern const bcstring be_const_str_acos;
-extern const bcstring be_const_str_gen_cb;
-extern const bcstring be_const_str_read_bytes;
-extern const bcstring be_const_str_AudioFileSource;
-extern const bcstring be_const_str_SERIAL_5N1;
-extern const bcstring be_const_str_wire;
-extern const bcstring be_const_str_while;
-extern const bcstring be_const_str_SERIAL_7N2;
-extern const bcstring be_const_str_get_size;
-extern const bcstring be_const_str_exec_rules;
-extern const bcstring be_const_str__available;
-extern const bcstring be_const_str_search;
-extern const bcstring be_const_str_global;
-extern const bcstring be_const_str_collect;
-extern const bcstring be_const_str_input;
-extern const bcstring be_const_str_response_append;
-extern const bcstring be_const_str_str;
-extern const bcstring be_const_str_SERIAL_6E2;
-extern const bcstring be_const_str_SERIAL_7E1;
-extern const bcstring be_const_str_content_button;
-extern const bcstring be_const_str_number;
-extern const bcstring be_const_str_tanh;
-extern const bcstring be_const_str_toptr;
-extern const bcstring be_const_str_write_bit;
-extern const bcstring be_const_str_add_cmd;
-extern const bcstring be_const_str_select;
-extern const bcstring be_const_str_traceback;
-extern const bcstring be_const_str_atan2;
-extern const bcstring be_const_str_loop;
-extern const bcstring be_const_str_millis;
-extern const bcstring be_const_str_url_encode;
-extern const bcstring be_const_str__end_transmission;
-extern const bcstring be_const_str_deinit;
-extern const bcstring be_const_str_tan;
-extern const bcstring be_const_str_geti;
-extern const bcstring be_const_str_seti;
-extern const bcstring be_const_str__buffer;
-extern const bcstring be_const_str_atan;
-extern const bcstring be_const_str_content_flush;
-extern const bcstring be_const_str_list;
-extern const bcstring be_const_str_tolower;
-extern const bcstring be_const_str_dot_len;
-extern const bcstring be_const_str__request_from;
-extern const bcstring be_const_str_has_arg;
-extern const bcstring be_const_str_pow;
-extern const bcstring be_const_str_push;
-extern const bcstring be_const_str_read24;
-extern const bcstring be_const_str_enabled;
-extern const bcstring be_const_str_webclient;
-extern const bcstring be_const_str_opt_neq;
-extern const bcstring be_const_str_dot_p2;
-extern const bcstring be_const_str_Wire;
-extern const bcstring be_const_str_decrypt;
-extern const bcstring be_const_str_floor;
-extern const bcstring be_const_str_issubclass;
-extern const bcstring be_const_str_classname;
+extern const bcstring be_const_str_publish;
extern const bcstring be_const_str_rtc;
+extern const bcstring be_const_str_scan;
+extern const bcstring be_const_str_EC_C25519;
+extern const bcstring be_const_str_nil;
+extern const bcstring be_const_str_ceil;
+extern const bcstring be_const_str_item;
+extern const bcstring be_const_str_log;
+extern const bcstring be_const_str__global_def;
+extern const bcstring be_const_str_clear;
+extern const bcstring be_const_str_atan2;
+extern const bcstring be_const_str_dump;
+extern const bcstring be_const_str_fromb64;
+extern const bcstring be_const_str_deinit;
+extern const bcstring be_const_str_read13;
+extern const bcstring be_const_str_SERIAL_8O1;
+extern const bcstring be_const_str_SERIAL_6O1;
+extern const bcstring be_const_str_add_rule;
+extern const bcstring be_const_str_fromstring;
+extern const bcstring be_const_str_SERIAL_6E2;
+extern const bcstring be_const_str_try_rule;
+extern const bcstring be_const_str_gc;
+extern const bcstring be_const_str_publish_result;
+extern const bcstring be_const_str_response_append;
+extern const bcstring be_const_str_continue;
+extern const bcstring be_const_str_dot_p1;
+extern const bcstring be_const_str__def;
+extern const bcstring be_const_str_imin;
+extern const bcstring be_const_str_chars_in_string;
+extern const bcstring be_const_str_concat;
+extern const bcstring be_const_str_content_stop;
+extern const bcstring be_const_str_def;
+extern const bcstring be_const_str_traceback;
+extern const bcstring be_const_str_wire;
+extern const bcstring be_const_str_calldepth;
+extern const bcstring be_const_str_finish;
+extern const bcstring be_const_str_log10;
+extern const bcstring be_const_str_name;
+extern const bcstring be_const_str_time_str;
+extern const bcstring be_const_str_do;
+extern const bcstring be_const_str_read;
+extern const bcstring be_const_str_set_auth;
+extern const bcstring be_const_str_Tasmota;
+extern const bcstring be_const_str_SERIAL_7E2;
+extern const bcstring be_const_str_resolvecmnd;
+extern const bcstring be_const_str___lower__;
+extern const bcstring be_const_str_addr;
+extern const bcstring be_const_str_gamma8;
+extern const bcstring be_const_str_member;
+extern const bcstring be_const_str_scale_uint;
+extern const bcstring be_const_str_codedump;
+extern const bcstring be_const_str_opt_call;
+extern const bcstring be_const_str_SERIAL_5N2;
+extern const bcstring be_const_str_attrdump;
+extern const bcstring be_const_str_hex;
+extern const bcstring be_const_str_remove_cmd;
+extern const bcstring be_const_str_AudioOutput;
+extern const bcstring be_const_str_break;
+extern const bcstring be_const_str_SERIAL_5O1;
+extern const bcstring be_const_str_rand;
+extern const bcstring be_const_str_class;
+extern const bcstring be_const_str_public_key;
+extern const bcstring be_const_str_search;
+extern const bcstring be_const_str_update;
+extern const bcstring be_const_str_end;
+extern const bcstring be_const_str_i2c_enabled;
+extern const bcstring be_const_str_read_bytes;
+extern const bcstring be_const_str_fromptr;
+extern const bcstring be_const_str_pin_used;
+extern const bcstring be_const_str_redirect;
+extern const bcstring be_const_str__drivers;
+extern const bcstring be_const_str_get_size;
+extern const bcstring be_const_str_set_power;
+extern const bcstring be_const_str_loop;
+extern const bcstring be_const_str_read32;
+extern const bcstring be_const_str_add_cmd;
+extern const bcstring be_const_str__settings_ptr;
+extern const bcstring be_const_str_reset;
+extern const bcstring be_const_str__ptr;
+extern const bcstring be_const_str_detect;
+extern const bcstring be_const_str_reset_search;
+extern const bcstring be_const_str_SERIAL_6E1;
+extern const bcstring be_const_str__read;
+extern const bcstring be_const_str_true;
+extern const bcstring be_const_str_opt_eq;
extern const bcstring be_const_str_add_driver;
+extern const bcstring be_const_str_tob64;
+extern const bcstring be_const_str_wire1;
+extern const bcstring be_const_str__timers;
+extern const bcstring be_const_str_opt_connect;
+extern const bcstring be_const_str_SERIAL_5E1;
+extern const bcstring be_const_str_select;
+extern const bcstring be_const_str_setbits;
+extern const bcstring be_const_str_webclient;
+extern const bcstring be_const_str_deg;
+extern const bcstring be_const_str_flush;
+extern const bcstring be_const_str_hs2rgb;
+extern const bcstring be_const_str_SERIAL_8E1;
+extern const bcstring be_const_str_setrange;
+extern const bcstring be_const_str_dot_len;
+extern const bcstring be_const_str_byte;
+extern const bcstring be_const_str_issubclass;
+extern const bcstring be_const_str_while;
+extern const bcstring be_const_str_enabled;
+extern const bcstring be_const_str_sin;
+extern const bcstring be_const_str_except;
+extern const bcstring be_const_str_AudioOutputI2S;
+extern const bcstring be_const_str_SERIAL_7N2;
+extern const bcstring be_const_str_call;
+extern const bcstring be_const_str_imax;
+extern const bcstring be_const_str_isrunning;
+extern const bcstring be_const_str_read8;
+extern const bcstring be_const_str_resp_cmnd_error;
+extern const bcstring be_const_str_AudioFileSourceFS;
+extern const bcstring be_const_str___iterator__;
+extern const bcstring be_const_str_contains;
+extern const bcstring be_const_str_web_send_decimal;
+extern const bcstring be_const_str_dac_voltage;
+extern const bcstring be_const_str_time_reached;
+extern const bcstring be_const_str_if;
+extern const bcstring be_const_str_read24;
+extern const bcstring be_const_str_toptr;
+extern const bcstring be_const_str_else;
+extern const bcstring be_const_str__global_addr;
+extern const bcstring be_const_str_classof;
+extern const bcstring be_const_str_SERIAL_7O1;
+extern const bcstring be_const_str_print;
+extern const bcstring be_const_str_setmember;
+extern const bcstring be_const_str_dot_size;
+extern const bcstring be_const_str__write;
+extern const bcstring be_const_str_init;
+extern const bcstring be_const_str_gamma10;
+extern const bcstring be_const_str_gen_cb;
+extern const bcstring be_const_str_remove_rule;
+extern const bcstring be_const_str_ctypes_bytes_dyn;
+extern const bcstring be_const_str_SERIAL_6N2;
+extern const bcstring be_const_str_available;
+extern const bcstring be_const_str_cb_dispatch;
+extern const bcstring be_const_str_isinstance;
+extern const bcstring be_const_str_copy;
+extern const bcstring be_const_str_find;
+extern const bcstring be_const_str_POST;
+extern const bcstring be_const_str_write_bytes;
+extern const bcstring be_const_str_;
+extern const bcstring be_const_str_type;
+extern const bcstring be_const_str_allocated;
+extern const bcstring be_const_str_insert;
+extern const bcstring be_const_str_tolower;
+extern const bcstring be_const_str_dot_w;
+extern const bcstring be_const_str_srand;
+extern const bcstring be_const_str_wire2;
+extern const bcstring be_const_str_format;
+extern const bcstring be_const_str_yield;
+extern const bcstring be_const_str_SERIAL_5E2;
+extern const bcstring be_const_str_reduce;
+extern const bcstring be_const_str_resp_cmnd_done;
+extern const bcstring be_const_str_abs;
+extern const bcstring be_const_str_setitem;
+extern const bcstring be_const_str_OneWire;
+extern const bcstring be_const_str_upper;
+extern const bcstring be_const_str_module;
+extern const bcstring be_const_str_counters;
+extern const bcstring be_const_str_tag;
+extern const bcstring be_const_str_tanh;
+extern const bcstring be_const_str_get_string;
+extern const bcstring be_const_str_read12;
+extern const bcstring be_const_str_wire_scan;
+extern const bcstring be_const_str_seti;
+extern const bcstring be_const_str_cmd;
+extern const bcstring be_const_str_content_send;
+extern const bcstring be_const_str_global;
+extern const bcstring be_const_str_var;
+extern const bcstring be_const_str_SERIAL_7N1;
+extern const bcstring be_const_str_resize;
+extern const bcstring be_const_str_split;
+extern const bcstring be_const_str_str;
+extern const bcstring be_const_str_url_encode;
+extern const bcstring be_const_str_get_option;
+extern const bcstring be_const_str_listdir;
+extern const bcstring be_const_str_tomap;
+extern const bcstring be_const_str_check_privileged_access;
+extern const bcstring be_const_str_pin_mode;
+extern const bcstring be_const_str_pin;
+extern const bcstring be_const_str_try;
+extern const bcstring be_const_str__buffer;
+extern const bcstring be_const_str_cos;
+extern const bcstring be_const_str_dot_p;
+extern const bcstring be_const_str_SERIAL_7O2;
+extern const bcstring be_const_str_real;
+extern const bcstring be_const_str_set_timer;
+extern const bcstring be_const_str_count;
+extern const bcstring be_const_str_write;
+extern const bcstring be_const_str__settings_def;
+extern const bcstring be_const_str_digital_read;
+extern const bcstring be_const_str_path;
+extern const bcstring be_const_str_delay;
+extern const bcstring be_const_str_stop;
+extern const bcstring be_const_str_AES_GCM;
+extern const bcstring be_const_str_SERIAL_6O2;
+extern const bcstring be_const_str_open;
+extern const bcstring be_const_str_top;
+extern const bcstring be_const_str_write_bit;
+extern const bcstring be_const_str_state;
+extern const bcstring be_const_str_set_useragent;
+extern const bcstring be_const_str_as;
+extern const bcstring be_const_str_erase;
+extern const bcstring be_const_str_has_arg;
+extern const bcstring be_const_str_map;
+extern const bcstring be_const_str_on;
+extern const bcstring be_const_str_AudioGeneratorWAV;
+extern const bcstring be_const_str__cb;
+extern const bcstring be_const_str_decrypt;
+extern const bcstring be_const_str_sqrt;
+extern const bcstring be_const_str_SERIAL_5N1;
+extern const bcstring be_const_str_find_key_i;
+extern const bcstring be_const_str_arg;
+extern const bcstring be_const_str_depower;
+extern const bcstring be_const_str_write_file;
+extern const bcstring be_const_str_SERIAL_5O2;
+extern const bcstring be_const_str_get_light;
+extern const bcstring be_const_str_pop;
+extern const bcstring be_const_str_exec_tele;
+extern const bcstring be_const_str_set_light;
+extern const bcstring be_const_str_set_timeouts;
+extern const bcstring be_const_str_sinh;
+extern const bcstring be_const_str_AudioGenerator;
+extern const bcstring be_const_str_SERIAL_7E1;
+extern const bcstring be_const_str_getbits;
+extern const bcstring be_const_str_shared_key;
+extern const bcstring be_const_str_time_dump;
+extern const bcstring be_const_str_content_button;
+extern const bcstring be_const_str_geti;
+extern const bcstring be_const_str_arch;
+extern const bcstring be_const_str_asin;
+extern const bcstring be_const_str_get_free_heap;
+extern const bcstring be_const_str_resp_cmnd;
+extern const bcstring be_const_str_content_flush;
+extern const bcstring be_const_str_millis;
+extern const bcstring be_const_str_serial;
+extern const bcstring be_const_str_skip;
+extern const bcstring be_const_str_event;
+extern const bcstring be_const_str_opt_add;
+extern const bcstring be_const_str_bus;
+extern const bcstring be_const_str_acos;
+extern const bcstring be_const_str_bytes;
+extern const bcstring be_const_str_compile;
+extern const bcstring be_const_str_get;
+extern const bcstring be_const_str_tan;
+extern const bcstring be_const_str_encrypt;
+extern const bcstring be_const_str_cmd_res;
+extern const bcstring be_const_str_collect;
+extern const bcstring be_const_str_arg_size;
+extern const bcstring be_const_str_reverse;
+extern const bcstring be_const_str_close;
+extern const bcstring be_const_str_members;
+extern const bcstring be_const_str_assert;
+extern const bcstring be_const_str_exec_cmd;
+extern const bcstring be_const_str_get_power;
+extern const bcstring be_const_str_resp_cmnd_failed;
+extern const bcstring be_const_str_target_search;
+extern const bcstring be_const_str_AudioFileSource;
+extern const bcstring be_const_str_SERIAL_8N1;
+extern const bcstring be_const_str_pi;
+extern const bcstring be_const_str_add_header;
+extern const bcstring be_const_str_list;
+extern const bcstring be_const_str_super;
+extern const bcstring be_const_str_has;
+extern const bcstring be_const_str___upper__;
+extern const bcstring be_const_str_exp;
+extern const bcstring be_const_str_int;
+extern const bcstring be_const_str_size;
+extern const bcstring be_const_str_for;
+extern const bcstring be_const_str_ctypes_bytes;
+extern const bcstring be_const_str_wifi;
+extern const bcstring be_const_str_elif;
+extern const bcstring be_const_str_arg_name;
+extern const bcstring be_const_str_cosh;
+extern const bcstring be_const_str_lower;
+extern const bcstring be_const_str_push;
+extern const bcstring be_const_str_save;
+extern const bcstring be_const_str_load;
+extern const bcstring be_const_str_SERIAL_8E2;
+extern const bcstring be_const_str_nan;
+extern const bcstring be_const_str_remove_driver;
+extern const bcstring be_const_str_write8;
+extern const bcstring be_const_str__get_cb;
+extern const bcstring be_const_str_iter;
+extern const bcstring be_const_str__cmd;
+extern const bcstring be_const_str_exists;
+extern const bcstring be_const_str_AudioGeneratorMP3;
+extern const bcstring be_const_str__end_transmission;
+extern const bcstring be_const_str_get_switch;
+extern const bcstring be_const_str__available;
+extern const bcstring be_const_str_false;
+extern const bcstring be_const_str_settings;
+extern const bcstring be_const_str_wd;
+extern const bcstring be_const_str_SERIAL_8O2;
+extern const bcstring be_const_str_rad;
+extern const bcstring be_const_str_kv;
+extern const bcstring be_const_str_toupper;
+extern const bcstring be_const_str_tr;
+extern const bcstring be_const_str_return;
+extern const bcstring be_const_str_memory;
+extern const bcstring be_const_str_tostring;
diff --git a/lib/libesp32/Berry/generate/be_const_strtab_def.h b/lib/libesp32/Berry/generate/be_const_strtab_def.h
index aed550fdc..759cf6c02 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab_def.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab_def.h
@@ -1,518 +1,520 @@
-be_define_const_str(setmember, "setmember", 1432909441u, 0, 9, NULL);
-be_define_const_str(hex, "hex", 4273249610u, 0, 3, NULL);
-be_define_const_str(arch, "arch", 2952804297u, 0, 4, &be_const_str_resolvecmnd);
-be_define_const_str(resolvecmnd, "resolvecmnd", 993361485u, 0, 11, &be_const_str_resp_cmnd_done);
-be_define_const_str(resp_cmnd_done, "resp_cmnd_done", 2601874875u, 0, 14, NULL);
-be_define_const_str(top, "top", 2802900028u, 0, 3, NULL);
-be_define_const_str(content_start, "content_start", 2937509069u, 0, 13, &be_const_str_deg);
-be_define_const_str(deg, "deg", 3327754271u, 0, 3, &be_const_str_fromptr);
-be_define_const_str(fromptr, "fromptr", 666189689u, 0, 7, &be_const_str_time_dump);
-be_define_const_str(time_dump, "time_dump", 3330410747u, 0, 9, NULL);
-be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_members);
-be_define_const_str(members, "members", 937576464u, 0, 7, NULL);
-be_define_const_str(arg_name, "arg_name", 1345046155u, 0, 8, &be_const_str_real);
-be_define_const_str(real, "real", 3604983901u, 0, 4, NULL);
-be_define_const_str(insert, "insert", 3332609576u, 0, 6, NULL);
-be_define_const_str(open, "open", 3546203337u, 0, 4, NULL);
-be_define_const_str(ctypes_bytes, "ctypes_bytes", 3879019703u, 0, 12, &be_const_str_tag);
-be_define_const_str(tag, "tag", 2516003219u, 0, 3, NULL);
-be_define_const_str(reset, "reset", 1695364032u, 0, 5, &be_const_str_toupper);
-be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, NULL);
-be_define_const_str(POST, "POST", 1929554311u, 0, 4, &be_const_str_SERIAL_6O2);
-be_define_const_str(SERIAL_6O2, "SERIAL_6O2", 316486129u, 0, 10, &be_const_str_iter);
-be_define_const_str(iter, "iter", 3124256359u, 0, 4, &be_const_str_load);
-be_define_const_str(load, "load", 3859241449u, 0, 4, NULL);
-be_define_const_str(available, "available", 1727918744u, 0, 9, &be_const_str_ceil);
-be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_clear);
-be_define_const_str(clear, "clear", 1550717474u, 0, 5, &be_const_str_digital_read);
-be_define_const_str(digital_read, "digital_read", 3585496928u, 0, 12, NULL);
-be_define_const_str(_get_cb, "_get_cb", 1448849122u, 0, 7, &be_const_str_bytes);
-be_define_const_str(bytes, "bytes", 1706151940u, 0, 5, &be_const_str_settings);
-be_define_const_str(settings, "settings", 1745255176u, 0, 8, NULL);
-be_define_const_str(get_string, "get_string", 4195847969u, 0, 10, NULL);
-be_define_const_str(asstring, "asstring", 1298225088u, 0, 8, &be_const_str_pin_used);
-be_define_const_str(pin_used, "pin_used", 4033854612u, 0, 8, &be_const_str_pop);
-be_define_const_str(pop, "pop", 1362321360u, 0, 3, NULL);
-be_define_const_str(static, "static", 3532702267u, 71, 6, NULL);
-be_define_const_str(AES_GCM, "AES_GCM", 3832208678u, 0, 7, &be_const_str_SERIAL_8N2);
-be_define_const_str(SERIAL_8N2, "SERIAL_8N2", 2386074854u, 0, 10, NULL);
-be_define_const_str(close, "close", 667630371u, 0, 5, &be_const_str_set_power);
-be_define_const_str(set_power, "set_power", 549820893u, 0, 9, NULL);
-be_define_const_str(find_op, "find_op", 3766713376u, 0, 7, NULL);
-be_define_const_str(get, "get", 1410115415u, 0, 3, NULL);
-be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_publish_result);
-be_define_const_str(publish_result, "publish_result", 2013351252u, 0, 14, NULL);
-be_define_const_str(target_search, "target_search", 1947846553u, 0, 13, NULL);
-be_define_const_str(_ccmd, "_ccmd", 2163421413u, 0, 5, &be_const_str_fromb64);
-be_define_const_str(fromb64, "fromb64", 2717019639u, 0, 7, &be_const_str_module);
-be_define_const_str(module, "module", 3617558685u, 0, 6, NULL);
-be_define_const_str(allocated, "allocated", 429986098u, 0, 9, NULL);
-be_define_const_str(GET, "GET", 2531704439u, 0, 3, NULL);
-be_define_const_str(SERIAL_8E1, "SERIAL_8E1", 2371121616u, 0, 10, &be_const_str_classof);
-be_define_const_str(classof, "classof", 1796577762u, 0, 7, &be_const_str_cos);
-be_define_const_str(cos, "cos", 4220379804u, 0, 3, NULL);
-be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_content_send);
-be_define_const_str(content_send, "content_send", 1673733649u, 0, 12, &be_const_str_read13);
-be_define_const_str(read13, "read13", 12887293u, 0, 6, &be_const_str_reverse);
-be_define_const_str(reverse, "reverse", 558918661u, 0, 7, &be_const_str_set_timer);
-be_define_const_str(set_timer, "set_timer", 2135414533u, 0, 9, &be_const_str_class);
-be_define_const_str(class, "class", 2872970239u, 57, 5, NULL);
-be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, &be_const_str_isrunning);
-be_define_const_str(isrunning, "isrunning", 1688182268u, 0, 9, &be_const_str_publish);
-be_define_const_str(publish, "publish", 264247304u, 0, 7, &be_const_str_range);
-be_define_const_str(range, "range", 4208725202u, 0, 5, &be_const_str_write);
-be_define_const_str(write, "write", 3190202204u, 0, 5, NULL);
-be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str_SERIAL_7O1);
-be_define_const_str(SERIAL_7O1, "SERIAL_7O1", 1823802675u, 0, 10, NULL);
-be_define_const_str(update, "update", 672109684u, 0, 6, NULL);
-be_define_const_str(_cmd, "_cmd", 3419822142u, 0, 4, &be_const_str_isnan);
-be_define_const_str(isnan, "isnan", 2981347434u, 0, 5, &be_const_str_resp_cmnd_failed);
-be_define_const_str(resp_cmnd_failed, "resp_cmnd_failed", 2136281562u, 0, 16, NULL);
-be_define_const_str(SERIAL_5O1, "SERIAL_5O1", 3782657917u, 0, 10, &be_const_str_abs);
-be_define_const_str(abs, "abs", 709362235u, 0, 3, NULL);
-be_define_const_str(SERIAL_7E2, "SERIAL_7E2", 97385204u, 0, 10, NULL);
-be_define_const_str(SERIAL_6N1, "SERIAL_6N1", 198895701u, 0, 10, &be_const_str__cb);
-be_define_const_str(_cb, "_cb", 4043300367u, 0, 3, &be_const_str_depower);
-be_define_const_str(depower, "depower", 3563819571u, 0, 7, NULL);
-be_define_const_str(Tasmota, "Tasmota", 4047617668u, 0, 7, &be_const_str_item);
-be_define_const_str(item, "item", 2671260646u, 0, 4, &be_const_str_set_useragent);
-be_define_const_str(set_useragent, "set_useragent", 612237244u, 0, 13, &be_const_str_wire2);
-be_define_const_str(wire2, "wire2", 3229499038u, 0, 5, NULL);
-be_define_const_str(time_reached, "time_reached", 2075136773u, 0, 12, NULL);
-be_define_const_str(chars_in_string, "chars_in_string", 3148785132u, 0, 15, &be_const_str_false);
-be_define_const_str(false, "false", 184981848u, 62, 5, NULL);
-be_define_const_str(add_rule, "add_rule", 596540743u, 0, 8, &be_const_str_setbits);
-be_define_const_str(setbits, "setbits", 2762408167u, 0, 7, &be_const_str_write_file);
-be_define_const_str(write_file, "write_file", 3177658879u, 0, 10, NULL);
-be_define_const_str(hs2rgb, "hs2rgb", 1040816349u, 0, 6, NULL);
-be_define_const_str(SERIAL_8O1, "SERIAL_8O1", 289122742u, 0, 10, &be_const_str_wd);
-be_define_const_str(wd, "wd", 1531424278u, 0, 2, &be_const_str_wire_scan);
-be_define_const_str(wire_scan, "wire_scan", 2671275880u, 0, 9, NULL);
-be_define_const_str(AudioFileSourceFS, "AudioFileSourceFS", 1839147653u, 0, 17, &be_const_str_get_free_heap);
-be_define_const_str(get_free_heap, "get_free_heap", 625069757u, 0, 13, NULL);
-be_define_const_str(AudioGenerator, "AudioGenerator", 1839297342u, 0, 14, &be_const_str_SERIAL_5E2);
-be_define_const_str(SERIAL_5E2, "SERIAL_5E2", 1180552854u, 0, 10, NULL);
-be_define_const_str(_global_addr, "_global_addr", 533766721u, 0, 12, &be_const_str_content_send_style);
-be_define_const_str(content_send_style, "content_send_style", 1087907647u, 0, 18, &be_const_str_remove_timer);
-be_define_const_str(remove_timer, "remove_timer", 4141472215u, 0, 12, &be_const_str_tr);
-be_define_const_str(tr, "tr", 1195724803u, 0, 2, NULL);
-be_define_const_str(dot_w, ".w", 1255414514u, 0, 2, NULL);
-be_define_const_str(MD5, "MD5", 1935726387u, 0, 3, NULL);
-be_define_const_str(break, "break", 3378807160u, 58, 5, NULL);
+be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_remove);
+be_define_const_str(remove, "remove", 3683784189u, 0, 6, &be_const_str_remove_timer);
+be_define_const_str(remove_timer, "remove_timer", 4141472215u, 0, 12, NULL);
+be_define_const_str(MD5, "MD5", 1935726387u, 0, 3, &be_const_str__ccmd);
+be_define_const_str(_ccmd, "_ccmd", 2163421413u, 0, 5, &be_const_str_digital_write);
be_define_const_str(digital_write, "digital_write", 3435877979u, 0, 13, NULL);
-be_define_const_str(asin, "asin", 4272848550u, 0, 4, NULL);
-be_define_const_str(_def, "_def", 1985022181u, 0, 4, &be_const_str_exec_cmd);
-be_define_const_str(exec_cmd, "exec_cmd", 493567399u, 0, 8, &be_const_str_exists);
-be_define_const_str(exists, "exists", 1002329533u, 0, 6, &be_const_str_flush);
-be_define_const_str(flush, "flush", 3002334877u, 0, 5, &be_const_str_as);
-be_define_const_str(as, "as", 1579491469u, 67, 2, NULL);
-be_define_const_str(set_light, "set_light", 3176076152u, 0, 9, &be_const_str_time_str);
-be_define_const_str(time_str, "time_str", 2613827612u, 0, 8, NULL);
-be_define_const_str(arg_size, "arg_size", 3310243257u, 0, 8, &be_const_str_bus);
-be_define_const_str(bus, "bus", 1607822841u, 0, 3, NULL);
-be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, &be_const_str_try_rule);
-be_define_const_str(try_rule, "try_rule", 1986449405u, 0, 8, NULL);
-be_define_const_str(kv, "kv", 1497177492u, 0, 2, &be_const_str_reverse_gamma10);
-be_define_const_str(reverse_gamma10, "reverse_gamma10", 739112262u, 0, 15, NULL);
-be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, NULL);
-be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_tob64);
-be_define_const_str(tob64, "tob64", 373777640u, 0, 5, &be_const_str_continue);
-be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL);
-be_define_const_str(log, "log", 1062293841u, 0, 3, NULL);
-be_define_const_str(SERIAL_7N1, "SERIAL_7N1", 1891060246u, 0, 10, &be_const_str_lower);
-be_define_const_str(lower, "lower", 3038577850u, 0, 5, NULL);
-be_define_const_str(stop, "stop", 3411225317u, 0, 4, NULL);
-be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_encrypt);
-be_define_const_str(encrypt, "encrypt", 2194327650u, 0, 7, &be_const_str_resp_cmnd_str);
-be_define_const_str(resp_cmnd_str, "resp_cmnd_str", 737845590u, 0, 13, NULL);
-be_define_const_str(byte, "byte", 1683620383u, 0, 4, NULL);
-be_define_const_str(fromstring, "fromstring", 610302344u, 0, 10, &be_const_str_run_deferred);
-be_define_const_str(run_deferred, "run_deferred", 371594696u, 0, 12, &be_const_str_setitem);
-be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL);
-be_define_const_str(cmd, "cmd", 4136785899u, 0, 3, &be_const_str_event);
-be_define_const_str(event, "event", 4264611999u, 0, 5, NULL);
-be_define_const_str(SERIAL_6E1, "SERIAL_6E1", 334249486u, 0, 10, &be_const_str_SERIAL_6O1);
-be_define_const_str(SERIAL_6O1, "SERIAL_6O1", 266153272u, 0, 10, &be_const_str_remove_driver);
-be_define_const_str(remove_driver, "remove_driver", 1030243768u, 0, 13, NULL);
-be_define_const_str(EC_C25519, "EC_C25519", 95492591u, 0, 9, NULL);
-be_define_const_str(read12, "read12", 4291076970u, 0, 6, NULL);
-be_define_const_str(_write, "_write", 2215462825u, 0, 6, NULL);
-be_define_const_str(opt_call, "()", 685372826u, 0, 2, &be_const_str_AudioOutput);
-be_define_const_str(AudioOutput, "AudioOutput", 3257792048u, 0, 11, &be_const_str_attrdump);
-be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_int);
-be_define_const_str(int, "int", 2515107422u, 0, 3, NULL);
-be_define_const_str(AudioGeneratorMP3, "AudioGeneratorMP3", 2199818488u, 0, 17, &be_const_str_add_header);
-be_define_const_str(add_header, "add_header", 927130612u, 0, 10, NULL);
-be_define_const_str(ctypes_bytes_dyn, "ctypes_bytes_dyn", 915205307u, 0, 16, &be_const_str_keys);
-be_define_const_str(keys, "keys", 4182378701u, 0, 4, NULL);
-be_define_const_str(set_auth, "set_auth", 1057170930u, 0, 8, &be_const_str_def);
-be_define_const_str(def, "def", 3310976652u, 55, 3, NULL);
-be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_SERIAL_5N2);
-be_define_const_str(SERIAL_5N2, "SERIAL_5N2", 3363364537u, 0, 10, &be_const_str__rules);
-be_define_const_str(_rules, "_rules", 4266217105u, 0, 6, &be_const_str_has);
-be_define_const_str(has, "has", 3988721635u, 0, 3, &be_const_str_set);
-be_define_const_str(set, "set", 3324446467u, 0, 3, NULL);
-be_define_const_str(public_key, "public_key", 4169142980u, 0, 10, NULL);
-be_define_const_str(get_power, "get_power", 3009799377u, 0, 9, &be_const_str_type);
-be_define_const_str(type, "type", 1361572173u, 0, 4, NULL);
-be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_dot_size);
-be_define_const_str(dot_size, ".size", 1965188224u, 0, 5, &be_const_str_set_timeouts);
-be_define_const_str(set_timeouts, "set_timeouts", 3732850900u, 0, 12, &be_const_str_tomap);
-be_define_const_str(tomap, "tomap", 612167626u, 0, 5, NULL);
-be_define_const_str(getbits, "getbits", 3094168979u, 0, 7, &be_const_str_sinh);
-be_define_const_str(sinh, "sinh", 282220607u, 0, 4, &be_const_str_sqrt);
-be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL);
-be_define_const_str(dot_p1, ".p1", 249175686u, 0, 3, &be_const_str_begin);
-be_define_const_str(begin, "begin", 1748273790u, 0, 5, &be_const_str_delay);
-be_define_const_str(delay, "delay", 1322381784u, 0, 5, &be_const_str_scan);
-be_define_const_str(scan, "scan", 3974641896u, 0, 4, &be_const_str_for);
-be_define_const_str(for, "for", 2901640080u, 54, 3, NULL);
-be_define_const_str(read8, "read8", 2802788167u, 0, 5, NULL);
-be_define_const_str(AudioGeneratorWAV, "AudioGeneratorWAV", 2746509368u, 0, 17, &be_const_str_get_light);
-be_define_const_str(get_light, "get_light", 381930476u, 0, 9, NULL);
-be_define_const_str(_global_def, "_global_def", 646007001u, 0, 11, &be_const_str_map);
-be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_redirect);
-be_define_const_str(redirect, "redirect", 389758641u, 0, 8, NULL);
-be_define_const_str(_ptr, "_ptr", 306235816u, 0, 4, &be_const_str_isinstance);
-be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, NULL);
-be_define_const_str(pin, "pin", 1866532500u, 0, 3, &be_const_str_size);
-be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_state);
-be_define_const_str(state, "state", 2016490230u, 0, 5, NULL);
-be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str__drivers);
-be_define_const_str(_drivers, "_drivers", 3260328985u, 0, 8, &be_const_str_erase);
-be_define_const_str(erase, "erase", 1010949589u, 0, 5, NULL);
-be_define_const_str(I2C_Driver, "I2C_Driver", 1714501658u, 0, 10, &be_const_str_addr);
-be_define_const_str(addr, "addr", 1087856498u, 0, 4, &be_const_str_copy);
-be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_find_key_i);
-be_define_const_str(find_key_i, "find_key_i", 850136726u, 0, 10, &be_const_str_pin_mode);
-be_define_const_str(pin_mode, "pin_mode", 3258314030u, 0, 8, &be_const_str_setrange);
-be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, NULL);
-be_define_const_str(SERIAL_8N1, "SERIAL_8N1", 2369297235u, 0, 10, &be_const_str_char);
-be_define_const_str(char, "char", 2823553821u, 0, 4, &be_const_str_concat);
-be_define_const_str(concat, "concat", 4124019837u, 0, 6, &be_const_str_remove);
-be_define_const_str(remove, "remove", 3683784189u, 0, 6, &be_const_str_serial);
-be_define_const_str(serial, "serial", 3687697785u, 0, 6, NULL);
-be_define_const_str(SERIAL_5O2, "SERIAL_5O2", 3732325060u, 0, 10, &be_const_str__read);
-be_define_const_str(_read, "_read", 346717030u, 0, 5, &be_const_str_cmd_res);
-be_define_const_str(cmd_res, "cmd_res", 921166762u, 0, 7, &be_const_str_contains);
-be_define_const_str(contains, "contains", 1825239352u, 0, 8, &be_const_str_imax);
-be_define_const_str(imax, "imax", 3084515410u, 0, 4, &be_const_str_super);
-be_define_const_str(super, "super", 4152230356u, 0, 5, &be_const_str_try);
-be_define_const_str(try, "try", 2887626766u, 68, 3, NULL);
-be_define_const_str(last_modified, "last_modified", 772177145u, 0, 13, &be_const_str_return);
-be_define_const_str(return, "return", 2246981567u, 60, 6, NULL);
-be_define_const_str(SERIAL_6N2, "SERIAL_6N2", 148562844u, 0, 10, NULL);
-be_define_const_str(call, "call", 3018949801u, 0, 4, &be_const_str_resize);
-be_define_const_str(resize, "resize", 3514612129u, 0, 6, NULL);
-be_define_const_str(escape, "escape", 2652972038u, 0, 6, NULL);
-be_define_const_str(upper, "upper", 176974407u, 0, 5, NULL);
-be_define_const_str(end, "end", 1787721130u, 56, 3, NULL);
-be_define_const_str(gamma8, "gamma8", 3802843830u, 0, 6, &be_const_str_memory);
-be_define_const_str(memory, "memory", 2229924270u, 0, 6, &be_const_str_wifi);
-be_define_const_str(wifi, "wifi", 120087624u, 0, 4, NULL);
-be_define_const_str(yield, "yield", 1821831854u, 0, 5, NULL);
-be_define_const_str(get_option, "get_option", 2123730033u, 0, 10, &be_const_str_init);
-be_define_const_str(init, "init", 380752755u, 0, 4, &be_const_str_read);
-be_define_const_str(read, "read", 3470762949u, 0, 4, NULL);
-be_define_const_str(_settings_ptr, "_settings_ptr", 1825772182u, 0, 13, &be_const_str__timers);
-be_define_const_str(_timers, "_timers", 2600100916u, 0, 7, &be_const_str_finish);
-be_define_const_str(finish, "finish", 1494643858u, 0, 6, NULL);
-be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_dump);
-be_define_const_str(dump, "dump", 3663001223u, 0, 4, NULL);
-be_define_const_str(save, "save", 3439296072u, 0, 4, NULL);
-be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_listdir);
-be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, NULL);
-be_define_const_str(check_privileged_access, "check_privileged_access", 3692933968u, 0, 23, &be_const_str_rand);
-be_define_const_str(rand, "rand", 2711325910u, 0, 4, &be_const_str_web_send);
-be_define_const_str(web_send, "web_send", 2989941448u, 0, 8, NULL);
-be_define_const_str(i2c_enabled, "i2c_enabled", 218388101u, 0, 11, &be_const_str_wire1);
-be_define_const_str(wire1, "wire1", 3212721419u, 0, 5, NULL);
-be_define_const_str(dac_voltage, "dac_voltage", 1552257222u, 0, 11, &be_const_str_imin);
-be_define_const_str(imin, "imin", 2714127864u, 0, 4, &be_const_str_log10);
-be_define_const_str(log10, "log10", 2346846000u, 0, 5, &be_const_str_skip);
-be_define_const_str(skip, "skip", 1097563074u, 0, 4, &be_const_str_else);
-be_define_const_str(else, "else", 3183434736u, 52, 4, &be_const_str_except);
-be_define_const_str(except, "except", 950914032u, 69, 6, &be_const_str_nil);
-be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL);
-be_define_const_str(resp_cmnd_error, "resp_cmnd_error", 2404088863u, 0, 15, NULL);
-be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, &be_const_str_do);
-be_define_const_str(do, "do", 1646057492u, 65, 2, NULL);
-be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_true);
-be_define_const_str(true, "true", 1303515621u, 61, 4, NULL);
-be_define_const_str(rad, "rad", 1358899048u, 0, 3, &be_const_str_import);
-be_define_const_str(import, "import", 288002260u, 66, 6, NULL);
-be_define_const_str(SERIAL_8O2, "SERIAL_8O2", 272345123u, 0, 10, &be_const_str_gamma10);
-be_define_const_str(gamma10, "gamma10", 3472052483u, 0, 7, &be_const_str_elif);
-be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL);
-be_define_const_str(resp_cmnd, "resp_cmnd", 2869459626u, 0, 9, &be_const_str_shared_key);
-be_define_const_str(shared_key, "shared_key", 2200833624u, 0, 10, &be_const_str_web_send_decimal);
-be_define_const_str(web_send_decimal, "web_send_decimal", 1407210204u, 0, 16, &be_const_str_write8);
-be_define_const_str(write8, "write8", 3133991532u, 0, 6, NULL);
-be_define_const_str(SERIAL_5E1, "SERIAL_5E1", 1163775235u, 0, 10, &be_const_str_member);
-be_define_const_str(member, "member", 719708611u, 0, 6, &be_const_str_sin);
-be_define_const_str(sin, "sin", 3761252941u, 0, 3, NULL);
-be_define_const_str(OneWire, "OneWire", 2298990722u, 0, 7, &be_const_str_SERIAL_7O2);
-be_define_const_str(SERIAL_7O2, "SERIAL_7O2", 1840580294u, 0, 10, &be_const_str__begin_transmission);
-be_define_const_str(_begin_transmission, "_begin_transmission", 2779461176u, 0, 19, &be_const_str_get_switch);
-be_define_const_str(get_switch, "get_switch", 164821028u, 0, 10, &be_const_str_name);
-be_define_const_str(name, "name", 2369371622u, 0, 4, &be_const_str_nan);
-be_define_const_str(nan, "nan", 797905850u, 0, 3, NULL);
-be_define_const_str(add, "add", 993596020u, 0, 3, &be_const_str_eth);
-be_define_const_str(eth, "eth", 2191266556u, 0, 3, &be_const_str_find);
-be_define_const_str(find, "find", 3186656602u, 0, 4, &be_const_str_read32);
-be_define_const_str(read32, "read32", 1741276240u, 0, 6, &be_const_str_remove_cmd);
-be_define_const_str(remove_cmd, "remove_cmd", 3832315702u, 0, 10, NULL);
-be_define_const_str(gc, "gc", 1042313471u, 0, 2, &be_const_str_reset_search);
-be_define_const_str(reset_search, "reset_search", 1350414305u, 0, 12, NULL);
-be_define_const_str(content_stop, "content_stop", 658554751u, 0, 12, NULL);
-be_define_const_str(counters, "counters", 4095866864u, 0, 8, &be_const_str_detect);
-be_define_const_str(detect, "detect", 8884370u, 0, 6, &be_const_str_exp);
-be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_on);
-be_define_const_str(on, "on", 1630810064u, 0, 2, NULL);
-be_define_const_str(arg, "arg", 1047474471u, 0, 3, &be_const_str_reduce);
-be_define_const_str(reduce, "reduce", 2002030311u, 0, 6, &be_const_str_split);
-be_define_const_str(split, "split", 2276994531u, 0, 5, &be_const_str_strftime);
-be_define_const_str(strftime, "strftime", 187738851u, 0, 8, &be_const_str_raise);
+be_define_const_str(dot_p2, ".p2", 232398067u, 0, 3, &be_const_str_floor);
+be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_input);
+be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_range);
+be_define_const_str(range, "range", 4208725202u, 0, 5, NULL);
+be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_find_op);
+be_define_const_str(find_op, "find_op", 3766713376u, 0, 7, NULL);
+be_define_const_str(SERIAL_6N1, "SERIAL_6N1", 198895701u, 0, 10, &be_const_str_classname);
+be_define_const_str(classname, "classname", 1998589948u, 0, 9, NULL);
+be_define_const_str(content_start, "content_start", 2937509069u, 0, 13, &be_const_str_import);
+be_define_const_str(import, "import", 288002260u, 66, 6, &be_const_str_raise);
be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL);
-be_define_const_str(AudioOutputI2S, "AudioOutputI2S", 638031784u, 0, 14, &be_const_str_if);
-be_define_const_str(if, "if", 959999494u, 50, 2, NULL);
-be_define_const_str(cb_dispatch, "cb_dispatch", 1741510499u, 0, 11, &be_const_str_exec_tele);
-be_define_const_str(exec_tele, "exec_tele", 1020751601u, 0, 9, &be_const_str_srand);
-be_define_const_str(srand, "srand", 465518633u, 0, 5, NULL);
-be_define_const_str(write_bytes, "write_bytes", 1227543792u, 0, 11, NULL);
-be_define_const_str(_settings_def, "_settings_def", 3775560307u, 0, 13, NULL);
-be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, &be_const_str_pi);
-be_define_const_str(pi, "pi", 1213090802u, 0, 2, &be_const_str_remove_rule);
-be_define_const_str(remove_rule, "remove_rule", 3456211328u, 0, 11, &be_const_str_scale_uint);
-be_define_const_str(scale_uint, "scale_uint", 3090811094u, 0, 10, &be_const_str_var);
-be_define_const_str(var, "var", 2317739966u, 64, 3, NULL);
-be_define_const_str(SERIAL_8E2, "SERIAL_8E2", 2421454473u, 0, 10, &be_const_str_acos);
-be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_gen_cb);
-be_define_const_str(gen_cb, "gen_cb", 3245227551u, 0, 6, &be_const_str_read_bytes);
-be_define_const_str(read_bytes, "read_bytes", 3576733173u, 0, 10, NULL);
-be_define_const_str(AudioFileSource, "AudioFileSource", 2959980058u, 0, 15, &be_const_str_SERIAL_5N1);
-be_define_const_str(SERIAL_5N1, "SERIAL_5N1", 3313031680u, 0, 10, &be_const_str_wire);
-be_define_const_str(wire, "wire", 4082753944u, 0, 4, &be_const_str_while);
-be_define_const_str(while, "while", 231090382u, 53, 5, NULL);
-be_define_const_str(SERIAL_7N2, "SERIAL_7N2", 1874282627u, 0, 10, &be_const_str_get_size);
-be_define_const_str(get_size, "get_size", 2803644713u, 0, 8, NULL);
-be_define_const_str(exec_rules, "exec_rules", 1445221092u, 0, 10, NULL);
-be_define_const_str(_available, "_available", 1306196581u, 0, 10, &be_const_str_search);
-be_define_const_str(search, "search", 2150836393u, 0, 6, NULL);
-be_define_const_str(global, "global", 503252654u, 0, 6, NULL);
-be_define_const_str(collect, "collect", 2399039025u, 0, 7, &be_const_str_input);
-be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_response_append);
+be_define_const_str(SERIAL_8N2, "SERIAL_8N2", 2386074854u, 0, 10, &be_const_str_keys);
+be_define_const_str(keys, "keys", 4182378701u, 0, 4, NULL);
+be_define_const_str(content_send_style, "content_send_style", 1087907647u, 0, 18, &be_const_str_static);
+be_define_const_str(static, "static", 3532702267u, 71, 6, NULL);
+be_define_const_str(_begin_transmission, "_begin_transmission", 2779461176u, 0, 19, &be_const_str__request_from);
+be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, &be_const_str_isnan);
+be_define_const_str(isnan, "isnan", 2981347434u, 0, 5, &be_const_str_reverse_gamma10);
+be_define_const_str(reverse_gamma10, "reverse_gamma10", 739112262u, 0, 15, NULL);
+be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_resp_cmnd_str);
+be_define_const_str(resp_cmnd_str, "resp_cmnd_str", 737845590u, 0, 13, &be_const_str_run_deferred);
+be_define_const_str(run_deferred, "run_deferred", 371594696u, 0, 12, NULL);
+be_define_const_str(exec_rules, "exec_rules", 1445221092u, 0, 10, &be_const_str_web_send);
+be_define_const_str(web_send, "web_send", 2989941448u, 0, 8, NULL);
+be_define_const_str(GET, "GET", 2531704439u, 0, 3, &be_const_str__rules);
+be_define_const_str(_rules, "_rules", 4266217105u, 0, 6, &be_const_str_begin);
+be_define_const_str(begin, "begin", 1748273790u, 0, 5, &be_const_str_escape);
+be_define_const_str(escape, "escape", 2652972038u, 0, 6, NULL);
+be_define_const_str(I2C_Driver, "I2C_Driver", 1714501658u, 0, 10, &be_const_str_char);
+be_define_const_str(char, "char", 2823553821u, 0, 4, NULL);
+be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_Wire);
+be_define_const_str(Wire, "Wire", 1938276536u, 0, 4, &be_const_str_asstring);
+be_define_const_str(asstring, "asstring", 1298225088u, 0, 8, &be_const_str_strftime);
+be_define_const_str(strftime, "strftime", 187738851u, 0, 8, NULL);
+be_define_const_str(last_modified, "last_modified", 772177145u, 0, 13, &be_const_str_set);
+be_define_const_str(set, "set", 3324446467u, 0, 3, NULL);
+be_define_const_str(add, "add", 993596020u, 0, 3, &be_const_str_eth);
+be_define_const_str(eth, "eth", 2191266556u, 0, 3, &be_const_str_publish);
+be_define_const_str(publish, "publish", 264247304u, 0, 7, NULL);
+be_define_const_str(rtc, "rtc", 1070575216u, 0, 3, &be_const_str_scan);
+be_define_const_str(scan, "scan", 3974641896u, 0, 4, NULL);
+be_define_const_str(EC_C25519, "EC_C25519", 95492591u, 0, 9, &be_const_str_nil);
+be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL);
+be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_item);
+be_define_const_str(item, "item", 2671260646u, 0, 4, NULL);
+be_define_const_str(log, "log", 1062293841u, 0, 3, NULL);
+be_define_const_str(_global_def, "_global_def", 646007001u, 0, 11, &be_const_str_clear);
+be_define_const_str(clear, "clear", 1550717474u, 0, 5, NULL);
+be_define_const_str(atan2, "atan2", 3173440503u, 0, 5, &be_const_str_dump);
+be_define_const_str(dump, "dump", 3663001223u, 0, 4, &be_const_str_fromb64);
+be_define_const_str(fromb64, "fromb64", 2717019639u, 0, 7, NULL);
+be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_read13);
+be_define_const_str(read13, "read13", 12887293u, 0, 6, NULL);
+be_define_const_str(SERIAL_8O1, "SERIAL_8O1", 289122742u, 0, 10, NULL);
+be_define_const_str(SERIAL_6O1, "SERIAL_6O1", 266153272u, 0, 10, &be_const_str_add_rule);
+be_define_const_str(add_rule, "add_rule", 596540743u, 0, 8, &be_const_str_fromstring);
+be_define_const_str(fromstring, "fromstring", 610302344u, 0, 10, NULL);
+be_define_const_str(SERIAL_6E2, "SERIAL_6E2", 317471867u, 0, 10, &be_const_str_try_rule);
+be_define_const_str(try_rule, "try_rule", 1986449405u, 0, 8, NULL);
+be_define_const_str(gc, "gc", 1042313471u, 0, 2, &be_const_str_publish_result);
+be_define_const_str(publish_result, "publish_result", 2013351252u, 0, 14, &be_const_str_response_append);
be_define_const_str(response_append, "response_append", 450346371u, 0, 15, NULL);
-be_define_const_str(str, "str", 3259748752u, 0, 3, NULL);
-be_define_const_str(SERIAL_6E2, "SERIAL_6E2", 317471867u, 0, 10, &be_const_str_SERIAL_7E1);
-be_define_const_str(SERIAL_7E1, "SERIAL_7E1", 147718061u, 0, 10, &be_const_str_content_button);
-be_define_const_str(content_button, "content_button", 1956476087u, 0, 14, NULL);
-be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_tanh);
-be_define_const_str(tanh, "tanh", 153638352u, 0, 4, &be_const_str_toptr);
-be_define_const_str(toptr, "toptr", 3379847454u, 0, 5, &be_const_str_write_bit);
-be_define_const_str(write_bit, "write_bit", 2660990436u, 0, 9, NULL);
-be_define_const_str(add_cmd, "add_cmd", 3361630879u, 0, 7, &be_const_str_select);
-be_define_const_str(select, "select", 297952813u, 0, 6, &be_const_str_traceback);
-be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, NULL);
-be_define_const_str(atan2, "atan2", 3173440503u, 0, 5, &be_const_str_loop);
-be_define_const_str(loop, "loop", 3723446379u, 0, 4, &be_const_str_millis);
-be_define_const_str(millis, "millis", 1214679063u, 0, 6, &be_const_str_url_encode);
-be_define_const_str(url_encode, "url_encode", 528392145u, 0, 10, NULL);
-be_define_const_str(_end_transmission, "_end_transmission", 3237480400u, 0, 17, &be_const_str_deinit);
-be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_tan);
-be_define_const_str(tan, "tan", 2633446552u, 0, 3, NULL);
-be_define_const_str(geti, "geti", 2381006490u, 0, 4, &be_const_str_seti);
-be_define_const_str(seti, "seti", 1500556254u, 0, 4, NULL);
-be_define_const_str(_buffer, "_buffer", 2044888568u, 0, 7, NULL);
-be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_content_flush);
-be_define_const_str(content_flush, "content_flush", 214922475u, 0, 13, &be_const_str_list);
-be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_tolower);
-be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL);
-be_define_const_str(dot_len, ".len", 850842136u, 0, 4, &be_const_str__request_from);
-be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, &be_const_str_has_arg);
-be_define_const_str(has_arg, "has_arg", 424878688u, 0, 7, NULL);
-be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_push);
-be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_read24);
-be_define_const_str(read24, "read24", 1808533811u, 0, 6, NULL);
-be_define_const_str(enabled, "enabled", 49525662u, 0, 7, &be_const_str_webclient);
+be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL);
+be_define_const_str(dot_p1, ".p1", 249175686u, 0, 3, &be_const_str__def);
+be_define_const_str(_def, "_def", 1985022181u, 0, 4, &be_const_str_imin);
+be_define_const_str(imin, "imin", 2714127864u, 0, 4, NULL);
+be_define_const_str(chars_in_string, "chars_in_string", 3148785132u, 0, 15, &be_const_str_concat);
+be_define_const_str(concat, "concat", 4124019837u, 0, 6, &be_const_str_content_stop);
+be_define_const_str(content_stop, "content_stop", 658554751u, 0, 12, &be_const_str_def);
+be_define_const_str(def, "def", 3310976652u, 55, 3, NULL);
+be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, &be_const_str_wire);
+be_define_const_str(wire, "wire", 4082753944u, 0, 4, NULL);
+be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, NULL);
+be_define_const_str(finish, "finish", 1494643858u, 0, 6, &be_const_str_log10);
+be_define_const_str(log10, "log10", 2346846000u, 0, 5, &be_const_str_name);
+be_define_const_str(name, "name", 2369371622u, 0, 4, &be_const_str_time_str);
+be_define_const_str(time_str, "time_str", 2613827612u, 0, 8, &be_const_str_do);
+be_define_const_str(do, "do", 1646057492u, 65, 2, NULL);
+be_define_const_str(read, "read", 3470762949u, 0, 4, &be_const_str_set_auth);
+be_define_const_str(set_auth, "set_auth", 1057170930u, 0, 8, NULL);
+be_define_const_str(Tasmota, "Tasmota", 4047617668u, 0, 7, NULL);
+be_define_const_str(SERIAL_7E2, "SERIAL_7E2", 97385204u, 0, 10, &be_const_str_resolvecmnd);
+be_define_const_str(resolvecmnd, "resolvecmnd", 993361485u, 0, 11, NULL);
+be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_addr);
+be_define_const_str(addr, "addr", 1087856498u, 0, 4, &be_const_str_gamma8);
+be_define_const_str(gamma8, "gamma8", 3802843830u, 0, 6, NULL);
+be_define_const_str(member, "member", 719708611u, 0, 6, &be_const_str_scale_uint);
+be_define_const_str(scale_uint, "scale_uint", 3090811094u, 0, 10, NULL);
+be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, NULL);
+be_define_const_str(opt_call, "()", 685372826u, 0, 2, &be_const_str_SERIAL_5N2);
+be_define_const_str(SERIAL_5N2, "SERIAL_5N2", 3363364537u, 0, 10, NULL);
+be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_hex);
+be_define_const_str(hex, "hex", 4273249610u, 0, 3, &be_const_str_remove_cmd);
+be_define_const_str(remove_cmd, "remove_cmd", 3832315702u, 0, 10, NULL);
+be_define_const_str(AudioOutput, "AudioOutput", 3257792048u, 0, 11, &be_const_str_break);
+be_define_const_str(break, "break", 3378807160u, 58, 5, NULL);
+be_define_const_str(SERIAL_5O1, "SERIAL_5O1", 3782657917u, 0, 10, &be_const_str_rand);
+be_define_const_str(rand, "rand", 2711325910u, 0, 4, &be_const_str_class);
+be_define_const_str(class, "class", 2872970239u, 57, 5, NULL);
+be_define_const_str(public_key, "public_key", 4169142980u, 0, 10, &be_const_str_search);
+be_define_const_str(search, "search", 2150836393u, 0, 6, &be_const_str_update);
+be_define_const_str(update, "update", 672109684u, 0, 6, &be_const_str_end);
+be_define_const_str(end, "end", 1787721130u, 56, 3, NULL);
+be_define_const_str(i2c_enabled, "i2c_enabled", 218388101u, 0, 11, &be_const_str_read_bytes);
+be_define_const_str(read_bytes, "read_bytes", 3576733173u, 0, 10, NULL);
+be_define_const_str(fromptr, "fromptr", 666189689u, 0, 7, &be_const_str_pin_used);
+be_define_const_str(pin_used, "pin_used", 4033854612u, 0, 8, &be_const_str_redirect);
+be_define_const_str(redirect, "redirect", 389758641u, 0, 8, NULL);
+be_define_const_str(_drivers, "_drivers", 3260328985u, 0, 8, &be_const_str_get_size);
+be_define_const_str(get_size, "get_size", 2803644713u, 0, 8, &be_const_str_set_power);
+be_define_const_str(set_power, "set_power", 549820893u, 0, 9, NULL);
+be_define_const_str(loop, "loop", 3723446379u, 0, 4, &be_const_str_read32);
+be_define_const_str(read32, "read32", 1741276240u, 0, 6, NULL);
+be_define_const_str(add_cmd, "add_cmd", 3361630879u, 0, 7, NULL);
+be_define_const_str(_settings_ptr, "_settings_ptr", 1825772182u, 0, 13, &be_const_str_reset);
+be_define_const_str(reset, "reset", 1695364032u, 0, 5, NULL);
+be_define_const_str(_ptr, "_ptr", 306235816u, 0, 4, &be_const_str_detect);
+be_define_const_str(detect, "detect", 8884370u, 0, 6, &be_const_str_reset_search);
+be_define_const_str(reset_search, "reset_search", 1350414305u, 0, 12, NULL);
+be_define_const_str(SERIAL_6E1, "SERIAL_6E1", 334249486u, 0, 10, &be_const_str__read);
+be_define_const_str(_read, "_read", 346717030u, 0, 5, NULL);
+be_define_const_str(true, "true", 1303515621u, 61, 4, NULL);
+be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, &be_const_str_add_driver);
+be_define_const_str(add_driver, "add_driver", 1654458371u, 0, 10, &be_const_str_tob64);
+be_define_const_str(tob64, "tob64", 373777640u, 0, 5, &be_const_str_wire1);
+be_define_const_str(wire1, "wire1", 3212721419u, 0, 5, NULL);
+be_define_const_str(_timers, "_timers", 2600100916u, 0, 7, NULL);
+be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str_SERIAL_5E1);
+be_define_const_str(SERIAL_5E1, "SERIAL_5E1", 1163775235u, 0, 10, &be_const_str_select);
+be_define_const_str(select, "select", 297952813u, 0, 6, &be_const_str_setbits);
+be_define_const_str(setbits, "setbits", 2762408167u, 0, 7, &be_const_str_webclient);
be_define_const_str(webclient, "webclient", 4076389146u, 0, 9, NULL);
-be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_dot_p2);
-be_define_const_str(dot_p2, ".p2", 232398067u, 0, 3, NULL);
-be_define_const_str(Wire, "Wire", 1938276536u, 0, 4, &be_const_str_decrypt);
-be_define_const_str(decrypt, "decrypt", 2886974618u, 0, 7, NULL);
-be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_issubclass);
-be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, NULL);
-be_define_const_str(classname, "classname", 1998589948u, 0, 9, &be_const_str_rtc);
-be_define_const_str(rtc, "rtc", 1070575216u, 0, 3, NULL);
-be_define_const_str(add_driver, "add_driver", 1654458371u, 0, 10, NULL);
+be_define_const_str(deg, "deg", 3327754271u, 0, 3, &be_const_str_flush);
+be_define_const_str(flush, "flush", 3002334877u, 0, 5, &be_const_str_hs2rgb);
+be_define_const_str(hs2rgb, "hs2rgb", 1040816349u, 0, 6, NULL);
+be_define_const_str(SERIAL_8E1, "SERIAL_8E1", 2371121616u, 0, 10, &be_const_str_setrange);
+be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, NULL);
+be_define_const_str(dot_len, ".len", 850842136u, 0, 4, &be_const_str_byte);
+be_define_const_str(byte, "byte", 1683620383u, 0, 4, &be_const_str_issubclass);
+be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, &be_const_str_while);
+be_define_const_str(while, "while", 231090382u, 53, 5, NULL);
+be_define_const_str(enabled, "enabled", 49525662u, 0, 7, &be_const_str_sin);
+be_define_const_str(sin, "sin", 3761252941u, 0, 3, &be_const_str_except);
+be_define_const_str(except, "except", 950914032u, 69, 6, NULL);
+be_define_const_str(AudioOutputI2S, "AudioOutputI2S", 638031784u, 0, 14, &be_const_str_SERIAL_7N2);
+be_define_const_str(SERIAL_7N2, "SERIAL_7N2", 1874282627u, 0, 10, &be_const_str_call);
+be_define_const_str(call, "call", 3018949801u, 0, 4, &be_const_str_imax);
+be_define_const_str(imax, "imax", 3084515410u, 0, 4, NULL);
+be_define_const_str(isrunning, "isrunning", 1688182268u, 0, 9, &be_const_str_read8);
+be_define_const_str(read8, "read8", 2802788167u, 0, 5, &be_const_str_resp_cmnd_error);
+be_define_const_str(resp_cmnd_error, "resp_cmnd_error", 2404088863u, 0, 15, NULL);
+be_define_const_str(AudioFileSourceFS, "AudioFileSourceFS", 1839147653u, 0, 17, &be_const_str___iterator__);
+be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_contains);
+be_define_const_str(contains, "contains", 1825239352u, 0, 8, &be_const_str_web_send_decimal);
+be_define_const_str(web_send_decimal, "web_send_decimal", 1407210204u, 0, 16, NULL);
+be_define_const_str(dac_voltage, "dac_voltage", 1552257222u, 0, 11, NULL);
+be_define_const_str(time_reached, "time_reached", 2075136773u, 0, 12, &be_const_str_if);
+be_define_const_str(if, "if", 959999494u, 50, 2, NULL);
+be_define_const_str(read24, "read24", 1808533811u, 0, 6, &be_const_str_toptr);
+be_define_const_str(toptr, "toptr", 3379847454u, 0, 5, &be_const_str_else);
+be_define_const_str(else, "else", 3183434736u, 52, 4, NULL);
+be_define_const_str(_global_addr, "_global_addr", 533766721u, 0, 12, &be_const_str_classof);
+be_define_const_str(classof, "classof", 1796577762u, 0, 7, NULL);
+be_define_const_str(SERIAL_7O1, "SERIAL_7O1", 1823802675u, 0, 10, &be_const_str_print);
+be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_setmember);
+be_define_const_str(setmember, "setmember", 1432909441u, 0, 9, NULL);
+be_define_const_str(dot_size, ".size", 1965188224u, 0, 5, &be_const_str__write);
+be_define_const_str(_write, "_write", 2215462825u, 0, 6, &be_const_str_init);
+be_define_const_str(init, "init", 380752755u, 0, 4, NULL);
+be_define_const_str(gamma10, "gamma10", 3472052483u, 0, 7, &be_const_str_gen_cb);
+be_define_const_str(gen_cb, "gen_cb", 3245227551u, 0, 6, &be_const_str_remove_rule);
+be_define_const_str(remove_rule, "remove_rule", 3456211328u, 0, 11, NULL);
+be_define_const_str(ctypes_bytes_dyn, "ctypes_bytes_dyn", 915205307u, 0, 16, NULL);
+be_define_const_str(SERIAL_6N2, "SERIAL_6N2", 148562844u, 0, 10, &be_const_str_available);
+be_define_const_str(available, "available", 1727918744u, 0, 9, &be_const_str_cb_dispatch);
+be_define_const_str(cb_dispatch, "cb_dispatch", 1741510499u, 0, 11, &be_const_str_isinstance);
+be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, NULL);
+be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_find);
+be_define_const_str(find, "find", 3186656602u, 0, 4, NULL);
+be_define_const_str(POST, "POST", 1929554311u, 0, 4, &be_const_str_write_bytes);
+be_define_const_str(write_bytes, "write_bytes", 1227543792u, 0, 11, NULL);
+be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_type);
+be_define_const_str(type, "type", 1361572173u, 0, 4, NULL);
+be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_insert);
+be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_tolower);
+be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL);
+be_define_const_str(dot_w, ".w", 1255414514u, 0, 2, &be_const_str_srand);
+be_define_const_str(srand, "srand", 465518633u, 0, 5, &be_const_str_wire2);
+be_define_const_str(wire2, "wire2", 3229499038u, 0, 5, NULL);
+be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_yield);
+be_define_const_str(yield, "yield", 1821831854u, 0, 5, NULL);
+be_define_const_str(SERIAL_5E2, "SERIAL_5E2", 1180552854u, 0, 10, &be_const_str_reduce);
+be_define_const_str(reduce, "reduce", 2002030311u, 0, 6, &be_const_str_resp_cmnd_done);
+be_define_const_str(resp_cmnd_done, "resp_cmnd_done", 2601874875u, 0, 14, NULL);
+be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_setitem);
+be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL);
+be_define_const_str(OneWire, "OneWire", 2298990722u, 0, 7, &be_const_str_upper);
+be_define_const_str(upper, "upper", 176974407u, 0, 5, NULL);
+be_define_const_str(module, "module", 3617558685u, 0, 6, NULL);
+be_define_const_str(counters, "counters", 4095866864u, 0, 8, &be_const_str_tag);
+be_define_const_str(tag, "tag", 2516003219u, 0, 3, NULL);
+be_define_const_str(tanh, "tanh", 153638352u, 0, 4, NULL);
+be_define_const_str(get_string, "get_string", 4195847969u, 0, 10, &be_const_str_read12);
+be_define_const_str(read12, "read12", 4291076970u, 0, 6, &be_const_str_wire_scan);
+be_define_const_str(wire_scan, "wire_scan", 2671275880u, 0, 9, NULL);
+be_define_const_str(seti, "seti", 1500556254u, 0, 4, NULL);
+be_define_const_str(cmd, "cmd", 4136785899u, 0, 3, &be_const_str_content_send);
+be_define_const_str(content_send, "content_send", 1673733649u, 0, 12, &be_const_str_global);
+be_define_const_str(global, "global", 503252654u, 0, 6, &be_const_str_var);
+be_define_const_str(var, "var", 2317739966u, 64, 3, NULL);
+be_define_const_str(SERIAL_7N1, "SERIAL_7N1", 1891060246u, 0, 10, &be_const_str_resize);
+be_define_const_str(resize, "resize", 3514612129u, 0, 6, &be_const_str_split);
+be_define_const_str(split, "split", 2276994531u, 0, 5, &be_const_str_str);
+be_define_const_str(str, "str", 3259748752u, 0, 3, &be_const_str_url_encode);
+be_define_const_str(url_encode, "url_encode", 528392145u, 0, 10, NULL);
+be_define_const_str(get_option, "get_option", 2123730033u, 0, 10, &be_const_str_listdir);
+be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, &be_const_str_tomap);
+be_define_const_str(tomap, "tomap", 612167626u, 0, 5, NULL);
+be_define_const_str(check_privileged_access, "check_privileged_access", 3692933968u, 0, 23, NULL);
+be_define_const_str(pin_mode, "pin_mode", 3258314030u, 0, 8, NULL);
+be_define_const_str(pin, "pin", 1866532500u, 0, 3, &be_const_str_try);
+be_define_const_str(try, "try", 2887626766u, 68, 3, NULL);
+be_define_const_str(_buffer, "_buffer", 2044888568u, 0, 7, &be_const_str_cos);
+be_define_const_str(cos, "cos", 4220379804u, 0, 3, NULL);
+be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str_SERIAL_7O2);
+be_define_const_str(SERIAL_7O2, "SERIAL_7O2", 1840580294u, 0, 10, NULL);
+be_define_const_str(real, "real", 3604983901u, 0, 4, NULL);
+be_define_const_str(set_timer, "set_timer", 2135414533u, 0, 9, NULL);
+be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_write);
+be_define_const_str(write, "write", 3190202204u, 0, 5, NULL);
+be_define_const_str(_settings_def, "_settings_def", 3775560307u, 0, 13, &be_const_str_digital_read);
+be_define_const_str(digital_read, "digital_read", 3585496928u, 0, 12, NULL);
+be_define_const_str(path, "path", 2223459638u, 0, 4, NULL);
+be_define_const_str(delay, "delay", 1322381784u, 0, 5, &be_const_str_stop);
+be_define_const_str(stop, "stop", 3411225317u, 0, 4, NULL);
+be_define_const_str(AES_GCM, "AES_GCM", 3832208678u, 0, 7, NULL);
+be_define_const_str(SERIAL_6O2, "SERIAL_6O2", 316486129u, 0, 10, &be_const_str_open);
+be_define_const_str(open, "open", 3546203337u, 0, 4, &be_const_str_top);
+be_define_const_str(top, "top", 2802900028u, 0, 3, NULL);
+be_define_const_str(write_bit, "write_bit", 2660990436u, 0, 9, NULL);
+be_define_const_str(state, "state", 2016490230u, 0, 5, NULL);
+be_define_const_str(set_useragent, "set_useragent", 612237244u, 0, 13, &be_const_str_as);
+be_define_const_str(as, "as", 1579491469u, 67, 2, NULL);
+be_define_const_str(erase, "erase", 1010949589u, 0, 5, &be_const_str_has_arg);
+be_define_const_str(has_arg, "has_arg", 424878688u, 0, 7, &be_const_str_map);
+be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_on);
+be_define_const_str(on, "on", 1630810064u, 0, 2, NULL);
+be_define_const_str(AudioGeneratorWAV, "AudioGeneratorWAV", 2746509368u, 0, 17, &be_const_str__cb);
+be_define_const_str(_cb, "_cb", 4043300367u, 0, 3, &be_const_str_decrypt);
+be_define_const_str(decrypt, "decrypt", 2886974618u, 0, 7, &be_const_str_sqrt);
+be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL);
+be_define_const_str(SERIAL_5N1, "SERIAL_5N1", 3313031680u, 0, 10, NULL);
+be_define_const_str(find_key_i, "find_key_i", 850136726u, 0, 10, NULL);
+be_define_const_str(arg, "arg", 1047474471u, 0, 3, &be_const_str_depower);
+be_define_const_str(depower, "depower", 3563819571u, 0, 7, &be_const_str_write_file);
+be_define_const_str(write_file, "write_file", 3177658879u, 0, 10, NULL);
+be_define_const_str(SERIAL_5O2, "SERIAL_5O2", 3732325060u, 0, 10, &be_const_str_get_light);
+be_define_const_str(get_light, "get_light", 381930476u, 0, 9, &be_const_str_pop);
+be_define_const_str(pop, "pop", 1362321360u, 0, 3, NULL);
+be_define_const_str(exec_tele, "exec_tele", 1020751601u, 0, 9, NULL);
+be_define_const_str(set_light, "set_light", 3176076152u, 0, 9, &be_const_str_set_timeouts);
+be_define_const_str(set_timeouts, "set_timeouts", 3732850900u, 0, 12, &be_const_str_sinh);
+be_define_const_str(sinh, "sinh", 282220607u, 0, 4, NULL);
+be_define_const_str(AudioGenerator, "AudioGenerator", 1839297342u, 0, 14, &be_const_str_SERIAL_7E1);
+be_define_const_str(SERIAL_7E1, "SERIAL_7E1", 147718061u, 0, 10, &be_const_str_getbits);
+be_define_const_str(getbits, "getbits", 3094168979u, 0, 7, &be_const_str_shared_key);
+be_define_const_str(shared_key, "shared_key", 2200833624u, 0, 10, &be_const_str_time_dump);
+be_define_const_str(time_dump, "time_dump", 3330410747u, 0, 9, NULL);
+be_define_const_str(content_button, "content_button", 1956476087u, 0, 14, &be_const_str_geti);
+be_define_const_str(geti, "geti", 2381006490u, 0, 4, NULL);
+be_define_const_str(arch, "arch", 2952804297u, 0, 4, &be_const_str_asin);
+be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_get_free_heap);
+be_define_const_str(get_free_heap, "get_free_heap", 625069757u, 0, 13, &be_const_str_resp_cmnd);
+be_define_const_str(resp_cmnd, "resp_cmnd", 2869459626u, 0, 9, NULL);
+be_define_const_str(content_flush, "content_flush", 214922475u, 0, 13, &be_const_str_millis);
+be_define_const_str(millis, "millis", 1214679063u, 0, 6, &be_const_str_serial);
+be_define_const_str(serial, "serial", 3687697785u, 0, 6, &be_const_str_skip);
+be_define_const_str(skip, "skip", 1097563074u, 0, 4, NULL);
+be_define_const_str(event, "event", 4264611999u, 0, 5, NULL);
+be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_bus);
+be_define_const_str(bus, "bus", 1607822841u, 0, 3, NULL);
+be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_bytes);
+be_define_const_str(bytes, "bytes", 1706151940u, 0, 5, &be_const_str_compile);
+be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_get);
+be_define_const_str(get, "get", 1410115415u, 0, 3, &be_const_str_tan);
+be_define_const_str(tan, "tan", 2633446552u, 0, 3, NULL);
+be_define_const_str(encrypt, "encrypt", 2194327650u, 0, 7, NULL);
+be_define_const_str(cmd_res, "cmd_res", 921166762u, 0, 7, &be_const_str_collect);
+be_define_const_str(collect, "collect", 2399039025u, 0, 7, NULL);
+be_define_const_str(arg_size, "arg_size", 3310243257u, 0, 8, &be_const_str_reverse);
+be_define_const_str(reverse, "reverse", 558918661u, 0, 7, NULL);
+be_define_const_str(close, "close", 667630371u, 0, 5, &be_const_str_members);
+be_define_const_str(members, "members", 937576464u, 0, 7, NULL);
+be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_exec_cmd);
+be_define_const_str(exec_cmd, "exec_cmd", 493567399u, 0, 8, &be_const_str_get_power);
+be_define_const_str(get_power, "get_power", 3009799377u, 0, 9, &be_const_str_resp_cmnd_failed);
+be_define_const_str(resp_cmnd_failed, "resp_cmnd_failed", 2136281562u, 0, 16, &be_const_str_target_search);
+be_define_const_str(target_search, "target_search", 1947846553u, 0, 13, NULL);
+be_define_const_str(AudioFileSource, "AudioFileSource", 2959980058u, 0, 15, &be_const_str_SERIAL_8N1);
+be_define_const_str(SERIAL_8N1, "SERIAL_8N1", 2369297235u, 0, 10, &be_const_str_pi);
+be_define_const_str(pi, "pi", 1213090802u, 0, 2, NULL);
+be_define_const_str(add_header, "add_header", 927130612u, 0, 10, &be_const_str_list);
+be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_super);
+be_define_const_str(super, "super", 4152230356u, 0, 5, NULL);
+be_define_const_str(has, "has", 3988721635u, 0, 3, NULL);
+be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_exp);
+be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_int);
+be_define_const_str(int, "int", 2515107422u, 0, 3, &be_const_str_size);
+be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_for);
+be_define_const_str(for, "for", 2901640080u, 54, 3, NULL);
+be_define_const_str(ctypes_bytes, "ctypes_bytes", 3879019703u, 0, 12, &be_const_str_wifi);
+be_define_const_str(wifi, "wifi", 120087624u, 0, 4, &be_const_str_elif);
+be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL);
+be_define_const_str(arg_name, "arg_name", 1345046155u, 0, 8, &be_const_str_cosh);
+be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, &be_const_str_lower);
+be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_push);
+be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_save);
+be_define_const_str(save, "save", 3439296072u, 0, 4, NULL);
+be_define_const_str(load, "load", 3859241449u, 0, 4, NULL);
+be_define_const_str(SERIAL_8E2, "SERIAL_8E2", 2421454473u, 0, 10, &be_const_str_nan);
+be_define_const_str(nan, "nan", 797905850u, 0, 3, &be_const_str_remove_driver);
+be_define_const_str(remove_driver, "remove_driver", 1030243768u, 0, 13, &be_const_str_write8);
+be_define_const_str(write8, "write8", 3133991532u, 0, 6, NULL);
+be_define_const_str(_get_cb, "_get_cb", 1448849122u, 0, 7, NULL);
+be_define_const_str(iter, "iter", 3124256359u, 0, 4, NULL);
+be_define_const_str(_cmd, "_cmd", 3419822142u, 0, 4, &be_const_str_exists);
+be_define_const_str(exists, "exists", 1002329533u, 0, 6, NULL);
+be_define_const_str(AudioGeneratorMP3, "AudioGeneratorMP3", 2199818488u, 0, 17, &be_const_str__end_transmission);
+be_define_const_str(_end_transmission, "_end_transmission", 3237480400u, 0, 17, NULL);
+be_define_const_str(get_switch, "get_switch", 164821028u, 0, 10, NULL);
+be_define_const_str(_available, "_available", 1306196581u, 0, 10, NULL);
+be_define_const_str(false, "false", 184981848u, 62, 5, NULL);
+be_define_const_str(settings, "settings", 1745255176u, 0, 8, &be_const_str_wd);
+be_define_const_str(wd, "wd", 1531424278u, 0, 2, NULL);
+be_define_const_str(SERIAL_8O2, "SERIAL_8O2", 272345123u, 0, 10, &be_const_str_rad);
+be_define_const_str(rad, "rad", 1358899048u, 0, 3, NULL);
+be_define_const_str(kv, "kv", 1497177492u, 0, 2, &be_const_str_toupper);
+be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, &be_const_str_tr);
+be_define_const_str(tr, "tr", 1195724803u, 0, 2, &be_const_str_return);
+be_define_const_str(return, "return", 2246981567u, 60, 6, NULL);
+be_define_const_str(memory, "memory", 2229924270u, 0, 6, &be_const_str_tostring);
+be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, NULL);
static const bstring* const m_string_table[] = {
- NULL,
- (const bstring *)&be_const_str_setmember,
- (const bstring *)&be_const_str_hex,
- (const bstring *)&be_const_str_arch,
- (const bstring *)&be_const_str_top,
- (const bstring *)&be_const_str_content_start,
- (const bstring *)&be_const_str_compile,
- (const bstring *)&be_const_str_arg_name,
- (const bstring *)&be_const_str_insert,
- (const bstring *)&be_const_str_open,
- NULL,
- (const bstring *)&be_const_str_ctypes_bytes,
- (const bstring *)&be_const_str_reset,
- (const bstring *)&be_const_str_POST,
- (const bstring *)&be_const_str_available,
- NULL,
- (const bstring *)&be_const_str__get_cb,
- (const bstring *)&be_const_str_get_string,
- (const bstring *)&be_const_str_asstring,
- (const bstring *)&be_const_str_static,
- (const bstring *)&be_const_str_AES_GCM,
- (const bstring *)&be_const_str_close,
- (const bstring *)&be_const_str_find_op,
- (const bstring *)&be_const_str_get,
- (const bstring *)&be_const_str_print,
- (const bstring *)&be_const_str_target_search,
- NULL,
- (const bstring *)&be_const_str__ccmd,
- (const bstring *)&be_const_str_allocated,
- (const bstring *)&be_const_str_GET,
- (const bstring *)&be_const_str_SERIAL_8E1,
- (const bstring *)&be_const_str_assert,
- (const bstring *)&be_const_str_codedump,
- (const bstring *)&be_const_str_opt_connect,
- (const bstring *)&be_const_str_update,
- NULL,
- (const bstring *)&be_const_str__cmd,
- (const bstring *)&be_const_str_SERIAL_5O1,
- (const bstring *)&be_const_str_SERIAL_7E2,
- (const bstring *)&be_const_str_SERIAL_6N1,
- (const bstring *)&be_const_str_Tasmota,
- (const bstring *)&be_const_str_time_reached,
- (const bstring *)&be_const_str_chars_in_string,
- (const bstring *)&be_const_str_add_rule,
- NULL,
- (const bstring *)&be_const_str_hs2rgb,
- (const bstring *)&be_const_str_SERIAL_8O1,
- (const bstring *)&be_const_str_AudioFileSourceFS,
- (const bstring *)&be_const_str_AudioGenerator,
- (const bstring *)&be_const_str__global_addr,
- (const bstring *)&be_const_str_dot_w,
+ (const bstring *)&be_const_str_pow,
(const bstring *)&be_const_str_MD5,
- (const bstring *)&be_const_str_break,
- (const bstring *)&be_const_str_digital_write,
- (const bstring *)&be_const_str_asin,
- (const bstring *)&be_const_str__def,
- (const bstring *)&be_const_str_set_light,
- (const bstring *)&be_const_str_arg_size,
+ (const bstring *)&be_const_str_dot_p2,
+ (const bstring *)&be_const_str_atan,
+ (const bstring *)&be_const_str_SERIAL_6N1,
+ (const bstring *)&be_const_str_content_start,
+ (const bstring *)&be_const_str_SERIAL_8N2,
+ (const bstring *)&be_const_str_content_send_style,
NULL,
- (const bstring *)&be_const_str_opt_eq,
- (const bstring *)&be_const_str_kv,
- (const bstring *)&be_const_str_tostring,
- (const bstring *)&be_const_str_format,
- (const bstring *)&be_const_str_log,
- (const bstring *)&be_const_str_SERIAL_7N1,
- (const bstring *)&be_const_str_stop,
- (const bstring *)&be_const_str_count,
- (const bstring *)&be_const_str_byte,
- (const bstring *)&be_const_str_fromstring,
- (const bstring *)&be_const_str_cmd,
- (const bstring *)&be_const_str_SERIAL_6E1,
+ (const bstring *)&be_const_str__begin_transmission,
+ (const bstring *)&be_const_str_number,
+ (const bstring *)&be_const_str_exec_rules,
+ (const bstring *)&be_const_str_GET,
+ (const bstring *)&be_const_str_I2C_Driver,
+ NULL,
+ (const bstring *)&be_const_str_opt_neq,
+ (const bstring *)&be_const_str_last_modified,
+ (const bstring *)&be_const_str_add,
+ (const bstring *)&be_const_str_rtc,
(const bstring *)&be_const_str_EC_C25519,
- (const bstring *)&be_const_str_read12,
- (const bstring *)&be_const_str__write,
+ (const bstring *)&be_const_str_ceil,
+ (const bstring *)&be_const_str_log,
+ (const bstring *)&be_const_str__global_def,
+ (const bstring *)&be_const_str_atan2,
+ (const bstring *)&be_const_str_deinit,
+ (const bstring *)&be_const_str_SERIAL_8O1,
+ (const bstring *)&be_const_str_SERIAL_6O1,
+ (const bstring *)&be_const_str_SERIAL_6E2,
+ (const bstring *)&be_const_str_gc,
+ (const bstring *)&be_const_str_continue,
+ NULL,
+ (const bstring *)&be_const_str_dot_p1,
+ (const bstring *)&be_const_str_chars_in_string,
+ NULL,
+ (const bstring *)&be_const_str_traceback,
+ (const bstring *)&be_const_str_calldepth,
+ (const bstring *)&be_const_str_finish,
+ (const bstring *)&be_const_str_read,
+ (const bstring *)&be_const_str_Tasmota,
+ (const bstring *)&be_const_str_SERIAL_7E2,
+ (const bstring *)&be_const_str___lower__,
+ (const bstring *)&be_const_str_member,
+ (const bstring *)&be_const_str_codedump,
(const bstring *)&be_const_str_opt_call,
NULL,
- (const bstring *)&be_const_str_AudioGeneratorMP3,
- (const bstring *)&be_const_str_ctypes_bytes_dyn,
- (const bstring *)&be_const_str_set_auth,
- (const bstring *)&be_const_str_,
+ (const bstring *)&be_const_str_attrdump,
+ (const bstring *)&be_const_str_AudioOutput,
+ (const bstring *)&be_const_str_SERIAL_5O1,
(const bstring *)&be_const_str_public_key,
- (const bstring *)&be_const_str_get_power,
- (const bstring *)&be_const_str_opt_add,
- (const bstring *)&be_const_str_getbits,
- (const bstring *)&be_const_str_dot_p1,
- (const bstring *)&be_const_str_read8,
- (const bstring *)&be_const_str_AudioGeneratorWAV,
- (const bstring *)&be_const_str__global_def,
- (const bstring *)&be_const_str__ptr,
- NULL,
- (const bstring *)&be_const_str_pin,
- (const bstring *)&be_const_str_dot_p,
- (const bstring *)&be_const_str_I2C_Driver,
- (const bstring *)&be_const_str_SERIAL_8N1,
- (const bstring *)&be_const_str_SERIAL_5O2,
- (const bstring *)&be_const_str_last_modified,
- (const bstring *)&be_const_str_SERIAL_6N2,
- (const bstring *)&be_const_str_call,
- (const bstring *)&be_const_str_escape,
- (const bstring *)&be_const_str_upper,
- (const bstring *)&be_const_str_end,
- NULL,
- (const bstring *)&be_const_str_gamma8,
- NULL,
- (const bstring *)&be_const_str_yield,
- (const bstring *)&be_const_str_get_option,
- (const bstring *)&be_const_str__settings_ptr,
- (const bstring *)&be_const_str___upper__,
- (const bstring *)&be_const_str_save,
- NULL,
- (const bstring *)&be_const_str___lower__,
- NULL,
- (const bstring *)&be_const_str_check_privileged_access,
(const bstring *)&be_const_str_i2c_enabled,
- (const bstring *)&be_const_str_dac_voltage,
- (const bstring *)&be_const_str_resp_cmnd_error,
- (const bstring *)&be_const_str_calldepth,
- (const bstring *)&be_const_str___iterator__,
- (const bstring *)&be_const_str_rad,
- (const bstring *)&be_const_str_SERIAL_8O2,
- (const bstring *)&be_const_str_resp_cmnd,
- (const bstring *)&be_const_str_SERIAL_5E1,
- (const bstring *)&be_const_str_OneWire,
- NULL,
- (const bstring *)&be_const_str_add,
- (const bstring *)&be_const_str_gc,
- NULL,
- (const bstring *)&be_const_str_content_stop,
- (const bstring *)&be_const_str_counters,
- (const bstring *)&be_const_str_arg,
- (const bstring *)&be_const_str_AudioOutputI2S,
- (const bstring *)&be_const_str_cb_dispatch,
- (const bstring *)&be_const_str_write_bytes,
- (const bstring *)&be_const_str__settings_def,
- (const bstring *)&be_const_str_cosh,
- (const bstring *)&be_const_str_SERIAL_8E2,
- (const bstring *)&be_const_str_AudioFileSource,
- (const bstring *)&be_const_str_SERIAL_7N2,
- (const bstring *)&be_const_str_exec_rules,
- (const bstring *)&be_const_str__available,
- (const bstring *)&be_const_str_global,
- (const bstring *)&be_const_str_collect,
- (const bstring *)&be_const_str_str,
- (const bstring *)&be_const_str_SERIAL_6E2,
- (const bstring *)&be_const_str_number,
+ (const bstring *)&be_const_str_fromptr,
+ (const bstring *)&be_const_str__drivers,
+ (const bstring *)&be_const_str_loop,
(const bstring *)&be_const_str_add_cmd,
+ (const bstring *)&be_const_str__settings_ptr,
+ (const bstring *)&be_const_str__ptr,
+ (const bstring *)&be_const_str_SERIAL_6E1,
+ (const bstring *)&be_const_str_true,
+ (const bstring *)&be_const_str_opt_eq,
+ (const bstring *)&be_const_str__timers,
+ (const bstring *)&be_const_str_opt_connect,
+ (const bstring *)&be_const_str_deg,
+ (const bstring *)&be_const_str_SERIAL_8E1,
NULL,
- (const bstring *)&be_const_str_atan2,
- (const bstring *)&be_const_str__end_transmission,
NULL,
- (const bstring *)&be_const_str_geti,
NULL,
- (const bstring *)&be_const_str__buffer,
- (const bstring *)&be_const_str_atan,
(const bstring *)&be_const_str_dot_len,
- (const bstring *)&be_const_str_pow,
+ NULL,
(const bstring *)&be_const_str_enabled,
- (const bstring *)&be_const_str_opt_neq,
- (const bstring *)&be_const_str_Wire,
- (const bstring *)&be_const_str_floor,
- (const bstring *)&be_const_str_classname,
- (const bstring *)&be_const_str_add_driver
+ (const bstring *)&be_const_str_AudioOutputI2S,
+ (const bstring *)&be_const_str_isrunning,
+ (const bstring *)&be_const_str_AudioFileSourceFS,
+ (const bstring *)&be_const_str_dac_voltage,
+ (const bstring *)&be_const_str_time_reached,
+ (const bstring *)&be_const_str_read24,
+ (const bstring *)&be_const_str__global_addr,
+ (const bstring *)&be_const_str_SERIAL_7O1,
+ (const bstring *)&be_const_str_dot_size,
+ (const bstring *)&be_const_str_gamma10,
+ (const bstring *)&be_const_str_ctypes_bytes_dyn,
+ (const bstring *)&be_const_str_SERIAL_6N2,
+ NULL,
+ (const bstring *)&be_const_str_copy,
+ (const bstring *)&be_const_str_POST,
+ (const bstring *)&be_const_str_,
+ (const bstring *)&be_const_str_allocated,
+ NULL,
+ (const bstring *)&be_const_str_dot_w,
+ (const bstring *)&be_const_str_format,
+ (const bstring *)&be_const_str_SERIAL_5E2,
+ (const bstring *)&be_const_str_abs,
+ (const bstring *)&be_const_str_OneWire,
+ (const bstring *)&be_const_str_module,
+ (const bstring *)&be_const_str_counters,
+ (const bstring *)&be_const_str_tanh,
+ (const bstring *)&be_const_str_get_string,
+ (const bstring *)&be_const_str_seti,
+ (const bstring *)&be_const_str_cmd,
+ (const bstring *)&be_const_str_SERIAL_7N1,
+ (const bstring *)&be_const_str_get_option,
+ (const bstring *)&be_const_str_check_privileged_access,
+ NULL,
+ (const bstring *)&be_const_str_pin_mode,
+ (const bstring *)&be_const_str_pin,
+ (const bstring *)&be_const_str__buffer,
+ (const bstring *)&be_const_str_dot_p,
+ (const bstring *)&be_const_str_real,
+ (const bstring *)&be_const_str_set_timer,
+ (const bstring *)&be_const_str_count,
+ (const bstring *)&be_const_str__settings_def,
+ (const bstring *)&be_const_str_path,
+ (const bstring *)&be_const_str_delay,
+ (const bstring *)&be_const_str_AES_GCM,
+ (const bstring *)&be_const_str_SERIAL_6O2,
+ (const bstring *)&be_const_str_write_bit,
+ (const bstring *)&be_const_str_state,
+ (const bstring *)&be_const_str_set_useragent,
+ (const bstring *)&be_const_str_erase,
+ (const bstring *)&be_const_str_AudioGeneratorWAV,
+ (const bstring *)&be_const_str_SERIAL_5N1,
+ (const bstring *)&be_const_str_find_key_i,
+ NULL,
+ (const bstring *)&be_const_str_arg,
+ (const bstring *)&be_const_str_SERIAL_5O2,
+ (const bstring *)&be_const_str_exec_tele,
+ (const bstring *)&be_const_str_set_light,
+ (const bstring *)&be_const_str_AudioGenerator,
+ (const bstring *)&be_const_str_content_button,
+ (const bstring *)&be_const_str_arch,
+ (const bstring *)&be_const_str_content_flush,
+ (const bstring *)&be_const_str_event,
+ NULL,
+ (const bstring *)&be_const_str_opt_add,
+ (const bstring *)&be_const_str_acos,
+ (const bstring *)&be_const_str_encrypt,
+ (const bstring *)&be_const_str_cmd_res,
+ NULL,
+ (const bstring *)&be_const_str_arg_size,
+ (const bstring *)&be_const_str_close,
+ (const bstring *)&be_const_str_assert,
+ (const bstring *)&be_const_str_AudioFileSource,
+ (const bstring *)&be_const_str_add_header,
+ NULL,
+ (const bstring *)&be_const_str_has,
+ (const bstring *)&be_const_str___upper__,
+ (const bstring *)&be_const_str_ctypes_bytes,
+ NULL,
+ (const bstring *)&be_const_str_arg_name,
+ (const bstring *)&be_const_str_load,
+ (const bstring *)&be_const_str_SERIAL_8E2,
+ (const bstring *)&be_const_str__get_cb,
+ (const bstring *)&be_const_str_iter,
+ NULL,
+ (const bstring *)&be_const_str__cmd,
+ (const bstring *)&be_const_str_AudioGeneratorMP3,
+ (const bstring *)&be_const_str_get_switch,
+ (const bstring *)&be_const_str__available,
+ (const bstring *)&be_const_str_false,
+ (const bstring *)&be_const_str_settings,
+ (const bstring *)&be_const_str_SERIAL_8O2,
+ NULL,
+ (const bstring *)&be_const_str_kv,
+ (const bstring *)&be_const_str_memory
};
static const struct bconststrtab m_const_string_table = {
- .size = 162,
- .count = 325,
+ .size = 163,
+ .count = 326,
.table = m_string_table
};
diff --git a/lib/libesp32/Berry/generate/be_fixed_sys.h b/lib/libesp32/Berry/generate/be_fixed_sys.h
index 12eff88ab..91403719c 100644
--- a/lib/libesp32/Berry/generate/be_fixed_sys.h
+++ b/lib/libesp32/Berry/generate/be_fixed_sys.h
@@ -1,2 +1,17 @@
#include "be_constobj.h"
+static be_define_const_map_slots(m_libsys_map) {
+ { be_const_key(path, -1), be_const_func(m_path) },
+};
+
+static be_define_const_map(
+ m_libsys_map,
+ 1
+);
+
+static be_define_const_module(
+ m_libsys,
+ "sys"
+);
+
+BE_EXPORT_VARIABLE be_define_const_native_module(sys);
diff --git a/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp b/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp
index 61e83b683..2f036ad8c 100644
--- a/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp
+++ b/lib/libesp32/Zip-readonly-FS/src/ZipReadFS.cpp
@@ -400,6 +400,8 @@ FileImplPtr ZipReadFSImpl::open(const char* path, const char* mode, const bool c
char *tok;
char *prefix = strtok_r(sub_path, "#", &tok);
char *suffix = strtok_r(NULL, "", &tok);
+ // if suffix starts with '/', skip the first char
+ if (*suffix == '/') { suffix++; }
AddLog(LOG_LEVEL_DEBUG, "ZIP: prefix=%s suffix=%s", prefix, suffix);
// parse ZIP archive
File zipfile = (*_fs)->open(prefix, "r", false);
From fb41a57ae2ddbe6f81cf8373a3cfe1df84702ce0 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 20 Nov 2021 12:07:11 +0100
Subject: [PATCH 105/174] Delete scrape_supported_devices.py
---
.../tools/scrape_supported_devices.py | 426 ------------------
1 file changed, 426 deletions(-)
delete mode 100755 lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py
diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py
deleted file mode 100755
index f40b3e959..000000000
--- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/tools/scrape_supported_devices.py
+++ /dev/null
@@ -1,426 +0,0 @@
-#!/usr/bin/env python3
-"""Generate SupportedProtocols.md by scraping source code files"""
-import pathlib
-import argparse
-import subprocess
-from io import StringIO
-import sys
-import re
-import time
-
-CODE_URL = "https://github.com/crankyoldgit/IRremoteESP8266/blob/master/src/ir_"
-
-BRAND_MODEL = re.compile(r"""
- Brand:\s{1,20} # "Brand:" label followd by between 1 and 20 whitespace chars.
- \b(?P.{1,40})\b # The actual brand of the device, max 40 chars.
- \s{0,10}, # Followed by at most 10 whitespace chars, then a comma.
- \s{1,20} # The between 1 and 20 whitespace chars.
- Model:\s{1,20} # "Model:" label followd by between 1 and 20 whitespace chars.
- \b(?P.{1,80}) # The model info of the device, max 80 chars.
- \s{0,5}$ # Followed by at most 5 whitespaces before the end of line.
- """, re.VERBOSE)
-ENUMS = re.compile(r"enum (\w{1,60}) {(.{1,5000}?)};", re.DOTALL)
-ENUM_ENTRY = re.compile(r"^\s{1,80}(\w{1,80})", re.MULTILINE)
-DECODED_PROTOCOLS = re.compile(r"""
- .{0,80} # Ignore upto an 80 char line of whitespace/code etc.
- # Now look for code that looks like we are assigning the Protocol type.
- # There are two typical styles used:
- (?:results->decode_type # The first style.
- | # Or
- typeguess) # The second style
- \s{0,5}=\s{0,5} # The assignment operator and potential whitespace
- (?:decode_type_t::)? # The protocol could have an optional type prefix.
- (\w{1,40}); # Finally, the last word of code should be the Protocol.
- """, re.VERBOSE)
-AC_FN = re.compile(r"ir_(.{1,80})\.h")
-AC_MODEL_ENUM_RE = re.compile(r"(.{1,40})_ac_remote_model_t")
-IRSEND_FN_RE = re.compile(r"IRsend\.h")
-ALL_FN = re.compile(r"ir_(.{1,80})\.(h|cpp)")
-
-EXCLUDED_PROTOCOLS = ["UNKNOWN", "UNUSED", "kLastDecodeType", "typeguess"]
-EXCLUDED_ACS = ["Magiquest", "NEC"]
-
-def getgitcommittime():
- """Call git to get time of last commit
- """
- try:
- label = subprocess.check_output(\
- ["git", "show", "-s", "--format=%ct", "HEAD"]).strip()
- return int(label)
- except FileNotFoundError as err:
- print("Git failed, which is ok, no git binary found?:", err)
- return None
- except subprocess.SubprocessError as err:
- print("Git failed, which is ok, see output, maybe no git checkout?:", err)
- return None
-
-def getmarkdownheader():
- """Get the generated header
- """
- srctime = getgitcommittime()
- # pylint: disable=C0209
- return """""".format(
- time.strftime("%a %d %b %Y %H:%M:%S +0000", time.gmtime(srctime)))
- # pylint: enable=C0209
-
-
-
-def getallprotocols():
- """Return all protocls configured in IRremoteESP8266.h
- """
- irremote = ARGS.directory / "IRremoteESP8266.h"
- enums = getenums(irremote)["decode_type_t"]
- if not enums:
- errorexit("Error getting ENUMS from IRremoteESP8266.h")
- return enums
-
-
-def getdecodedprotocols():
- """All protocols that include decoding support"""
- ret = set()
- for path in ARGS.directory.iterdir():
- if path.suffix != ".cpp":
- continue
- matches = DECODED_PROTOCOLS.finditer(path.open(encoding="utf-8").read())
- for match in matches:
- protocol = match.group(1)
- if protocol not in EXCLUDED_PROTOCOLS:
- ret.add(protocol)
- return ret
-
-
-def getallacs():
- """All supported A/C codes"""
- ret = {}
- for path in ARGS.directory.iterdir():
- match = AC_FN.match(path.name)
- if match:
- acprotocol = match.group(1)
- rawmodels = getenums(path)
- models = set()
- for model in rawmodels:
- model = model.upper()
- model = model.replace(f"K{acprotocol.upper()}", "")
- if model and model not in EXCLUDED_PROTOCOLS:
- models.add(model)
- if acprotocol in ret:
- ret[acprotocol].update(models)
- else:
- ret[acprotocol] = models
- # Parse IRsend.h's enums
- match = IRSEND_FN_RE.match(path.name)
- if match:
- rawmodels = getenums(path)
- for acprotocol, acmodels in rawmodels.items():
- models = set()
- for model in acmodels:
- model = model.upper()
- model = model.replace(f"K{acprotocol.upper()}", "")
- if model and model not in EXCLUDED_PROTOCOLS:
- models.add(model)
- if acprotocol in ret:
- ret[acprotocol].update(models)
- else:
- ret[acprotocol] = models
- return ret
-
-class FnSets():
- """Container for getalldevices"""
- def __init__(self):
- self.allcodes = {}
- self.fnnomatch = set()
- self.allhfileprotos = set()
- self.fnhmatch = set()
- self.fncppmatch = set()
-
- def add(self, supports, path):
- """add the path to correct set based on supports"""
- if path.suffix == ".h":
- self.allhfileprotos.add(path.stem)
- if supports:
- if path.suffix == ".h":
- self.fnhmatch.add(path.stem)
- elif path.suffix == ".cpp":
- self.fncppmatch.add(path.stem)
- else:
- self.fnnomatch.add(path.stem)
-
- def printwarnings(self):
- """print warnings"""
- # all protos with support in .cpp file, when there is a .h file
- # meaning that the documentation should probably be moved to .h
- # in the future, with doxygen, that might change
- protosincppwithh = list(self.fncppmatch & self.allhfileprotos)
- if protosincppwithh:
- protosincppwithh.sort()
- print("The following files has supports section in .cpp, expected in .h")
- for path in protosincppwithh:
- print(f"\t{path}")
-
- protosincppandh = list(self.fncppmatch & self.fnhmatch)
- if protosincppandh:
- protosincppandh.sort()
- print("The following files has supports section in both .h and .cpp")
- for path in protosincppandh:
- print(f"\t{path}")
-
- nosupports = self.getnosupports()
- if nosupports:
- nosupports.sort()
- print("The following files had no supports section:")
- for path in nosupports:
- print(f"\t{path}")
-
- return protosincppwithh or protosincppandh or nosupports
-
- def getnosupports(self):
- """get protos without supports sections"""
- return list(self.fnnomatch - self.fnhmatch - self.fncppmatch)
-
-
-def getalldevices():
- """All devices and associated branding and model information (if available)
- """
- sets = FnSets()
- for path in ARGS.directory.iterdir():
- match = ALL_FN.match(path.name)
- if not match:
- continue
- supports = extractsupports(path)
- sets.add(supports, path)
- protocol = match.group(1)
- for brand, model in supports:
- protocolbrand = (protocol, brand)
- pbset = sets.allcodes.get(protocolbrand, [])
- if model in pbset:
- print(f"Model {model} is duplicated for {protocol}, {brand}")
- sets.allcodes[protocolbrand] = pbset + [model]
-
- for fnprotocol in sets.getnosupports():
- sets.allcodes[(fnprotocol[3:], "Unknown")] = []
- return sets
-
-
-def getenums(path):
- """Returns the keys for the first enum type in path
- """
- ret = {}
- for enums in ENUMS.finditer(path.open(encoding="utf-8").read()):
- if enums:
- enum_name = AC_MODEL_ENUM_RE.search(enums.group(1))
- if enum_name:
- enum_name = enum_name.group(1).capitalize()
- else:
- enum_name = enums.group(1)
- ret[enum_name] = set()
- for enum in ENUM_ENTRY.finditer(enums.group(2)):
- enum = enum.group(1)
- if enum in EXCLUDED_PROTOCOLS:
- continue
- ret[enum_name].add(enum)
- return ret
-
-
-ARGS = None
-
-
-def initargs():
- """Init the command line arguments"""
- global ARGS # pylint: disable=global-statement
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "-n",
- "--noout",
- help="generate no output data, combine with --alert to only check",
- action="store_true",
- )
- parser.add_argument(
- "-s",
- "--stdout",
- help="output to stdout rather than SupportedProtocols.md",
- action="store_true",
- )
- parser.add_argument("-v",
- "--verbose",
- help="increase output verbosity",
- action="store_true")
- parser.add_argument(
- "-a",
- "--alert",
- help="alert if a file does not have a supports section, "
- "non zero exit code if issues where found",
- action="store_true",
- )
- parser.add_argument(
- "directory",
- nargs="?",
- help="directory of the source git checkout",
- default=None,
- )
- ARGS = parser.parse_args()
- if ARGS.directory is None:
- src = pathlib.Path("../src")
- if not src.is_dir():
- src = pathlib.Path("./src")
- else:
- src = pathlib.Path(ARGS.directory) / "src"
- if not src.is_dir():
- errorexit(f"Directory not valid: {src!s}")
- ARGS.directory = src
- return ARGS
-
-def getmdfile():
- """Resolves SupportedProtocols.md path"""
- foutpath = ARGS.directory / "../SupportedProtocols.md"
- return foutpath.resolve()
-
-def errorexit(msg):
- """Print an error and exit on critical error"""
- sys.stderr.write(f"{msg}\n")
- sys.exit(1)
-
-def extractsupports(path):
- """Extract all of the Supports: sections and associated brands and models
- """
- supports = []
- insupports = False
- for line in path.open(encoding="utf-8"):
- if not line.startswith("//"):
- continue
- line = line[2:].strip()
- if line == "Supports:":
- insupports = True
- continue
- if insupports:
- match = BRAND_MODEL.match(line)
- if match:
- supports.append((match.group("brand"), match.group("model")))
- else:
- insupports = False
- continue
- # search and inform about any legacy formated supports data
- elif any(x in line for x in [ \
- "seems compatible with",
- "be compatible with",
- "it working with here"]):
- print(f"\t{path.name} Legacy supports format found\n\t\t{line}")
- return supports
-
-
-def makeurl(txt, path):
- """Make a Markup URL from given filename"""
- return f"[{txt}]({CODE_URL + path})"
-
-
-def outputprotocols(fout, protocols):
- """For a given protocol set, sort and output the markdown"""
- protocols = list(protocols)
- protocols.sort()
- for protocol in protocols:
- fout.write(f"- {protocol}\n")
-
-
-def generate(fout):
- """Generate data to fout
- return True on any issues (when alert is active)"""
- decodedprotocols = getdecodedprotocols()
- sendonly = getallprotocols() - decodedprotocols
- allacs = getallacs()
-
- sets = getalldevices()
- allcodes = sets.allcodes
- allbrands = list(allcodes.keys())
- allbrands.sort()
-
- fout.write("\n# IR Protocols supported by this library\n\n")
- fout.write(
- "| Protocol | Brand | Model | A/C Model | Detailed A/C Support |\n")
- fout.write("| --- | --- | --- | --- | --- |\n")
-
- for protocolbrand in allbrands:
- protocol, brand = protocolbrand
- codes = allcodes[protocolbrand]
- codes.sort()
- acmodels = []
- acsupport = "-"
- if protocol in allacs:
- acmodels = list(allacs[protocol])
- acmodels.sort()
- brand = makeurl(brand, protocol + ".h")
- if protocol not in EXCLUDED_ACS:
- acsupport = "Yes"
- # pylint: disable=C0209
- fout.write("| {} | **{}** | {} | {} | {} |\n".format(
- makeurl(protocol, protocol + ".cpp"),
- brand,
- " ".join(codes).replace("|", "\\|"),
- " ".join(acmodels),
- acsupport,
- ))
- # pylint: enable=C0209
-
- fout.write("\n\n## Send only protocols:\n\n")
- outputprotocols(fout, sendonly)
-
- fout.write("\n\n## Send & decodable protocols:\n\n")
- outputprotocols(fout, decodedprotocols)
-
- return ARGS.alert and sets.printwarnings()
-
-def generatenone():
- """No out write
- return True on any issues"""
- return generate(StringIO())
-
-def generatestdout():
- """Standard out write
- return True on any issues"""
- fout = sys.stdout
- fout.write(getmarkdownheader())
- return generate(fout)
-
-def generatefile():
- """File write, extra detection of changes in existing file
- return True on any issues, but only if there is changes"""
- # get file path
- foutpath = getmdfile()
- if ARGS.verbose:
- print(f"Output path: {foutpath!s}")
- # write data to temp memorystream
- ftemp = StringIO()
- ret = generate(ftemp)
- # get old filedata, skipping header
- with getmdfile().open("r", encoding="utf-8") as forg:
- olddata = forg.readlines()[3:]
- # get new data, skip first empty line
- ftemp.seek(0)
- newdata = ftemp.readlines()[1:]
- # if new data is same as old we don't need to write anything
- if newdata == olddata:
- print("No changes, exit without write")
- return False
- # write output
- with foutpath.open("w", encoding="utf-8") as fout:
- fout.write(getmarkdownheader())
- fout.write(ftemp.getvalue())
-
- return ret
-
-def main():
- """Default main function
- return True on any issues"""
- initargs()
- if ARGS.verbose:
- print(f"Looking for files in: {ARGS.directory.resolve()!s}")
- if ARGS.noout:
- return generatenone()
- if ARGS.stdout:
- return generatestdout()
- # default file
- return generatefile()
-
-
-if __name__ == "__main__":
- sys.exit(1 if main() else 0)
From 26dddb5b7474ed1584e576588dfd85b61decf030 Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Sat, 20 Nov 2021 12:40:35 +0100
Subject: [PATCH 106/174] Berry animate also returns value (#13744)
* Berry animate also returns value
* Berry Animate make closure optional
---
lib/libesp32/Berry/default/be_animate_lib.c | 539 +++++++++---------
.../Berry/default/embedded/Animate.be | 27 +-
2 files changed, 275 insertions(+), 291 deletions(-)
diff --git a/lib/libesp32/Berry/default/be_animate_lib.c b/lib/libesp32/Berry/default/be_animate_lib.c
index 3253d25e5..db6052653 100644
--- a/lib/libesp32/Berry/default/be_animate_lib.c
+++ b/lib/libesp32/Berry/default/be_animate_lib.c
@@ -31,35 +31,32 @@ be_local_closure(Animate_rotate_init, /* name */
}),
(be_nested_const_str("init", 380752755, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[28]) { /* code */
+ ( &(const binstruction[25]) { /* code */
0x60140003, // 0000 GETGBL R5 G3
0x5C180000, // 0001 MOVE R6 R0
0x7C140200, // 0002 CALL R5 1
0x8C140B00, // 0003 GETMET R5 R5 K0
0x7C140200, // 0004 CALL R5 1
- 0x4C140000, // 0005 LDNIL R5
- 0x20140205, // 0006 NE R5 R1 R5
- 0x78160000, // 0007 JMPF R5 #0009
- 0x90020201, // 0008 SETMBR R0 K1 R1
- 0x88140102, // 0009 GETMBR R5 R0 K2
- 0x8C140B03, // 000A GETMET R5 R5 K3
- 0xB81E0800, // 000B GETNGBL R7 K4
- 0x8C1C0F05, // 000C GETMET R7 R7 K5
- 0x5C240400, // 000D MOVE R9 R2
- 0x5C280600, // 000E MOVE R10 R3
- 0x5C2C0800, // 000F MOVE R11 R4
- 0x7C1C0800, // 0010 CALL R7 4
- 0x7C140400, // 0011 CALL R5 2
- 0x88140102, // 0012 GETMBR R5 R0 K2
- 0x8C140B03, // 0013 GETMET R5 R5 K3
- 0xB81E0800, // 0014 GETNGBL R7 K4
- 0x8C1C0F06, // 0015 GETMET R7 R7 K6
- 0x58240007, // 0016 LDCONST R9 K7
- 0x58280007, // 0017 LDCONST R10 K7
- 0x582C0007, // 0018 LDCONST R11 K7
- 0x7C1C0800, // 0019 CALL R7 4
- 0x7C140400, // 001A CALL R5 2
- 0x80000000, // 001B RET 0
+ 0x90020201, // 0005 SETMBR R0 K1 R1
+ 0x88140102, // 0006 GETMBR R5 R0 K2
+ 0x8C140B03, // 0007 GETMET R5 R5 K3
+ 0xB81E0800, // 0008 GETNGBL R7 K4
+ 0x8C1C0F05, // 0009 GETMET R7 R7 K5
+ 0x5C240400, // 000A MOVE R9 R2
+ 0x5C280600, // 000B MOVE R10 R3
+ 0x5C2C0800, // 000C MOVE R11 R4
+ 0x7C1C0800, // 000D CALL R7 4
+ 0x7C140400, // 000E CALL R5 2
+ 0x88140102, // 000F GETMBR R5 R0 K2
+ 0x8C140B03, // 0010 GETMET R5 R5 K3
+ 0xB81E0800, // 0011 GETNGBL R7 K4
+ 0x8C1C0F06, // 0012 GETMET R7 R7 K6
+ 0x58240007, // 0013 LDCONST R9 K7
+ 0x58280007, // 0014 LDCONST R10 K7
+ 0x582C0007, // 0015 LDCONST R11 K7
+ 0x7C1C0800, // 0016 CALL R7 4
+ 0x7C140400, // 0017 CALL R5 2
+ 0x80000000, // 0018 RET 0
})
)
);
@@ -103,26 +100,23 @@ be_local_closure(Animate_from_to_init, /* name */
}),
(be_nested_const_str("init", 380752755, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[19]) { /* code */
+ ( &(const binstruction[16]) { /* code */
0x60140003, // 0000 GETGBL R5 G3
0x5C180000, // 0001 MOVE R6 R0
0x7C140200, // 0002 CALL R5 1
0x8C140B00, // 0003 GETMET R5 R5 K0
0x7C140200, // 0004 CALL R5 1
- 0x4C140000, // 0005 LDNIL R5
- 0x20140205, // 0006 NE R5 R1 R5
- 0x78160000, // 0007 JMPF R5 #0009
- 0x90020201, // 0008 SETMBR R0 K1 R1
- 0x88140102, // 0009 GETMBR R5 R0 K2
- 0x8C140B03, // 000A GETMET R5 R5 K3
- 0xB81E0800, // 000B GETNGBL R7 K4
- 0x8C1C0F05, // 000C GETMET R7 R7 K5
- 0x5C240400, // 000D MOVE R9 R2
- 0x5C280600, // 000E MOVE R10 R3
- 0x5C2C0800, // 000F MOVE R11 R4
- 0x7C1C0800, // 0010 CALL R7 4
- 0x7C140400, // 0011 CALL R5 2
- 0x80000000, // 0012 RET 0
+ 0x90020201, // 0005 SETMBR R0 K1 R1
+ 0x88140102, // 0006 GETMBR R5 R0 K2
+ 0x8C140B03, // 0007 GETMET R5 R5 K3
+ 0xB81E0800, // 0008 GETNGBL R7 K4
+ 0x8C1C0F05, // 0009 GETMET R7 R7 K5
+ 0x5C240400, // 000A MOVE R9 R2
+ 0x5C280600, // 000B MOVE R10 R3
+ 0x5C2C0800, // 000C MOVE R11 R4
+ 0x7C1C0800, // 000D CALL R7 4
+ 0x7C140400, // 000E CALL R5 2
+ 0x80000000, // 000F RET 0
})
)
);
@@ -169,44 +163,41 @@ be_local_closure(Animate_back_forth_init, /* name */
}),
(be_nested_const_str("init", 380752755, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[37]) { /* code */
+ ( &(const binstruction[34]) { /* code */
0x60140003, // 0000 GETGBL R5 G3
0x5C180000, // 0001 MOVE R6 R0
0x7C140200, // 0002 CALL R5 1
0x8C140B00, // 0003 GETMET R5 R5 K0
0x7C140200, // 0004 CALL R5 1
- 0x4C140000, // 0005 LDNIL R5
- 0x20140205, // 0006 NE R5 R1 R5
- 0x78160000, // 0007 JMPF R5 #0009
- 0x90020201, // 0008 SETMBR R0 K1 R1
- 0x88140102, // 0009 GETMBR R5 R0 K2
- 0x8C140B03, // 000A GETMET R5 R5 K3
- 0xB81E0800, // 000B GETNGBL R7 K4
- 0x8C1C0F05, // 000C GETMET R7 R7 K5
- 0x5C240400, // 000D MOVE R9 R2
- 0x5C280600, // 000E MOVE R10 R3
- 0x0C2C0906, // 000F DIV R11 R4 K6
- 0x7C1C0800, // 0010 CALL R7 4
- 0x7C140400, // 0011 CALL R5 2
- 0x88140102, // 0012 GETMBR R5 R0 K2
- 0x8C140B03, // 0013 GETMET R5 R5 K3
- 0xB81E0800, // 0014 GETNGBL R7 K4
- 0x8C1C0F05, // 0015 GETMET R7 R7 K5
- 0x5C240600, // 0016 MOVE R9 R3
- 0x5C280400, // 0017 MOVE R10 R2
- 0x0C2C0906, // 0018 DIV R11 R4 K6
- 0x7C1C0800, // 0019 CALL R7 4
- 0x7C140400, // 001A CALL R5 2
- 0x88140102, // 001B GETMBR R5 R0 K2
- 0x8C140B03, // 001C GETMET R5 R5 K3
- 0xB81E0800, // 001D GETNGBL R7 K4
- 0x8C1C0F07, // 001E GETMET R7 R7 K7
- 0x58240008, // 001F LDCONST R9 K8
- 0x58280008, // 0020 LDCONST R10 K8
- 0x582C0008, // 0021 LDCONST R11 K8
- 0x7C1C0800, // 0022 CALL R7 4
- 0x7C140400, // 0023 CALL R5 2
- 0x80000000, // 0024 RET 0
+ 0x90020201, // 0005 SETMBR R0 K1 R1
+ 0x88140102, // 0006 GETMBR R5 R0 K2
+ 0x8C140B03, // 0007 GETMET R5 R5 K3
+ 0xB81E0800, // 0008 GETNGBL R7 K4
+ 0x8C1C0F05, // 0009 GETMET R7 R7 K5
+ 0x5C240400, // 000A MOVE R9 R2
+ 0x5C280600, // 000B MOVE R10 R3
+ 0x0C2C0906, // 000C DIV R11 R4 K6
+ 0x7C1C0800, // 000D CALL R7 4
+ 0x7C140400, // 000E CALL R5 2
+ 0x88140102, // 000F GETMBR R5 R0 K2
+ 0x8C140B03, // 0010 GETMET R5 R5 K3
+ 0xB81E0800, // 0011 GETNGBL R7 K4
+ 0x8C1C0F05, // 0012 GETMET R7 R7 K5
+ 0x5C240600, // 0013 MOVE R9 R3
+ 0x5C280400, // 0014 MOVE R10 R2
+ 0x0C2C0906, // 0015 DIV R11 R4 K6
+ 0x7C1C0800, // 0016 CALL R7 4
+ 0x7C140400, // 0017 CALL R5 2
+ 0x88140102, // 0018 GETMBR R5 R0 K2
+ 0x8C140B03, // 0019 GETMET R5 R5 K3
+ 0xB81E0800, // 001A GETNGBL R7 K4
+ 0x8C1C0F07, // 001B GETMET R7 R7 K7
+ 0x58240008, // 001C LDCONST R9 K8
+ 0x58280008, // 001D LDCONST R10 K8
+ 0x582C0008, // 001E LDCONST R11 K8
+ 0x7C1C0800, // 001F CALL R7 4
+ 0x7C140400, // 0020 CALL R5 2
+ 0x80000000, // 0021 RET 0
})
)
);
@@ -321,71 +312,49 @@ be_local_class(Animate_ins_ramp,
(be_nested_const_str("Animate_ins_ramp", 785058280, 16))
);
-/********************************************************************
-** Solidified function: is_running
-********************************************************************/
-be_local_closure(Animate_engine_is_running, /* name */
- be_nested_proto(
- 2, /* nstack */
- 1, /* argc */
- 0, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_string("running", 343848780, 7),
- }),
- (be_nested_const_str("is_running", -2068120035, 10)),
- ((bstring*) &be_const_str_input),
- ( &(const binstruction[ 2]) { /* code */
- 0x88040100, // 0000 GETMBR R1 R0 K0
- 0x80040200, // 0001 RET 1 R1
- })
- )
-);
-/*******************************************************************/
-
-
/********************************************************************
** Solidified function: run
********************************************************************/
be_local_closure(Animate_engine_run, /* name */
be_nested_proto(
- 5, /* nstack */
- 2, /* argc */
+ 6, /* nstack */
+ 3, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 5]) { /* constants */
+ ( &(const bvalue[ 6]) { /* constants */
/* K0 */ be_nested_string("tasmota", 424643812, 7),
/* K1 */ be_nested_string("millis", 1214679063, 6),
- /* K2 */ be_nested_string("ins_time", -1314721743, 8),
- /* K3 */ be_nested_string("running", 343848780, 7),
- /* K4 */ be_nested_string("add_driver", 1654458371, 10),
+ /* K2 */ be_nested_string("value", 1113510858, 5),
+ /* K3 */ be_nested_string("ins_time", -1314721743, 8),
+ /* K4 */ be_nested_string("running", 343848780, 7),
+ /* K5 */ be_nested_string("add_driver", 1654458371, 10),
}),
(be_nested_const_str("run", 718098122, 3)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[15]) { /* code */
- 0x4C080000, // 0000 LDNIL R2
- 0x1C080202, // 0001 EQ R2 R1 R2
- 0x780A0003, // 0002 JMPF R2 #0007
- 0xB80A0000, // 0003 GETNGBL R2 K0
- 0x8C080501, // 0004 GETMET R2 R2 K1
- 0x7C080200, // 0005 CALL R2 1
- 0x5C040400, // 0006 MOVE R1 R2
- 0x90020401, // 0007 SETMBR R0 K2 R1
- 0x50080200, // 0008 LDBOOL R2 1 0
- 0x90020602, // 0009 SETMBR R0 K3 R2
- 0xB80A0000, // 000A GETNGBL R2 K0
- 0x8C080504, // 000B GETMET R2 R2 K4
- 0x5C100000, // 000C MOVE R4 R0
- 0x7C080400, // 000D CALL R2 2
- 0x80000000, // 000E RET 0
+ ( &(const binstruction[19]) { /* code */
+ 0x4C0C0000, // 0000 LDNIL R3
+ 0x1C0C0203, // 0001 EQ R3 R1 R3
+ 0x780E0003, // 0002 JMPF R3 #0007
+ 0xB80E0000, // 0003 GETNGBL R3 K0
+ 0x8C0C0701, // 0004 GETMET R3 R3 K1
+ 0x7C0C0200, // 0005 CALL R3 1
+ 0x5C040600, // 0006 MOVE R1 R3
+ 0x4C0C0000, // 0007 LDNIL R3
+ 0x200C0403, // 0008 NE R3 R2 R3
+ 0x780E0000, // 0009 JMPF R3 #000B
+ 0x90020402, // 000A SETMBR R0 K2 R2
+ 0x90020601, // 000B SETMBR R0 K3 R1
+ 0x500C0200, // 000C LDBOOL R3 1 0
+ 0x90020803, // 000D SETMBR R0 K4 R3
+ 0xB80E0000, // 000E GETNGBL R3 K0
+ 0x8C0C0705, // 000F GETMET R3 R3 K5
+ 0x5C140000, // 0010 MOVE R5 R0
+ 0x7C0C0400, // 0011 CALL R3 2
+ 0x80000000, // 0012 RET 0
})
)
);
@@ -402,53 +371,27 @@ be_local_closure(Animate_engine_init, /* name */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
- 1, /* has sup protos */
- ( &(const struct bproto*[ 1]) {
- be_nested_proto(
- 4, /* nstack */
- 1, /* argc */
- 0, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_string("Animate next value:", 443143038, 19),
- }),
- (be_nested_const_str("_anonymous_", 1957281476, 11)),
- ((bstring*) &be_const_str_input),
- ( &(const binstruction[ 5]) { /* code */
- 0x60040001, // 0000 GETGBL R1 G1
- 0x58080000, // 0001 LDCONST R2 K0
- 0x5C0C0000, // 0002 MOVE R3 R0
- 0x7C040400, // 0003 CALL R1 2
- 0x80000000, // 0004 RET 0
- })
- ),
- }),
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 6]) { /* constants */
+ ( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_string("code", -114201356, 4),
- /* K1 */ be_nested_string("closure", 1548407746, 7),
- /* K2 */ be_nested_string("pc", 1313756516, 2),
- /* K3 */ be_const_int(0),
- /* K4 */ be_nested_string("ins_time", -1314721743, 8),
- /* K5 */ be_nested_string("running", 343848780, 7),
+ /* K1 */ be_nested_string("pc", 1313756516, 2),
+ /* K2 */ be_const_int(0),
+ /* K3 */ be_nested_string("ins_time", -1314721743, 8),
+ /* K4 */ be_nested_string("running", 343848780, 7),
}),
(be_nested_const_str("init", 380752755, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[10]) { /* code */
+ ( &(const binstruction[ 8]) { /* code */
0x60040012, // 0000 GETGBL R1 G18
0x7C040000, // 0001 CALL R1 0
0x90020001, // 0002 SETMBR R0 K0 R1
- 0x84040000, // 0003 CLOSURE R1 P0
- 0x90020201, // 0004 SETMBR R0 K1 R1
- 0x90020503, // 0005 SETMBR R0 K2 K3
- 0x90020903, // 0006 SETMBR R0 K4 K3
- 0x50040000, // 0007 LDBOOL R1 0 0
- 0x90020A01, // 0008 SETMBR R0 K5 R1
- 0x80000000, // 0009 RET 0
+ 0x90020302, // 0003 SETMBR R0 K1 K2
+ 0x90020702, // 0004 SETMBR R0 K3 K2
+ 0x50040000, // 0005 LDBOOL R1 0 0
+ 0x90020801, // 0006 SETMBR R0 K4 R1
+ 0x80000000, // 0007 RET 0
})
)
);
@@ -456,27 +399,35 @@ be_local_closure(Animate_engine_init, /* name */
/********************************************************************
-** Solidified function: every_50ms
+** Solidified function: autorun
********************************************************************/
-be_local_closure(Animate_engine_every_50ms, /* name */
+be_local_closure(Animate_engine_autorun, /* name */
be_nested_proto(
- 3, /* nstack */
- 1, /* argc */
+ 7, /* nstack */
+ 3, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[ 1]) { /* constants */
- /* K0 */ be_nested_string("animate", -409180496, 7),
+ ( &(const bvalue[ 3]) { /* constants */
+ /* K0 */ be_nested_string("run", 718098122, 3),
+ /* K1 */ be_nested_string("tasmota", 424643812, 7),
+ /* K2 */ be_nested_string("add_driver", 1654458371, 10),
}),
- (be_nested_const_str("every_50ms", -1911083288, 10)),
+ (be_nested_const_str("autorun", 1447527407, 7)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[ 3]) { /* code */
- 0x8C040100, // 0000 GETMET R1 R0 K0
- 0x7C040200, // 0001 CALL R1 1
- 0x80000000, // 0002 RET 0
+ ( &(const binstruction[ 9]) { /* code */
+ 0x8C0C0100, // 0000 GETMET R3 R0 K0
+ 0x5C140200, // 0001 MOVE R5 R1
+ 0x5C180400, // 0002 MOVE R6 R2
+ 0x7C0C0600, // 0003 CALL R3 3
+ 0xB80E0200, // 0004 GETNGBL R3 K1
+ 0x8C0C0702, // 0005 GETMET R3 R3 K2
+ 0x5C140000, // 0006 MOVE R5 R0
+ 0x7C0C0400, // 0007 CALL R3 2
+ 0x80000000, // 0008 RET 0
})
)
);
@@ -517,6 +468,61 @@ be_local_closure(Animate_engine_stop, /* name */
/*******************************************************************/
+/********************************************************************
+** Solidified function: is_running
+********************************************************************/
+be_local_closure(Animate_engine_is_running, /* name */
+ be_nested_proto(
+ 2, /* nstack */
+ 1, /* argc */
+ 0, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_string("running", 343848780, 7),
+ }),
+ (be_nested_const_str("is_running", -2068120035, 10)),
+ ((bstring*) &be_const_str_input),
+ ( &(const binstruction[ 2]) { /* code */
+ 0x88040100, // 0000 GETMBR R1 R0 K0
+ 0x80040200, // 0001 RET 1 R1
+ })
+ )
+);
+/*******************************************************************/
+
+
+/********************************************************************
+** Solidified function: every_50ms
+********************************************************************/
+be_local_closure(Animate_engine_every_50ms, /* name */
+ be_nested_proto(
+ 3, /* nstack */
+ 1, /* argc */
+ 0, /* varg */
+ 0, /* has upvals */
+ NULL, /* no upvals */
+ 0, /* has sup protos */
+ NULL, /* no sub protos */
+ 1, /* has constants */
+ ( &(const bvalue[ 1]) { /* constants */
+ /* K0 */ be_nested_string("animate", -409180496, 7),
+ }),
+ (be_nested_const_str("every_50ms", -1911083288, 10)),
+ ((bstring*) &be_const_str_input),
+ ( &(const binstruction[ 3]) { /* code */
+ 0x8C040100, // 0000 GETMET R1 R0 K0
+ 0x7C040200, // 0001 CALL R1 1
+ 0x80000000, // 0002 RET 0
+ })
+ )
+);
+/*******************************************************************/
+
+
/********************************************************************
** Solidified function: animate
********************************************************************/
@@ -530,7 +536,7 @@ be_local_closure(Animate_engine_animate, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[21]) { /* constants */
+ ( &(const bvalue[22]) { /* constants */
/* K0 */ be_nested_string("running", 343848780, 7),
/* K1 */ be_nested_string("tasmota", 424643812, 7),
/* K2 */ be_nested_string("millis", 1214679063, 6),
@@ -544,18 +550,19 @@ be_local_closure(Animate_engine_animate, /* name */
/* K10 */ be_nested_string("ins_ramp", 1068049360, 8),
/* K11 */ be_nested_string("closure", 1548407746, 7),
/* K12 */ be_nested_string("duration", 799079693, 8),
- /* K13 */ be_nested_string("scale_uint", -1204156202, 10),
- /* K14 */ be_nested_string("a", -468965076, 1),
- /* K15 */ be_nested_string("b", -418632219, 1),
- /* K16 */ be_const_int(1),
- /* K17 */ be_nested_string("ins_goto", 1342843963, 8),
- /* K18 */ be_nested_string("pc_rel", 991921176, 6),
- /* K19 */ be_nested_string("pc_abs", 920256495, 6),
- /* K20 */ be_nested_string("unknown instruction", 1093911841, 19),
+ /* K13 */ be_nested_string("value", 1113510858, 5),
+ /* K14 */ be_nested_string("scale_uint", -1204156202, 10),
+ /* K15 */ be_nested_string("a", -468965076, 1),
+ /* K16 */ be_nested_string("b", -418632219, 1),
+ /* K17 */ be_const_int(1),
+ /* K18 */ be_nested_string("ins_goto", 1342843963, 8),
+ /* K19 */ be_nested_string("pc_rel", 991921176, 6),
+ /* K20 */ be_nested_string("pc_abs", 920256495, 6),
+ /* K21 */ be_nested_string("unknown instruction", 1093911841, 19),
}),
(be_nested_const_str("animate", -409180496, 7)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[93]) { /* code */
+ ( &(const binstruction[99]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x740A0000, // 0001 JMPT R2 #0003
0x80000400, // 0002 RET 0
@@ -567,7 +574,7 @@ be_local_closure(Animate_engine_animate, /* name */
0x7C080200, // 0008 CALL R2 1
0x5C040400, // 0009 MOVE R1 R2
0x50080200, // 000A LDBOOL R2 1 0
- 0x780A004F, // 000B JMPF R2 #005C
+ 0x780A0054, // 000B JMPF R2 #0061
0x88080103, // 000C GETMBR R2 R0 K3
0x04080202, // 000D SUB R2 R1 R2
0x880C0104, // 000E GETMBR R3 R0 K4
@@ -578,7 +585,7 @@ be_local_closure(Animate_engine_animate, /* name */
0x780E0002, // 0013 JMPF R3 #0017
0x500C0000, // 0014 LDBOOL R3 0 0
0x90020003, // 0015 SETMBR R0 K0 R3
- 0x70020044, // 0016 JMP #005C
+ 0x70020049, // 0016 JMP #0061
0x880C0104, // 0017 GETMBR R3 R0 K4
0x140C0706, // 0018 LT R3 R3 K6
0x780E0000, // 0019 JMPF R3 #001B
@@ -591,99 +598,70 @@ be_local_closure(Animate_engine_animate, /* name */
0xB81E1200, // 0020 GETNGBL R7 K9
0x881C0F0A, // 0021 GETMBR R7 R7 K10
0x7C140400, // 0022 CALL R5 2
- 0x7816001B, // 0023 JMPF R5 #0040
+ 0x78160020, // 0023 JMPF R5 #0045
0x8810010B, // 0024 GETMBR R4 R0 K11
0x8814070C, // 0025 GETMBR R5 R3 K12
0x14140405, // 0026 LT R5 R2 R5
- 0x7816000C, // 0027 JMPF R5 #0035
+ 0x7816000E, // 0027 JMPF R5 #0037
0xB8160200, // 0028 GETNGBL R5 K1
- 0x8C140B0D, // 0029 GETMET R5 R5 K13
+ 0x8C140B0E, // 0029 GETMET R5 R5 K14
0x5C1C0400, // 002A MOVE R7 R2
0x58200006, // 002B LDCONST R8 K6
0x8824070C, // 002C GETMBR R9 R3 K12
- 0x8828070E, // 002D GETMBR R10 R3 K14
- 0x882C070F, // 002E GETMBR R11 R3 K15
+ 0x8828070F, // 002D GETMBR R10 R3 K15
+ 0x882C0710, // 002E GETMBR R11 R3 K16
0x7C140C00, // 002F CALL R5 6
- 0x5C180800, // 0030 MOVE R6 R4
- 0x5C1C0A00, // 0031 MOVE R7 R5
- 0x7C180200, // 0032 CALL R6 1
- 0x70020027, // 0033 JMP #005C
- 0x70020009, // 0034 JMP #003F
- 0x5C140800, // 0035 MOVE R5 R4
- 0x8818070F, // 0036 GETMBR R6 R3 K15
- 0x7C140200, // 0037 CALL R5 1
- 0x88140104, // 0038 GETMBR R5 R0 K4
- 0x00140B10, // 0039 ADD R5 R5 K16
- 0x90020805, // 003A SETMBR R0 K4 R5
- 0x8814070C, // 003B GETMBR R5 R3 K12
- 0x04140405, // 003C SUB R5 R2 R5
- 0x04140205, // 003D SUB R5 R1 R5
- 0x90020605, // 003E SETMBR R0 K3 R5
- 0x7002001A, // 003F JMP #005B
- 0x6010000F, // 0040 GETGBL R4 G15
- 0x5C140600, // 0041 MOVE R5 R3
- 0xB81A1200, // 0042 GETNGBL R6 K9
- 0x88180D11, // 0043 GETMBR R6 R6 K17
- 0x7C100400, // 0044 CALL R4 2
- 0x78120013, // 0045 JMPF R4 #005A
- 0x8810070C, // 0046 GETMBR R4 R3 K12
- 0x14100404, // 0047 LT R4 R2 R4
- 0x78120001, // 0048 JMPF R4 #004B
- 0x70020011, // 0049 JMP #005C
- 0x7002000D, // 004A JMP #0059
- 0x88100712, // 004B GETMBR R4 R3 K18
- 0x20100906, // 004C NE R4 R4 K6
- 0x78120004, // 004D JMPF R4 #0053
- 0x88100104, // 004E GETMBR R4 R0 K4
- 0x88140712, // 004F GETMBR R5 R3 K18
- 0x00100805, // 0050 ADD R4 R4 R5
- 0x90020804, // 0051 SETMBR R0 K4 R4
- 0x70020001, // 0052 JMP #0055
- 0x88100713, // 0053 GETMBR R4 R3 K19
- 0x90020804, // 0054 SETMBR R0 K4 R4
- 0x8810070C, // 0055 GETMBR R4 R3 K12
- 0x04100404, // 0056 SUB R4 R2 R4
- 0x04100204, // 0057 SUB R4 R1 R4
- 0x90020604, // 0058 SETMBR R0 K3 R4
- 0x70020000, // 0059 JMP #005B
- 0xB0060F14, // 005A RAISE 1 K7 K20
- 0x7001FFAD, // 005B JMP #000A
- 0x80000000, // 005C RET 0
- })
- )
-);
-/*******************************************************************/
-
-
-/********************************************************************
-** Solidified function: autorun
-********************************************************************/
-be_local_closure(Animate_engine_autorun, /* name */
- be_nested_proto(
- 5, /* nstack */
- 2, /* argc */
- 0, /* varg */
- 0, /* has upvals */
- NULL, /* no upvals */
- 0, /* has sup protos */
- NULL, /* no sub protos */
- 1, /* has constants */
- ( &(const bvalue[ 3]) { /* constants */
- /* K0 */ be_nested_string("run", 718098122, 3),
- /* K1 */ be_nested_string("tasmota", 424643812, 7),
- /* K2 */ be_nested_string("add_driver", 1654458371, 10),
- }),
- (be_nested_const_str("autorun", 1447527407, 7)),
- ((bstring*) &be_const_str_input),
- ( &(const binstruction[ 8]) { /* code */
- 0x8C080100, // 0000 GETMET R2 R0 K0
- 0x5C100200, // 0001 MOVE R4 R1
- 0x7C080400, // 0002 CALL R2 2
- 0xB80A0200, // 0003 GETNGBL R2 K1
- 0x8C080502, // 0004 GETMET R2 R2 K2
- 0x5C100000, // 0005 MOVE R4 R0
- 0x7C080400, // 0006 CALL R2 2
- 0x80000000, // 0007 RET 0
+ 0x90021A05, // 0030 SETMBR R0 K13 R5
+ 0x78120002, // 0031 JMPF R4 #0035
+ 0x5C140800, // 0032 MOVE R5 R4
+ 0x8818010D, // 0033 GETMBR R6 R0 K13
+ 0x7C140200, // 0034 CALL R5 1
+ 0x7002002A, // 0035 JMP #0061
+ 0x7002000C, // 0036 JMP #0044
+ 0x88140710, // 0037 GETMBR R5 R3 K16
+ 0x90021A05, // 0038 SETMBR R0 K13 R5
+ 0x78120002, // 0039 JMPF R4 #003D
+ 0x5C140800, // 003A MOVE R5 R4
+ 0x8818010D, // 003B GETMBR R6 R0 K13
+ 0x7C140200, // 003C CALL R5 1
+ 0x88140104, // 003D GETMBR R5 R0 K4
+ 0x00140B11, // 003E ADD R5 R5 K17
+ 0x90020805, // 003F SETMBR R0 K4 R5
+ 0x8814070C, // 0040 GETMBR R5 R3 K12
+ 0x04140405, // 0041 SUB R5 R2 R5
+ 0x04140205, // 0042 SUB R5 R1 R5
+ 0x90020605, // 0043 SETMBR R0 K3 R5
+ 0x7002001A, // 0044 JMP #0060
+ 0x6010000F, // 0045 GETGBL R4 G15
+ 0x5C140600, // 0046 MOVE R5 R3
+ 0xB81A1200, // 0047 GETNGBL R6 K9
+ 0x88180D12, // 0048 GETMBR R6 R6 K18
+ 0x7C100400, // 0049 CALL R4 2
+ 0x78120013, // 004A JMPF R4 #005F
+ 0x8810070C, // 004B GETMBR R4 R3 K12
+ 0x14100404, // 004C LT R4 R2 R4
+ 0x78120001, // 004D JMPF R4 #0050
+ 0x70020011, // 004E JMP #0061
+ 0x7002000D, // 004F JMP #005E
+ 0x88100713, // 0050 GETMBR R4 R3 K19
+ 0x20100906, // 0051 NE R4 R4 K6
+ 0x78120004, // 0052 JMPF R4 #0058
+ 0x88100104, // 0053 GETMBR R4 R0 K4
+ 0x88140713, // 0054 GETMBR R5 R3 K19
+ 0x00100805, // 0055 ADD R4 R4 R5
+ 0x90020804, // 0056 SETMBR R0 K4 R4
+ 0x70020001, // 0057 JMP #005A
+ 0x88100714, // 0058 GETMBR R4 R3 K20
+ 0x90020804, // 0059 SETMBR R0 K4 R4
+ 0x8810070C, // 005A GETMBR R4 R3 K12
+ 0x04100404, // 005B SUB R4 R2 R4
+ 0x04100204, // 005C SUB R4 R1 R4
+ 0x90020604, // 005D SETMBR R0 K3 R4
+ 0x70020000, // 005E JMP #0060
+ 0xB0060F15, // 005F RAISE 1 K7 K21
+ 0x7001FFA8, // 0060 JMP #000A
+ 0x8808010D, // 0061 GETMBR R2 R0 K13
+ 0x80040400, // 0062 RET 1 R2
})
)
);
@@ -694,22 +672,23 @@ be_local_closure(Animate_engine_autorun, /* name */
** Solidified class: Animate_engine
********************************************************************/
be_local_class(Animate_engine,
- 5,
+ 6,
NULL,
- be_nested_map(12,
+ be_nested_map(13,
( (struct bmapnode*) &(const bmapnode[]) {
- { be_nested_key("running", 343848780, 7, -1), be_const_var(4) },
- { be_nested_key("is_running", -2068120035, 10, 7), be_const_closure(Animate_engine_is_running_closure) },
- { be_nested_key("run", 718098122, 3, -1), be_const_closure(Animate_engine_run_closure) },
+ { be_nested_key("code", -114201356, 4, -1), be_const_var(0) },
+ { be_nested_key("run", 718098122, 3, 4), be_const_closure(Animate_engine_run_closure) },
+ { be_nested_key("running", 343848780, 7, 8), be_const_var(4) },
{ be_nested_key("init", 380752755, 4, -1), be_const_closure(Animate_engine_init_closure) },
- { be_nested_key("every_50ms", -1911083288, 10, -1), be_const_closure(Animate_engine_every_50ms_closure) },
- { be_nested_key("stop", -883741979, 4, -1), be_const_closure(Animate_engine_stop_closure) },
- { be_nested_key("pc", 1313756516, 2, 4), be_const_var(2) },
- { be_nested_key("ins_time", -1314721743, 8, -1), be_const_var(3) },
- { be_nested_key("animate", -409180496, 7, 9), be_const_closure(Animate_engine_animate_closure) },
- { be_nested_key("code", -114201356, 4, 6), be_const_var(0) },
- { be_nested_key("closure", 1548407746, 7, -1), be_const_var(1) },
{ be_nested_key("autorun", 1447527407, 7, -1), be_const_closure(Animate_engine_autorun_closure) },
+ { be_nested_key("value", 1113510858, 5, -1), be_const_var(5) },
+ { be_nested_key("stop", -883741979, 4, 3), be_const_closure(Animate_engine_stop_closure) },
+ { be_nested_key("pc", 1313756516, 2, -1), be_const_var(2) },
+ { be_nested_key("is_running", -2068120035, 10, 11), be_const_closure(Animate_engine_is_running_closure) },
+ { be_nested_key("every_50ms", -1911083288, 10, 10), be_const_closure(Animate_engine_every_50ms_closure) },
+ { be_nested_key("animate", -409180496, 7, -1), be_const_closure(Animate_engine_animate_closure) },
+ { be_nested_key("closure", 1548407746, 7, -1), be_const_var(1) },
+ { be_nested_key("ins_time", -1314721743, 8, 9), be_const_var(3) },
})),
(be_nested_const_str("Animate_engine", 1498417667, 14))
);
diff --git a/lib/libesp32/Berry/default/embedded/Animate.be b/lib/libesp32/Berry/default/embedded/Animate.be
index 6f4f28fcc..279fd39ed 100644
--- a/lib/libesp32/Berry/default/embedded/Animate.be
+++ b/lib/libesp32/Berry/default/embedded/Animate.be
@@ -40,10 +40,10 @@ class Animate_engine
var pc # program-counter
var ins_time # absolute time when the current instruction started
var running # is the animation running? allows fast return
+ var value # current value
def init()
self.code = []
- self.closure = def (v) print("Animate next value:", v) end # default to debug function
self.pc = 0 # start at instruction 0
self.ins_time = 0
self.running = false # not running by default
@@ -51,8 +51,11 @@ class Animate_engine
end
# run but needs external calls to `animate()`
- def run(cur_time)
+ # cur_time:int (opt) current timestamp in ms, defaults to `tasmota.millis()`
+ # val:int (opt) starting value, default to `nil`
+ def run(cur_time, val)
if cur_time == nil cur_time = tasmota.millis() end
+ if (val != nil) self.value = val end
self.ins_time = cur_time
self.running = true
@@ -60,8 +63,8 @@ class Animate_engine
end
# runs autonomously in the Tasmota event loop
- def autorun(cur_time)
- self.run(cur_time)
+ def autorun(cur_time, val)
+ self.run(cur_time, val)
tasmota.add_driver(self)
end
@@ -96,15 +99,16 @@ class Animate_engine
# Instruction Ramp
if isinstance(ins, animate.ins_ramp)
- var f = self.closure # assign to a local variable to not call a method
+ var f = self.closure # assign to a local variable to not call a method
if sub_index < ins.duration
# we're still in the ramp
- var v = tasmota.scale_uint(sub_index, 0, ins.duration, ins.a, ins.b)
+ self.value = tasmota.scale_uint(sub_index, 0, ins.duration, ins.a, ins.b)
# call closure
- f(v) # call closure, need try? TODO
+ if f f(self.value) end # call closure, need try? TODO
break
else
- f(ins.b) # set to last value
+ self.value = ins.b
+ if f f(self.value) end # set to last value
self.pc += 1 # next instruction
self.ins_time = cur_time - (sub_index - ins.duration)
end
@@ -127,6 +131,7 @@ class Animate_engine
raise "internal_error", "unknown instruction"
end
end
+ return self.value
end
end
@@ -136,7 +141,7 @@ class Animate_from_to : Animate_engine
def init(closure, from, to, duration)
super(self).init()
- if closure != nil self.closure = closure end
+ self.closure = closure
self.code.push(animate.ins_ramp(from, to, duration))
end
@@ -152,7 +157,7 @@ class Animate_rotate : Animate_engine
def init(closure, from, to, duration)
super(self).init()
- if closure != nil self.closure = closure end
+ self.closure = closure
self.code.push(animate.ins_ramp(from, to, duration))
self.code.push(animate.ins_goto(0, 0, 0)) # goto abs pc = 0 without any pause
end
@@ -169,7 +174,7 @@ class Animate_back_forth : Animate_engine
def init(closure, from, to, duration)
super(self).init()
- if closure != nil self.closure = closure end
+ self.closure = closure
self.code.push(animate.ins_ramp(from, to, duration / 2))
self.code.push(animate.ins_ramp(to, from, duration / 2))
self.code.push(animate.ins_goto(0, 0, 0)) # goto abs pc = 0 without any pause
From cc5f799bdf8783a72930738b976f9d443963d288 Mon Sep 17 00:00:00 2001
From: s-hadinger <49731213+s-hadinger@users.noreply.github.com>
Date: Sat, 20 Nov 2021 12:40:46 +0100
Subject: [PATCH 107/174] Plug zip (#13746)
---
tasmota/xdrv_54_lvgl.ino | 40 ++++++++++++----------------------------
1 file changed, 12 insertions(+), 28 deletions(-)
diff --git a/tasmota/xdrv_54_lvgl.ino b/tasmota/xdrv_54_lvgl.ino
index c8f533310..e772ea910 100644
--- a/tasmota/xdrv_54_lvgl.ino
+++ b/tasmota/xdrv_54_lvgl.ino
@@ -121,6 +121,12 @@ void lv_flush_callback(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *c
************************************************************/
#ifdef USE_UFILESYS
+
+#include
+#include "ZipReadFS.h"
+extern FS *ffsp;
+FS lv_zip_ufsp(ZipReadFSImplPtr(new ZipReadFSImpl(&ffsp)));
+
extern "C" {
typedef void lvbe_FILE;
@@ -132,7 +138,7 @@ extern "C" {
String file_path = "/";
file_path += filename;
- File f = dfsp->open(file_path, mode);
+ File f = lv_zip_ufsp.open(file_path, mode);
// AddLog(LOG_LEVEL_INFO, "LVG: lvbe_fopen(%s) -> %i", file_path.c_str(), (int32_t)f);
// AddLog(LOG_LEVEL_INFO, "LVG: F=%*_H", sizeof(f), &f);
if (f) {
@@ -202,15 +208,9 @@ static void * lvbe_fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mo
// AddLog(LOG_LEVEL_INFO, "LVG: lvbe_fs_open(%p, %p, %s, %i) %i", drv, file_p, path, mode, sizeof(File));
const char * modes = nullptr;
switch (mode) {
- case LV_FS_MODE_WR:
- modes = "w";
- break;
- case LV_FS_MODE_RD:
- modes = "r";
- break;
- case LV_FS_MODE_WR | LV_FS_MODE_RD:
- modes = "rw";
- break;
+ case LV_FS_MODE_WR: modes = "w"; break;
+ case LV_FS_MODE_RD: modes = "r"; break;
+ case LV_FS_MODE_WR | LV_FS_MODE_RD: modes = "rw"; break;
}
if (modes == nullptr) {
@@ -218,28 +218,12 @@ static void * lvbe_fs_open(lv_fs_drv_t * drv, const char * path, lv_fs_mode_t mo
return nullptr;
}
- // Add "/" prefix
- String file_path = "/";
- file_path += path;
-
- File f = dfsp->open(file_path.c_str(), modes);
- // AddLog(LOG_LEVEL_INFO, "LVG: lvbe_fs_open(%s) -> %i", file_path.c_str(), (int32_t)f);
- // AddLog(LOG_LEVEL_INFO, "LVG: F=%*_H", sizeof(f), &f);
- if (f) {
- File * f_ptr = new File(f); // copy to dynamic object
- return f_ptr;
- } else {
- return nullptr;
- }
+ return (void*) lvbe_fopen(path, modes);
}
static lv_fs_res_t lvbe_fs_close(lv_fs_drv_t * drv, void * file_p);
static lv_fs_res_t lvbe_fs_close(lv_fs_drv_t * drv, void * file_p) {
- // AddLog(LOG_LEVEL_INFO, "LVG: lvbe_fs_close(%p, %p)", drv, file_p);
- File * f_ptr = (File*) file_p;
- f_ptr->close();
- delete f_ptr;
- return LV_FS_RES_OK;
+ return lvbe_fclose((void*)file_p);
}
static lv_fs_res_t lvbe_fs_read(lv_fs_drv_t * drv, void * file_p, void * buf, uint32_t btr, uint32_t * br);
From 476c2b3dc0d750f171ae7e1b2014291d96f574a8 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sat, 20 Nov 2021 13:00:35 +0100
Subject: [PATCH 108/174] IRremoteESP8266 library from v2.7.20 to v2.8.0
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 448585921..bf22faf1b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file.
### Changed
- ESP8266 Gratuitous ARP enabled and set to 60 seconds (#13623)
- Removed ILI9488 driver in favor of Unversal Display Driver
+- IRremoteESP8266 library from v2.7.20 to v2.8.0 (#13738)
## [10.0.0.2] 20211113
### Added
From 6999f875666258be7c96dad0964e45bac620fd05 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 20 Nov 2021 14:13:54 +0100
Subject: [PATCH 109/174] Fix exception 0 when width is 0
---
tasmota/xlgt_01_ws2812.ino | 75 +++++++++++++++++++-------------------
1 file changed, 38 insertions(+), 37 deletions(-)
diff --git a/tasmota/xlgt_01_ws2812.ino b/tasmota/xlgt_01_ws2812.ino
index e0030dcb8..bc8dd5f85 100644
--- a/tasmota/xlgt_01_ws2812.ino
+++ b/tasmota/xlgt_01_ws2812.ino
@@ -24,15 +24,15 @@
*
* light_scheme WS2812 3+ Colors 1+2 Colors Effect
* ------------ ------ --------- ---------- -----------------
- * 0 yes no no Clock
- * 1 yes no no Incandescent
- * 2 yes no no RGB
- * 3 yes no no Christmas
- * 4 yes no no Hanukkah
- * 5 yes no no Kwanzaa
- * 6 yes no no Rainbow
- * 7 yes no no Fire
- *
+ * 0 (5) yes no no Clock
+ * 1 (6) yes no no Incandescent
+ * 2 (7) yes no no RGB
+ * 3 (8) yes no no Christmas
+ * 4 (9) yes no no Hanukkah
+ * 5 (10) yes no no Kwanzaa
+ * 6 (11) yes no no Rainbow
+ * 7 (12) yes no no Fire
+ * 8 (13) yes no no Stairs
\*********************************************************************************************/
#define XLGT_01 1
@@ -174,7 +174,7 @@ ColorScheme kSchemes[WS2812_SCHEMES -1] = { // Skip clock scheme
kHanukkah, 2,
kwanzaa, 3,
kRainbow, 7,
- kFire, 3,
+ kFire, 3,
kStairs, 2 };
uint8_t kWidth[5] = {
@@ -401,8 +401,7 @@ void Ws2812Bars(uint32_t schemenr)
Ws2812StripShow();
}
-void Ws2812Steps(uint32_t schemenr)
-{
+void Ws2812Steps(uint32_t schemenr) {
#if (USE_WS2812_CTYPE > NEO_3LED)
RgbwColor c;
c.W = 0;
@@ -412,29 +411,32 @@ void Ws2812Steps(uint32_t schemenr)
ColorScheme scheme = kSchemes[schemenr];
// apply main color if current sheme == kStairs
- if(scheme.colors == kStairs){
+ if (scheme.colors == kStairs) {
scheme.colors[1].red = Settings->light_color[0];
scheme.colors[1].green = Settings->light_color[1];
scheme.colors[1].blue = Settings->light_color[2];
}
- uint8_t scheme_count=scheme.count;
- if(Settings->light_fade){
- scheme_count=Settings->ws_width[WS_HOUR];//Width4
+ uint8_t scheme_count = scheme.count;
+ if (Settings->light_fade) {
+ scheme_count = Settings->ws_width[WS_HOUR]; // Width4
}
+ if (scheme_count < 2) {
+ scheme_count = 2;
+ }
WsColor mcolor[scheme_count];
- uint8_t color_start=0;
- uint8_t color_end=1;
- if(Settings->light_rotation & 0x01){
- color_start=1;
- color_end=0;
+ uint8_t color_start = 0;
+ uint8_t color_end = 1;
+ if (Settings->light_rotation & 0x01) {
+ color_start = 1;
+ color_end = 0;
}
- if(Settings->light_fade){
+ if (Settings->light_fade) {
// generate gradient (width = Width4)
- for(uint32_t i=1; i < scheme_count - 1; i++){
+ for (uint32_t i = 1; i < scheme_count - 1; i++) {
mcolor[i].red = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].red, scheme.colors[color_end].red);
mcolor[i].green = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].green, scheme.colors[color_end].green);
mcolor[i].blue = (uint8_t) wsmap(i, 0, scheme_count, scheme.colors[color_start].blue, scheme.colors[color_end].blue);
@@ -442,14 +444,13 @@ void Ws2812Steps(uint32_t schemenr)
} else {
memcpy(mcolor, scheme.colors, sizeof(mcolor));
}
- // repair first & last color in gradient; apply scheme rotation if fade==0
- mcolor[0].red=scheme.colors[color_start].red;
- mcolor[0].green=scheme.colors[color_start].green;
- mcolor[0].blue=scheme.colors[color_start].blue;
- mcolor[scheme_count-1].red=scheme.colors[color_end].red;
- mcolor[scheme_count-1].green=scheme.colors[color_end].green;
- mcolor[scheme_count-1].blue=scheme.colors[color_end].blue;
-
+ // Repair first & last color in gradient; apply scheme rotation if fade==0
+ mcolor[0].red = scheme.colors[color_start].red;
+ mcolor[0].green = scheme.colors[color_start].green;
+ mcolor[0].blue = scheme.colors[color_start].blue;
+ mcolor[scheme_count-1].red = scheme.colors[color_end].red;
+ mcolor[scheme_count-1].green = scheme.colors[color_end].green;
+ mcolor[scheme_count-1].blue = scheme.colors[color_end].blue;
// Adjust to dimmer value
float dimmer = 100 / (float)Settings->light_dimmer;
@@ -466,23 +467,23 @@ void Ws2812Steps(uint32_t schemenr)
int32_t current_position = Light.strip_timer_counter / speed;
//all pixels are shown already | rotation change will not change current state
- if(current_position > Settings->light_pixels / Settings->light_step_pixels + scheme_count ) {
+ if (current_position > Settings->light_pixels / Settings->light_step_pixels + scheme_count ) {
return;
}
int32_t colorIndex;
int32_t step_nr;
-
+
for (uint32_t i = 0; i < Settings->light_pixels; i++) {
step_nr = i / Settings->light_step_pixels;
- colorIndex = current_position - step_nr;
- if(colorIndex < 0) colorIndex = 0;
- if(colorIndex > scheme_count - 1) colorIndex = scheme_count - 1;
+ colorIndex = current_position - step_nr;
+ if (colorIndex < 0) { colorIndex = 0; }
+ if (colorIndex > scheme_count - 1) { colorIndex = scheme_count - 1; }
c.R = mcolor[colorIndex].red;
c.G = mcolor[colorIndex].green;
c.B = mcolor[colorIndex].blue;
// Adjust the scheme rotation
- if(Settings->light_rotation & 0x02){
+ if (Settings->light_rotation & 0x02) {
strip->SetPixelColor(Settings->light_pixels - i - 1, c);
} else {
strip->SetPixelColor(i, c);
From 25f23b24066f6fc9c407fd684f24ab8b8628e49d Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 20 Nov 2021 14:37:12 +0100
Subject: [PATCH 110/174] Update changelogs
---
CHANGELOG.md | 7 +++++++
RELEASENOTES.md | 6 ++++++
2 files changed, 13 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf22faf1b..6d540abae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Autoconfiguration for ESP32 and variants
- ESP32 fix leftover GPIO configuration after restart
- ESP32 Proof of Concept Sonoff SPM with limited functionality (switching and energy monitoring) (#13447)
+- WS2812 scheme 13 stairs effect (#13595)
- Preliminary support for Tasmota Apps (.tapp extesions)
- Berry support for neopixel (WS2812, SK6812)
@@ -16,6 +17,12 @@ All notable changes to this project will be documented in this file.
- Removed ILI9488 driver in favor of Unversal Display Driver
- IRremoteESP8266 library from v2.7.20 to v2.8.0 (#13738)
+### Fixed
+- ESP32 analog NTC temperature calculation (#13703)
+
+### Removed
+- ILI9488 driver in favour of Universal Display driver (#13719)
+
## [10.0.0.2] 20211113
### Added
- Support for HDC2010 temperature/humidity sensor by Luc Boudreau (#13633)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index c73e1da40..510875d72 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -107,6 +107,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- ESP32 Proof of Concept Sonoff SPM with limited functionality (switching and energy monitoring) [#13447](https://github.com/arendst/Tasmota/issues/13447)
- Command ``TcpConfig`` for TCPBridge protocol configuration [#13565](https://github.com/arendst/Tasmota/issues/13565)
- Support for HDC2010 temperature/humidity sensor by Luc Boudreau [#13633](https://github.com/arendst/Tasmota/issues/13633)
+- WS2812 scheme 13 stairs effect [#13595](https://github.com/arendst/Tasmota/issues/13595)
### Breaking Changed
- ESP32-S2 TSettings memory usage fixed to 4096 bytes regression from v9.5.0.8
@@ -114,6 +115,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
### Changed
- ESP32 core library from v1.0.7.4 to v2.0.1
- ESP32-C3 core library from v2.0.0-post to v2.0.1
+- IRremoteESP8266 library from v2.7.20 to v2.8.0
- File editor no-wrap [#13427](https://github.com/arendst/Tasmota/issues/13427)
- ESP8266 Gratuitous ARP enabled and set to 60 seconds [#13623](https://github.com/arendst/Tasmota/issues/13623)
@@ -124,4 +126,8 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- GUI checkbox MQTT TLS not saved regression from v9.2.0.3 [#13442](https://github.com/arendst/Tasmota/issues/13442)
- Discovery of shutters [#13572](https://github.com/arendst/Tasmota/issues/13572)
- ESP32-C3 OneWire as used by DS18x20 [#13583](https://github.com/arendst/Tasmota/issues/13583)
+- ESP32 analog NTC temperature calculation [#13703](https://github.com/arendst/Tasmota/issues/13703)
+
+### Removed
+- ILI9488 driver in favour of Universal Display driver [#13719](https://github.com/arendst/Tasmota/issues/13719)
From efb77a65477f43441069195d18aece5b9afea61a Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sat, 20 Nov 2021 17:29:10 +0100
Subject: [PATCH 111/174] Rewrite Sonoff SPM state machine
- Rewrite Sonoff SPM state machine for easier maintenance
- Fix handling user output when initiating a scan
---
tasmota/xdrv_86_esp32_sonoff_spm.ino | 154 ++++++++++++++++-----------
1 file changed, 89 insertions(+), 65 deletions(-)
diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino
index f40c824fa..de2976d73 100644
--- a/tasmota/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino
@@ -30,7 +30,7 @@
* Bulk of the action is handled by ARM processors present in every unit communicating over modbus RS-485.
* Each SPM-4Relay has 4 bistable relays with their own CSE7761 energy monitoring device handled by an ARM processor.
* Green led is controlled by ARM processor indicating SD-Card access.
- * ESP32 is used as interface between Welink and ARM processor in SPM-Main unit communicating over proprietary serial protocol.
+ * ESP32 is used as interface between eWelink and ARM processor in SPM-Main unit communicating over proprietary serial protocol.
* Inductive/Capacitive loads are not reported correctly.
* Power on sequence for two SPM-4Relay modules is 00-00-15-10-(0F)-(13)-(13)-(19)-0C-09-04-09-04-0B-0B
*
@@ -124,10 +124,19 @@
#define SSPM_MODULE_NAME_SIZE 12
-enum SspmInitSteps { SPM_NONE, SPM_WAIT, SPM_RESET, SPM_POLL, SPM_POLL_ACK, SPM_SEND_FUNC_UNITS, SPM_STEP_WAIT2,
- SPM_DEVICES_FOUND,
- SPM_GET_ENERGY_TOTALS,
- SPM_ALLOW_LOOP};
+enum SspmMachineStates { SPM_NONE, // Do nothing
+ SPM_WAIT, // Wait 100ms
+ SPM_RESET, // Toggle ARM reset pin
+ SPM_POLL_ARM, // Wait for first acknowledge from ARM after reset
+ SPM_POLL_ARM_2, // Wait for second acknowledge from ARM after reset
+ SPM_SEND_FUNC_UNITS, // Get number of units
+ SPM_START_SCAN, // Start module scan sequence
+ SPM_WAIT_FOR_SCAN, // Wait for scan sequence to complete
+ SPM_SCAN_COMPLETE, // Scan complete
+ SPM_GET_ENERGY_TOTALS, // Init available Energy totals registers
+ SPM_UPDATE_CHANNELS, // Update Energy for powered on channels
+ SPM_UPDATE_TOTALS // Update Energy totals for powered on channels
+ };
#include
TasmotaSerial *SspmSerial;
@@ -156,7 +165,7 @@ typedef struct {
uint8_t counter;
uint8_t command_sequence;
uint8_t loop_step;
- uint8_t init_step;
+ uint8_t mstate;
uint8_t last_button;
bool discovery_triggered;
} TSspm;
@@ -528,7 +537,7 @@ void SSPMHandleReceivedData(void) {
|Er| |St|
*/
if ((1 == Sspm->expected_bytes) && (0 == SspmBuffer[19])) {
- Sspm->init_step++;
+ Sspm->mstate++; // Cycle to
}
break;
case SSPM_FUNC_GET_OPS:
@@ -591,15 +600,14 @@ void SSPMHandleReceivedData(void) {
} else {
AddLog(LOG_LEVEL_DEBUG, PSTR("SPM: Relay scan done"));
- Sspm->init_step = SPM_DEVICES_FOUND;
-// Sspm->get_energy_relay = 1;
-// Sspm->allow_updates = 1; // Enable requests from 100mSec loop
+ Sspm->mstate = SPM_SCAN_COMPLETE;
}
break;
case SSPM_FUNC_SET_TIME:
/* 0x0C
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 0c 00 01 00 04 3e 62
*/
+ TasmotaGlobal.devices_present = 0;
SSPMSendGetModuleState(Sspm->module_selected -1);
break;
case SSPM_FUNC_INIT_SCAN:
@@ -607,7 +615,6 @@ void SSPMHandleReceivedData(void) {
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
AA 55 01 ff ff ff ff ff ff ff ff ff ff ff ff 80 10 00 01 00 02 e5 03
*/
- Sspm->module_max = 0;
break;
case SSPM_FUNC_UNITS:
/* 0x15
@@ -615,7 +622,7 @@ void SSPMHandleReceivedData(void) {
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 80 15 00 04 00 01 00 00 01 81 b1
|?? ?? ?? ??|
*/
- SSPMSendInitScan();
+ Sspm->mstate = SPM_START_SCAN;
break;
case SSPM_FUNC_GET_ENERGY_TOTAL:
/* 0x16
@@ -746,7 +753,6 @@ void SSPMHandleReceivedData(void) {
/* 0x0F
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 0f 00 01 02 01 9d f8
*/
-// Sspm->module_max = 0;
SSPMSendAck(command_sequence);
break;
case SSPM_FUNC_SCAN_RESULT:
@@ -851,7 +857,7 @@ void SSPMInit(void) {
}
Sspm->old_power = TasmotaGlobal.power;
- Sspm->init_step = SPM_WAIT; // Start init sequence
+ Sspm->mstate = SPM_WAIT; // Start init sequence
}
void SSPMEvery100ms(void) {
@@ -865,17 +871,18 @@ void SSPMEvery100ms(void) {
}
// Fix race condition if the ARM doesn't respond
- if ((Sspm->init_step > SPM_NONE) && (Sspm->init_step < SPM_SEND_FUNC_UNITS)) {
+ if ((Sspm->mstate > SPM_NONE) && (Sspm->mstate < SPM_SEND_FUNC_UNITS)) {
Sspm->counter++;
if (Sspm->counter > 20) {
- Sspm->init_step = SPM_NONE;
+ Sspm->mstate = SPM_NONE;
}
}
- switch (Sspm->init_step) {
+ switch (Sspm->mstate) {
case SPM_NONE:
return;
case SPM_WAIT:
- Sspm->init_step++;
+ // 100ms wait
+ Sspm->mstate = SPM_RESET;
break;
case SPM_RESET:
// Reset ARM
@@ -883,22 +890,34 @@ void SSPMEvery100ms(void) {
delay(18);
digitalWrite(SSPM_GPIO_ARM_RESET, 1);
delay(18);
- Sspm->init_step++;
- case SPM_POLL:
+ Sspm->mstate = SPM_POLL_ARM;
+ case SPM_POLL_ARM:
+ // Wait for first acknowledge from ARM after reset
SSPMSendCmnd(SSPM_FUNC_FIND);
break;
- case SPM_POLL_ACK:
+ case SPM_POLL_ARM_2:
+ // Wait for second acknowledge from ARM after reset
SSPMSendCmnd(SSPM_FUNC_FIND);
break;
case SPM_SEND_FUNC_UNITS:
- Sspm->init_step++;
+ // Get number of units
SSPMSendCmnd(SSPM_FUNC_UNITS);
break;
- case SPM_DEVICES_FOUND:
- TasmotaGlobal.discovery_counter = 1; // force TasDiscovery()
+ case SPM_START_SCAN:
+ // Start scan module sequence
+ Sspm->module_max = 0;
+ SSPMSendInitScan();
+ Sspm->mstate = SPM_WAIT_FOR_SCAN;
+ break;
+ case SPM_WAIT_FOR_SCAN:
+ // Wait for scan sequence to complete
+ break;
+ case SPM_SCAN_COMPLETE:
+ // Scan sequence finished
+ TasmotaGlobal.discovery_counter = 1; // Force TasDiscovery()
Sspm->get_energy_relay = 1;
- Sspm->allow_updates = 1; // Enable requests from 100mSec loop
- Sspm->init_step++;
+ Sspm->allow_updates = 1; // Enable requests from 100mSec loop
+ Sspm->mstate = SPM_GET_ENERGY_TOTALS;
break;
case SPM_GET_ENERGY_TOTALS:
// Retrieve Energy total status from up to 128 relays
@@ -908,47 +927,54 @@ void SSPMEvery100ms(void) {
Sspm->get_energy_relay++;
if (Sspm->get_energy_relay > TasmotaGlobal.devices_present) {
Sspm->get_energy_relay = 1;
- Sspm->init_step++;
+ Sspm->mstate = SPM_UPDATE_CHANNELS;
}
}
break;
- case SPM_ALLOW_LOOP:
- // Retrieve Energy status from up to 128 relays
+ case SPM_UPDATE_CHANNELS:
+ // Retrieve Energy status from up to 128 powered on relays
if (Sspm->allow_updates && (Sspm->get_energy_relay > 0)) {
power_t powered_on = TasmotaGlobal.power >> (Sspm->get_energy_relay -1);
- if (0 == Sspm->loop_step) {
- // Get energy total only once in any 256 requests to safe comms
- if (powered_on &1) {
- SSPMSetLock(4);
- SSPMSendGetEnergyTotal(Sspm->get_energy_relay -1);
- }
- Sspm->get_energy_relay++;
- if (Sspm->get_energy_relay > TasmotaGlobal.devices_present) {
- Sspm->get_energy_relay = 1;
- Sspm->loop_step++;
- }
+ if (powered_on &1) {
+ SSPMSetLock(4);
+ SSPMSendGetEnergy(Sspm->get_energy_relay -1);
} else {
- if (powered_on &1) {
- SSPMSetLock(4);
- SSPMSendGetEnergy(Sspm->get_energy_relay -1);
- } else {
- uint32_t relay_set = (Sspm->get_energy_relay -1) >> 2;
- uint32_t relay_num = (Sspm->get_energy_relay -1) &3;
- if (Sspm->voltage[relay_set][relay_num]) {
- Sspm->voltage[relay_set][relay_num] = 0;
- Sspm->current[relay_set][relay_num] = 0;
- Sspm->active_power[relay_set][relay_num] = 0;
- Sspm->apparent_power[relay_set][relay_num] = 0;
- Sspm->reactive_power[relay_set][relay_num] = 0;
- Sspm->power_factor[relay_set][relay_num] = 0;
- }
- }
- Sspm->loop_step++; // Rolls over after 256 so allows for scanning at least all relays twice
- Sspm->get_energy_relay++;
- if ((Sspm->get_energy_relay > TasmotaGlobal.devices_present) || !Sspm->loop_step) {
- Sspm->get_energy_relay = 1;
+ uint32_t relay_set = (Sspm->get_energy_relay -1) >> 2;
+ uint32_t relay_num = (Sspm->get_energy_relay -1) &3;
+ if (Sspm->voltage[relay_set][relay_num]) {
+ Sspm->voltage[relay_set][relay_num] = 0;
+ Sspm->current[relay_set][relay_num] = 0;
+ Sspm->active_power[relay_set][relay_num] = 0;
+ Sspm->apparent_power[relay_set][relay_num] = 0;
+ Sspm->reactive_power[relay_set][relay_num] = 0;
+ Sspm->power_factor[relay_set][relay_num] = 0;
}
}
+ Sspm->get_energy_relay++;
+ if (Sspm->get_energy_relay > TasmotaGlobal.devices_present) {
+ Sspm->get_energy_relay = 1;
+ }
+ Sspm->loop_step++; // Rolls over after 256 so allows for scanning at least all relays twice
+ if (!Sspm->loop_step) {
+ Sspm->get_energy_relay = 1;
+ Sspm->mstate = SPM_UPDATE_TOTALS;
+ }
+ }
+ break;
+ case SPM_UPDATE_TOTALS:
+ // Retrieve Energy totals from up to 128 powered on relays
+ if (Sspm->allow_updates && (Sspm->get_energy_relay > 0)) {
+ power_t powered_on = TasmotaGlobal.power >> (Sspm->get_energy_relay -1);
+ // Get energy total only once in any 256 requests to safe comms
+ if (powered_on &1) {
+ SSPMSetLock(4);
+ SSPMSendGetEnergyTotal(Sspm->get_energy_relay -1);
+ }
+ Sspm->get_energy_relay++;
+ if (Sspm->get_energy_relay > TasmotaGlobal.devices_present) {
+ Sspm->get_energy_relay = 1;
+ Sspm->mstate = SPM_UPDATE_CHANNELS;
+ }
}
break;
}
@@ -973,7 +999,7 @@ bool SSPMButton(void) {
bool result = false;
uint32_t button = XdrvMailbox.payload;
if ((PRESSED == button) && (NOT_PRESSED == Sspm->last_button)) { // Button pressed
- SSPMSendInitScan();
+ Sspm->mstate = SPM_START_SCAN;
result = true; // Disable further button processing
}
Sspm->last_button = button;
@@ -1025,10 +1051,9 @@ void SSPMEnergyShow(bool json) {
ResponseAppend_P(PSTR("]}"));
} else {
Sspm->rotate++;
- if ((Sspm->rotate >> 2) == Sspm->module_max) {
+ if (Sspm->rotate >= TasmotaGlobal.devices_present) {
Sspm->rotate = 0;
}
-
uint32_t module = Sspm->rotate >> 2;
uint32_t relay_base = module * 4;
WSContentSend_P(PSTR("{s}" D_SENSOR_RELAY "{m}L%02d / L%02d / L%02d / L%02d{e}"), relay_base +1, relay_base +2, relay_base +3, relay_base +4);
@@ -1077,9 +1102,8 @@ void CmndSSPMEnergyHistory(void) {
}
void CmndSSPMScan(void) {
- SSPMSendInitScan();
-
- ResponseCmndDone();
+ Sspm->mstate = SPM_START_SCAN;
+ ResponseCmndChar(PSTR(D_JSON_STARTED));
}
/*********************************************************************************************\
From 235bf403c69a2f9925da3565c49efae85d2050de Mon Sep 17 00:00:00 2001
From: Barbudor
Date: Sat, 20 Nov 2021 22:35:07 +0100
Subject: [PATCH 112/174] add IfxPeriod
---
tasmota/settings.h | 3 ++-
tasmota/xdrv_59_influxdb.ino | 23 +++++++++++++++++++----
2 files changed, 21 insertions(+), 5 deletions(-)
diff --git a/tasmota/settings.h b/tasmota/settings.h
index 99a226cba..c75842aac 100644
--- a/tasmota/settings.h
+++ b/tasmota/settings.h
@@ -598,7 +598,8 @@ typedef struct {
int8_t shutter_tilt_config[5][MAX_SHUTTERS]; //508
int8_t shutter_tilt_pos[MAX_SHUTTERS]; //51C
- uint8_t free_520[12]; // 520
+ uint16_t influxdb_period; // 520
+ uint8_t free_522[10]; // 522
uint16_t mqtt_keepalive; // 52C
uint16_t mqtt_socket_timeout; // 52E
diff --git a/tasmota/xdrv_59_influxdb.ino b/tasmota/xdrv_59_influxdb.ino
index ecafe8003..13e50cbb6 100644
--- a/tasmota/xdrv_59_influxdb.ino
+++ b/tasmota/xdrv_59_influxdb.ino
@@ -37,6 +37,7 @@
* IfxBucket - Set Influxdb v2 and bucket name
* IfxOrg - Set Influxdb v2 and organization
* IfxToken - Set Influxdb v2 and token
+ * IfxPeriod - Set Influxdb period. If not set (or 0), use Teleperiod
*
* Set influxdb update interval with command teleperiod
*
@@ -364,8 +365,9 @@ void InfluxDbPublishPowerState(uint32_t device) {
void InfluxDbLoop(void) {
if (!TasmotaGlobal.global_state.network_down) {
IFDB.interval--;
- if (IFDB.interval <= 0 || IFDB.interval > Settings->tele_period) {
- IFDB.interval = Settings->tele_period;
+ uint16_t period = Settings->influxdb_period ? Settings->influxdb_period : Settings->tele_period;
+ if (IFDB.interval <= 0 || IFDB.interval > period) {
+ IFDB.interval = period;
if (!IFDB.init) {
if (InfluxDbParameterInit()) {
IFDB.init = InfluxDbValidateConnection();
@@ -408,20 +410,23 @@ void InfluxDbLoop(void) {
#define D_CMND_INFLUXDBTOKEN "Token"
#define D_CMND_INFLUXDBDATABASE "Database"
#define D_CMND_INFLUXDBBUCKET "Bucket"
+#define D_CMND_INFLUXDBPERIOD "Period"
const char kInfluxDbCommands[] PROGMEM = D_PRFX_INFLUXDB "|" // Prefix
"|" D_CMND_INFLUXDBLOG "|"
D_CMND_INFLUXDBHOST "|" D_CMND_INFLUXDBPORT "|"
D_CMND_INFLUXDBUSER "|" D_CMND_INFLUXDBORG "|"
D_CMND_INFLUXDBPASSWORD "|" D_CMND_INFLUXDBTOKEN "|"
- D_CMND_INFLUXDBDATABASE "|" D_CMND_INFLUXDBBUCKET;
+ D_CMND_INFLUXDBDATABASE "|" D_CMND_INFLUXDBBUCKET "|"
+ D_CMND_INFLUXDBPERIOD;
void (* const InfluxCommand[])(void) PROGMEM = {
&CmndInfluxDbState, &CmndInfluxDbLog,
&CmndInfluxDbHost, &CmndInfluxDbPort,
&CmndInfluxDbUser, &CmndInfluxDbUser,
&CmndInfluxDbPassword, &CmndInfluxDbPassword,
- &CmndInfluxDbDatabase, &CmndInfluxDbDatabase };
+ &CmndInfluxDbDatabase, &CmndInfluxDbDatabase,
+ &CmndInfluxDbPeriod };
void InfluxDbReinit(void) {
IFDB.init = false;
@@ -504,6 +509,16 @@ void CmndInfluxDbDatabase(void) {
ResponseCmndChar(SettingsText(SET_INFLUXDB_BUCKET));
}
+void CmndInfluxDbPeriod(void) {
+ if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) {
+ Settings->influxdb_period = XdrvMailbox.payload;
+ if(Settings->influxdb_period > 0 && Settings->influxdb_period < 10) {
+ Settings->influxdb_period = 10;
+ }
+ }
+ ResponseCmndNumber(Settings->influxdb_period);
+}
+
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
From ced7aa5a084192737364649b28a7c23a1959abbb Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 21 Nov 2021 13:30:05 +0100
Subject: [PATCH 113/174] Fix ESP32 ethernet broken by core 2.x
- Fix ESP32 ethernet broken by core 2.x
- Change ethernet hostname ending in ``_eth`` to ``-eth`` according to RFC952
---
CHANGELOG.md | 3 +++
RELEASENOTES.md | 2 ++
tasmota/xdrv_82_esp32_ethernet.ino | 16 ++++++++--------
3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 6d540abae..3a53c17c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,14 +11,17 @@ All notable changes to this project will be documented in this file.
- WS2812 scheme 13 stairs effect (#13595)
- Preliminary support for Tasmota Apps (.tapp extesions)
- Berry support for neopixel (WS2812, SK6812)
+- Command ``IfxPeriod `` to overrule ``Teleperiod`` for Influx messages (#13750)
### Changed
- ESP8266 Gratuitous ARP enabled and set to 60 seconds (#13623)
- Removed ILI9488 driver in favor of Unversal Display Driver
- IRremoteESP8266 library from v2.7.20 to v2.8.0 (#13738)
+- Ethernet hostname ending in ``_eth`` to ``-eth`` according to RFC952
### Fixed
- ESP32 analog NTC temperature calculation (#13703)
+- ESP32 ethernet broken by core 2.x
### Removed
- ILI9488 driver in favour of Universal Display driver (#13719)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 510875d72..985262bd6 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -108,6 +108,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- Command ``TcpConfig`` for TCPBridge protocol configuration [#13565](https://github.com/arendst/Tasmota/issues/13565)
- Support for HDC2010 temperature/humidity sensor by Luc Boudreau [#13633](https://github.com/arendst/Tasmota/issues/13633)
- WS2812 scheme 13 stairs effect [#13595](https://github.com/arendst/Tasmota/issues/13595)
+- Command ``IfxPeriod `` to overrule ``Teleperiod`` for Influx messages [#13750](https://github.com/arendst/Tasmota/issues/13750)
### Breaking Changed
- ESP32-S2 TSettings memory usage fixed to 4096 bytes regression from v9.5.0.8
@@ -118,6 +119,7 @@ The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmo
- IRremoteESP8266 library from v2.7.20 to v2.8.0
- File editor no-wrap [#13427](https://github.com/arendst/Tasmota/issues/13427)
- ESP8266 Gratuitous ARP enabled and set to 60 seconds [#13623](https://github.com/arendst/Tasmota/issues/13623)
+- Ethernet hostname ending in ``_eth`` to ``-eth`` according to RFC952
### Fixed
- Initial reset RTC memory based variables like EnergyToday and EnergyTotal
diff --git a/tasmota/xdrv_82_esp32_ethernet.ino b/tasmota/xdrv_82_esp32_ethernet.ino
index d276ad7fd..1deb646b5 100644
--- a/tasmota/xdrv_82_esp32_ethernet.ino
+++ b/tasmota/xdrv_82_esp32_ethernet.ino
@@ -86,15 +86,15 @@ char eth_hostname[sizeof(TasmotaGlobal.hostname)];
void EthernetEvent(WiFiEvent_t event) {
switch (event) {
- case SYSTEM_EVENT_ETH_START:
+ case ARDUINO_EVENT_ETH_START:
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: " D_ATTEMPTING_CONNECTION));
ETH.setHostname(eth_hostname);
break;
- case SYSTEM_EVENT_ETH_CONNECTED:
+ case ARDUINO_EVENT_ETH_CONNECTED:
AddLog(LOG_LEVEL_INFO, PSTR("ETH: " D_CONNECTED " at %dMbps%s"),
ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "");
break;
- case SYSTEM_EVENT_ETH_GOT_IP:
+ case ARDUINO_EVENT_ETH_GOT_IP:
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Mac %s, IPAddress %_I, Hostname %s"),
ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname);
Settings->ipv4_address[1] = (uint32_t)ETH.gatewayIP();
@@ -103,11 +103,11 @@ void EthernetEvent(WiFiEvent_t event) {
Settings->ipv4_address[4] = (uint32_t)ETH.dnsIP(1);
TasmotaGlobal.global_state.eth_down = 0;
break;
- case SYSTEM_EVENT_ETH_DISCONNECTED:
+ case ARDUINO_EVENT_ETH_DISCONNECTED:
AddLog(LOG_LEVEL_INFO, PSTR("ETH: Disconnected"));
TasmotaGlobal.global_state.eth_down = 1;
break;
- case SYSTEM_EVENT_ETH_STOP:
+ case ARDUINO_EVENT_ETH_STOP:
AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: Stopped"));
TasmotaGlobal.global_state.eth_down = 1;
break;
@@ -129,9 +129,9 @@ void EthernetInit(void) {
Settings->eth_clk_mode = ETH_CLOCK_GPIO0_IN; // EthClockMode
}
-// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s_eth"), TasmotaGlobal.hostname);
- strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "_eth"
- strcat(eth_hostname, "_eth");
+// snprintf_P(Eth.hostname, sizeof(Eth.hostname), PSTR("%s-eth"), TasmotaGlobal.hostname);
+ strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "-eth"
+ strcat(eth_hostname, "-eth");
WiFi.onEvent(EthernetEvent);
From 366ee8f2636364e857eb00ca12b43e3e4d0bec17 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 21 Nov 2021 13:53:03 +0100
Subject: [PATCH 114/174] Odroid
---
platformio_tasmota_env32.ini | 5 ++---
tasmota/tasmota_configurations_ESP32.h | 15 ++++++++++-----
tasmota/xdrv_55_touch.ino | 12 ++++++++----
3 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini
index b41146635..b67f4c90a 100644
--- a/platformio_tasmota_env32.ini
+++ b/platformio_tasmota_env32.ini
@@ -61,13 +61,12 @@ lib_extra_dirs = lib/libesp32
[env:tasmota32-odroidgo]
extends = env:tasmota32_base
board = esp32-odroid
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_ODROID_GO
-lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_ODROID_GO -DUSE_UNIVERSAL_DISPLAY -DUSE_AUTOCONF
[env:tasmota32-core2]
extends = env:tasmota32_base
board = esp32-m5core2
-build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_M5STACK_CORE2 -DUSE_UNIVERSAL_DISPLAY
+build_flags = ${env:tasmota32_base.build_flags} -DFIRMWARE_M5STACK_CORE2 -DUSE_UNIVERSAL_DISPLAY -DUSE_AUTOCONF
lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display, lib/lib_audio
[env:tasmota32-bluetooth]
diff --git a/tasmota/tasmota_configurations_ESP32.h b/tasmota/tasmota_configurations_ESP32.h
index b708201d7..b358d74e0 100644
--- a/tasmota/tasmota_configurations_ESP32.h
+++ b/tasmota/tasmota_configurations_ESP32.h
@@ -75,13 +75,18 @@
#undef USE_HOME_ASSISTANT
-#define USE_ADC
+#define USE_I2C
#define USE_SPI
- #define USE_DISPLAY // Add SPI Display Support (+2k code)
+ #define USE_DISPLAY
#define SHOW_SPLASH
- #ifndef USE_UNIVERSAL_DISPLAY
- #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code)
- #endif
+#ifdef USE_UNIVERSAL_DISPLAY
+ #define USE_LVGL
+ #define USE_LVGL_FREETYPE
+// #define USE_DISPLAY_LVGL_ONLY
+#else
+ #define USE_DISPLAY_ILI9341 // [DisplayModel 4] Enable ILI9341 Tft 480x320 display (+19k code)
+ #define USE_DISPLAY_MODES1TO5
+#endif
//#define USE_BLE_ESP32 // Enable new BLE driver
//#define USE_MI_ESP32 // (ESP32 only) Add support for ESP32 as a BLE-bridge (+9k2 mem, +292k flash)
#endif // FIRMWARE_ODROID_GO
diff --git a/tasmota/xdrv_55_touch.ino b/tasmota/xdrv_55_touch.ino
index 4abb9683e..5453176bc 100644
--- a/tasmota/xdrv_55_touch.ino
+++ b/tasmota/xdrv_55_touch.ino
@@ -21,9 +21,9 @@
#if defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS)
-// #ifdef USE_DISPLAY_LVGL_ONLY
-// #undef USE_TOUCH_BUTTONS
-// #endif
+#ifdef USE_DISPLAY_LVGL_ONLY
+#undef USE_TOUCH_BUTTONS
+#endif
#include
@@ -317,5 +317,9 @@ bool Xdrv55(uint8_t function) {
}
return result;
}
-
+#else
+// dummy for LVGL without a touch controller
+uint32_t Touch_Status(uint32_t sel) {
+return 0;
+}
#endif // USE_TOUCH
From 010f8f8d37a9820d3eb38d7a236a73fa7bc6ad95 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 21 Nov 2021 14:15:38 +0100
Subject: [PATCH 115/174] Add ethernet support to Sonoff SPM
- Add ethernet support to Sonoff SPM
- Update template to "Sonoff SPM (POC2)" (#13447)
---
tasmota/xdrv_86_esp32_sonoff_spm.ino | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino
index de2976d73..3a2e1166a 100644
--- a/tasmota/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino
@@ -24,7 +24,10 @@
/*********************************************************************************************\
* Sonoff Stackable Power Manager (Current state: PROOF OF CONCEPT)
*
+ * Initial POC template:
* {"NAME":"Sonoff SPM (POC1)","GPIO":[1,1,1,1,3200,1,1,1,1,1,1,1,3232,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1}
+ * Add ethernet support:
+ * {"NAME":"Sonoff SPM (POC2)","GPIO":[1,0,1,0,3200,5536,0,0,1,1,1,0,3232,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,544,1,1,32,1,0,0,1],"FLAG":0,"BASE":1}
*
* Things to know:
* Bulk of the action is handled by ARM processors present in every unit communicating over modbus RS-485.
@@ -40,8 +43,10 @@
* Button on SPM-Main initiates re-scan of SPM-4Relay units.
* Blue led equals Tasmota WiFi status.
*
+ * Tasmota POC2:
+ * Ethernet support.
+ *
* Todo:
- * Ethernet support (Find correct MDIO, MDC, POWER GPIO's and ETH_ parameters).
* Gui optimization for energy display.
* Gui for Overload Protection entry (is handled by ARM processor).
* Gui for Scheduling entry (is handled by ARM processor).
@@ -56,26 +61,26 @@
* GPIO01 - Serial console TX (921600bps8N1 originally)
* GPIO03 - Serial console RX
* GPIO04 - ARM processor TX (115200bps8N1)
+ * GPIO05 - ETH POWER
* GPIO12 - SPI MISO ARM pulsetrain code (input?)
* GPIO13 - SPI CLK
* GPIO14 - SPI CS ARM pulsetrain eoc (input?)
* GPIO15 - ARM reset (output) - 18ms low active 125ms after restart esp32
* GPIO16 - ARM processor RX
* GPIO17 - EMAC_CLK_OUT_180
- * GPIO18 - ??ETH MDIO
+ * GPIO18 - ETH MDIO
* GPIO19 - EMAC_TXD0(RMII)
* GPIO21 - EMAC_TX_EN(RMII)
* GPIO22 - EMAC_TXD1(RMII)
- * GPIO23 - ??ETH MDC
+ * GPIO23 - ETH MDC
* GPIO25 - EMAC_RXD0(RMII)
* GPIO26 - EMAC_RXD1(RMII)
* GPIO27 - EMAC_RX_CRS_DV
- * GPIO?? - ??ETH POWER
* GPIO32 - Blue status led2
* GPIO33 - Yellow error led3
* GPIO35 - Button
* #define ETH_TYPE ETH_PHY_LAN8720
- * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN
+ * #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT
* #define ETH_ADDRESS 0
*
* Variables used:
@@ -103,7 +108,6 @@
#define SSPM_FUNC_GET_ENERGY_TOTAL 22 // 0x16
#define SSPM_FUNC_GET_ENERGY 24 // 0x18
#define SSPM_FUNC_GET_LOG 26 // 0x1A
-
#define SSPM_FUNC_ENERGY_PERIOD 27 // 0x1B
// Receive
@@ -829,7 +833,8 @@ void SSPMSerialInput(void) {
}
void SSPMInit(void) {
- if (!ValidTemplate(PSTR("Sonoff SPM (POC1)"))) { return; }
+ if (!ValidTemplate(PSTR("Sonoff SPM (POC1)")) &&
+ !ValidTemplate(PSTR("Sonoff SPM (POC2)"))) { return; }
if (!PinUsed(GPIO_RXD) || !PinUsed(GPIO_TXD)) { return; }
Sspm = (TSspm*)calloc(sizeof(TSspm), 1);
@@ -856,6 +861,14 @@ void SSPMInit(void) {
Settings->flag2.energy_resolution = 0; // SPM has no decimals on total energy
}
+#if CONFIG_IDF_TARGET_ESP32
+#ifdef USE_ETHERNET
+ Settings->eth_address = 0; // EthAddress
+ Settings->eth_type = ETH_PHY_LAN8720; // EthType
+ Settings->eth_clk_mode = ETH_CLOCK_GPIO17_OUT; // EthClockMode
+#endif
+#endif
+
Sspm->old_power = TasmotaGlobal.power;
Sspm->mstate = SPM_WAIT; // Start init sequence
}
From 116da1f5d28d10e2759c171303173bc90f4b2954 Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Sun, 21 Nov 2021 14:32:57 +0100
Subject: [PATCH 116/174] Fix SPM JSON Energy Total values
---
tasmota/xdrv_86_esp32_sonoff_spm.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino
index 3a2e1166a..f2d83439e 100644
--- a/tasmota/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino
@@ -1039,7 +1039,7 @@ void SSPMEnergyShow(bool json) {
if (json) {
ResponseAppend_P(PSTR(",\"SPM\":{\"" D_JSON_TOTAL "\":["));
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
- ResponseAppend_P(PSTR("%s%*_f"), (i>0)?",":"", 0, &Sspm->total[i >>2][i &3]);
+ ResponseAppend_P(PSTR("%s%*_f"), (i>0)?",":"", -1, &Sspm->total[i >>2][i &3]);
}
ResponseAppend_P(PSTR("],\"" D_JSON_POWERUSAGE "\":["));
for (uint32_t i = 0; i < TasmotaGlobal.devices_present; i++) {
From 304f3399d628182e9070368481b75a0019d5b7b2 Mon Sep 17 00:00:00 2001
From: Jason2866 <24528715+Jason2866@users.noreply.github.com>
Date: Sun, 21 Nov 2021 15:12:09 +0100
Subject: [PATCH 117/174] add comment for corresponding if
---
tasmota/xdrv_55_touch.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xdrv_55_touch.ino b/tasmota/xdrv_55_touch.ino
index 5453176bc..269f775af 100644
--- a/tasmota/xdrv_55_touch.ino
+++ b/tasmota/xdrv_55_touch.ino
@@ -322,4 +322,4 @@ bool Xdrv55(uint8_t function) {
uint32_t Touch_Status(uint32_t sel) {
return 0;
}
-#endif // USE_TOUCH
+#endif // #if defined(USE_FT5206) || defined(USE_XPT2046) || defined(USE_LILYGO47) || defined(USE_TOUCH_BUTTONS)
From cb0ad2c75b93530c671498219c715bd3b6176f6e Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 21 Nov 2021 18:54:13 +0100
Subject: [PATCH 118/174] Berry tasmota.read_sensors()
---
lib/libesp32/Berry/default/be_tasmotalib.c | 4 +
lib/libesp32/Berry/generate/be_const_strtab.h | 1 +
.../Berry/generate/be_const_strtab_def.h | 5 +-
.../generate/be_fixed_be_class_tasmota.h | 149 +++++++++---------
tasmota/support_command.ino | 2 +-
tasmota/support_tasmota.ino | 8 +-
tasmota/xdrv_12_discovery.ino | 2 +-
tasmota/xdrv_12_home_assistant.ino | 2 +-
tasmota/xdrv_52_3_berry_tasmota.ino | 29 ++++
tasmota/xdrv_59_influxdb.ino | 2 +-
tasmota/xsns_75_prometheus.ino | 2 +-
11 files changed, 121 insertions(+), 85 deletions(-)
diff --git a/lib/libesp32/Berry/default/be_tasmotalib.c b/lib/libesp32/Berry/default/be_tasmotalib.c
index a6d936766..cba138c5d 100644
--- a/lib/libesp32/Berry/default/be_tasmotalib.c
+++ b/lib/libesp32/Berry/default/be_tasmotalib.c
@@ -32,6 +32,8 @@ extern int l_scaleuint(bvm *vm);
extern int l_logInfo(bvm *vm);
extern int l_save(bvm *vm);
+extern int l_read_sensors(bvm *vm);
+
extern int l_respCmnd(bvm *vm);
extern int l_respCmndStr(bvm *vm);
extern int l_respCmndDone(bvm *vm);
@@ -2010,6 +2012,8 @@ class be_class_tasmota (scope: global, name: Tasmota) {
log, func(l_logInfo)
save, func(l_save)
+ read_sensors, func(l_read_sensors)
+
resp_cmnd, func(l_respCmnd)
resp_cmnd_str, func(l_respCmndStr)
resp_cmnd_done, func(l_respCmndDone)
diff --git a/lib/libesp32/Berry/generate/be_const_strtab.h b/lib/libesp32/Berry/generate/be_const_strtab.h
index 12a0ebefc..c6a7bf5ec 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab.h
@@ -307,6 +307,7 @@ extern const bcstring be_const_str_SERIAL_8N1;
extern const bcstring be_const_str_pi;
extern const bcstring be_const_str_add_header;
extern const bcstring be_const_str_list;
+extern const bcstring be_const_str_read_sensors;
extern const bcstring be_const_str_super;
extern const bcstring be_const_str_has;
extern const bcstring be_const_str___upper__;
diff --git a/lib/libesp32/Berry/generate/be_const_strtab_def.h b/lib/libesp32/Berry/generate/be_const_strtab_def.h
index 759cf6c02..e7e4bc0f2 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab_def.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab_def.h
@@ -306,7 +306,8 @@ be_define_const_str(AudioFileSource, "AudioFileSource", 2959980058u, 0, 15, &be_
be_define_const_str(SERIAL_8N1, "SERIAL_8N1", 2369297235u, 0, 10, &be_const_str_pi);
be_define_const_str(pi, "pi", 1213090802u, 0, 2, NULL);
be_define_const_str(add_header, "add_header", 927130612u, 0, 10, &be_const_str_list);
-be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_super);
+be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_read_sensors);
+be_define_const_str(read_sensors, "read_sensors", 892689201u, 0, 12, &be_const_str_super);
be_define_const_str(super, "super", 4152230356u, 0, 5, NULL);
be_define_const_str(has, "has", 3988721635u, 0, 3, NULL);
be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_exp);
@@ -515,6 +516,6 @@ static const bstring* const m_string_table[] = {
static const struct bconststrtab m_const_string_table = {
.size = 163,
- .count = 326,
+ .count = 327,
.table = m_string_table
};
diff --git a/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h b/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
index 6a5f58838..c24ab2782 100644
--- a/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
+++ b/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
@@ -1,88 +1,89 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tasmota_map) {
- { be_const_key(chars_in_string, 62), be_const_closure(chars_in_string_closure) },
- { be_const_key(publish, -1), be_const_func(l_publish) },
- { be_const_key(try_rule, 5), be_const_closure(try_rule_closure) },
- { be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
- { be_const_key(get_free_heap, 43), be_const_func(l_getFreeHeap) },
- { be_const_key(eth, 55), be_const_func(l_eth) },
- { be_const_key(set_power, -1), be_const_func(l_setpower) },
- { be_const_key(exec_rules, -1), be_const_closure(exec_rules_closure) },
- { be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
- { be_const_key(event, -1), be_const_closure(event_closure) },
- { be_const_key(hs2rgb, -1), be_const_closure(hs2rgb_closure) },
- { be_const_key(time_str, 56), be_const_closure(time_str_closure) },
- { be_const_key(gen_cb, -1), be_const_closure(gen_cb_closure) },
- { be_const_key(response_append, 1), be_const_func(l_respAppend) },
- { be_const_key(set_light, -1), be_const_closure(set_light_closure) },
- { be_const_key(remove_driver, 47), be_const_closure(remove_driver_closure) },
- { be_const_key(yield, 37), be_const_func(l_yield) },
- { be_const_key(exec_cmd, 2), be_const_closure(exec_cmd_closure) },
- { be_const_key(rtc, 14), be_const_func(l_rtc) },
{ be_const_key(cmd_res, -1), be_const_var(0) },
- { be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
- { be_const_key(set_timer, -1), be_const_closure(set_timer_closure) },
- { be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
- { be_const_key(exec_tele, -1), be_const_closure(exec_tele_closure) },
- { be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
- { be_const_key(global, 51), be_const_var(1) },
- { be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
- { be_const_key(add_driver, 12), be_const_closure(add_driver_closure) },
- { be_const_key(_timers, 53), be_const_var(2) },
- { be_const_key(_cb, 71), be_const_var(3) },
- { be_const_key(resp_cmnd_failed, -1), be_const_func(l_respCmndFailed) },
- { be_const_key(remove_rule, 0), be_const_closure(remove_rule_closure) },
- { be_const_key(web_send, 9), be_const_func(l_webSend) },
- { be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
- { be_const_key(remove_timer, 10), be_const_closure(remove_timer_closure) },
- { be_const_key(memory, -1), be_const_func(l_memory) },
- { be_const_key(cb_dispatch, -1), be_const_closure(cb_dispatch_closure) },
- { be_const_key(wire2, -1), be_const_var(4) },
- { be_const_key(find_op, -1), be_const_closure(find_op_closure) },
- { be_const_key(resolvecmnd, -1), be_const_func(l_resolveCmnd) },
- { be_const_key(get_option, -1), be_const_func(l_getoption) },
- { be_const_key(kv, 65), be_const_closure(kv_closure) },
- { be_const_key(wire_scan, -1), be_const_closure(wire_scan_closure) },
- { be_const_key(get_light, -1), be_const_closure(get_light_closure) },
- { be_const_key(_cmd, -1), be_const_func(l_cmd) },
- { be_const_key(gc, -1), be_const_closure(gc_closure) },
- { be_const_key(get_power, -1), be_const_func(l_getpower) },
- { be_const_key(cmd, 60), be_const_closure(cmd_closure) },
- { be_const_key(time_dump, -1), be_const_func(l_time_dump) },
- { be_const_key(settings, -1), be_const_var(5) },
- { be_const_key(load, -1), be_const_closure(load_closure) },
- { be_const_key(arch, -1), be_const_func(l_arch) },
- { be_const_key(_ccmd, -1), be_const_var(6) },
- { be_const_key(_get_cb, -1), be_const_func(l_get_cb) },
- { be_const_key(find_key_i, 19), be_const_closure(find_key_i_closure) },
- { be_const_key(time_reached, -1), be_const_func(l_timereached) },
{ be_const_key(run_deferred, -1), be_const_closure(run_deferred_closure) },
- { be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
- { be_const_key(save, 25), be_const_func(l_save) },
- { be_const_key(millis, -1), be_const_func(l_millis) },
- { be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
- { be_const_key(wire1, 72), be_const_var(7) },
- { be_const_key(delay, -1), be_const_func(l_delay) },
- { be_const_key(scale_uint, 50), be_const_func(l_scaleuint) },
- { be_const_key(get_switch, -1), be_const_func(l_getswitch) },
- { be_const_key(wifi, 38), be_const_func(l_wifi) },
- { be_const_key(publish_result, -1), be_const_func(l_publish_result) },
- { be_const_key(_drivers, -1), be_const_var(8) },
- { be_const_key(add_cmd, -1), be_const_closure(add_cmd_closure) },
- { be_const_key(strftime, -1), be_const_func(l_strftime) },
- { be_const_key(log, -1), be_const_func(l_logInfo) },
+ { be_const_key(set_light, -1), be_const_closure(set_light_closure) },
+ { be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
+ { be_const_key(_timers, -1), be_const_var(1) },
+ { be_const_key(try_rule, -1), be_const_closure(try_rule_closure) },
+ { be_const_key(time_dump, -1), be_const_func(l_time_dump) },
+ { be_const_key(_rules, 73), be_const_var(2) },
+ { be_const_key(get_switch, 21), be_const_func(l_getswitch) },
+ { be_const_key(get_option, -1), be_const_func(l_getoption) },
+ { be_const_key(find_op, 4), be_const_closure(find_op_closure) },
+ { be_const_key(wire1, -1), be_const_var(3) },
+ { be_const_key(resp_cmnd_failed, 29), be_const_func(l_respCmndFailed) },
+ { be_const_key(exec_cmd, -1), be_const_closure(exec_cmd_closure) },
+ { be_const_key(gen_cb, -1), be_const_closure(gen_cb_closure) },
+ { be_const_key(_cb, 57), be_const_var(4) },
+ { be_const_key(hs2rgb, 71), be_const_closure(hs2rgb_closure) },
+ { be_const_key(gc, -1), be_const_closure(gc_closure) },
+ { be_const_key(kv, -1), be_const_closure(kv_closure) },
{ be_const_key(add_rule, -1), be_const_closure(add_rule_closure) },
- { be_const_key(resp_cmnd_done, 74), be_const_func(l_respCmndDone) },
- { be_const_key(_rules, 16), be_const_var(9) },
- { be_const_key(remove_cmd, -1), be_const_closure(remove_cmd_closure) },
+ { be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
+ { be_const_key(global, -1), be_const_var(5) },
+ { be_const_key(rtc, 0), be_const_func(l_rtc) },
+ { be_const_key(get_power, -1), be_const_func(l_getpower) },
+ { be_const_key(wd, -1), be_const_var(6) },
+ { be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
+ { be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
+ { be_const_key(read_sensors, 56), be_const_func(l_read_sensors) },
+ { be_const_key(settings, -1), be_const_var(7) },
+ { be_const_key(chars_in_string, -1), be_const_closure(chars_in_string_closure) },
+ { be_const_key(save, -1), be_const_func(l_save) },
+ { be_const_key(set_timer, -1), be_const_closure(set_timer_closure) },
+ { be_const_key(time_str, -1), be_const_closure(time_str_closure) },
+ { be_const_key(response_append, 14), be_const_func(l_respAppend) },
+ { be_const_key(remove_driver, -1), be_const_closure(remove_driver_closure) },
+ { be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
+ { be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
+ { be_const_key(load, -1), be_const_closure(load_closure) },
+ { be_const_key(_settings_ptr, 55), be_const_comptr(&Settings) },
+ { be_const_key(millis, 23), be_const_func(l_millis) },
+ { be_const_key(event, 67), be_const_closure(event_closure) },
+ { be_const_key(cmd, -1), be_const_closure(cmd_closure) },
+ { be_const_key(publish_result, 60), be_const_func(l_publish_result) },
+ { be_const_key(_drivers, -1), be_const_var(8) },
+ { be_const_key(get_light, 1), be_const_closure(get_light_closure) },
{ be_const_key(init, -1), be_const_closure(init_closure) },
- { be_const_key(wd, 52), be_const_var(10) },
+ { be_const_key(remove_cmd, 24), be_const_closure(remove_cmd_closure) },
+ { be_const_key(time_reached, -1), be_const_func(l_timereached) },
+ { be_const_key(_cmd, 68), be_const_func(l_cmd) },
+ { be_const_key(remove_timer, -1), be_const_closure(remove_timer_closure) },
+ { be_const_key(remove_rule, 70), be_const_closure(remove_rule_closure) },
+ { be_const_key(resolvecmnd, 41), be_const_func(l_resolveCmnd) },
+ { be_const_key(web_send, 38), be_const_func(l_webSend) },
+ { be_const_key(cb_dispatch, 6), be_const_closure(cb_dispatch_closure) },
+ { be_const_key(memory, -1), be_const_func(l_memory) },
+ { be_const_key(wire_scan, -1), be_const_closure(wire_scan_closure) },
+ { be_const_key(strftime, 16), be_const_func(l_strftime) },
+ { be_const_key(resp_cmnd_done, -1), be_const_func(l_respCmndDone) },
+ { be_const_key(_get_cb, -1), be_const_func(l_get_cb) },
+ { be_const_key(add_driver, -1), be_const_closure(add_driver_closure) },
+ { be_const_key(exec_rules, -1), be_const_closure(exec_rules_closure) },
+ { be_const_key(add_cmd, -1), be_const_closure(add_cmd_closure) },
+ { be_const_key(find_key_i, -1), be_const_closure(find_key_i_closure) },
+ { be_const_key(log, 40), be_const_func(l_logInfo) },
+ { be_const_key(wire2, -1), be_const_var(9) },
+ { be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
+ { be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
+ { be_const_key(set_power, -1), be_const_func(l_setpower) },
+ { be_const_key(delay, -1), be_const_func(l_delay) },
+ { be_const_key(wifi, -1), be_const_func(l_wifi) },
+ { be_const_key(yield, -1), be_const_func(l_yield) },
+ { be_const_key(arch, -1), be_const_func(l_arch) },
+ { be_const_key(resp_cmnd, 69), be_const_func(l_respCmnd) },
+ { be_const_key(_global_addr, 26), be_const_comptr(&TasmotaGlobal) },
+ { be_const_key(publish, -1), be_const_func(l_publish) },
+ { be_const_key(_ccmd, -1), be_const_var(10) },
+ { be_const_key(eth, -1), be_const_func(l_eth) },
+ { be_const_key(exec_tele, -1), be_const_closure(exec_tele_closure) },
};
static be_define_const_map(
be_class_tasmota_map,
- 77
+ 78
);
BE_EXPORT_VARIABLE be_define_const_class(
diff --git a/tasmota/support_command.ino b/tasmota/support_command.ino
index 3daea88a7..23cd04c0b 100644
--- a/tasmota/support_command.ino
+++ b/tasmota/support_command.ino
@@ -621,7 +621,7 @@ void CmndStatus(void)
if ((0 == payload) || (8 == payload) || (10 == payload)) {
Response_P(PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":"));
- MqttShowSensor();
+ MqttShowSensor(true);
ResponseJsonEnd();
CmndStatusResponse((8 == payload) ? 8 : 10);
}
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index bfe894446..76db6006f 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -835,7 +835,7 @@ String GetSwitchText(uint32_t i) {
return switch_text;
}
-bool MqttShowSensor(void)
+bool MqttShowSensor(bool call_show_sensor)
{
ResponseAppendTime();
@@ -894,20 +894,20 @@ bool MqttShowSensor(void)
}
ResponseJsonEnd();
- if (json_data_available) { XdrvCall(FUNC_SHOW_SENSOR); }
+ if (call_show_sensor && json_data_available) { XdrvCall(FUNC_SHOW_SENSOR); }
return json_data_available;
}
void MqttPublishSensor(void) {
ResponseClear();
- if (MqttShowSensor()) {
+ if (MqttShowSensor(true)) {
MqttPublishTeleSensor();
}
}
void MqttPublishTeleperiodSensor(void) {
ResponseClear();
- if (MqttShowSensor()) {
+ if (MqttShowSensor(true)) {
MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings->flag.mqtt_sensor_retain); // CMND_SENSORRETAIN
XdrvRulesProcess(1);
}
diff --git a/tasmota/xdrv_12_discovery.ino b/tasmota/xdrv_12_discovery.ino
index 3ade73dbb..da92495d5 100644
--- a/tasmota/xdrv_12_discovery.ino
+++ b/tasmota/xdrv_12_discovery.ino
@@ -215,7 +215,7 @@ void TasDiscovery(void) {
if (!Settings->flag.hass_discovery) { // SetOption19 - Clear retained message
Response_P(PSTR("{\"sn\":"));
- MqttShowSensor();
+ MqttShowSensor(true);
ResponseAppend_P(PSTR(",\"ver\":1}"));
}
snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/sensors"), NetworkUniqueId().c_str());
diff --git a/tasmota/xdrv_12_home_assistant.ino b/tasmota/xdrv_12_home_assistant.ino
index efb7a253d..2ece432c7 100644
--- a/tasmota/xdrv_12_home_assistant.ino
+++ b/tasmota/xdrv_12_home_assistant.ino
@@ -382,7 +382,7 @@ void NewHAssDiscovery(void) {
if (!Settings->flag.hass_discovery) { // SetOption19 - Clear retained message
Response_P(PSTR("{\"sn\":"));
- MqttShowSensor();
+ MqttShowSensor(true);
ResponseAppend_P(PSTR(",\"ver\":1}"));
}
snprintf_P(stopic, sizeof(stopic), PSTR("tasmota/discovery/%s/sensors"), NetworkUniqueId().c_str());
diff --git a/tasmota/xdrv_52_3_berry_tasmota.ino b/tasmota/xdrv_52_3_berry_tasmota.ino
index 573298789..438bd69c1 100644
--- a/tasmota/xdrv_52_3_berry_tasmota.ino
+++ b/tasmota/xdrv_52_3_berry_tasmota.ino
@@ -541,6 +541,35 @@ extern "C" {
}
}
+/*********************************************************************************************\
+ * Native functions mapped to Berry functions
+ *
+ * read_sensors(show_sensor:bool) -> string
+ *
+\*********************************************************************************************/
+extern "C" {
+ int32_t l_read_sensors(struct bvm *vm);
+ int32_t l_read_sensors(struct bvm *vm) {
+ int32_t top = be_top(vm); // Get the number of arguments
+ bool sensor_display = false; // don't trigger a display by default
+ if (top >= 2) {
+ sensor_display = be_tobool(vm, 2);
+ }
+ ResponseClear();
+ if (MqttShowSensor(sensor_display)) {
+ // return string
+ be_pushstring(vm, ResponseData());
+ be_return(vm);
+ } else {
+ be_return_nil(vm);
+ }
+ }
+}
+
+/*********************************************************************************************\
+ * Logging functions
+ *
+\*********************************************************************************************/
// called as a replacement to Berry `print()`
void berry_log(const char * berry_buf);
void berry_log(const char * berry_buf) {
diff --git a/tasmota/xdrv_59_influxdb.ino b/tasmota/xdrv_59_influxdb.ino
index ecafe8003..3afb6ada8 100644
--- a/tasmota/xdrv_59_influxdb.ino
+++ b/tasmota/xdrv_59_influxdb.ino
@@ -385,7 +385,7 @@ void InfluxDbLoop(void) {
// {"Time":"2021-08-14T17:19:33","Switch1":"ON","Switch2":"OFF","ANALOG":{"Temperature":184.72},"DS18B20":{"Id":"01144A0CB2AA","Temperature":27.50},"HTU21":{"Temperature":28.23,"Humidity":39.7,"DewPoint":13.20},"Global":{"Temperature":27.50,"Humidity":39.7,"DewPoint":12.55},"TempUnit":"C"}
ResponseClear();
- if (MqttShowSensor()) { // Pull sensor data
+ if (MqttShowSensor(true)) { // Pull sensor data
InfluxDbProcessJson();
};
diff --git a/tasmota/xsns_75_prometheus.ino b/tasmota/xsns_75_prometheus.ino
index caa2330fa..df9d41881 100644
--- a/tasmota/xsns_75_prometheus.ino
+++ b/tasmota/xsns_75_prometheus.ino
@@ -282,7 +282,7 @@ void HandleMetrics(void) {
}
ResponseClear();
- MqttShowSensor(); //Pull sensor data
+ MqttShowSensor(true); //Pull sensor data
String jsonStr = ResponseData();
JsonParser parser((char *)jsonStr.c_str());
JsonParserObject root = parser.getRootObject();
From e173f7492e406056301e7bdb289dbb9d33f06188 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 21 Nov 2021 22:05:07 +0100
Subject: [PATCH 119/174] DisplayDimmer support for M5StickC
---
tasmota/berry/drivers/i2c_axp192_M5StickC.be | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/tasmota/berry/drivers/i2c_axp192_M5StickC.be b/tasmota/berry/drivers/i2c_axp192_M5StickC.be
index 9d38bea3a..2d0c63d24 100644
--- a/tasmota/berry/drivers/i2c_axp192_M5StickC.be
+++ b/tasmota/berry/drivers/i2c_axp192_M5StickC.be
@@ -85,6 +85,19 @@ class AXP192_M5StickC : AXP192
def set_lcd_reset(state)
self.set_ldo_enable(3, state)
end
+
+ # Dimmer in percentage
+ def set_displaydimmer(x)
+ var v = tasmota.scale_uint(x, 0, 100, 2500, 3300)
+ self.set_lcd_voltage(v)
+ end
+
+ # respond to display events
+ def display(cmd, idx, payload, raw)
+ if cmd == "dim" || cmd == "power"
+ self.set_displaydimmer(idx)
+ end
+ end
end
axp = AXP192_M5StickC()
From 871baa7f4172f4487a4e9de1c6f50591bdd36b20 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 21 Nov 2021 23:08:54 +0100
Subject: [PATCH 120/174] Berry remove warning when no debug
---
lib/libesp32/Berry/default/be_tasmotalib.c | 221 ++--
.../Berry/default/embedded/Tasmota.be | 19 +-
lib/libesp32/Berry/generate/be_const_strtab.h | 677 +++++------
.../Berry/generate/be_const_strtab_def.h | 1008 +++++++++--------
.../generate/be_fixed_be_class_tasmota.h | 151 +--
lib/libesp32/Berry/src/be_constobj.h | 7 +
lib/libesp32/Berry/src/be_solidifylib.c | 7 +-
7 files changed, 1065 insertions(+), 1025 deletions(-)
diff --git a/lib/libesp32/Berry/default/be_tasmotalib.c b/lib/libesp32/Berry/default/be_tasmotalib.c
index cba138c5d..76720b7b4 100644
--- a/lib/libesp32/Berry/default/be_tasmotalib.c
+++ b/lib/libesp32/Berry/default/be_tasmotalib.c
@@ -143,24 +143,26 @@ be_local_closure(init, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
- ( &(const bvalue[13]) { /* constants */
- /* K0 */ be_nested_string("global", 503252654, 6),
- /* K1 */ be_nested_string("ctypes_bytes_dyn", 915205307, 16),
- /* K2 */ be_nested_string("_global_addr", 533766721, 12),
- /* K3 */ be_nested_string("_global_def", 646007001, 11),
- /* K4 */ be_nested_string("introspect", 164638290, 10),
- /* K5 */ be_nested_string("_settings_ptr", 1825772182, 13),
- /* K6 */ be_nested_string("get", 1410115415, 3),
+ ( &(const bvalue[15]) { /* constants */
+ /* K0 */ be_nested_str_literal("global"),
+ /* K1 */ be_nested_str_literal("ctypes_bytes_dyn"),
+ /* K2 */ be_nested_str_literal("_global_addr"),
+ /* K3 */ be_nested_str_literal("_global_def"),
+ /* K4 */ be_nested_str_literal("introspect"),
+ /* K5 */ be_nested_str_literal("_settings_ptr"),
+ /* K6 */ be_nested_str_literal("get"),
/* K7 */ be_const_int(0),
- /* K8 */ be_nested_string("settings", 1745255176, 8),
- /* K9 */ be_nested_string("toptr", -915119842, 5),
- /* K10 */ be_nested_string("_settings_def", -519406989, 13),
- /* K11 */ be_nested_string("wd", 1531424278, 2),
- /* K12 */ be_nested_string("", -2128831035, 0),
+ /* K8 */ be_nested_str_literal("settings"),
+ /* K9 */ be_nested_str_literal("toptr"),
+ /* K10 */ be_nested_str_literal("_settings_def"),
+ /* K11 */ be_nested_str_literal("wd"),
+ /* K12 */ be_nested_str_literal(""),
+ /* K13 */ be_nested_str_literal("_debug_present"),
+ /* K14 */ be_nested_str_literal("debug"),
}),
(be_nested_const_str("init", 380752755, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[24]) { /* code */
+ ( &(const binstruction[36]) { /* code */
0xB8060200, // 0000 GETNGBL R1 K1
0x88080102, // 0001 GETMBR R2 R0 K2
0x880C0103, // 0002 GETMBR R3 R0 K3
@@ -184,7 +186,19 @@ be_local_closure(init, /* name */
0x7C0C0400, // 0014 CALL R3 2
0x90021003, // 0015 SETMBR R0 K8 R3
0x9002170C, // 0016 SETMBR R0 K11 K12
- 0x80000000, // 0017 RET 0
+ 0x500C0000, // 0017 LDBOOL R3 0 0
+ 0x90021A03, // 0018 SETMBR R0 K13 R3
+ 0xA8020004, // 0019 EXBLK 0 #001F
+ 0xA40E1C00, // 001A IMPORT R3 K14
+ 0x50100200, // 001B LDBOOL R4 1 0
+ 0x90021A04, // 001C SETMBR R0 K13 R4
+ 0xA8040001, // 001D EXBLK 1 1
+ 0x70020003, // 001E JMP #0023
+ 0xAC0C0000, // 001F CATCH R3 0 0
+ 0x70020000, // 0020 JMP #0022
+ 0x70020000, // 0021 JMP #0023
+ 0xB0080000, // 0022 RAISE 2 R0 R0
+ 0x80000000, // 0023 RET 0
})
)
);
@@ -864,31 +878,31 @@ be_local_closure(load, /* name */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[21]) { /* constants */
- /* K0 */ be_nested_string("string", 398550328, 6),
- /* K1 */ be_nested_string("path", -2071507658, 4),
+ /* K0 */ be_nested_str_literal("string"),
+ /* K1 */ be_nested_str_literal("path"),
/* K2 */ be_const_int(0),
- /* K3 */ be_nested_string("/", 705468254, 1),
- /* K4 */ be_nested_string("split", -2017972765, 5),
- /* K5 */ be_nested_string("#", 638357778, 1),
+ /* K3 */ be_nested_str_literal("/"),
+ /* K4 */ be_nested_str_literal("split"),
+ /* K5 */ be_nested_str_literal("#"),
/* K6 */ be_const_int(1),
- /* K7 */ be_nested_string("find", -1108310694, 4),
- /* K8 */ be_nested_string(".", 722245873, 1),
- /* K9 */ be_nested_string(".be", 1325797348, 3),
- /* K10 */ be_nested_string(".bec", -309694075, 4),
- /* K11 */ be_nested_string("io_error", 1970281036, 8),
- /* K12 */ be_nested_string("file extension is not '.be' or '.bec'", -1199247657, 37),
- /* K13 */ be_nested_string("last_modified", 772177145, 13),
- /* K14 */ be_nested_string("c", -435409838, 1),
- /* K15 */ be_nested_string("wd", 1531424278, 2),
- /* K16 */ be_nested_string("", -2128831035, 0),
- /* K17 */ be_nested_string("file", -1427482813, 4),
- /* K18 */ be_nested_string("save", -855671224, 4),
- /* K19 */ be_nested_string("format", -1180859054, 6),
- /* K20 */ be_nested_string("BRY: could not save compiled file %s (%s)", 736659787, 41),
+ /* K7 */ be_nested_str_literal("find"),
+ /* K8 */ be_nested_str_literal("."),
+ /* K9 */ be_nested_str_literal(".be"),
+ /* K10 */ be_nested_str_literal(".bec"),
+ /* K11 */ be_nested_str_literal("io_error"),
+ /* K12 */ be_nested_str_literal("file extension is not '.be' or '.bec'"),
+ /* K13 */ be_nested_str_literal("last_modified"),
+ /* K14 */ be_nested_str_literal("c"),
+ /* K15 */ be_nested_str_literal("wd"),
+ /* K16 */ be_nested_str_literal(""),
+ /* K17 */ be_nested_str_literal("file"),
+ /* K18 */ be_nested_str_literal("save"),
+ /* K19 */ be_nested_str_literal("format"),
+ /* K20 */ be_nested_str_literal("BRY: could not save compiled file %s (%s)"),
}),
(be_nested_const_str("load", -435725847, 4)),
((bstring*) &be_const_str_input),
- ( &(const binstruction[108]) { /* code */
+ ( &(const binstruction[112]) { /* code */
0xA40A0000, // 0000 IMPORT R2 K0
0xA40E0200, // 0001 IMPORT R3 K1
0x6010000C, // 0002 GETGBL R4 G12
@@ -931,72 +945,76 @@ be_local_closure(load, /* name */
0x4024120A, // 0027 CONNECT R9 R9 R10
0x94240C09, // 0028 GETIDX R9 R6 R9
0x1C24130A, // 0029 EQ R9 R9 K10
- 0x74220001, // 002A JMPT R8 #002D
- 0x74260000, // 002B JMPT R9 #002D
- 0xB006170C, // 002C RAISE 1 K11 K12
- 0x8C28070D, // 002D GETMET R10 R3 K13
- 0x5C300A00, // 002E MOVE R12 R5
- 0x7C280400, // 002F CALL R10 2
- 0x78260005, // 0030 JMPF R9 #0037
- 0x4C2C0000, // 0031 LDNIL R11
- 0x1C2C140B, // 0032 EQ R11 R10 R11
- 0x782E0001, // 0033 JMPF R11 #0036
- 0x502C0000, // 0034 LDBOOL R11 0 0
- 0x80041600, // 0035 RET 1 R11
- 0x70020013, // 0036 JMP #004B
- 0x8C2C070D, // 0037 GETMET R11 R3 K13
- 0x0034030E, // 0038 ADD R13 R1 K14
- 0x7C2C0400, // 0039 CALL R11 2
- 0x4C300000, // 003A LDNIL R12
- 0x1C30140C, // 003B EQ R12 R10 R12
- 0x78320004, // 003C JMPF R12 #0042
- 0x4C300000, // 003D LDNIL R12
- 0x1C30160C, // 003E EQ R12 R11 R12
- 0x78320001, // 003F JMPF R12 #0042
- 0x50300000, // 0040 LDBOOL R12 0 0
- 0x80041800, // 0041 RET 1 R12
- 0x4C300000, // 0042 LDNIL R12
- 0x2030160C, // 0043 NE R12 R11 R12
- 0x78320005, // 0044 JMPF R12 #004B
- 0x4C300000, // 0045 LDNIL R12
- 0x1C30140C, // 0046 EQ R12 R10 R12
- 0x74320001, // 0047 JMPT R12 #004A
- 0x2830160A, // 0048 GE R12 R11 R10
- 0x78320000, // 0049 JMPF R12 #004B
- 0x50240200, // 004A LDBOOL R9 1 0
- 0x781E0002, // 004B JMPF R7 #004F
- 0x002C0B05, // 004C ADD R11 R5 K5
- 0x90021E0B, // 004D SETMBR R0 K15 R11
- 0x70020000, // 004E JMP #0050
- 0x90021F10, // 004F SETMBR R0 K15 K16
- 0x602C000D, // 0050 GETGBL R11 G13
- 0x5C300200, // 0051 MOVE R12 R1
- 0x58340011, // 0052 LDCONST R13 K17
- 0x7C2C0400, // 0053 CALL R11 2
- 0x74260012, // 0054 JMPT R9 #0068
- 0x741E0011, // 0055 JMPT R7 #0068
- 0xA8020005, // 0056 EXBLK 0 #005D
- 0x8C300112, // 0057 GETMET R12 R0 K18
- 0x0038030E, // 0058 ADD R14 R1 K14
- 0x5C3C1600, // 0059 MOVE R15 R11
- 0x7C300600, // 005A CALL R12 3
- 0xA8040001, // 005B EXBLK 1 1
- 0x7002000A, // 005C JMP #0068
- 0xAC300001, // 005D CATCH R12 0 1
- 0x70020007, // 005E JMP #0067
- 0x60340001, // 005F GETGBL R13 G1
- 0x8C380513, // 0060 GETMET R14 R2 K19
- 0x58400014, // 0061 LDCONST R16 K20
- 0x0044030E, // 0062 ADD R17 R1 K14
- 0x5C481800, // 0063 MOVE R18 R12
- 0x7C380800, // 0064 CALL R14 4
- 0x7C340200, // 0065 CALL R13 1
- 0x70020000, // 0066 JMP #0068
- 0xB0080000, // 0067 RAISE 2 R0 R0
- 0x5C301600, // 0068 MOVE R12 R11
- 0x7C300000, // 0069 CALL R12 0
- 0x50300200, // 006A LDBOOL R12 1 0
- 0x80041800, // 006B RET 1 R12
+ 0x5C281000, // 002A MOVE R10 R8
+ 0x742A0002, // 002B JMPT R10 #002F
+ 0x5C281200, // 002C MOVE R10 R9
+ 0x742A0000, // 002D JMPT R10 #002F
+ 0xB006170C, // 002E RAISE 1 K11 K12
+ 0x8C28070D, // 002F GETMET R10 R3 K13
+ 0x5C300A00, // 0030 MOVE R12 R5
+ 0x7C280400, // 0031 CALL R10 2
+ 0x78260005, // 0032 JMPF R9 #0039
+ 0x4C2C0000, // 0033 LDNIL R11
+ 0x1C2C140B, // 0034 EQ R11 R10 R11
+ 0x782E0001, // 0035 JMPF R11 #0038
+ 0x502C0000, // 0036 LDBOOL R11 0 0
+ 0x80041600, // 0037 RET 1 R11
+ 0x70020013, // 0038 JMP #004D
+ 0x8C2C070D, // 0039 GETMET R11 R3 K13
+ 0x0034030E, // 003A ADD R13 R1 K14
+ 0x7C2C0400, // 003B CALL R11 2
+ 0x4C300000, // 003C LDNIL R12
+ 0x1C30140C, // 003D EQ R12 R10 R12
+ 0x78320004, // 003E JMPF R12 #0044
+ 0x4C300000, // 003F LDNIL R12
+ 0x1C30160C, // 0040 EQ R12 R11 R12
+ 0x78320001, // 0041 JMPF R12 #0044
+ 0x50300000, // 0042 LDBOOL R12 0 0
+ 0x80041800, // 0043 RET 1 R12
+ 0x4C300000, // 0044 LDNIL R12
+ 0x2030160C, // 0045 NE R12 R11 R12
+ 0x78320005, // 0046 JMPF R12 #004D
+ 0x4C300000, // 0047 LDNIL R12
+ 0x1C30140C, // 0048 EQ R12 R10 R12
+ 0x74320001, // 0049 JMPT R12 #004C
+ 0x2830160A, // 004A GE R12 R11 R10
+ 0x78320000, // 004B JMPF R12 #004D
+ 0x50240200, // 004C LDBOOL R9 1 0
+ 0x781E0002, // 004D JMPF R7 #0051
+ 0x002C0B05, // 004E ADD R11 R5 K5
+ 0x90021E0B, // 004F SETMBR R0 K15 R11
+ 0x70020000, // 0050 JMP #0052
+ 0x90021F10, // 0051 SETMBR R0 K15 K16
+ 0x602C000D, // 0052 GETGBL R11 G13
+ 0x5C300200, // 0053 MOVE R12 R1
+ 0x58340011, // 0054 LDCONST R13 K17
+ 0x7C2C0400, // 0055 CALL R11 2
+ 0x5C301200, // 0056 MOVE R12 R9
+ 0x74320013, // 0057 JMPT R12 #006C
+ 0x5C300E00, // 0058 MOVE R12 R7
+ 0x74320011, // 0059 JMPT R12 #006C
+ 0xA8020005, // 005A EXBLK 0 #0061
+ 0x8C300112, // 005B GETMET R12 R0 K18
+ 0x0038030E, // 005C ADD R14 R1 K14
+ 0x5C3C1600, // 005D MOVE R15 R11
+ 0x7C300600, // 005E CALL R12 3
+ 0xA8040001, // 005F EXBLK 1 1
+ 0x7002000A, // 0060 JMP #006C
+ 0xAC300001, // 0061 CATCH R12 0 1
+ 0x70020007, // 0062 JMP #006B
+ 0x60340001, // 0063 GETGBL R13 G1
+ 0x8C380513, // 0064 GETMET R14 R2 K19
+ 0x58400014, // 0065 LDCONST R16 K20
+ 0x0044030E, // 0066 ADD R17 R1 K14
+ 0x5C481800, // 0067 MOVE R18 R12
+ 0x7C380800, // 0068 CALL R14 4
+ 0x7C340200, // 0069 CALL R13 1
+ 0x70020000, // 006A JMP #006C
+ 0xB0080000, // 006B RAISE 2 R0 R0
+ 0x5C301600, // 006C MOVE R12 R11
+ 0x7C300000, // 006D CALL R12 0
+ 0x50300200, // 006E LDBOOL R12 1 0
+ 0x80041800, // 006F RET 1 R12
})
)
);
@@ -1982,6 +2000,7 @@ class be_class_tasmota (scope: global, name: Tasmota) {
settings, var
cmd_res, var
wd, var
+ _debug_present, var
_global_def, comptr(&be_tasmota_global_struct)
_settings_def, comptr(&be_tasmota_settings_struct)
diff --git a/lib/libesp32/Berry/default/embedded/Tasmota.be b/lib/libesp32/Berry/default/embedded/Tasmota.be
index abbc22cb6..814af338f 100644
--- a/lib/libesp32/Berry/default/embedded/Tasmota.be
+++ b/lib/libesp32/Berry/default/embedded/Tasmota.be
@@ -24,10 +24,11 @@ class Tasmota
var _cb
var wire1
var wire2
- var cmd_res # store the command result, nil if disables, true if capture enabled, contains return value
- var global # mapping to TasmotaGlobal
+ var cmd_res # store the command result, nil if disables, true if capture enabled, contains return value
+ var global # mapping to TasmotaGlobal
var settings
- var wd # last working directory
+ var wd # when load() is called, `tasmota.wd` contains the name of the archive. Ex: `/M5StickC.autoconf#`
+ var _debug_present # is `import debug` present?
def init()
# instanciate the mapping object to TasmotaGlobal
@@ -38,6 +39,12 @@ class Tasmota
self.settings = ctypes_bytes_dyn(introspect.toptr(settings_addr), self._settings_def)
end
self.wd = ""
+ self._debug_present = false
+ try
+ import debug
+ self._debug_present = true
+ except ..
+ end
end
# create a specific sub-class for rules: pattern(string) -> closure
@@ -416,8 +423,10 @@ class Tasmota
if done break end
except .. as e,m
print(string.format("BRY: Exception> '%s' - %s", e, m))
- import debug
- debug.traceback()
+ if self._debug_present
+ import debug
+ debug.traceback()
+ end
end
end
i += 1
diff --git a/lib/libesp32/Berry/generate/be_const_strtab.h b/lib/libesp32/Berry/generate/be_const_strtab.h
index c6a7bf5ec..cee6bc29d 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab.h
@@ -1,349 +1,350 @@
-extern const bcstring be_const_str_pow;
-extern const bcstring be_const_str_remove;
-extern const bcstring be_const_str_remove_timer;
-extern const bcstring be_const_str_MD5;
-extern const bcstring be_const_str__ccmd;
-extern const bcstring be_const_str_digital_write;
-extern const bcstring be_const_str_dot_p2;
-extern const bcstring be_const_str_floor;
-extern const bcstring be_const_str_input;
-extern const bcstring be_const_str_range;
-extern const bcstring be_const_str_atan;
-extern const bcstring be_const_str_find_op;
-extern const bcstring be_const_str_SERIAL_6N1;
-extern const bcstring be_const_str_classname;
-extern const bcstring be_const_str_content_start;
-extern const bcstring be_const_str_import;
-extern const bcstring be_const_str_raise;
-extern const bcstring be_const_str_SERIAL_8N2;
-extern const bcstring be_const_str_keys;
-extern const bcstring be_const_str_content_send_style;
-extern const bcstring be_const_str_static;
-extern const bcstring be_const_str__begin_transmission;
-extern const bcstring be_const_str__request_from;
-extern const bcstring be_const_str_isnan;
-extern const bcstring be_const_str_reverse_gamma10;
-extern const bcstring be_const_str_number;
-extern const bcstring be_const_str_resp_cmnd_str;
-extern const bcstring be_const_str_run_deferred;
-extern const bcstring be_const_str_exec_rules;
-extern const bcstring be_const_str_web_send;
-extern const bcstring be_const_str_GET;
-extern const bcstring be_const_str__rules;
-extern const bcstring be_const_str_begin;
-extern const bcstring be_const_str_escape;
-extern const bcstring be_const_str_I2C_Driver;
-extern const bcstring be_const_str_char;
-extern const bcstring be_const_str_opt_neq;
-extern const bcstring be_const_str_Wire;
-extern const bcstring be_const_str_asstring;
-extern const bcstring be_const_str_strftime;
-extern const bcstring be_const_str_last_modified;
-extern const bcstring be_const_str_set;
-extern const bcstring be_const_str_add;
-extern const bcstring be_const_str_eth;
-extern const bcstring be_const_str_publish;
-extern const bcstring be_const_str_rtc;
-extern const bcstring be_const_str_scan;
-extern const bcstring be_const_str_EC_C25519;
-extern const bcstring be_const_str_nil;
-extern const bcstring be_const_str_ceil;
-extern const bcstring be_const_str_item;
-extern const bcstring be_const_str_log;
-extern const bcstring be_const_str__global_def;
-extern const bcstring be_const_str_clear;
-extern const bcstring be_const_str_atan2;
-extern const bcstring be_const_str_dump;
-extern const bcstring be_const_str_fromb64;
-extern const bcstring be_const_str_deinit;
-extern const bcstring be_const_str_read13;
-extern const bcstring be_const_str_SERIAL_8O1;
-extern const bcstring be_const_str_SERIAL_6O1;
-extern const bcstring be_const_str_add_rule;
-extern const bcstring be_const_str_fromstring;
-extern const bcstring be_const_str_SERIAL_6E2;
-extern const bcstring be_const_str_try_rule;
-extern const bcstring be_const_str_gc;
-extern const bcstring be_const_str_publish_result;
-extern const bcstring be_const_str_response_append;
-extern const bcstring be_const_str_continue;
-extern const bcstring be_const_str_dot_p1;
-extern const bcstring be_const_str__def;
-extern const bcstring be_const_str_imin;
-extern const bcstring be_const_str_chars_in_string;
-extern const bcstring be_const_str_concat;
-extern const bcstring be_const_str_content_stop;
-extern const bcstring be_const_str_def;
-extern const bcstring be_const_str_traceback;
-extern const bcstring be_const_str_wire;
-extern const bcstring be_const_str_calldepth;
-extern const bcstring be_const_str_finish;
-extern const bcstring be_const_str_log10;
-extern const bcstring be_const_str_name;
-extern const bcstring be_const_str_time_str;
-extern const bcstring be_const_str_do;
-extern const bcstring be_const_str_read;
-extern const bcstring be_const_str_set_auth;
-extern const bcstring be_const_str_Tasmota;
-extern const bcstring be_const_str_SERIAL_7E2;
-extern const bcstring be_const_str_resolvecmnd;
-extern const bcstring be_const_str___lower__;
-extern const bcstring be_const_str_addr;
-extern const bcstring be_const_str_gamma8;
-extern const bcstring be_const_str_member;
-extern const bcstring be_const_str_scale_uint;
-extern const bcstring be_const_str_codedump;
-extern const bcstring be_const_str_opt_call;
-extern const bcstring be_const_str_SERIAL_5N2;
-extern const bcstring be_const_str_attrdump;
-extern const bcstring be_const_str_hex;
-extern const bcstring be_const_str_remove_cmd;
-extern const bcstring be_const_str_AudioOutput;
-extern const bcstring be_const_str_break;
-extern const bcstring be_const_str_SERIAL_5O1;
-extern const bcstring be_const_str_rand;
-extern const bcstring be_const_str_class;
-extern const bcstring be_const_str_public_key;
-extern const bcstring be_const_str_search;
-extern const bcstring be_const_str_update;
-extern const bcstring be_const_str_end;
-extern const bcstring be_const_str_i2c_enabled;
-extern const bcstring be_const_str_read_bytes;
-extern const bcstring be_const_str_fromptr;
-extern const bcstring be_const_str_pin_used;
-extern const bcstring be_const_str_redirect;
-extern const bcstring be_const_str__drivers;
-extern const bcstring be_const_str_get_size;
-extern const bcstring be_const_str_set_power;
-extern const bcstring be_const_str_loop;
-extern const bcstring be_const_str_read32;
-extern const bcstring be_const_str_add_cmd;
-extern const bcstring be_const_str__settings_ptr;
-extern const bcstring be_const_str_reset;
-extern const bcstring be_const_str__ptr;
-extern const bcstring be_const_str_detect;
-extern const bcstring be_const_str_reset_search;
-extern const bcstring be_const_str_SERIAL_6E1;
-extern const bcstring be_const_str__read;
-extern const bcstring be_const_str_true;
-extern const bcstring be_const_str_opt_eq;
-extern const bcstring be_const_str_add_driver;
-extern const bcstring be_const_str_tob64;
-extern const bcstring be_const_str_wire1;
-extern const bcstring be_const_str__timers;
-extern const bcstring be_const_str_opt_connect;
-extern const bcstring be_const_str_SERIAL_5E1;
-extern const bcstring be_const_str_select;
-extern const bcstring be_const_str_setbits;
-extern const bcstring be_const_str_webclient;
-extern const bcstring be_const_str_deg;
-extern const bcstring be_const_str_flush;
-extern const bcstring be_const_str_hs2rgb;
-extern const bcstring be_const_str_SERIAL_8E1;
-extern const bcstring be_const_str_setrange;
-extern const bcstring be_const_str_dot_len;
-extern const bcstring be_const_str_byte;
-extern const bcstring be_const_str_issubclass;
-extern const bcstring be_const_str_while;
-extern const bcstring be_const_str_enabled;
-extern const bcstring be_const_str_sin;
-extern const bcstring be_const_str_except;
-extern const bcstring be_const_str_AudioOutputI2S;
-extern const bcstring be_const_str_SERIAL_7N2;
-extern const bcstring be_const_str_call;
-extern const bcstring be_const_str_imax;
-extern const bcstring be_const_str_isrunning;
-extern const bcstring be_const_str_read8;
-extern const bcstring be_const_str_resp_cmnd_error;
-extern const bcstring be_const_str_AudioFileSourceFS;
-extern const bcstring be_const_str___iterator__;
-extern const bcstring be_const_str_contains;
-extern const bcstring be_const_str_web_send_decimal;
-extern const bcstring be_const_str_dac_voltage;
-extern const bcstring be_const_str_time_reached;
-extern const bcstring be_const_str_if;
-extern const bcstring be_const_str_read24;
-extern const bcstring be_const_str_toptr;
-extern const bcstring be_const_str_else;
-extern const bcstring be_const_str__global_addr;
-extern const bcstring be_const_str_classof;
-extern const bcstring be_const_str_SERIAL_7O1;
-extern const bcstring be_const_str_print;
-extern const bcstring be_const_str_setmember;
-extern const bcstring be_const_str_dot_size;
-extern const bcstring be_const_str__write;
-extern const bcstring be_const_str_init;
-extern const bcstring be_const_str_gamma10;
-extern const bcstring be_const_str_gen_cb;
-extern const bcstring be_const_str_remove_rule;
-extern const bcstring be_const_str_ctypes_bytes_dyn;
extern const bcstring be_const_str_SERIAL_6N2;
-extern const bcstring be_const_str_available;
-extern const bcstring be_const_str_cb_dispatch;
-extern const bcstring be_const_str_isinstance;
-extern const bcstring be_const_str_copy;
-extern const bcstring be_const_str_find;
-extern const bcstring be_const_str_POST;
-extern const bcstring be_const_str_write_bytes;
-extern const bcstring be_const_str_;
-extern const bcstring be_const_str_type;
-extern const bcstring be_const_str_allocated;
-extern const bcstring be_const_str_insert;
-extern const bcstring be_const_str_tolower;
-extern const bcstring be_const_str_dot_w;
-extern const bcstring be_const_str_srand;
-extern const bcstring be_const_str_wire2;
-extern const bcstring be_const_str_format;
-extern const bcstring be_const_str_yield;
+extern const bcstring be_const_str__begin_transmission;
+extern const bcstring be_const_str_set_light;
+extern const bcstring be_const_str_time_reached;
extern const bcstring be_const_str_SERIAL_5E2;
-extern const bcstring be_const_str_reduce;
-extern const bcstring be_const_str_resp_cmnd_done;
-extern const bcstring be_const_str_abs;
-extern const bcstring be_const_str_setitem;
-extern const bcstring be_const_str_OneWire;
-extern const bcstring be_const_str_upper;
-extern const bcstring be_const_str_module;
-extern const bcstring be_const_str_counters;
+extern const bcstring be_const_str___lower__;
+extern const bcstring be_const_str_SERIAL_7O1;
+extern const bcstring be_const_str_getbits;
+extern const bcstring be_const_str_input;
+extern const bcstring be_const_str_dot_size;
+extern const bcstring be_const_str_publish_result;
+extern const bcstring be_const_str_web_send_decimal;
+extern const bcstring be_const_str_def;
+extern const bcstring be_const_str__cmd;
+extern const bcstring be_const_str_begin;
+extern const bcstring be_const_str_resp_cmnd;
+extern const bcstring be_const_str_assert;
+extern const bcstring be_const_str_set;
extern const bcstring be_const_str_tag;
-extern const bcstring be_const_str_tanh;
-extern const bcstring be_const_str_get_string;
-extern const bcstring be_const_str_read12;
-extern const bcstring be_const_str_wire_scan;
-extern const bcstring be_const_str_seti;
-extern const bcstring be_const_str_cmd;
-extern const bcstring be_const_str_content_send;
-extern const bcstring be_const_str_global;
-extern const bcstring be_const_str_var;
-extern const bcstring be_const_str_SERIAL_7N1;
-extern const bcstring be_const_str_resize;
-extern const bcstring be_const_str_split;
-extern const bcstring be_const_str_str;
-extern const bcstring be_const_str_url_encode;
-extern const bcstring be_const_str_get_option;
-extern const bcstring be_const_str_listdir;
-extern const bcstring be_const_str_tomap;
extern const bcstring be_const_str_check_privileged_access;
-extern const bcstring be_const_str_pin_mode;
-extern const bcstring be_const_str_pin;
-extern const bcstring be_const_str_try;
-extern const bcstring be_const_str__buffer;
-extern const bcstring be_const_str_cos;
-extern const bcstring be_const_str_dot_p;
-extern const bcstring be_const_str_SERIAL_7O2;
-extern const bcstring be_const_str_real;
-extern const bcstring be_const_str_set_timer;
-extern const bcstring be_const_str_count;
-extern const bcstring be_const_str_write;
-extern const bcstring be_const_str__settings_def;
-extern const bcstring be_const_str_digital_read;
-extern const bcstring be_const_str_path;
-extern const bcstring be_const_str_delay;
-extern const bcstring be_const_str_stop;
-extern const bcstring be_const_str_AES_GCM;
-extern const bcstring be_const_str_SERIAL_6O2;
+extern const bcstring be_const_str_kv;
+extern const bcstring be_const_str_publish;
+extern const bcstring be_const_str_read32;
+extern const bcstring be_const_str_load;
+extern const bcstring be_const_str_read13;
+extern const bcstring be_const_str_search;
+extern const bcstring be_const_str_dac_voltage;
+extern const bcstring be_const_str_finish;
+extern const bcstring be_const_str_hex;
+extern const bcstring be_const_str_isinstance;
+extern const bcstring be_const_str_rand;
+extern const bcstring be_const_str_POST;
+extern const bcstring be_const_str_SERIAL_6E2;
+extern const bcstring be_const_str_classname;
+extern const bcstring be_const_str__global_def;
extern const bcstring be_const_str_open;
-extern const bcstring be_const_str_top;
-extern const bcstring be_const_str_write_bit;
+extern const bcstring be_const_str_redirect;
+extern const bcstring be_const_str_AES_GCM;
+extern const bcstring be_const_str_resp_cmnd_failed;
+extern const bcstring be_const_str_reverse_gamma10;
+extern const bcstring be_const_str_strftime;
+extern const bcstring be_const_str_insert;
+extern const bcstring be_const_str_false;
+extern const bcstring be_const_str_arg_size;
+extern const bcstring be_const_str_serial;
+extern const bcstring be_const_str_OneWire;
+extern const bcstring be_const_str_scale_uint;
+extern const bcstring be_const_str_return;
+extern const bcstring be_const_str_wire;
+extern const bcstring be_const_str_write_bytes;
+extern const bcstring be_const_str__global_addr;
+extern const bcstring be_const_str_exec_tele;
+extern const bcstring be_const_str_target_search;
+extern const bcstring be_const_str_gamma8;
+extern const bcstring be_const_str_pi;
extern const bcstring be_const_str_state;
-extern const bcstring be_const_str_set_useragent;
-extern const bcstring be_const_str_as;
-extern const bcstring be_const_str_erase;
-extern const bcstring be_const_str_has_arg;
-extern const bcstring be_const_str_map;
-extern const bcstring be_const_str_on;
+extern const bcstring be_const_str_depower;
+extern const bcstring be_const_str_init;
+extern const bcstring be_const_str_member;
+extern const bcstring be_const_str__end_transmission;
+extern const bcstring be_const_str_digital_read;
+extern const bcstring be_const_str_imin;
+extern const bcstring be_const_str_hs2rgb;
+extern const bcstring be_const_str_keys;
+extern const bcstring be_const_str_real;
+extern const bcstring be_const_str_sin;
+extern const bcstring be_const_str_SERIAL_7N1;
+extern const bcstring be_const_str_ctypes_bytes;
+extern const bcstring be_const_str_ctypes_bytes_dyn;
+extern const bcstring be_const_str_raise;
+extern const bcstring be_const_str_GET;
+extern const bcstring be_const_str__settings_def;
+extern const bcstring be_const_str_read24;
+extern const bcstring be_const_str_cos;
+extern const bcstring be_const_str_remove_driver;
+extern const bcstring be_const_str__settings_ptr;
+extern const bcstring be_const_str_memory;
+extern const bcstring be_const_str_set_auth;
+extern const bcstring be_const_str_content_send_style;
+extern const bcstring be_const_str_class;
+extern const bcstring be_const_str_SERIAL_7E2;
+extern const bcstring be_const_str_shared_key;
+extern const bcstring be_const_str_tanh;
+extern const bcstring be_const_str_nil;
+extern const bcstring be_const_str_get_power;
+extern const bcstring be_const_str_last_modified;
+extern const bcstring be_const_str_resolvecmnd;
+extern const bcstring be_const_str__read;
+extern const bcstring be_const_str_atan;
+extern const bcstring be_const_str_content_button;
+extern const bcstring be_const_str_setbits;
+extern const bcstring be_const_str_upper;
+extern const bcstring be_const_str_contains;
+extern const bcstring be_const_str_time_str;
+extern const bcstring be_const_str_arch;
+extern const bcstring be_const_str_fromptr;
+extern const bcstring be_const_str_push;
+extern const bcstring be_const_str_srand;
+extern const bcstring be_const_str_geti;
+extern const bcstring be_const_str_seti;
+extern const bcstring be_const_str_add_cmd;
+extern const bcstring be_const_str_cmd;
+extern const bcstring be_const_str_get_switch;
+extern const bcstring be_const_str_size;
+extern const bcstring be_const_str_try;
+extern const bcstring be_const_str_web_send;
+extern const bcstring be_const_str_except;
+extern const bcstring be_const_str_SERIAL_5O1;
+extern const bcstring be_const_str_SERIAL_8E2;
+extern const bcstring be_const_str__available;
+extern const bcstring be_const_str_codedump;
+extern const bcstring be_const_str_wire2;
+extern const bcstring be_const_str_dump;
+extern const bcstring be_const_str_exec_cmd;
+extern const bcstring be_const_str_add;
+extern const bcstring be_const_str_exp;
+extern const bcstring be_const_str_isrunning;
+extern const bcstring be_const_str_remove_rule;
+extern const bcstring be_const_str_run_deferred;
+extern const bcstring be_const_str_scan;
+extern const bcstring be_const_str_for;
+extern const bcstring be_const_str_set_timer;
+extern const bcstring be_const_str_url_encode;
+extern const bcstring be_const_str_addr;
+extern const bcstring be_const_str___upper__;
+extern const bcstring be_const_str_loop;
extern const bcstring be_const_str_AudioGeneratorWAV;
+extern const bcstring be_const_str_chars_in_string;
+extern const bcstring be_const_str_cosh;
+extern const bcstring be_const_str_import;
+extern const bcstring be_const_str_SERIAL_5N2;
+extern const bcstring be_const_str_type;
+extern const bcstring be_const_str_clear;
+extern const bcstring be_const_str_SERIAL_8N1;
+extern const bcstring be_const_str_issubclass;
+extern const bcstring be_const_str_remove_timer;
+extern const bcstring be_const_str_sinh;
+extern const bcstring be_const_str_AudioGeneratorMP3;
+extern const bcstring be_const_str_Wire;
+extern const bcstring be_const_str_get_light;
+extern const bcstring be_const_str_get_option;
+extern const bcstring be_const_str_list;
+extern const bcstring be_const_str_stop;
+extern const bcstring be_const_str_try_rule;
+extern const bcstring be_const_str_webclient;
+extern const bcstring be_const_str_dot_p2;
+extern const bcstring be_const_str_has;
+extern const bcstring be_const_str__request_from;
+extern const bcstring be_const_str_setrange;
+extern const bcstring be_const_str_I2C_Driver;
+extern const bcstring be_const_str_ceil;
+extern const bcstring be_const_str_else;
+extern const bcstring be_const_str_concat;
+extern const bcstring be_const_str_set_power;
+extern const bcstring be_const_str_tomap;
+extern const bcstring be_const_str_resp_cmnd_error;
+extern const bcstring be_const_str_add_header;
+extern const bcstring be_const_str_eth;
+extern const bcstring be_const_str_write_bit;
+extern const bcstring be_const_str_exists;
+extern const bcstring be_const_str_pow;
+extern const bcstring be_const_str_select;
+extern const bcstring be_const_str_allocated;
+extern const bcstring be_const_str_classof;
+extern const bcstring be_const_str_if;
+extern const bcstring be_const_str_SERIAL_5E1;
+extern const bcstring be_const_str_arg;
+extern const bcstring be_const_str_cb_dispatch;
+extern const bcstring be_const_str_response_append;
+extern const bcstring be_const_str_pin_used;
+extern const bcstring be_const_str_write;
+extern const bcstring be_const_str_write8;
+extern const bcstring be_const_str_SERIAL_6O2;
+extern const bcstring be_const_str_log;
+extern const bcstring be_const_str_pin_mode;
+extern const bcstring be_const_str_read12;
+extern const bcstring be_const_str_resp_cmnd_str;
+extern const bcstring be_const_str_abs;
+extern const bcstring be_const_str_digital_write;
+extern const bcstring be_const_str_static;
+extern const bcstring be_const_str_bytes;
+extern const bcstring be_const_str_find_op;
+extern const bcstring be_const_str_call;
+extern const bcstring be_const_str_cmd_res;
+extern const bcstring be_const_str_opt_eq;
+extern const bcstring be_const_str_save;
+extern const bcstring be_const_str_find_key_i;
extern const bcstring be_const_str__cb;
-extern const bcstring be_const_str_decrypt;
+extern const bcstring be_const_str_Tasmota;
+extern const bcstring be_const_str_public_key;
+extern const bcstring be_const_str_as;
+extern const bcstring be_const_str_dot_w;
+extern const bcstring be_const_str_SERIAL_8O1;
+extern const bcstring be_const_str_compile;
+extern const bcstring be_const_str_range;
+extern const bcstring be_const_str_add_rule;
+extern const bcstring be_const_str__ptr;
+extern const bcstring be_const_str_delay;
+extern const bcstring be_const_str_pop;
+extern const bcstring be_const_str_reset;
+extern const bcstring be_const_str_wire_scan;
+extern const bcstring be_const_str_reset_search;
+extern const bcstring be_const_str_tolower;
+extern const bcstring be_const_str_SERIAL_7O2;
+extern const bcstring be_const_str_asin;
+extern const bcstring be_const_str_nan;
+extern const bcstring be_const_str_deg;
+extern const bcstring be_const_str_log10;
+extern const bcstring be_const_str_char;
+extern const bcstring be_const_str_get_size;
+extern const bcstring be_const_str_opt_call;
+extern const bcstring be_const_str_end;
+extern const bcstring be_const_str_SERIAL_7N2;
+extern const bcstring be_const_str_time_dump;
+extern const bcstring be_const_str_listdir;
+extern const bcstring be_const_str_wifi;
+extern const bcstring be_const_str_read_bytes;
+extern const bcstring be_const_str_reverse;
+extern const bcstring be_const_str_SERIAL_6E1;
+extern const bcstring be_const_str_SERIAL_5O2;
+extern const bcstring be_const_str_SERIAL_8E1;
+extern const bcstring be_const_str_asstring;
+extern const bcstring be_const_str_deinit;
+extern const bcstring be_const_str_encrypt;
+extern const bcstring be_const_str_iter;
+extern const bcstring be_const_str_millis;
+extern const bcstring be_const_str_AudioOutput;
+extern const bcstring be_const_str_members;
+extern const bcstring be_const_str_rtc;
+extern const bcstring be_const_str_SERIAL_6N1;
+extern const bcstring be_const_str__write;
+extern const bcstring be_const_str_content_start;
+extern const bcstring be_const_str_module;
+extern const bcstring be_const_str_item;
+extern const bcstring be_const_str_remove_cmd;
+extern const bcstring be_const_str_MD5;
extern const bcstring be_const_str_sqrt;
extern const bcstring be_const_str_SERIAL_5N1;
-extern const bcstring be_const_str_find_key_i;
-extern const bcstring be_const_str_arg;
-extern const bcstring be_const_str_depower;
-extern const bcstring be_const_str_write_file;
-extern const bcstring be_const_str_SERIAL_5O2;
-extern const bcstring be_const_str_get_light;
-extern const bcstring be_const_str_pop;
-extern const bcstring be_const_str_exec_tele;
-extern const bcstring be_const_str_set_light;
-extern const bcstring be_const_str_set_timeouts;
-extern const bcstring be_const_str_sinh;
-extern const bcstring be_const_str_AudioGenerator;
-extern const bcstring be_const_str_SERIAL_7E1;
-extern const bcstring be_const_str_getbits;
-extern const bcstring be_const_str_shared_key;
-extern const bcstring be_const_str_time_dump;
-extern const bcstring be_const_str_content_button;
-extern const bcstring be_const_str_geti;
-extern const bcstring be_const_str_arch;
-extern const bcstring be_const_str_asin;
-extern const bcstring be_const_str_get_free_heap;
-extern const bcstring be_const_str_resp_cmnd;
-extern const bcstring be_const_str_content_flush;
-extern const bcstring be_const_str_millis;
-extern const bcstring be_const_str_serial;
-extern const bcstring be_const_str_skip;
-extern const bcstring be_const_str_event;
-extern const bcstring be_const_str_opt_add;
-extern const bcstring be_const_str_bus;
-extern const bcstring be_const_str_acos;
-extern const bcstring be_const_str_bytes;
-extern const bcstring be_const_str_compile;
-extern const bcstring be_const_str_get;
-extern const bcstring be_const_str_tan;
-extern const bcstring be_const_str_encrypt;
-extern const bcstring be_const_str_cmd_res;
-extern const bcstring be_const_str_collect;
-extern const bcstring be_const_str_arg_size;
-extern const bcstring be_const_str_reverse;
-extern const bcstring be_const_str_close;
-extern const bcstring be_const_str_members;
-extern const bcstring be_const_str_assert;
-extern const bcstring be_const_str_exec_cmd;
-extern const bcstring be_const_str_get_power;
-extern const bcstring be_const_str_resp_cmnd_failed;
-extern const bcstring be_const_str_target_search;
-extern const bcstring be_const_str_AudioFileSource;
-extern const bcstring be_const_str_SERIAL_8N1;
-extern const bcstring be_const_str_pi;
-extern const bcstring be_const_str_add_header;
-extern const bcstring be_const_str_list;
-extern const bcstring be_const_str_read_sensors;
-extern const bcstring be_const_str_super;
-extern const bcstring be_const_str_has;
-extern const bcstring be_const_str___upper__;
-extern const bcstring be_const_str_exp;
-extern const bcstring be_const_str_int;
-extern const bcstring be_const_str_size;
-extern const bcstring be_const_str_for;
-extern const bcstring be_const_str_ctypes_bytes;
-extern const bcstring be_const_str_wifi;
-extern const bcstring be_const_str_elif;
-extern const bcstring be_const_str_arg_name;
-extern const bcstring be_const_str_cosh;
-extern const bcstring be_const_str_lower;
-extern const bcstring be_const_str_push;
-extern const bcstring be_const_str_save;
-extern const bcstring be_const_str_load;
-extern const bcstring be_const_str_SERIAL_8E2;
-extern const bcstring be_const_str_nan;
-extern const bcstring be_const_str_remove_driver;
-extern const bcstring be_const_str_write8;
-extern const bcstring be_const_str__get_cb;
-extern const bcstring be_const_str_iter;
-extern const bcstring be_const_str__cmd;
-extern const bcstring be_const_str_exists;
-extern const bcstring be_const_str_AudioGeneratorMP3;
-extern const bcstring be_const_str__end_transmission;
-extern const bcstring be_const_str_get_switch;
-extern const bcstring be_const_str__available;
-extern const bcstring be_const_str_false;
-extern const bcstring be_const_str_settings;
-extern const bcstring be_const_str_wd;
-extern const bcstring be_const_str_SERIAL_8O2;
-extern const bcstring be_const_str_rad;
-extern const bcstring be_const_str_kv;
-extern const bcstring be_const_str_toupper;
-extern const bcstring be_const_str_tr;
-extern const bcstring be_const_str_return;
-extern const bcstring be_const_str_memory;
+extern const bcstring be_const_str_break;
+extern const bcstring be_const_str_map;
+extern const bcstring be_const_str_setmember;
extern const bcstring be_const_str_tostring;
+extern const bcstring be_const_str_AudioGenerator;
+extern const bcstring be_const_str_while;
+extern const bcstring be_const_str_event;
+extern const bcstring be_const_str_resp_cmnd_done;
+extern const bcstring be_const_str_AudioOutputI2S;
+extern const bcstring be_const_str_has_arg;
+extern const bcstring be_const_str_floor;
+extern const bcstring be_const_str_read;
+extern const bcstring be_const_str_remove;
+extern const bcstring be_const_str_calldepth;
+extern const bcstring be_const_str_lower;
+extern const bcstring be_const_str_path;
+extern const bcstring be_const_str_gamma10;
+extern const bcstring be_const_str_get;
+extern const bcstring be_const_str_elif;
+extern const bcstring be_const_str__buffer;
+extern const bcstring be_const_str_exec_rules;
+extern const bcstring be_const_str_pin;
+extern const bcstring be_const_str_collect;
+extern const bcstring be_const_str_enabled;
+extern const bcstring be_const_str_global;
+extern const bcstring be_const_str_acos;
+extern const bcstring be_const_str_content_stop;
+extern const bcstring be_const_str_read8;
+extern const bcstring be_const_str_wire1;
+extern const bcstring be_const_str_fromstring;
+extern const bcstring be_const_str_setitem;
+extern const bcstring be_const_str__debug_present;
+extern const bcstring be_const_str_erase;
+extern const bcstring be_const_str_i2c_enabled;
+extern const bcstring be_const_str_resize;
+extern const bcstring be_const_str_decrypt;
+extern const bcstring be_const_str_escape;
+extern const bcstring be_const_str_isnan;
+extern const bcstring be_const_str_skip;
+extern const bcstring be_const_str_var;
+extern const bcstring be_const_str_dot_p;
+extern const bcstring be_const_str_write_file;
+extern const bcstring be_const_str_copy;
+extern const bcstring be_const_str_str;
+extern const bcstring be_const_str_super;
+extern const bcstring be_const_str_update;
+extern const bcstring be_const_str__def;
+extern const bcstring be_const_str__drivers;
+extern const bcstring be_const_str_imax;
+extern const bcstring be_const_str_add_driver;
+extern const bcstring be_const_str_dot_len;
+extern const bcstring be_const_str_SERIAL_6O1;
+extern const bcstring be_const_str_attrdump;
+extern const bcstring be_const_str_on;
+extern const bcstring be_const_str_rad;
+extern const bcstring be_const_str_bus;
+extern const bcstring be_const_str_yield;
+extern const bcstring be_const_str_top;
+extern const bcstring be_const_str_get_string;
+extern const bcstring be_const_str_read_sensors;
+extern const bcstring be_const_str_settings;
+extern const bcstring be_const_str__get_cb;
+extern const bcstring be_const_str_int;
+extern const bcstring be_const_str_opt_neq;
+extern const bcstring be_const_str_gen_cb;
+extern const bcstring be_const_str__timers;
+extern const bcstring be_const_str_continue;
+extern const bcstring be_const_str_SERIAL_7E1;
+extern const bcstring be_const_str_AudioFileSource;
+extern const bcstring be_const_str_format;
+extern const bcstring be_const_str_EC_C25519;
+extern const bcstring be_const_str_close;
+extern const bcstring be_const_str_content_flush;
+extern const bcstring be_const_str_reduce;
+extern const bcstring be_const_str_tr;
+extern const bcstring be_const_str_available;
+extern const bcstring be_const_str_traceback;
+extern const bcstring be_const_str_opt_add;
+extern const bcstring be_const_str_SERIAL_8N2;
+extern const bcstring be_const_str_wd;
+extern const bcstring be_const_str___iterator__;
+extern const bcstring be_const_str_fromb64;
+extern const bcstring be_const_str_number;
+extern const bcstring be_const_str_print;
+extern const bcstring be_const_str_set_useragent;
+extern const bcstring be_const_str_tan;
+extern const bcstring be_const_str_do;
+extern const bcstring be_const_str_;
+extern const bcstring be_const_str_opt_connect;
+extern const bcstring be_const_str__rules;
+extern const bcstring be_const_str_dot_p1;
+extern const bcstring be_const_str_find;
+extern const bcstring be_const_str_name;
+extern const bcstring be_const_str_toptr;
+extern const bcstring be_const_str_arg_name;
+extern const bcstring be_const_str_byte;
+extern const bcstring be_const_str_gc;
+extern const bcstring be_const_str_count;
+extern const bcstring be_const_str_counters;
+extern const bcstring be_const_str_tob64;
+extern const bcstring be_const_str_AudioFileSourceFS;
+extern const bcstring be_const_str_get_free_heap;
+extern const bcstring be_const_str_atan2;
+extern const bcstring be_const_str_set_timeouts;
+extern const bcstring be_const_str_toupper;
+extern const bcstring be_const_str__ccmd;
+extern const bcstring be_const_str_content_send;
+extern const bcstring be_const_str_flush;
+extern const bcstring be_const_str_true;
+extern const bcstring be_const_str_detect;
+extern const bcstring be_const_str_SERIAL_8O2;
+extern const bcstring be_const_str_split;
diff --git a/lib/libesp32/Berry/generate/be_const_strtab_def.h b/lib/libesp32/Berry/generate/be_const_strtab_def.h
index e7e4bc0f2..16488ae94 100644
--- a/lib/libesp32/Berry/generate/be_const_strtab_def.h
+++ b/lib/libesp32/Berry/generate/be_const_strtab_def.h
@@ -1,521 +1,523 @@
-be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_remove);
-be_define_const_str(remove, "remove", 3683784189u, 0, 6, &be_const_str_remove_timer);
-be_define_const_str(remove_timer, "remove_timer", 4141472215u, 0, 12, NULL);
-be_define_const_str(MD5, "MD5", 1935726387u, 0, 3, &be_const_str__ccmd);
-be_define_const_str(_ccmd, "_ccmd", 2163421413u, 0, 5, &be_const_str_digital_write);
-be_define_const_str(digital_write, "digital_write", 3435877979u, 0, 13, NULL);
-be_define_const_str(dot_p2, ".p2", 232398067u, 0, 3, &be_const_str_floor);
-be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_input);
-be_define_const_str(input, "input", 4191711099u, 0, 5, &be_const_str_range);
-be_define_const_str(range, "range", 4208725202u, 0, 5, NULL);
-be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_find_op);
-be_define_const_str(find_op, "find_op", 3766713376u, 0, 7, NULL);
-be_define_const_str(SERIAL_6N1, "SERIAL_6N1", 198895701u, 0, 10, &be_const_str_classname);
-be_define_const_str(classname, "classname", 1998589948u, 0, 9, NULL);
-be_define_const_str(content_start, "content_start", 2937509069u, 0, 13, &be_const_str_import);
-be_define_const_str(import, "import", 288002260u, 66, 6, &be_const_str_raise);
-be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL);
-be_define_const_str(SERIAL_8N2, "SERIAL_8N2", 2386074854u, 0, 10, &be_const_str_keys);
-be_define_const_str(keys, "keys", 4182378701u, 0, 4, NULL);
-be_define_const_str(content_send_style, "content_send_style", 1087907647u, 0, 18, &be_const_str_static);
-be_define_const_str(static, "static", 3532702267u, 71, 6, NULL);
-be_define_const_str(_begin_transmission, "_begin_transmission", 2779461176u, 0, 19, &be_const_str__request_from);
-be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, &be_const_str_isnan);
-be_define_const_str(isnan, "isnan", 2981347434u, 0, 5, &be_const_str_reverse_gamma10);
-be_define_const_str(reverse_gamma10, "reverse_gamma10", 739112262u, 0, 15, NULL);
-be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_resp_cmnd_str);
-be_define_const_str(resp_cmnd_str, "resp_cmnd_str", 737845590u, 0, 13, &be_const_str_run_deferred);
-be_define_const_str(run_deferred, "run_deferred", 371594696u, 0, 12, NULL);
-be_define_const_str(exec_rules, "exec_rules", 1445221092u, 0, 10, &be_const_str_web_send);
-be_define_const_str(web_send, "web_send", 2989941448u, 0, 8, NULL);
-be_define_const_str(GET, "GET", 2531704439u, 0, 3, &be_const_str__rules);
-be_define_const_str(_rules, "_rules", 4266217105u, 0, 6, &be_const_str_begin);
-be_define_const_str(begin, "begin", 1748273790u, 0, 5, &be_const_str_escape);
-be_define_const_str(escape, "escape", 2652972038u, 0, 6, NULL);
-be_define_const_str(I2C_Driver, "I2C_Driver", 1714501658u, 0, 10, &be_const_str_char);
-be_define_const_str(char, "char", 2823553821u, 0, 4, NULL);
-be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_Wire);
-be_define_const_str(Wire, "Wire", 1938276536u, 0, 4, &be_const_str_asstring);
-be_define_const_str(asstring, "asstring", 1298225088u, 0, 8, &be_const_str_strftime);
-be_define_const_str(strftime, "strftime", 187738851u, 0, 8, NULL);
-be_define_const_str(last_modified, "last_modified", 772177145u, 0, 13, &be_const_str_set);
-be_define_const_str(set, "set", 3324446467u, 0, 3, NULL);
-be_define_const_str(add, "add", 993596020u, 0, 3, &be_const_str_eth);
-be_define_const_str(eth, "eth", 2191266556u, 0, 3, &be_const_str_publish);
-be_define_const_str(publish, "publish", 264247304u, 0, 7, NULL);
-be_define_const_str(rtc, "rtc", 1070575216u, 0, 3, &be_const_str_scan);
-be_define_const_str(scan, "scan", 3974641896u, 0, 4, NULL);
-be_define_const_str(EC_C25519, "EC_C25519", 95492591u, 0, 9, &be_const_str_nil);
-be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL);
-be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_item);
-be_define_const_str(item, "item", 2671260646u, 0, 4, NULL);
-be_define_const_str(log, "log", 1062293841u, 0, 3, NULL);
-be_define_const_str(_global_def, "_global_def", 646007001u, 0, 11, &be_const_str_clear);
-be_define_const_str(clear, "clear", 1550717474u, 0, 5, NULL);
-be_define_const_str(atan2, "atan2", 3173440503u, 0, 5, &be_const_str_dump);
-be_define_const_str(dump, "dump", 3663001223u, 0, 4, &be_const_str_fromb64);
-be_define_const_str(fromb64, "fromb64", 2717019639u, 0, 7, NULL);
-be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, &be_const_str_read13);
-be_define_const_str(read13, "read13", 12887293u, 0, 6, NULL);
-be_define_const_str(SERIAL_8O1, "SERIAL_8O1", 289122742u, 0, 10, NULL);
-be_define_const_str(SERIAL_6O1, "SERIAL_6O1", 266153272u, 0, 10, &be_const_str_add_rule);
-be_define_const_str(add_rule, "add_rule", 596540743u, 0, 8, &be_const_str_fromstring);
-be_define_const_str(fromstring, "fromstring", 610302344u, 0, 10, NULL);
-be_define_const_str(SERIAL_6E2, "SERIAL_6E2", 317471867u, 0, 10, &be_const_str_try_rule);
-be_define_const_str(try_rule, "try_rule", 1986449405u, 0, 8, NULL);
-be_define_const_str(gc, "gc", 1042313471u, 0, 2, &be_const_str_publish_result);
-be_define_const_str(publish_result, "publish_result", 2013351252u, 0, 14, &be_const_str_response_append);
-be_define_const_str(response_append, "response_append", 450346371u, 0, 15, NULL);
-be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL);
-be_define_const_str(dot_p1, ".p1", 249175686u, 0, 3, &be_const_str__def);
-be_define_const_str(_def, "_def", 1985022181u, 0, 4, &be_const_str_imin);
-be_define_const_str(imin, "imin", 2714127864u, 0, 4, NULL);
-be_define_const_str(chars_in_string, "chars_in_string", 3148785132u, 0, 15, &be_const_str_concat);
-be_define_const_str(concat, "concat", 4124019837u, 0, 6, &be_const_str_content_stop);
-be_define_const_str(content_stop, "content_stop", 658554751u, 0, 12, &be_const_str_def);
+be_define_const_str(SERIAL_6N2, "SERIAL_6N2", 148562844u, 0, 10, &be_const_str__begin_transmission);
+be_define_const_str(_begin_transmission, "_begin_transmission", 2779461176u, 0, 19, &be_const_str_set_light);
+be_define_const_str(set_light, "set_light", 3176076152u, 0, 9, NULL);
+be_define_const_str(time_reached, "time_reached", 2075136773u, 0, 12, NULL);
+be_define_const_str(SERIAL_5E2, "SERIAL_5E2", 1180552854u, 0, 10, &be_const_str___lower__);
+be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, NULL);
+be_define_const_str(SERIAL_7O1, "SERIAL_7O1", 1823802675u, 0, 10, &be_const_str_getbits);
+be_define_const_str(getbits, "getbits", 3094168979u, 0, 7, &be_const_str_input);
+be_define_const_str(input, "input", 4191711099u, 0, 5, NULL);
+be_define_const_str(dot_size, ".size", 1965188224u, 0, 5, &be_const_str_publish_result);
+be_define_const_str(publish_result, "publish_result", 2013351252u, 0, 14, &be_const_str_web_send_decimal);
+be_define_const_str(web_send_decimal, "web_send_decimal", 1407210204u, 0, 16, &be_const_str_def);
be_define_const_str(def, "def", 3310976652u, 55, 3, NULL);
-be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, &be_const_str_wire);
-be_define_const_str(wire, "wire", 4082753944u, 0, 4, NULL);
-be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, NULL);
-be_define_const_str(finish, "finish", 1494643858u, 0, 6, &be_const_str_log10);
-be_define_const_str(log10, "log10", 2346846000u, 0, 5, &be_const_str_name);
-be_define_const_str(name, "name", 2369371622u, 0, 4, &be_const_str_time_str);
-be_define_const_str(time_str, "time_str", 2613827612u, 0, 8, &be_const_str_do);
-be_define_const_str(do, "do", 1646057492u, 65, 2, NULL);
-be_define_const_str(read, "read", 3470762949u, 0, 4, &be_const_str_set_auth);
-be_define_const_str(set_auth, "set_auth", 1057170930u, 0, 8, NULL);
-be_define_const_str(Tasmota, "Tasmota", 4047617668u, 0, 7, NULL);
-be_define_const_str(SERIAL_7E2, "SERIAL_7E2", 97385204u, 0, 10, &be_const_str_resolvecmnd);
-be_define_const_str(resolvecmnd, "resolvecmnd", 993361485u, 0, 11, NULL);
-be_define_const_str(__lower__, "__lower__", 123855590u, 0, 9, &be_const_str_addr);
-be_define_const_str(addr, "addr", 1087856498u, 0, 4, &be_const_str_gamma8);
-be_define_const_str(gamma8, "gamma8", 3802843830u, 0, 6, NULL);
-be_define_const_str(member, "member", 719708611u, 0, 6, &be_const_str_scale_uint);
-be_define_const_str(scale_uint, "scale_uint", 3090811094u, 0, 10, NULL);
-be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, NULL);
-be_define_const_str(opt_call, "()", 685372826u, 0, 2, &be_const_str_SERIAL_5N2);
-be_define_const_str(SERIAL_5N2, "SERIAL_5N2", 3363364537u, 0, 10, NULL);
-be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_hex);
-be_define_const_str(hex, "hex", 4273249610u, 0, 3, &be_const_str_remove_cmd);
-be_define_const_str(remove_cmd, "remove_cmd", 3832315702u, 0, 10, NULL);
-be_define_const_str(AudioOutput, "AudioOutput", 3257792048u, 0, 11, &be_const_str_break);
-be_define_const_str(break, "break", 3378807160u, 58, 5, NULL);
-be_define_const_str(SERIAL_5O1, "SERIAL_5O1", 3782657917u, 0, 10, &be_const_str_rand);
-be_define_const_str(rand, "rand", 2711325910u, 0, 4, &be_const_str_class);
-be_define_const_str(class, "class", 2872970239u, 57, 5, NULL);
-be_define_const_str(public_key, "public_key", 4169142980u, 0, 10, &be_const_str_search);
-be_define_const_str(search, "search", 2150836393u, 0, 6, &be_const_str_update);
-be_define_const_str(update, "update", 672109684u, 0, 6, &be_const_str_end);
-be_define_const_str(end, "end", 1787721130u, 56, 3, NULL);
-be_define_const_str(i2c_enabled, "i2c_enabled", 218388101u, 0, 11, &be_const_str_read_bytes);
-be_define_const_str(read_bytes, "read_bytes", 3576733173u, 0, 10, NULL);
-be_define_const_str(fromptr, "fromptr", 666189689u, 0, 7, &be_const_str_pin_used);
-be_define_const_str(pin_used, "pin_used", 4033854612u, 0, 8, &be_const_str_redirect);
-be_define_const_str(redirect, "redirect", 389758641u, 0, 8, NULL);
-be_define_const_str(_drivers, "_drivers", 3260328985u, 0, 8, &be_const_str_get_size);
-be_define_const_str(get_size, "get_size", 2803644713u, 0, 8, &be_const_str_set_power);
-be_define_const_str(set_power, "set_power", 549820893u, 0, 9, NULL);
-be_define_const_str(loop, "loop", 3723446379u, 0, 4, &be_const_str_read32);
-be_define_const_str(read32, "read32", 1741276240u, 0, 6, NULL);
-be_define_const_str(add_cmd, "add_cmd", 3361630879u, 0, 7, NULL);
-be_define_const_str(_settings_ptr, "_settings_ptr", 1825772182u, 0, 13, &be_const_str_reset);
-be_define_const_str(reset, "reset", 1695364032u, 0, 5, NULL);
-be_define_const_str(_ptr, "_ptr", 306235816u, 0, 4, &be_const_str_detect);
-be_define_const_str(detect, "detect", 8884370u, 0, 6, &be_const_str_reset_search);
-be_define_const_str(reset_search, "reset_search", 1350414305u, 0, 12, NULL);
-be_define_const_str(SERIAL_6E1, "SERIAL_6E1", 334249486u, 0, 10, &be_const_str__read);
-be_define_const_str(_read, "_read", 346717030u, 0, 5, NULL);
-be_define_const_str(true, "true", 1303515621u, 61, 4, NULL);
-be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, &be_const_str_add_driver);
-be_define_const_str(add_driver, "add_driver", 1654458371u, 0, 10, &be_const_str_tob64);
-be_define_const_str(tob64, "tob64", 373777640u, 0, 5, &be_const_str_wire1);
-be_define_const_str(wire1, "wire1", 3212721419u, 0, 5, NULL);
-be_define_const_str(_timers, "_timers", 2600100916u, 0, 7, NULL);
-be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str_SERIAL_5E1);
-be_define_const_str(SERIAL_5E1, "SERIAL_5E1", 1163775235u, 0, 10, &be_const_str_select);
-be_define_const_str(select, "select", 297952813u, 0, 6, &be_const_str_setbits);
-be_define_const_str(setbits, "setbits", 2762408167u, 0, 7, &be_const_str_webclient);
-be_define_const_str(webclient, "webclient", 4076389146u, 0, 9, NULL);
-be_define_const_str(deg, "deg", 3327754271u, 0, 3, &be_const_str_flush);
-be_define_const_str(flush, "flush", 3002334877u, 0, 5, &be_const_str_hs2rgb);
-be_define_const_str(hs2rgb, "hs2rgb", 1040816349u, 0, 6, NULL);
-be_define_const_str(SERIAL_8E1, "SERIAL_8E1", 2371121616u, 0, 10, &be_const_str_setrange);
-be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, NULL);
-be_define_const_str(dot_len, ".len", 850842136u, 0, 4, &be_const_str_byte);
-be_define_const_str(byte, "byte", 1683620383u, 0, 4, &be_const_str_issubclass);
-be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, &be_const_str_while);
-be_define_const_str(while, "while", 231090382u, 53, 5, NULL);
-be_define_const_str(enabled, "enabled", 49525662u, 0, 7, &be_const_str_sin);
-be_define_const_str(sin, "sin", 3761252941u, 0, 3, &be_const_str_except);
-be_define_const_str(except, "except", 950914032u, 69, 6, NULL);
-be_define_const_str(AudioOutputI2S, "AudioOutputI2S", 638031784u, 0, 14, &be_const_str_SERIAL_7N2);
-be_define_const_str(SERIAL_7N2, "SERIAL_7N2", 1874282627u, 0, 10, &be_const_str_call);
-be_define_const_str(call, "call", 3018949801u, 0, 4, &be_const_str_imax);
-be_define_const_str(imax, "imax", 3084515410u, 0, 4, NULL);
-be_define_const_str(isrunning, "isrunning", 1688182268u, 0, 9, &be_const_str_read8);
-be_define_const_str(read8, "read8", 2802788167u, 0, 5, &be_const_str_resp_cmnd_error);
-be_define_const_str(resp_cmnd_error, "resp_cmnd_error", 2404088863u, 0, 15, NULL);
-be_define_const_str(AudioFileSourceFS, "AudioFileSourceFS", 1839147653u, 0, 17, &be_const_str___iterator__);
-be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_contains);
-be_define_const_str(contains, "contains", 1825239352u, 0, 8, &be_const_str_web_send_decimal);
-be_define_const_str(web_send_decimal, "web_send_decimal", 1407210204u, 0, 16, NULL);
-be_define_const_str(dac_voltage, "dac_voltage", 1552257222u, 0, 11, NULL);
-be_define_const_str(time_reached, "time_reached", 2075136773u, 0, 12, &be_const_str_if);
-be_define_const_str(if, "if", 959999494u, 50, 2, NULL);
-be_define_const_str(read24, "read24", 1808533811u, 0, 6, &be_const_str_toptr);
-be_define_const_str(toptr, "toptr", 3379847454u, 0, 5, &be_const_str_else);
-be_define_const_str(else, "else", 3183434736u, 52, 4, NULL);
-be_define_const_str(_global_addr, "_global_addr", 533766721u, 0, 12, &be_const_str_classof);
-be_define_const_str(classof, "classof", 1796577762u, 0, 7, NULL);
-be_define_const_str(SERIAL_7O1, "SERIAL_7O1", 1823802675u, 0, 10, &be_const_str_print);
-be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_setmember);
-be_define_const_str(setmember, "setmember", 1432909441u, 0, 9, NULL);
-be_define_const_str(dot_size, ".size", 1965188224u, 0, 5, &be_const_str__write);
-be_define_const_str(_write, "_write", 2215462825u, 0, 6, &be_const_str_init);
-be_define_const_str(init, "init", 380752755u, 0, 4, NULL);
-be_define_const_str(gamma10, "gamma10", 3472052483u, 0, 7, &be_const_str_gen_cb);
-be_define_const_str(gen_cb, "gen_cb", 3245227551u, 0, 6, &be_const_str_remove_rule);
-be_define_const_str(remove_rule, "remove_rule", 3456211328u, 0, 11, NULL);
-be_define_const_str(ctypes_bytes_dyn, "ctypes_bytes_dyn", 915205307u, 0, 16, NULL);
-be_define_const_str(SERIAL_6N2, "SERIAL_6N2", 148562844u, 0, 10, &be_const_str_available);
-be_define_const_str(available, "available", 1727918744u, 0, 9, &be_const_str_cb_dispatch);
-be_define_const_str(cb_dispatch, "cb_dispatch", 1741510499u, 0, 11, &be_const_str_isinstance);
-be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, NULL);
-be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_find);
-be_define_const_str(find, "find", 3186656602u, 0, 4, NULL);
-be_define_const_str(POST, "POST", 1929554311u, 0, 4, &be_const_str_write_bytes);
-be_define_const_str(write_bytes, "write_bytes", 1227543792u, 0, 11, NULL);
-be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_type);
-be_define_const_str(type, "type", 1361572173u, 0, 4, NULL);
-be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_insert);
-be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_tolower);
-be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL);
-be_define_const_str(dot_w, ".w", 1255414514u, 0, 2, &be_const_str_srand);
-be_define_const_str(srand, "srand", 465518633u, 0, 5, &be_const_str_wire2);
-be_define_const_str(wire2, "wire2", 3229499038u, 0, 5, NULL);
-be_define_const_str(format, "format", 3114108242u, 0, 6, &be_const_str_yield);
-be_define_const_str(yield, "yield", 1821831854u, 0, 5, NULL);
-be_define_const_str(SERIAL_5E2, "SERIAL_5E2", 1180552854u, 0, 10, &be_const_str_reduce);
-be_define_const_str(reduce, "reduce", 2002030311u, 0, 6, &be_const_str_resp_cmnd_done);
-be_define_const_str(resp_cmnd_done, "resp_cmnd_done", 2601874875u, 0, 14, NULL);
-be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_setitem);
-be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL);
-be_define_const_str(OneWire, "OneWire", 2298990722u, 0, 7, &be_const_str_upper);
-be_define_const_str(upper, "upper", 176974407u, 0, 5, NULL);
-be_define_const_str(module, "module", 3617558685u, 0, 6, NULL);
-be_define_const_str(counters, "counters", 4095866864u, 0, 8, &be_const_str_tag);
-be_define_const_str(tag, "tag", 2516003219u, 0, 3, NULL);
-be_define_const_str(tanh, "tanh", 153638352u, 0, 4, NULL);
-be_define_const_str(get_string, "get_string", 4195847969u, 0, 10, &be_const_str_read12);
-be_define_const_str(read12, "read12", 4291076970u, 0, 6, &be_const_str_wire_scan);
-be_define_const_str(wire_scan, "wire_scan", 2671275880u, 0, 9, NULL);
-be_define_const_str(seti, "seti", 1500556254u, 0, 4, NULL);
-be_define_const_str(cmd, "cmd", 4136785899u, 0, 3, &be_const_str_content_send);
-be_define_const_str(content_send, "content_send", 1673733649u, 0, 12, &be_const_str_global);
-be_define_const_str(global, "global", 503252654u, 0, 6, &be_const_str_var);
-be_define_const_str(var, "var", 2317739966u, 64, 3, NULL);
-be_define_const_str(SERIAL_7N1, "SERIAL_7N1", 1891060246u, 0, 10, &be_const_str_resize);
-be_define_const_str(resize, "resize", 3514612129u, 0, 6, &be_const_str_split);
-be_define_const_str(split, "split", 2276994531u, 0, 5, &be_const_str_str);
-be_define_const_str(str, "str", 3259748752u, 0, 3, &be_const_str_url_encode);
-be_define_const_str(url_encode, "url_encode", 528392145u, 0, 10, NULL);
-be_define_const_str(get_option, "get_option", 2123730033u, 0, 10, &be_const_str_listdir);
-be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, &be_const_str_tomap);
-be_define_const_str(tomap, "tomap", 612167626u, 0, 5, NULL);
-be_define_const_str(check_privileged_access, "check_privileged_access", 3692933968u, 0, 23, NULL);
-be_define_const_str(pin_mode, "pin_mode", 3258314030u, 0, 8, NULL);
-be_define_const_str(pin, "pin", 1866532500u, 0, 3, &be_const_str_try);
-be_define_const_str(try, "try", 2887626766u, 68, 3, NULL);
-be_define_const_str(_buffer, "_buffer", 2044888568u, 0, 7, &be_const_str_cos);
-be_define_const_str(cos, "cos", 4220379804u, 0, 3, NULL);
-be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str_SERIAL_7O2);
-be_define_const_str(SERIAL_7O2, "SERIAL_7O2", 1840580294u, 0, 10, NULL);
-be_define_const_str(real, "real", 3604983901u, 0, 4, NULL);
-be_define_const_str(set_timer, "set_timer", 2135414533u, 0, 9, NULL);
-be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_write);
-be_define_const_str(write, "write", 3190202204u, 0, 5, NULL);
-be_define_const_str(_settings_def, "_settings_def", 3775560307u, 0, 13, &be_const_str_digital_read);
-be_define_const_str(digital_read, "digital_read", 3585496928u, 0, 12, NULL);
-be_define_const_str(path, "path", 2223459638u, 0, 4, NULL);
-be_define_const_str(delay, "delay", 1322381784u, 0, 5, &be_const_str_stop);
-be_define_const_str(stop, "stop", 3411225317u, 0, 4, NULL);
-be_define_const_str(AES_GCM, "AES_GCM", 3832208678u, 0, 7, NULL);
-be_define_const_str(SERIAL_6O2, "SERIAL_6O2", 316486129u, 0, 10, &be_const_str_open);
-be_define_const_str(open, "open", 3546203337u, 0, 4, &be_const_str_top);
-be_define_const_str(top, "top", 2802900028u, 0, 3, NULL);
-be_define_const_str(write_bit, "write_bit", 2660990436u, 0, 9, NULL);
-be_define_const_str(state, "state", 2016490230u, 0, 5, NULL);
-be_define_const_str(set_useragent, "set_useragent", 612237244u, 0, 13, &be_const_str_as);
-be_define_const_str(as, "as", 1579491469u, 67, 2, NULL);
-be_define_const_str(erase, "erase", 1010949589u, 0, 5, &be_const_str_has_arg);
-be_define_const_str(has_arg, "has_arg", 424878688u, 0, 7, &be_const_str_map);
-be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_on);
-be_define_const_str(on, "on", 1630810064u, 0, 2, NULL);
-be_define_const_str(AudioGeneratorWAV, "AudioGeneratorWAV", 2746509368u, 0, 17, &be_const_str__cb);
-be_define_const_str(_cb, "_cb", 4043300367u, 0, 3, &be_const_str_decrypt);
-be_define_const_str(decrypt, "decrypt", 2886974618u, 0, 7, &be_const_str_sqrt);
-be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL);
-be_define_const_str(SERIAL_5N1, "SERIAL_5N1", 3313031680u, 0, 10, NULL);
-be_define_const_str(find_key_i, "find_key_i", 850136726u, 0, 10, NULL);
-be_define_const_str(arg, "arg", 1047474471u, 0, 3, &be_const_str_depower);
-be_define_const_str(depower, "depower", 3563819571u, 0, 7, &be_const_str_write_file);
-be_define_const_str(write_file, "write_file", 3177658879u, 0, 10, NULL);
-be_define_const_str(SERIAL_5O2, "SERIAL_5O2", 3732325060u, 0, 10, &be_const_str_get_light);
-be_define_const_str(get_light, "get_light", 381930476u, 0, 9, &be_const_str_pop);
-be_define_const_str(pop, "pop", 1362321360u, 0, 3, NULL);
-be_define_const_str(exec_tele, "exec_tele", 1020751601u, 0, 9, NULL);
-be_define_const_str(set_light, "set_light", 3176076152u, 0, 9, &be_const_str_set_timeouts);
-be_define_const_str(set_timeouts, "set_timeouts", 3732850900u, 0, 12, &be_const_str_sinh);
-be_define_const_str(sinh, "sinh", 282220607u, 0, 4, NULL);
-be_define_const_str(AudioGenerator, "AudioGenerator", 1839297342u, 0, 14, &be_const_str_SERIAL_7E1);
-be_define_const_str(SERIAL_7E1, "SERIAL_7E1", 147718061u, 0, 10, &be_const_str_getbits);
-be_define_const_str(getbits, "getbits", 3094168979u, 0, 7, &be_const_str_shared_key);
-be_define_const_str(shared_key, "shared_key", 2200833624u, 0, 10, &be_const_str_time_dump);
-be_define_const_str(time_dump, "time_dump", 3330410747u, 0, 9, NULL);
-be_define_const_str(content_button, "content_button", 1956476087u, 0, 14, &be_const_str_geti);
-be_define_const_str(geti, "geti", 2381006490u, 0, 4, NULL);
-be_define_const_str(arch, "arch", 2952804297u, 0, 4, &be_const_str_asin);
-be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_get_free_heap);
-be_define_const_str(get_free_heap, "get_free_heap", 625069757u, 0, 13, &be_const_str_resp_cmnd);
+be_define_const_str(_cmd, "_cmd", 3419822142u, 0, 4, &be_const_str_begin);
+be_define_const_str(begin, "begin", 1748273790u, 0, 5, &be_const_str_resp_cmnd);
be_define_const_str(resp_cmnd, "resp_cmnd", 2869459626u, 0, 9, NULL);
-be_define_const_str(content_flush, "content_flush", 214922475u, 0, 13, &be_const_str_millis);
-be_define_const_str(millis, "millis", 1214679063u, 0, 6, &be_const_str_serial);
-be_define_const_str(serial, "serial", 3687697785u, 0, 6, &be_const_str_skip);
-be_define_const_str(skip, "skip", 1097563074u, 0, 4, NULL);
-be_define_const_str(event, "event", 4264611999u, 0, 5, NULL);
-be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_bus);
-be_define_const_str(bus, "bus", 1607822841u, 0, 3, NULL);
-be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_bytes);
-be_define_const_str(bytes, "bytes", 1706151940u, 0, 5, &be_const_str_compile);
-be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_get);
-be_define_const_str(get, "get", 1410115415u, 0, 3, &be_const_str_tan);
-be_define_const_str(tan, "tan", 2633446552u, 0, 3, NULL);
-be_define_const_str(encrypt, "encrypt", 2194327650u, 0, 7, NULL);
-be_define_const_str(cmd_res, "cmd_res", 921166762u, 0, 7, &be_const_str_collect);
-be_define_const_str(collect, "collect", 2399039025u, 0, 7, NULL);
-be_define_const_str(arg_size, "arg_size", 3310243257u, 0, 8, &be_const_str_reverse);
-be_define_const_str(reverse, "reverse", 558918661u, 0, 7, NULL);
-be_define_const_str(close, "close", 667630371u, 0, 5, &be_const_str_members);
-be_define_const_str(members, "members", 937576464u, 0, 7, NULL);
-be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_exec_cmd);
-be_define_const_str(exec_cmd, "exec_cmd", 493567399u, 0, 8, &be_const_str_get_power);
-be_define_const_str(get_power, "get_power", 3009799377u, 0, 9, &be_const_str_resp_cmnd_failed);
-be_define_const_str(resp_cmnd_failed, "resp_cmnd_failed", 2136281562u, 0, 16, &be_const_str_target_search);
-be_define_const_str(target_search, "target_search", 1947846553u, 0, 13, NULL);
-be_define_const_str(AudioFileSource, "AudioFileSource", 2959980058u, 0, 15, &be_const_str_SERIAL_8N1);
-be_define_const_str(SERIAL_8N1, "SERIAL_8N1", 2369297235u, 0, 10, &be_const_str_pi);
-be_define_const_str(pi, "pi", 1213090802u, 0, 2, NULL);
-be_define_const_str(add_header, "add_header", 927130612u, 0, 10, &be_const_str_list);
-be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_read_sensors);
-be_define_const_str(read_sensors, "read_sensors", 892689201u, 0, 12, &be_const_str_super);
-be_define_const_str(super, "super", 4152230356u, 0, 5, NULL);
-be_define_const_str(has, "has", 3988721635u, 0, 3, NULL);
-be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_exp);
-be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_int);
-be_define_const_str(int, "int", 2515107422u, 0, 3, &be_const_str_size);
-be_define_const_str(size, "size", 597743964u, 0, 4, &be_const_str_for);
-be_define_const_str(for, "for", 2901640080u, 54, 3, NULL);
-be_define_const_str(ctypes_bytes, "ctypes_bytes", 3879019703u, 0, 12, &be_const_str_wifi);
-be_define_const_str(wifi, "wifi", 120087624u, 0, 4, &be_const_str_elif);
-be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL);
-be_define_const_str(arg_name, "arg_name", 1345046155u, 0, 8, &be_const_str_cosh);
-be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, &be_const_str_lower);
-be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_push);
-be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_save);
-be_define_const_str(save, "save", 3439296072u, 0, 4, NULL);
-be_define_const_str(load, "load", 3859241449u, 0, 4, NULL);
-be_define_const_str(SERIAL_8E2, "SERIAL_8E2", 2421454473u, 0, 10, &be_const_str_nan);
-be_define_const_str(nan, "nan", 797905850u, 0, 3, &be_const_str_remove_driver);
-be_define_const_str(remove_driver, "remove_driver", 1030243768u, 0, 13, &be_const_str_write8);
-be_define_const_str(write8, "write8", 3133991532u, 0, 6, NULL);
-be_define_const_str(_get_cb, "_get_cb", 1448849122u, 0, 7, NULL);
-be_define_const_str(iter, "iter", 3124256359u, 0, 4, NULL);
-be_define_const_str(_cmd, "_cmd", 3419822142u, 0, 4, &be_const_str_exists);
-be_define_const_str(exists, "exists", 1002329533u, 0, 6, NULL);
-be_define_const_str(AudioGeneratorMP3, "AudioGeneratorMP3", 2199818488u, 0, 17, &be_const_str__end_transmission);
-be_define_const_str(_end_transmission, "_end_transmission", 3237480400u, 0, 17, NULL);
-be_define_const_str(get_switch, "get_switch", 164821028u, 0, 10, NULL);
-be_define_const_str(_available, "_available", 1306196581u, 0, 10, NULL);
+be_define_const_str(assert, "assert", 2774883451u, 0, 6, &be_const_str_set);
+be_define_const_str(set, "set", 3324446467u, 0, 3, &be_const_str_tag);
+be_define_const_str(tag, "tag", 2516003219u, 0, 3, NULL);
+be_define_const_str(check_privileged_access, "check_privileged_access", 3692933968u, 0, 23, &be_const_str_kv);
+be_define_const_str(kv, "kv", 1497177492u, 0, 2, &be_const_str_publish);
+be_define_const_str(publish, "publish", 264247304u, 0, 7, &be_const_str_read32);
+be_define_const_str(read32, "read32", 1741276240u, 0, 6, NULL);
+be_define_const_str(load, "load", 3859241449u, 0, 4, &be_const_str_read13);
+be_define_const_str(read13, "read13", 12887293u, 0, 6, &be_const_str_search);
+be_define_const_str(search, "search", 2150836393u, 0, 6, NULL);
+be_define_const_str(dac_voltage, "dac_voltage", 1552257222u, 0, 11, &be_const_str_finish);
+be_define_const_str(finish, "finish", 1494643858u, 0, 6, &be_const_str_hex);
+be_define_const_str(hex, "hex", 4273249610u, 0, 3, &be_const_str_isinstance);
+be_define_const_str(isinstance, "isinstance", 3669352738u, 0, 10, &be_const_str_rand);
+be_define_const_str(rand, "rand", 2711325910u, 0, 4, NULL);
+be_define_const_str(POST, "POST", 1929554311u, 0, 4, &be_const_str_SERIAL_6E2);
+be_define_const_str(SERIAL_6E2, "SERIAL_6E2", 317471867u, 0, 10, NULL);
+be_define_const_str(classname, "classname", 1998589948u, 0, 9, NULL);
+be_define_const_str(_global_def, "_global_def", 646007001u, 0, 11, &be_const_str_open);
+be_define_const_str(open, "open", 3546203337u, 0, 4, &be_const_str_redirect);
+be_define_const_str(redirect, "redirect", 389758641u, 0, 8, NULL);
+be_define_const_str(AES_GCM, "AES_GCM", 3832208678u, 0, 7, &be_const_str_resp_cmnd_failed);
+be_define_const_str(resp_cmnd_failed, "resp_cmnd_failed", 2136281562u, 0, 16, &be_const_str_reverse_gamma10);
+be_define_const_str(reverse_gamma10, "reverse_gamma10", 739112262u, 0, 15, NULL);
+be_define_const_str(strftime, "strftime", 187738851u, 0, 8, NULL);
+be_define_const_str(insert, "insert", 3332609576u, 0, 6, &be_const_str_false);
be_define_const_str(false, "false", 184981848u, 62, 5, NULL);
-be_define_const_str(settings, "settings", 1745255176u, 0, 8, &be_const_str_wd);
-be_define_const_str(wd, "wd", 1531424278u, 0, 2, NULL);
-be_define_const_str(SERIAL_8O2, "SERIAL_8O2", 272345123u, 0, 10, &be_const_str_rad);
-be_define_const_str(rad, "rad", 1358899048u, 0, 3, NULL);
-be_define_const_str(kv, "kv", 1497177492u, 0, 2, &be_const_str_toupper);
-be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, &be_const_str_tr);
-be_define_const_str(tr, "tr", 1195724803u, 0, 2, &be_const_str_return);
+be_define_const_str(arg_size, "arg_size", 3310243257u, 0, 8, &be_const_str_serial);
+be_define_const_str(serial, "serial", 3687697785u, 0, 6, NULL);
+be_define_const_str(OneWire, "OneWire", 2298990722u, 0, 7, &be_const_str_scale_uint);
+be_define_const_str(scale_uint, "scale_uint", 3090811094u, 0, 10, NULL);
be_define_const_str(return, "return", 2246981567u, 60, 6, NULL);
-be_define_const_str(memory, "memory", 2229924270u, 0, 6, &be_const_str_tostring);
+be_define_const_str(wire, "wire", 4082753944u, 0, 4, &be_const_str_write_bytes);
+be_define_const_str(write_bytes, "write_bytes", 1227543792u, 0, 11, NULL);
+be_define_const_str(_global_addr, "_global_addr", 533766721u, 0, 12, &be_const_str_exec_tele);
+be_define_const_str(exec_tele, "exec_tele", 1020751601u, 0, 9, &be_const_str_target_search);
+be_define_const_str(target_search, "target_search", 1947846553u, 0, 13, NULL);
+be_define_const_str(gamma8, "gamma8", 3802843830u, 0, 6, &be_const_str_pi);
+be_define_const_str(pi, "pi", 1213090802u, 0, 2, &be_const_str_state);
+be_define_const_str(state, "state", 2016490230u, 0, 5, NULL);
+be_define_const_str(depower, "depower", 3563819571u, 0, 7, &be_const_str_init);
+be_define_const_str(init, "init", 380752755u, 0, 4, &be_const_str_member);
+be_define_const_str(member, "member", 719708611u, 0, 6, NULL);
+be_define_const_str(_end_transmission, "_end_transmission", 3237480400u, 0, 17, &be_const_str_digital_read);
+be_define_const_str(digital_read, "digital_read", 3585496928u, 0, 12, &be_const_str_imin);
+be_define_const_str(imin, "imin", 2714127864u, 0, 4, NULL);
+be_define_const_str(hs2rgb, "hs2rgb", 1040816349u, 0, 6, &be_const_str_keys);
+be_define_const_str(keys, "keys", 4182378701u, 0, 4, &be_const_str_real);
+be_define_const_str(real, "real", 3604983901u, 0, 4, &be_const_str_sin);
+be_define_const_str(sin, "sin", 3761252941u, 0, 3, NULL);
+be_define_const_str(SERIAL_7N1, "SERIAL_7N1", 1891060246u, 0, 10, NULL);
+be_define_const_str(ctypes_bytes, "ctypes_bytes", 3879019703u, 0, 12, &be_const_str_ctypes_bytes_dyn);
+be_define_const_str(ctypes_bytes_dyn, "ctypes_bytes_dyn", 915205307u, 0, 16, &be_const_str_raise);
+be_define_const_str(raise, "raise", 1593437475u, 70, 5, NULL);
+be_define_const_str(GET, "GET", 2531704439u, 0, 3, &be_const_str__settings_def);
+be_define_const_str(_settings_def, "_settings_def", 3775560307u, 0, 13, &be_const_str_read24);
+be_define_const_str(read24, "read24", 1808533811u, 0, 6, NULL);
+be_define_const_str(cos, "cos", 4220379804u, 0, 3, &be_const_str_remove_driver);
+be_define_const_str(remove_driver, "remove_driver", 1030243768u, 0, 13, NULL);
+be_define_const_str(_settings_ptr, "_settings_ptr", 1825772182u, 0, 13, &be_const_str_memory);
+be_define_const_str(memory, "memory", 2229924270u, 0, 6, &be_const_str_set_auth);
+be_define_const_str(set_auth, "set_auth", 1057170930u, 0, 8, NULL);
+be_define_const_str(content_send_style, "content_send_style", 1087907647u, 0, 18, &be_const_str_class);
+be_define_const_str(class, "class", 2872970239u, 57, 5, NULL);
+be_define_const_str(SERIAL_7E2, "SERIAL_7E2", 97385204u, 0, 10, &be_const_str_shared_key);
+be_define_const_str(shared_key, "shared_key", 2200833624u, 0, 10, &be_const_str_tanh);
+be_define_const_str(tanh, "tanh", 153638352u, 0, 4, &be_const_str_nil);
+be_define_const_str(nil, "nil", 228849900u, 63, 3, NULL);
+be_define_const_str(get_power, "get_power", 3009799377u, 0, 9, &be_const_str_last_modified);
+be_define_const_str(last_modified, "last_modified", 772177145u, 0, 13, &be_const_str_resolvecmnd);
+be_define_const_str(resolvecmnd, "resolvecmnd", 993361485u, 0, 11, NULL);
+be_define_const_str(_read, "_read", 346717030u, 0, 5, NULL);
+be_define_const_str(atan, "atan", 108579519u, 0, 4, &be_const_str_content_button);
+be_define_const_str(content_button, "content_button", 1956476087u, 0, 14, &be_const_str_setbits);
+be_define_const_str(setbits, "setbits", 2762408167u, 0, 7, &be_const_str_upper);
+be_define_const_str(upper, "upper", 176974407u, 0, 5, NULL);
+be_define_const_str(contains, "contains", 1825239352u, 0, 8, &be_const_str_time_str);
+be_define_const_str(time_str, "time_str", 2613827612u, 0, 8, NULL);
+be_define_const_str(arch, "arch", 2952804297u, 0, 4, &be_const_str_fromptr);
+be_define_const_str(fromptr, "fromptr", 666189689u, 0, 7, &be_const_str_push);
+be_define_const_str(push, "push", 2272264157u, 0, 4, &be_const_str_srand);
+be_define_const_str(srand, "srand", 465518633u, 0, 5, NULL);
+be_define_const_str(geti, "geti", 2381006490u, 0, 4, &be_const_str_seti);
+be_define_const_str(seti, "seti", 1500556254u, 0, 4, NULL);
+be_define_const_str(add_cmd, "add_cmd", 3361630879u, 0, 7, &be_const_str_cmd);
+be_define_const_str(cmd, "cmd", 4136785899u, 0, 3, NULL);
+be_define_const_str(get_switch, "get_switch", 164821028u, 0, 10, &be_const_str_size);
+be_define_const_str(size, "size", 597743964u, 0, 4, NULL);
+be_define_const_str(try, "try", 2887626766u, 68, 3, NULL);
+be_define_const_str(web_send, "web_send", 2989941448u, 0, 8, &be_const_str_except);
+be_define_const_str(except, "except", 950914032u, 69, 6, NULL);
+be_define_const_str(SERIAL_5O1, "SERIAL_5O1", 3782657917u, 0, 10, &be_const_str_SERIAL_8E2);
+be_define_const_str(SERIAL_8E2, "SERIAL_8E2", 2421454473u, 0, 10, &be_const_str__available);
+be_define_const_str(_available, "_available", 1306196581u, 0, 10, NULL);
+be_define_const_str(codedump, "codedump", 1786337906u, 0, 8, &be_const_str_wire2);
+be_define_const_str(wire2, "wire2", 3229499038u, 0, 5, NULL);
+be_define_const_str(dump, "dump", 3663001223u, 0, 4, &be_const_str_exec_cmd);
+be_define_const_str(exec_cmd, "exec_cmd", 493567399u, 0, 8, NULL);
+be_define_const_str(add, "add", 993596020u, 0, 3, &be_const_str_exp);
+be_define_const_str(exp, "exp", 1923516200u, 0, 3, &be_const_str_isrunning);
+be_define_const_str(isrunning, "isrunning", 1688182268u, 0, 9, &be_const_str_remove_rule);
+be_define_const_str(remove_rule, "remove_rule", 3456211328u, 0, 11, &be_const_str_run_deferred);
+be_define_const_str(run_deferred, "run_deferred", 371594696u, 0, 12, &be_const_str_scan);
+be_define_const_str(scan, "scan", 3974641896u, 0, 4, &be_const_str_for);
+be_define_const_str(for, "for", 2901640080u, 54, 3, NULL);
+be_define_const_str(set_timer, "set_timer", 2135414533u, 0, 9, &be_const_str_url_encode);
+be_define_const_str(url_encode, "url_encode", 528392145u, 0, 10, NULL);
+be_define_const_str(addr, "addr", 1087856498u, 0, 4, NULL);
+be_define_const_str(__upper__, "__upper__", 3612202883u, 0, 9, &be_const_str_loop);
+be_define_const_str(loop, "loop", 3723446379u, 0, 4, NULL);
+be_define_const_str(AudioGeneratorWAV, "AudioGeneratorWAV", 2746509368u, 0, 17, &be_const_str_chars_in_string);
+be_define_const_str(chars_in_string, "chars_in_string", 3148785132u, 0, 15, &be_const_str_cosh);
+be_define_const_str(cosh, "cosh", 4099687964u, 0, 4, &be_const_str_import);
+be_define_const_str(import, "import", 288002260u, 66, 6, NULL);
+be_define_const_str(SERIAL_5N2, "SERIAL_5N2", 3363364537u, 0, 10, &be_const_str_type);
+be_define_const_str(type, "type", 1361572173u, 0, 4, NULL);
+be_define_const_str(clear, "clear", 1550717474u, 0, 5, NULL);
+be_define_const_str(SERIAL_8N1, "SERIAL_8N1", 2369297235u, 0, 10, &be_const_str_issubclass);
+be_define_const_str(issubclass, "issubclass", 4078395519u, 0, 10, &be_const_str_remove_timer);
+be_define_const_str(remove_timer, "remove_timer", 4141472215u, 0, 12, &be_const_str_sinh);
+be_define_const_str(sinh, "sinh", 282220607u, 0, 4, NULL);
+be_define_const_str(AudioGeneratorMP3, "AudioGeneratorMP3", 2199818488u, 0, 17, &be_const_str_Wire);
+be_define_const_str(Wire, "Wire", 1938276536u, 0, 4, &be_const_str_get_light);
+be_define_const_str(get_light, "get_light", 381930476u, 0, 9, NULL);
+be_define_const_str(get_option, "get_option", 2123730033u, 0, 10, &be_const_str_list);
+be_define_const_str(list, "list", 217798785u, 0, 4, &be_const_str_stop);
+be_define_const_str(stop, "stop", 3411225317u, 0, 4, &be_const_str_try_rule);
+be_define_const_str(try_rule, "try_rule", 1986449405u, 0, 8, NULL);
+be_define_const_str(webclient, "webclient", 4076389146u, 0, 9, NULL);
+be_define_const_str(dot_p2, ".p2", 232398067u, 0, 3, &be_const_str_has);
+be_define_const_str(has, "has", 3988721635u, 0, 3, NULL);
+be_define_const_str(_request_from, "_request_from", 3965148604u, 0, 13, &be_const_str_setrange);
+be_define_const_str(setrange, "setrange", 3794019032u, 0, 8, NULL);
+be_define_const_str(I2C_Driver, "I2C_Driver", 1714501658u, 0, 10, NULL);
+be_define_const_str(ceil, "ceil", 1659167240u, 0, 4, &be_const_str_else);
+be_define_const_str(else, "else", 3183434736u, 52, 4, NULL);
+be_define_const_str(concat, "concat", 4124019837u, 0, 6, &be_const_str_set_power);
+be_define_const_str(set_power, "set_power", 549820893u, 0, 9, NULL);
+be_define_const_str(tomap, "tomap", 612167626u, 0, 5, NULL);
+be_define_const_str(resp_cmnd_error, "resp_cmnd_error", 2404088863u, 0, 15, NULL);
+be_define_const_str(add_header, "add_header", 927130612u, 0, 10, &be_const_str_eth);
+be_define_const_str(eth, "eth", 2191266556u, 0, 3, &be_const_str_write_bit);
+be_define_const_str(write_bit, "write_bit", 2660990436u, 0, 9, NULL);
+be_define_const_str(exists, "exists", 1002329533u, 0, 6, &be_const_str_pow);
+be_define_const_str(pow, "pow", 1479764693u, 0, 3, &be_const_str_select);
+be_define_const_str(select, "select", 297952813u, 0, 6, NULL);
+be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_classof);
+be_define_const_str(classof, "classof", 1796577762u, 0, 7, &be_const_str_if);
+be_define_const_str(if, "if", 959999494u, 50, 2, NULL);
+be_define_const_str(SERIAL_5E1, "SERIAL_5E1", 1163775235u, 0, 10, &be_const_str_arg);
+be_define_const_str(arg, "arg", 1047474471u, 0, 3, &be_const_str_cb_dispatch);
+be_define_const_str(cb_dispatch, "cb_dispatch", 1741510499u, 0, 11, &be_const_str_response_append);
+be_define_const_str(response_append, "response_append", 450346371u, 0, 15, NULL);
+be_define_const_str(pin_used, "pin_used", 4033854612u, 0, 8, &be_const_str_write);
+be_define_const_str(write, "write", 3190202204u, 0, 5, &be_const_str_write8);
+be_define_const_str(write8, "write8", 3133991532u, 0, 6, NULL);
+be_define_const_str(SERIAL_6O2, "SERIAL_6O2", 316486129u, 0, 10, &be_const_str_log);
+be_define_const_str(log, "log", 1062293841u, 0, 3, NULL);
+be_define_const_str(pin_mode, "pin_mode", 3258314030u, 0, 8, &be_const_str_read12);
+be_define_const_str(read12, "read12", 4291076970u, 0, 6, &be_const_str_resp_cmnd_str);
+be_define_const_str(resp_cmnd_str, "resp_cmnd_str", 737845590u, 0, 13, NULL);
+be_define_const_str(abs, "abs", 709362235u, 0, 3, &be_const_str_digital_write);
+be_define_const_str(digital_write, "digital_write", 3435877979u, 0, 13, &be_const_str_static);
+be_define_const_str(static, "static", 3532702267u, 71, 6, NULL);
+be_define_const_str(bytes, "bytes", 1706151940u, 0, 5, &be_const_str_find_op);
+be_define_const_str(find_op, "find_op", 3766713376u, 0, 7, NULL);
+be_define_const_str(call, "call", 3018949801u, 0, 4, NULL);
+be_define_const_str(cmd_res, "cmd_res", 921166762u, 0, 7, NULL);
+be_define_const_str(opt_eq, "==", 2431966415u, 0, 2, NULL);
+be_define_const_str(save, "save", 3439296072u, 0, 4, NULL);
+be_define_const_str(find_key_i, "find_key_i", 850136726u, 0, 10, NULL);
+be_define_const_str(_cb, "_cb", 4043300367u, 0, 3, NULL);
+be_define_const_str(Tasmota, "Tasmota", 4047617668u, 0, 7, &be_const_str_public_key);
+be_define_const_str(public_key, "public_key", 4169142980u, 0, 10, NULL);
+be_define_const_str(as, "as", 1579491469u, 67, 2, NULL);
+be_define_const_str(dot_w, ".w", 1255414514u, 0, 2, &be_const_str_SERIAL_8O1);
+be_define_const_str(SERIAL_8O1, "SERIAL_8O1", 289122742u, 0, 10, &be_const_str_compile);
+be_define_const_str(compile, "compile", 1000265118u, 0, 7, &be_const_str_range);
+be_define_const_str(range, "range", 4208725202u, 0, 5, NULL);
+be_define_const_str(add_rule, "add_rule", 596540743u, 0, 8, NULL);
+be_define_const_str(_ptr, "_ptr", 306235816u, 0, 4, &be_const_str_delay);
+be_define_const_str(delay, "delay", 1322381784u, 0, 5, &be_const_str_pop);
+be_define_const_str(pop, "pop", 1362321360u, 0, 3, &be_const_str_reset);
+be_define_const_str(reset, "reset", 1695364032u, 0, 5, &be_const_str_wire_scan);
+be_define_const_str(wire_scan, "wire_scan", 2671275880u, 0, 9, NULL);
+be_define_const_str(reset_search, "reset_search", 1350414305u, 0, 12, &be_const_str_tolower);
+be_define_const_str(tolower, "tolower", 1042520049u, 0, 7, NULL);
+be_define_const_str(SERIAL_7O2, "SERIAL_7O2", 1840580294u, 0, 10, &be_const_str_asin);
+be_define_const_str(asin, "asin", 4272848550u, 0, 4, &be_const_str_nan);
+be_define_const_str(nan, "nan", 797905850u, 0, 3, NULL);
+be_define_const_str(deg, "deg", 3327754271u, 0, 3, NULL);
+be_define_const_str(log10, "log10", 2346846000u, 0, 5, NULL);
+be_define_const_str(char, "char", 2823553821u, 0, 4, &be_const_str_get_size);
+be_define_const_str(get_size, "get_size", 2803644713u, 0, 8, NULL);
+be_define_const_str(opt_call, "()", 685372826u, 0, 2, &be_const_str_end);
+be_define_const_str(end, "end", 1787721130u, 56, 3, NULL);
+be_define_const_str(SERIAL_7N2, "SERIAL_7N2", 1874282627u, 0, 10, &be_const_str_time_dump);
+be_define_const_str(time_dump, "time_dump", 3330410747u, 0, 9, NULL);
+be_define_const_str(listdir, "listdir", 2005220720u, 0, 7, &be_const_str_wifi);
+be_define_const_str(wifi, "wifi", 120087624u, 0, 4, NULL);
+be_define_const_str(read_bytes, "read_bytes", 3576733173u, 0, 10, &be_const_str_reverse);
+be_define_const_str(reverse, "reverse", 558918661u, 0, 7, NULL);
+be_define_const_str(SERIAL_6E1, "SERIAL_6E1", 334249486u, 0, 10, NULL);
+be_define_const_str(SERIAL_5O2, "SERIAL_5O2", 3732325060u, 0, 10, &be_const_str_SERIAL_8E1);
+be_define_const_str(SERIAL_8E1, "SERIAL_8E1", 2371121616u, 0, 10, &be_const_str_asstring);
+be_define_const_str(asstring, "asstring", 1298225088u, 0, 8, &be_const_str_deinit);
+be_define_const_str(deinit, "deinit", 2345559592u, 0, 6, NULL);
+be_define_const_str(encrypt, "encrypt", 2194327650u, 0, 7, NULL);
+be_define_const_str(iter, "iter", 3124256359u, 0, 4, &be_const_str_millis);
+be_define_const_str(millis, "millis", 1214679063u, 0, 6, NULL);
+be_define_const_str(AudioOutput, "AudioOutput", 3257792048u, 0, 11, &be_const_str_members);
+be_define_const_str(members, "members", 937576464u, 0, 7, &be_const_str_rtc);
+be_define_const_str(rtc, "rtc", 1070575216u, 0, 3, NULL);
+be_define_const_str(SERIAL_6N1, "SERIAL_6N1", 198895701u, 0, 10, &be_const_str__write);
+be_define_const_str(_write, "_write", 2215462825u, 0, 6, &be_const_str_content_start);
+be_define_const_str(content_start, "content_start", 2937509069u, 0, 13, &be_const_str_module);
+be_define_const_str(module, "module", 3617558685u, 0, 6, NULL);
+be_define_const_str(item, "item", 2671260646u, 0, 4, &be_const_str_remove_cmd);
+be_define_const_str(remove_cmd, "remove_cmd", 3832315702u, 0, 10, NULL);
+be_define_const_str(MD5, "MD5", 1935726387u, 0, 3, &be_const_str_sqrt);
+be_define_const_str(sqrt, "sqrt", 2112764879u, 0, 4, NULL);
+be_define_const_str(SERIAL_5N1, "SERIAL_5N1", 3313031680u, 0, 10, &be_const_str_break);
+be_define_const_str(break, "break", 3378807160u, 58, 5, NULL);
+be_define_const_str(map, "map", 3751997361u, 0, 3, &be_const_str_setmember);
+be_define_const_str(setmember, "setmember", 1432909441u, 0, 9, &be_const_str_tostring);
be_define_const_str(tostring, "tostring", 2299708645u, 0, 8, NULL);
+be_define_const_str(AudioGenerator, "AudioGenerator", 1839297342u, 0, 14, &be_const_str_while);
+be_define_const_str(while, "while", 231090382u, 53, 5, NULL);
+be_define_const_str(event, "event", 4264611999u, 0, 5, &be_const_str_resp_cmnd_done);
+be_define_const_str(resp_cmnd_done, "resp_cmnd_done", 2601874875u, 0, 14, NULL);
+be_define_const_str(AudioOutputI2S, "AudioOutputI2S", 638031784u, 0, 14, &be_const_str_has_arg);
+be_define_const_str(has_arg, "has_arg", 424878688u, 0, 7, NULL);
+be_define_const_str(floor, "floor", 3102149661u, 0, 5, &be_const_str_read);
+be_define_const_str(read, "read", 3470762949u, 0, 4, &be_const_str_remove);
+be_define_const_str(remove, "remove", 3683784189u, 0, 6, NULL);
+be_define_const_str(calldepth, "calldepth", 3122364302u, 0, 9, &be_const_str_lower);
+be_define_const_str(lower, "lower", 3038577850u, 0, 5, &be_const_str_path);
+be_define_const_str(path, "path", 2223459638u, 0, 4, NULL);
+be_define_const_str(gamma10, "gamma10", 3472052483u, 0, 7, &be_const_str_get);
+be_define_const_str(get, "get", 1410115415u, 0, 3, &be_const_str_elif);
+be_define_const_str(elif, "elif", 3232090307u, 51, 4, NULL);
+be_define_const_str(_buffer, "_buffer", 2044888568u, 0, 7, &be_const_str_exec_rules);
+be_define_const_str(exec_rules, "exec_rules", 1445221092u, 0, 10, &be_const_str_pin);
+be_define_const_str(pin, "pin", 1866532500u, 0, 3, NULL);
+be_define_const_str(collect, "collect", 2399039025u, 0, 7, NULL);
+be_define_const_str(enabled, "enabled", 49525662u, 0, 7, &be_const_str_global);
+be_define_const_str(global, "global", 503252654u, 0, 6, NULL);
+be_define_const_str(acos, "acos", 1006755615u, 0, 4, &be_const_str_content_stop);
+be_define_const_str(content_stop, "content_stop", 658554751u, 0, 12, &be_const_str_read8);
+be_define_const_str(read8, "read8", 2802788167u, 0, 5, &be_const_str_wire1);
+be_define_const_str(wire1, "wire1", 3212721419u, 0, 5, NULL);
+be_define_const_str(fromstring, "fromstring", 610302344u, 0, 10, &be_const_str_setitem);
+be_define_const_str(setitem, "setitem", 1554834596u, 0, 7, NULL);
+be_define_const_str(_debug_present, "_debug_present", 4063411725u, 0, 14, &be_const_str_erase);
+be_define_const_str(erase, "erase", 1010949589u, 0, 5, &be_const_str_i2c_enabled);
+be_define_const_str(i2c_enabled, "i2c_enabled", 218388101u, 0, 11, &be_const_str_resize);
+be_define_const_str(resize, "resize", 3514612129u, 0, 6, NULL);
+be_define_const_str(decrypt, "decrypt", 2886974618u, 0, 7, &be_const_str_escape);
+be_define_const_str(escape, "escape", 2652972038u, 0, 6, &be_const_str_isnan);
+be_define_const_str(isnan, "isnan", 2981347434u, 0, 5, &be_const_str_skip);
+be_define_const_str(skip, "skip", 1097563074u, 0, 4, &be_const_str_var);
+be_define_const_str(var, "var", 2317739966u, 64, 3, NULL);
+be_define_const_str(dot_p, ".p", 1171526419u, 0, 2, &be_const_str_write_file);
+be_define_const_str(write_file, "write_file", 3177658879u, 0, 10, NULL);
+be_define_const_str(copy, "copy", 3848464964u, 0, 4, &be_const_str_str);
+be_define_const_str(str, "str", 3259748752u, 0, 3, &be_const_str_super);
+be_define_const_str(super, "super", 4152230356u, 0, 5, &be_const_str_update);
+be_define_const_str(update, "update", 672109684u, 0, 6, NULL);
+be_define_const_str(_def, "_def", 1985022181u, 0, 4, &be_const_str__drivers);
+be_define_const_str(_drivers, "_drivers", 3260328985u, 0, 8, NULL);
+be_define_const_str(imax, "imax", 3084515410u, 0, 4, NULL);
+be_define_const_str(add_driver, "add_driver", 1654458371u, 0, 10, NULL);
+be_define_const_str(dot_len, ".len", 850842136u, 0, 4, &be_const_str_SERIAL_6O1);
+be_define_const_str(SERIAL_6O1, "SERIAL_6O1", 266153272u, 0, 10, &be_const_str_attrdump);
+be_define_const_str(attrdump, "attrdump", 1521571304u, 0, 8, &be_const_str_on);
+be_define_const_str(on, "on", 1630810064u, 0, 2, &be_const_str_rad);
+be_define_const_str(rad, "rad", 1358899048u, 0, 3, NULL);
+be_define_const_str(bus, "bus", 1607822841u, 0, 3, NULL);
+be_define_const_str(yield, "yield", 1821831854u, 0, 5, NULL);
+be_define_const_str(top, "top", 2802900028u, 0, 3, NULL);
+be_define_const_str(get_string, "get_string", 4195847969u, 0, 10, &be_const_str_read_sensors);
+be_define_const_str(read_sensors, "read_sensors", 892689201u, 0, 12, NULL);
+be_define_const_str(settings, "settings", 1745255176u, 0, 8, NULL);
+be_define_const_str(_get_cb, "_get_cb", 1448849122u, 0, 7, &be_const_str_int);
+be_define_const_str(int, "int", 2515107422u, 0, 3, NULL);
+be_define_const_str(opt_neq, "!=", 2428715011u, 0, 2, &be_const_str_gen_cb);
+be_define_const_str(gen_cb, "gen_cb", 3245227551u, 0, 6, NULL);
+be_define_const_str(_timers, "_timers", 2600100916u, 0, 7, &be_const_str_continue);
+be_define_const_str(continue, "continue", 2977070660u, 59, 8, NULL);
+be_define_const_str(SERIAL_7E1, "SERIAL_7E1", 147718061u, 0, 10, NULL);
+be_define_const_str(AudioFileSource, "AudioFileSource", 2959980058u, 0, 15, &be_const_str_format);
+be_define_const_str(format, "format", 3114108242u, 0, 6, NULL);
+be_define_const_str(EC_C25519, "EC_C25519", 95492591u, 0, 9, &be_const_str_close);
+be_define_const_str(close, "close", 667630371u, 0, 5, &be_const_str_content_flush);
+be_define_const_str(content_flush, "content_flush", 214922475u, 0, 13, &be_const_str_reduce);
+be_define_const_str(reduce, "reduce", 2002030311u, 0, 6, &be_const_str_tr);
+be_define_const_str(tr, "tr", 1195724803u, 0, 2, NULL);
+be_define_const_str(available, "available", 1727918744u, 0, 9, NULL);
+be_define_const_str(traceback, "traceback", 3385188109u, 0, 9, NULL);
+be_define_const_str(opt_add, "+", 772578730u, 0, 1, &be_const_str_SERIAL_8N2);
+be_define_const_str(SERIAL_8N2, "SERIAL_8N2", 2386074854u, 0, 10, &be_const_str_wd);
+be_define_const_str(wd, "wd", 1531424278u, 0, 2, NULL);
+be_define_const_str(__iterator__, "__iterator__", 3884039703u, 0, 12, &be_const_str_fromb64);
+be_define_const_str(fromb64, "fromb64", 2717019639u, 0, 7, NULL);
+be_define_const_str(number, "number", 467038368u, 0, 6, &be_const_str_print);
+be_define_const_str(print, "print", 372738696u, 0, 5, &be_const_str_set_useragent);
+be_define_const_str(set_useragent, "set_useragent", 612237244u, 0, 13, &be_const_str_tan);
+be_define_const_str(tan, "tan", 2633446552u, 0, 3, &be_const_str_do);
+be_define_const_str(do, "do", 1646057492u, 65, 2, NULL);
+be_define_const_str(, "", 2166136261u, 0, 0, &be_const_str_opt_connect);
+be_define_const_str(opt_connect, "..", 2748622605u, 0, 2, &be_const_str__rules);
+be_define_const_str(_rules, "_rules", 4266217105u, 0, 6, NULL);
+be_define_const_str(dot_p1, ".p1", 249175686u, 0, 3, &be_const_str_find);
+be_define_const_str(find, "find", 3186656602u, 0, 4, &be_const_str_name);
+be_define_const_str(name, "name", 2369371622u, 0, 4, &be_const_str_toptr);
+be_define_const_str(toptr, "toptr", 3379847454u, 0, 5, NULL);
+be_define_const_str(arg_name, "arg_name", 1345046155u, 0, 8, &be_const_str_byte);
+be_define_const_str(byte, "byte", 1683620383u, 0, 4, &be_const_str_gc);
+be_define_const_str(gc, "gc", 1042313471u, 0, 2, NULL);
+be_define_const_str(count, "count", 967958004u, 0, 5, &be_const_str_counters);
+be_define_const_str(counters, "counters", 4095866864u, 0, 8, &be_const_str_tob64);
+be_define_const_str(tob64, "tob64", 373777640u, 0, 5, NULL);
+be_define_const_str(AudioFileSourceFS, "AudioFileSourceFS", 1839147653u, 0, 17, &be_const_str_get_free_heap);
+be_define_const_str(get_free_heap, "get_free_heap", 625069757u, 0, 13, NULL);
+be_define_const_str(atan2, "atan2", 3173440503u, 0, 5, NULL);
+be_define_const_str(set_timeouts, "set_timeouts", 3732850900u, 0, 12, &be_const_str_toupper);
+be_define_const_str(toupper, "toupper", 3691983576u, 0, 7, NULL);
+be_define_const_str(_ccmd, "_ccmd", 2163421413u, 0, 5, &be_const_str_content_send);
+be_define_const_str(content_send, "content_send", 1673733649u, 0, 12, &be_const_str_flush);
+be_define_const_str(flush, "flush", 3002334877u, 0, 5, &be_const_str_true);
+be_define_const_str(true, "true", 1303515621u, 61, 4, NULL);
+be_define_const_str(detect, "detect", 8884370u, 0, 6, NULL);
+be_define_const_str(SERIAL_8O2, "SERIAL_8O2", 272345123u, 0, 10, &be_const_str_split);
+be_define_const_str(split, "split", 2276994531u, 0, 5, NULL);
static const bstring* const m_string_table[] = {
- (const bstring *)&be_const_str_pow,
- (const bstring *)&be_const_str_MD5,
- (const bstring *)&be_const_str_dot_p2,
- (const bstring *)&be_const_str_atan,
- (const bstring *)&be_const_str_SERIAL_6N1,
- (const bstring *)&be_const_str_content_start,
- (const bstring *)&be_const_str_SERIAL_8N2,
- (const bstring *)&be_const_str_content_send_style,
- NULL,
- (const bstring *)&be_const_str__begin_transmission,
- (const bstring *)&be_const_str_number,
- (const bstring *)&be_const_str_exec_rules,
- (const bstring *)&be_const_str_GET,
- (const bstring *)&be_const_str_I2C_Driver,
- NULL,
- (const bstring *)&be_const_str_opt_neq,
- (const bstring *)&be_const_str_last_modified,
- (const bstring *)&be_const_str_add,
- (const bstring *)&be_const_str_rtc,
- (const bstring *)&be_const_str_EC_C25519,
- (const bstring *)&be_const_str_ceil,
- (const bstring *)&be_const_str_log,
- (const bstring *)&be_const_str__global_def,
- (const bstring *)&be_const_str_atan2,
- (const bstring *)&be_const_str_deinit,
- (const bstring *)&be_const_str_SERIAL_8O1,
- (const bstring *)&be_const_str_SERIAL_6O1,
- (const bstring *)&be_const_str_SERIAL_6E2,
- (const bstring *)&be_const_str_gc,
- (const bstring *)&be_const_str_continue,
- NULL,
- (const bstring *)&be_const_str_dot_p1,
- (const bstring *)&be_const_str_chars_in_string,
- NULL,
- (const bstring *)&be_const_str_traceback,
- (const bstring *)&be_const_str_calldepth,
- (const bstring *)&be_const_str_finish,
- (const bstring *)&be_const_str_read,
- (const bstring *)&be_const_str_Tasmota,
- (const bstring *)&be_const_str_SERIAL_7E2,
- (const bstring *)&be_const_str___lower__,
- (const bstring *)&be_const_str_member,
- (const bstring *)&be_const_str_codedump,
- (const bstring *)&be_const_str_opt_call,
- NULL,
- (const bstring *)&be_const_str_attrdump,
- (const bstring *)&be_const_str_AudioOutput,
- (const bstring *)&be_const_str_SERIAL_5O1,
- (const bstring *)&be_const_str_public_key,
- (const bstring *)&be_const_str_i2c_enabled,
- (const bstring *)&be_const_str_fromptr,
- (const bstring *)&be_const_str__drivers,
- (const bstring *)&be_const_str_loop,
- (const bstring *)&be_const_str_add_cmd,
- (const bstring *)&be_const_str__settings_ptr,
- (const bstring *)&be_const_str__ptr,
- (const bstring *)&be_const_str_SERIAL_6E1,
- (const bstring *)&be_const_str_true,
- (const bstring *)&be_const_str_opt_eq,
- (const bstring *)&be_const_str__timers,
- (const bstring *)&be_const_str_opt_connect,
- (const bstring *)&be_const_str_deg,
- (const bstring *)&be_const_str_SERIAL_8E1,
- NULL,
- NULL,
- NULL,
- (const bstring *)&be_const_str_dot_len,
- NULL,
- (const bstring *)&be_const_str_enabled,
- (const bstring *)&be_const_str_AudioOutputI2S,
- (const bstring *)&be_const_str_isrunning,
- (const bstring *)&be_const_str_AudioFileSourceFS,
- (const bstring *)&be_const_str_dac_voltage,
+ (const bstring *)&be_const_str_SERIAL_6N2,
(const bstring *)&be_const_str_time_reached,
- (const bstring *)&be_const_str_read24,
- (const bstring *)&be_const_str__global_addr,
+ (const bstring *)&be_const_str_SERIAL_5E2,
(const bstring *)&be_const_str_SERIAL_7O1,
(const bstring *)&be_const_str_dot_size,
- (const bstring *)&be_const_str_gamma10,
- (const bstring *)&be_const_str_ctypes_bytes_dyn,
- (const bstring *)&be_const_str_SERIAL_6N2,
- NULL,
- (const bstring *)&be_const_str_copy,
- (const bstring *)&be_const_str_POST,
- (const bstring *)&be_const_str_,
- (const bstring *)&be_const_str_allocated,
- NULL,
- (const bstring *)&be_const_str_dot_w,
- (const bstring *)&be_const_str_format,
- (const bstring *)&be_const_str_SERIAL_5E2,
- (const bstring *)&be_const_str_abs,
- (const bstring *)&be_const_str_OneWire,
- (const bstring *)&be_const_str_module,
- (const bstring *)&be_const_str_counters,
- (const bstring *)&be_const_str_tanh,
- (const bstring *)&be_const_str_get_string,
- (const bstring *)&be_const_str_seti,
- (const bstring *)&be_const_str_cmd,
- (const bstring *)&be_const_str_SERIAL_7N1,
- (const bstring *)&be_const_str_get_option,
- (const bstring *)&be_const_str_check_privileged_access,
- NULL,
- (const bstring *)&be_const_str_pin_mode,
- (const bstring *)&be_const_str_pin,
- (const bstring *)&be_const_str__buffer,
- (const bstring *)&be_const_str_dot_p,
- (const bstring *)&be_const_str_real,
- (const bstring *)&be_const_str_set_timer,
- (const bstring *)&be_const_str_count,
- (const bstring *)&be_const_str__settings_def,
- (const bstring *)&be_const_str_path,
- (const bstring *)&be_const_str_delay,
- (const bstring *)&be_const_str_AES_GCM,
- (const bstring *)&be_const_str_SERIAL_6O2,
- (const bstring *)&be_const_str_write_bit,
- (const bstring *)&be_const_str_state,
- (const bstring *)&be_const_str_set_useragent,
- (const bstring *)&be_const_str_erase,
- (const bstring *)&be_const_str_AudioGeneratorWAV,
- (const bstring *)&be_const_str_SERIAL_5N1,
- (const bstring *)&be_const_str_find_key_i,
- NULL,
- (const bstring *)&be_const_str_arg,
- (const bstring *)&be_const_str_SERIAL_5O2,
- (const bstring *)&be_const_str_exec_tele,
- (const bstring *)&be_const_str_set_light,
- (const bstring *)&be_const_str_AudioGenerator,
- (const bstring *)&be_const_str_content_button,
- (const bstring *)&be_const_str_arch,
- (const bstring *)&be_const_str_content_flush,
- (const bstring *)&be_const_str_event,
- NULL,
- (const bstring *)&be_const_str_opt_add,
- (const bstring *)&be_const_str_acos,
- (const bstring *)&be_const_str_encrypt,
- (const bstring *)&be_const_str_cmd_res,
- NULL,
- (const bstring *)&be_const_str_arg_size,
- (const bstring *)&be_const_str_close,
- (const bstring *)&be_const_str_assert,
- (const bstring *)&be_const_str_AudioFileSource,
- (const bstring *)&be_const_str_add_header,
- NULL,
- (const bstring *)&be_const_str_has,
- (const bstring *)&be_const_str___upper__,
- (const bstring *)&be_const_str_ctypes_bytes,
- NULL,
- (const bstring *)&be_const_str_arg_name,
- (const bstring *)&be_const_str_load,
- (const bstring *)&be_const_str_SERIAL_8E2,
- (const bstring *)&be_const_str__get_cb,
- (const bstring *)&be_const_str_iter,
NULL,
(const bstring *)&be_const_str__cmd,
- (const bstring *)&be_const_str_AudioGeneratorMP3,
- (const bstring *)&be_const_str_get_switch,
- (const bstring *)&be_const_str__available,
- (const bstring *)&be_const_str_false,
- (const bstring *)&be_const_str_settings,
- (const bstring *)&be_const_str_SERIAL_8O2,
+ (const bstring *)&be_const_str_assert,
+ (const bstring *)&be_const_str_check_privileged_access,
+ (const bstring *)&be_const_str_load,
+ (const bstring *)&be_const_str_dac_voltage,
+ (const bstring *)&be_const_str_POST,
+ (const bstring *)&be_const_str_classname,
+ (const bstring *)&be_const_str__global_def,
+ (const bstring *)&be_const_str_AES_GCM,
+ (const bstring *)&be_const_str_strftime,
+ (const bstring *)&be_const_str_insert,
+ (const bstring *)&be_const_str_arg_size,
+ (const bstring *)&be_const_str_OneWire,
+ (const bstring *)&be_const_str_return,
+ (const bstring *)&be_const_str_wire,
+ (const bstring *)&be_const_str__global_addr,
+ (const bstring *)&be_const_str_gamma8,
+ (const bstring *)&be_const_str_depower,
+ (const bstring *)&be_const_str__end_transmission,
+ (const bstring *)&be_const_str_hs2rgb,
+ (const bstring *)&be_const_str_SERIAL_7N1,
+ (const bstring *)&be_const_str_ctypes_bytes,
NULL,
- (const bstring *)&be_const_str_kv,
- (const bstring *)&be_const_str_memory
+ NULL,
+ NULL,
+ (const bstring *)&be_const_str_GET,
+ (const bstring *)&be_const_str_cos,
+ NULL,
+ (const bstring *)&be_const_str__settings_ptr,
+ (const bstring *)&be_const_str_content_send_style,
+ (const bstring *)&be_const_str_SERIAL_7E2,
+ (const bstring *)&be_const_str_get_power,
+ (const bstring *)&be_const_str__read,
+ (const bstring *)&be_const_str_atan,
+ (const bstring *)&be_const_str_contains,
+ (const bstring *)&be_const_str_arch,
+ (const bstring *)&be_const_str_geti,
+ (const bstring *)&be_const_str_add_cmd,
+ (const bstring *)&be_const_str_get_switch,
+ NULL,
+ (const bstring *)&be_const_str_try,
+ NULL,
+ (const bstring *)&be_const_str_web_send,
+ (const bstring *)&be_const_str_SERIAL_5O1,
+ (const bstring *)&be_const_str_codedump,
+ (const bstring *)&be_const_str_dump,
+ (const bstring *)&be_const_str_add,
+ (const bstring *)&be_const_str_set_timer,
+ (const bstring *)&be_const_str_addr,
+ (const bstring *)&be_const_str___upper__,
+ (const bstring *)&be_const_str_AudioGeneratorWAV,
+ (const bstring *)&be_const_str_SERIAL_5N2,
+ (const bstring *)&be_const_str_clear,
+ (const bstring *)&be_const_str_SERIAL_8N1,
+ (const bstring *)&be_const_str_AudioGeneratorMP3,
+ (const bstring *)&be_const_str_get_option,
+ (const bstring *)&be_const_str_webclient,
+ (const bstring *)&be_const_str_dot_p2,
+ (const bstring *)&be_const_str__request_from,
+ NULL,
+ (const bstring *)&be_const_str_I2C_Driver,
+ NULL,
+ (const bstring *)&be_const_str_ceil,
+ (const bstring *)&be_const_str_concat,
+ (const bstring *)&be_const_str_tomap,
+ (const bstring *)&be_const_str_resp_cmnd_error,
+ (const bstring *)&be_const_str_add_header,
+ (const bstring *)&be_const_str_exists,
+ (const bstring *)&be_const_str_allocated,
+ (const bstring *)&be_const_str_SERIAL_5E1,
+ (const bstring *)&be_const_str_pin_used,
+ (const bstring *)&be_const_str_SERIAL_6O2,
+ (const bstring *)&be_const_str_pin_mode,
+ (const bstring *)&be_const_str_abs,
+ (const bstring *)&be_const_str_bytes,
+ (const bstring *)&be_const_str_call,
+ (const bstring *)&be_const_str_cmd_res,
+ (const bstring *)&be_const_str_opt_eq,
+ (const bstring *)&be_const_str_save,
+ NULL,
+ (const bstring *)&be_const_str_find_key_i,
+ (const bstring *)&be_const_str__cb,
+ (const bstring *)&be_const_str_Tasmota,
+ (const bstring *)&be_const_str_as,
+ (const bstring *)&be_const_str_dot_w,
+ (const bstring *)&be_const_str_add_rule,
+ (const bstring *)&be_const_str__ptr,
+ (const bstring *)&be_const_str_reset_search,
+ (const bstring *)&be_const_str_SERIAL_7O2,
+ (const bstring *)&be_const_str_deg,
+ (const bstring *)&be_const_str_log10,
+ (const bstring *)&be_const_str_char,
+ (const bstring *)&be_const_str_opt_call,
+ (const bstring *)&be_const_str_SERIAL_7N2,
+ (const bstring *)&be_const_str_listdir,
+ (const bstring *)&be_const_str_read_bytes,
+ (const bstring *)&be_const_str_SERIAL_6E1,
+ NULL,
+ (const bstring *)&be_const_str_SERIAL_5O2,
+ NULL,
+ (const bstring *)&be_const_str_encrypt,
+ (const bstring *)&be_const_str_iter,
+ (const bstring *)&be_const_str_AudioOutput,
+ (const bstring *)&be_const_str_SERIAL_6N1,
+ (const bstring *)&be_const_str_item,
+ (const bstring *)&be_const_str_MD5,
+ (const bstring *)&be_const_str_SERIAL_5N1,
+ (const bstring *)&be_const_str_map,
+ (const bstring *)&be_const_str_AudioGenerator,
+ (const bstring *)&be_const_str_event,
+ (const bstring *)&be_const_str_AudioOutputI2S,
+ (const bstring *)&be_const_str_floor,
+ (const bstring *)&be_const_str_calldepth,
+ (const bstring *)&be_const_str_gamma10,
+ (const bstring *)&be_const_str__buffer,
+ (const bstring *)&be_const_str_collect,
+ (const bstring *)&be_const_str_enabled,
+ (const bstring *)&be_const_str_acos,
+ (const bstring *)&be_const_str_fromstring,
+ (const bstring *)&be_const_str__debug_present,
+ (const bstring *)&be_const_str_decrypt,
+ (const bstring *)&be_const_str_dot_p,
+ (const bstring *)&be_const_str_copy,
+ (const bstring *)&be_const_str__def,
+ (const bstring *)&be_const_str_imax,
+ (const bstring *)&be_const_str_add_driver,
+ (const bstring *)&be_const_str_dot_len,
+ (const bstring *)&be_const_str_bus,
+ (const bstring *)&be_const_str_yield,
+ NULL,
+ (const bstring *)&be_const_str_top,
+ (const bstring *)&be_const_str_get_string,
+ NULL,
+ NULL,
+ (const bstring *)&be_const_str_settings,
+ NULL,
+ (const bstring *)&be_const_str__get_cb,
+ (const bstring *)&be_const_str_opt_neq,
+ (const bstring *)&be_const_str__timers,
+ (const bstring *)&be_const_str_SERIAL_7E1,
+ (const bstring *)&be_const_str_AudioFileSource,
+ (const bstring *)&be_const_str_EC_C25519,
+ (const bstring *)&be_const_str_available,
+ (const bstring *)&be_const_str_traceback,
+ (const bstring *)&be_const_str_opt_add,
+ (const bstring *)&be_const_str___iterator__,
+ (const bstring *)&be_const_str_number,
+ (const bstring *)&be_const_str_,
+ (const bstring *)&be_const_str_dot_p1,
+ (const bstring *)&be_const_str_arg_name,
+ (const bstring *)&be_const_str_count,
+ (const bstring *)&be_const_str_AudioFileSourceFS,
+ NULL,
+ (const bstring *)&be_const_str_atan2,
+ (const bstring *)&be_const_str_set_timeouts,
+ (const bstring *)&be_const_str__ccmd,
+ (const bstring *)&be_const_str_detect,
+ (const bstring *)&be_const_str_SERIAL_8O2
};
static const struct bconststrtab m_const_string_table = {
- .size = 163,
- .count = 327,
+ .size = 164,
+ .count = 328,
.table = m_string_table
};
diff --git a/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h b/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
index c24ab2782..c931a3bc0 100644
--- a/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
+++ b/lib/libesp32/Berry/generate/be_fixed_be_class_tasmota.h
@@ -1,94 +1,95 @@
#include "be_constobj.h"
static be_define_const_map_slots(be_class_tasmota_map) {
- { be_const_key(cmd_res, -1), be_const_var(0) },
- { be_const_key(run_deferred, -1), be_const_closure(run_deferred_closure) },
- { be_const_key(set_light, -1), be_const_closure(set_light_closure) },
- { be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
- { be_const_key(_timers, -1), be_const_var(1) },
- { be_const_key(try_rule, -1), be_const_closure(try_rule_closure) },
- { be_const_key(time_dump, -1), be_const_func(l_time_dump) },
- { be_const_key(_rules, 73), be_const_var(2) },
- { be_const_key(get_switch, 21), be_const_func(l_getswitch) },
- { be_const_key(get_option, -1), be_const_func(l_getoption) },
- { be_const_key(find_op, 4), be_const_closure(find_op_closure) },
- { be_const_key(wire1, -1), be_const_var(3) },
- { be_const_key(resp_cmnd_failed, 29), be_const_func(l_respCmndFailed) },
- { be_const_key(exec_cmd, -1), be_const_closure(exec_cmd_closure) },
- { be_const_key(gen_cb, -1), be_const_closure(gen_cb_closure) },
- { be_const_key(_cb, 57), be_const_var(4) },
- { be_const_key(hs2rgb, 71), be_const_closure(hs2rgb_closure) },
- { be_const_key(gc, -1), be_const_closure(gc_closure) },
- { be_const_key(kv, -1), be_const_closure(kv_closure) },
- { be_const_key(add_rule, -1), be_const_closure(add_rule_closure) },
- { be_const_key(scale_uint, -1), be_const_func(l_scaleuint) },
- { be_const_key(global, -1), be_const_var(5) },
- { be_const_key(rtc, 0), be_const_func(l_rtc) },
- { be_const_key(get_power, -1), be_const_func(l_getpower) },
- { be_const_key(wd, -1), be_const_var(6) },
- { be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
- { be_const_key(resp_cmnd_error, -1), be_const_func(l_respCmndError) },
- { be_const_key(read_sensors, 56), be_const_func(l_read_sensors) },
- { be_const_key(settings, -1), be_const_var(7) },
- { be_const_key(chars_in_string, -1), be_const_closure(chars_in_string_closure) },
- { be_const_key(save, -1), be_const_func(l_save) },
- { be_const_key(set_timer, -1), be_const_closure(set_timer_closure) },
- { be_const_key(time_str, -1), be_const_closure(time_str_closure) },
- { be_const_key(response_append, 14), be_const_func(l_respAppend) },
- { be_const_key(remove_driver, -1), be_const_closure(remove_driver_closure) },
- { be_const_key(i2c_enabled, -1), be_const_func(l_i2cenabled) },
- { be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
- { be_const_key(load, -1), be_const_closure(load_closure) },
- { be_const_key(_settings_ptr, 55), be_const_comptr(&Settings) },
- { be_const_key(millis, 23), be_const_func(l_millis) },
- { be_const_key(event, 67), be_const_closure(event_closure) },
- { be_const_key(cmd, -1), be_const_closure(cmd_closure) },
- { be_const_key(publish_result, 60), be_const_func(l_publish_result) },
- { be_const_key(_drivers, -1), be_const_var(8) },
- { be_const_key(get_light, 1), be_const_closure(get_light_closure) },
- { be_const_key(init, -1), be_const_closure(init_closure) },
- { be_const_key(remove_cmd, 24), be_const_closure(remove_cmd_closure) },
- { be_const_key(time_reached, -1), be_const_func(l_timereached) },
- { be_const_key(_cmd, 68), be_const_func(l_cmd) },
- { be_const_key(remove_timer, -1), be_const_closure(remove_timer_closure) },
- { be_const_key(remove_rule, 70), be_const_closure(remove_rule_closure) },
- { be_const_key(resolvecmnd, 41), be_const_func(l_resolveCmnd) },
- { be_const_key(web_send, 38), be_const_func(l_webSend) },
- { be_const_key(cb_dispatch, 6), be_const_closure(cb_dispatch_closure) },
- { be_const_key(memory, -1), be_const_func(l_memory) },
- { be_const_key(wire_scan, -1), be_const_closure(wire_scan_closure) },
- { be_const_key(strftime, 16), be_const_func(l_strftime) },
{ be_const_key(resp_cmnd_done, -1), be_const_func(l_respCmndDone) },
- { be_const_key(_get_cb, -1), be_const_func(l_get_cb) },
+ { be_const_key(resolvecmnd, 42), be_const_func(l_resolveCmnd) },
{ be_const_key(add_driver, -1), be_const_closure(add_driver_closure) },
- { be_const_key(exec_rules, -1), be_const_closure(exec_rules_closure) },
- { be_const_key(add_cmd, -1), be_const_closure(add_cmd_closure) },
- { be_const_key(find_key_i, -1), be_const_closure(find_key_i_closure) },
- { be_const_key(log, 40), be_const_func(l_logInfo) },
- { be_const_key(wire2, -1), be_const_var(9) },
- { be_const_key(get_free_heap, -1), be_const_func(l_getFreeHeap) },
- { be_const_key(resp_cmnd_str, -1), be_const_func(l_respCmndStr) },
+ { be_const_key(gc, -1), be_const_closure(gc_closure) },
+ { be_const_key(find_op, -1), be_const_closure(find_op_closure) },
+ { be_const_key(scale_uint, 15), be_const_func(l_scaleuint) },
+ { be_const_key(try_rule, -1), be_const_closure(try_rule_closure) },
+ { be_const_key(time_reached, -1), be_const_func(l_timereached) },
+ { be_const_key(web_send, -1), be_const_func(l_webSend) },
+ { be_const_key(eth, 21), be_const_func(l_eth) },
+ { be_const_key(get_switch, 34), be_const_func(l_getswitch) },
{ be_const_key(set_power, -1), be_const_func(l_setpower) },
- { be_const_key(delay, -1), be_const_func(l_delay) },
+ { be_const_key(_drivers, 50), be_const_var(0) },
+ { be_const_key(_rules, -1), be_const_var(1) },
+ { be_const_key(_ccmd, 6), be_const_var(2) },
+ { be_const_key(time_dump, -1), be_const_func(l_time_dump) },
+ { be_const_key(gen_cb, 17), be_const_closure(gen_cb_closure) },
+ { be_const_key(cmd_res, 20), be_const_var(3) },
+ { be_const_key(set_light, 63), be_const_closure(set_light_closure) },
+ { be_const_key(millis, -1), be_const_func(l_millis) },
+ { be_const_key(global, -1), be_const_var(4) },
+ { be_const_key(exec_tele, 67), be_const_closure(exec_tele_closure) },
+ { be_const_key(_settings_ptr, -1), be_const_comptr(&Settings) },
+ { be_const_key(get_power, -1), be_const_func(l_getpower) },
+ { be_const_key(_cb, 57), be_const_var(5) },
+ { be_const_key(save, -1), be_const_func(l_save) },
+ { be_const_key(run_deferred, -1), be_const_closure(run_deferred_closure) },
+ { be_const_key(i2c_enabled, 9), be_const_func(l_i2cenabled) },
+ { be_const_key(remove_driver, -1), be_const_closure(remove_driver_closure) },
+ { be_const_key(event, -1), be_const_closure(event_closure) },
+ { be_const_key(find_key_i, -1), be_const_closure(find_key_i_closure) },
+ { be_const_key(web_send_decimal, -1), be_const_func(l_webSendDecimal) },
+ { be_const_key(get_free_heap, 3), be_const_func(l_getFreeHeap) },
+ { be_const_key(wire_scan, -1), be_const_closure(wire_scan_closure) },
+ { be_const_key(init, -1), be_const_closure(init_closure) },
+ { be_const_key(wd, -1), be_const_var(6) },
+ { be_const_key(_debug_present, -1), be_const_var(7) },
+ { be_const_key(time_str, 45), be_const_closure(time_str_closure) },
+ { be_const_key(remove_rule, 71), be_const_closure(remove_rule_closure) },
+ { be_const_key(memory, 62), be_const_func(l_memory) },
{ be_const_key(wifi, -1), be_const_func(l_wifi) },
- { be_const_key(yield, -1), be_const_func(l_yield) },
+ { be_const_key(get_option, 44), be_const_func(l_getoption) },
+ { be_const_key(rtc, -1), be_const_func(l_rtc) },
+ { be_const_key(load, 72), be_const_closure(load_closure) },
+ { be_const_key(chars_in_string, -1), be_const_closure(chars_in_string_closure) },
+ { be_const_key(cmd, -1), be_const_closure(cmd_closure) },
+ { be_const_key(publish, 43), be_const_func(l_publish) },
+ { be_const_key(resp_cmnd_error, 18), be_const_func(l_respCmndError) },
+ { be_const_key(add_cmd, -1), be_const_closure(add_cmd_closure) },
+ { be_const_key(_settings_def, -1), be_const_comptr(&be_tasmota_settings_struct) },
+ { be_const_key(strftime, 4), be_const_func(l_strftime) },
+ { be_const_key(add_rule, 41), be_const_closure(add_rule_closure) },
+ { be_const_key(wire2, -1), be_const_var(8) },
+ { be_const_key(settings, -1), be_const_var(9) },
+ { be_const_key(exec_rules, -1), be_const_closure(exec_rules_closure) },
+ { be_const_key(cb_dispatch, -1), be_const_closure(cb_dispatch_closure) },
+ { be_const_key(yield, 68), be_const_func(l_yield) },
+ { be_const_key(_get_cb, 75), be_const_func(l_get_cb) },
+ { be_const_key(wire1, 33), be_const_var(10) },
+ { be_const_key(resp_cmnd, -1), be_const_func(l_respCmnd) },
+ { be_const_key(resp_cmnd_failed, 16), be_const_func(l_respCmndFailed) },
+ { be_const_key(_global_addr, -1), be_const_comptr(&TasmotaGlobal) },
+ { be_const_key(hs2rgb, -1), be_const_closure(hs2rgb_closure) },
+ { be_const_key(resp_cmnd_str, 76), be_const_func(l_respCmndStr) },
+ { be_const_key(_global_def, -1), be_const_comptr(&be_tasmota_global_struct) },
+ { be_const_key(kv, 74), be_const_closure(kv_closure) },
+ { be_const_key(delay, -1), be_const_func(l_delay) },
+ { be_const_key(remove_cmd, 19), be_const_closure(remove_cmd_closure) },
+ { be_const_key(set_timer, -1), be_const_closure(set_timer_closure) },
+ { be_const_key(_cmd, 54), be_const_func(l_cmd) },
+ { be_const_key(publish_result, -1), be_const_func(l_publish_result) },
+ { be_const_key(log, -1), be_const_func(l_logInfo) },
{ be_const_key(arch, -1), be_const_func(l_arch) },
- { be_const_key(resp_cmnd, 69), be_const_func(l_respCmnd) },
- { be_const_key(_global_addr, 26), be_const_comptr(&TasmotaGlobal) },
- { be_const_key(publish, -1), be_const_func(l_publish) },
- { be_const_key(_ccmd, -1), be_const_var(10) },
- { be_const_key(eth, -1), be_const_func(l_eth) },
- { be_const_key(exec_tele, -1), be_const_closure(exec_tele_closure) },
+ { be_const_key(remove_timer, 66), be_const_closure(remove_timer_closure) },
+ { be_const_key(_timers, -1), be_const_var(11) },
+ { be_const_key(read_sensors, -1), be_const_func(l_read_sensors) },
+ { be_const_key(exec_cmd, -1), be_const_closure(exec_cmd_closure) },
+ { be_const_key(response_append, -1), be_const_func(l_respAppend) },
+ { be_const_key(get_light, -1), be_const_closure(get_light_closure) },
};
static be_define_const_map(
be_class_tasmota_map,
- 78
+ 79
);
BE_EXPORT_VARIABLE be_define_const_class(
be_class_tasmota,
- 11,
+ 12,
NULL,
Tasmota
);
diff --git a/lib/libesp32/Berry/src/be_constobj.h b/lib/libesp32/Berry/src/be_constobj.h
index a565d83f9..0e8f1081c 100644
--- a/lib/libesp32/Berry/src/be_constobj.h
+++ b/lib/libesp32/Berry/src/be_constobj.h
@@ -217,6 +217,13 @@ const bntvmodule be_native_module(_module) = { \
.data = _items \
}
+#define be_nested_str_literal(_str) \
+ { \
+ { .s=(be_nested_const_str(_str, 0, sizeof(_str)-1 )) \
+ }, \
+ BE_STRING \
+ }
+
#define be_nested_string(_str, _hash, _len) \
{ \
{ .s=(be_nested_const_str(_str, _hash, _len )) \
diff --git a/lib/libesp32/Berry/src/be_solidifylib.c b/lib/libesp32/Berry/src/be_solidifylib.c
index c91bc22a5..ec0b60ca1 100644
--- a/lib/libesp32/Berry/src/be_solidifylib.c
+++ b/lib/libesp32/Berry/src/be_solidifylib.c
@@ -121,9 +121,10 @@ static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, co
}
be_pushstring(vm, str(var_tostr(value)));
be_toescape(vm, -1, 'u');
- logfmt("be_nested_string(%s", be_tostring(vm, -1));
- be_pop(vm, 1);
- logfmt(", %i, %zu)", be_strhash(var_tostr(value)), len >= 255 ? 255 : len);
+ logfmt("be_nested_str_literal(%s)", be_tostring(vm, -1));
+ // logfmt("be_nested_string(%s", be_tostring(vm, -1));
+ // be_pop(vm, 1);
+ // logfmt(", %i, %zu)", be_strhash(var_tostr(value)), len >= 255 ? 255 : len);
}
break;
case BE_CLOSURE:
From 51e99fe4af7a31ebff61de34b754b08aac51fe48 Mon Sep 17 00:00:00 2001
From: Stephan Hadinger
Date: Sun, 21 Nov 2021 23:17:45 +0100
Subject: [PATCH 121/174] Berry fix raise counter
---
lib/libesp32/Berry/src/be_exec.c | 3 +++
lib/libesp32/Berry/src/be_vm.c | 3 ---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/libesp32/Berry/src/be_exec.c b/lib/libesp32/Berry/src/be_exec.c
index 8ed0bc8f1..7b741e4ff 100644
--- a/lib/libesp32/Berry/src/be_exec.c
+++ b/lib/libesp32/Berry/src/be_exec.c
@@ -74,6 +74,9 @@ struct filebuf {
void be_throw(bvm *vm, int errorcode)
{
+#if BE_USE_PERF_COUNTERS
+ vm->counter_exc++;
+#endif
if (vm->errjmp) {
vm->errjmp->status = errorcode;
exec_throw(vm->errjmp);
diff --git a/lib/libesp32/Berry/src/be_vm.c b/lib/libesp32/Berry/src/be_vm.c
index fabba9220..6f30835d5 100644
--- a/lib/libesp32/Berry/src/be_vm.c
+++ b/lib/libesp32/Berry/src/be_vm.c
@@ -1019,9 +1019,6 @@ newframe: /* a new call frame */
dispatch();
}
opcase(RAISE): {
-#if BE_USE_PERF_COUNTERS
- vm->counter_exc++;
-#endif
if (IGET_RA(ins) < 2) { /* A==2 means no arguments are passed to RAISE, i.e. rethrow with current exception */
bvalue *top = vm->top;
top[0] = *RKB(); /* push the exception value to top */
From a1720b2ba60d16bca49fd15e191e68180f3c1fcd Mon Sep 17 00:00:00 2001
From: Norbert Richter
Date: Mon, 22 Nov 2021 12:19:28 +0100
Subject: [PATCH 122/174] Fix NeoPool compile error
---
tasmota/xsns_83_neopool.ino | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tasmota/xsns_83_neopool.ino b/tasmota/xsns_83_neopool.ino
index 18d7a7ee7..5f0e96292 100644
--- a/tasmota/xsns_83_neopool.ino
+++ b/tasmota/xsns_83_neopool.ino
@@ -598,7 +598,7 @@ struct {
const uint16_t type;
union {
NeoPoolRegBlock block;
- NeoPoolRegList list[];
+ NeoPoolRegList *list;
};
} NeoPoolReg[] = {
// 6 entries so using 250ms poll interval we are through in 1,5 for all register
From 8ca727a5237c1fa6c54e5d8c75d132400096eebc Mon Sep 17 00:00:00 2001
From: Theo Arends <11044339+arendst@users.noreply.github.com>
Date: Mon, 22 Nov 2021 12:21:07 +0100
Subject: [PATCH 123/174] Fix SSPM Gui energy display
---
tasmota/xdrv_86_esp32_sonoff_spm.ino | 95 ++++++++++++++--------------
1 file changed, 46 insertions(+), 49 deletions(-)
diff --git a/tasmota/xdrv_86_esp32_sonoff_spm.ino b/tasmota/xdrv_86_esp32_sonoff_spm.ino
index f2d83439e..a786a5913 100644
--- a/tasmota/xdrv_86_esp32_sonoff_spm.ino
+++ b/tasmota/xdrv_86_esp32_sonoff_spm.ino
@@ -34,7 +34,6 @@
* Each SPM-4Relay has 4 bistable relays with their own CSE7761 energy monitoring device handled by an ARM processor.
* Green led is controlled by ARM processor indicating SD-Card access.
* ESP32 is used as interface between eWelink and ARM processor in SPM-Main unit communicating over proprietary serial protocol.
- * Inductive/Capacitive loads are not reported correctly.
* Power on sequence for two SPM-4Relay modules is 00-00-15-10-(0F)-(13)-(13)-(19)-0C-09-04-09-04-0B-0B
*
* Tasmota POC1:
@@ -45,9 +44,9 @@
*
* Tasmota POC2:
* Ethernet support.
+ * Gui optimized for energy display.
*
* Todo:
- * Gui optimization for energy display.
* Gui for Overload Protection entry (is handled by ARM processor).
* Gui for Scheduling entry (is handled by ARM processor).
* Yellow led functionality.
@@ -548,11 +547,13 @@ void SSPMHandleReceivedData(void) {
/* 0x04 - Overload Protection
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
AA 55 01 8b 34 32 37 39 37 34 13 4b 35 36 37 80 04 00 02 00 00 06 98 06
- Marker |Module id |Ac|Cm|Size | |Ch|Ra|Max P |Min P |Max U |Min U |Max I |De|Ix|Chksm|
- | | | 4400W| 0.1W| 240V| 0.1V| 20A| |
+ Marker |Module id |Ac|Cm|Size | |Ix|Chksm|
+
AA 55 01 6B 7E 32 37 39 37 34 13 4B 35 36 37 80 04 00 35 00 07 00 11 30 00 00 00 0A 00 F0 00 00 00 0A 00 14 00 00
00 11 30 00 00 00 0A 00 F0 00 00 00 0A 00 14 00 00
00 11 30 00 00 00 0A 00 F0 00 00 00 0A 00 14 00 00 07 8A 86
+ Marker |Module id |Ac|Cm|Size | |Ch|Ra|Max P |Min P |Max U |Min U |Max I |De|Ix|Chksm|
+ | | | 4400W| 0.1W| 240V| 0.1V| 20A| |
*/
if (0x02 == Sspm->expected_bytes) {
@@ -650,7 +651,10 @@ void SSPMHandleReceivedData(void) {
uint32_t total_energy = 0;
uint32_t entries = (Sspm->expected_bytes - 22) / 2;
for (uint32_t i = 0; i < entries; i++) {
- total_energy += (SspmBuffer[41 + (i*2)] << 8) + SspmBuffer[42 + (i*2)];
+ uint32_t today_energy = (SspmBuffer[41 + (i*2)] << 8) + SspmBuffer[42 + (i*2)];
+ if (today_energy != 28702) { // Unknown why sometimes 0x701E (=28702kWh) pops up
+ total_energy += today_energy;
+ }
}
uint32_t channel = SspmBuffer[32];
for (uint32_t module = 0; module < Sspm->module_max; module++) {
@@ -687,24 +691,6 @@ void SSPMHandleReceivedData(void) {
|Ch|Curre|Voltage |ActivePo|Reactive|Apparent|??|
Values are XX XX - number
XX - decimals
-
-
-
- Curr Voltag Active Reacti Appare
- 0 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031 3233 343536 373839 404142 434445 46 47 4849
- AA55010000000000000000000000000006001C8B343237393734134B35363708 000A 00E05B 001817 00013B 001825 4B BC 3DDA 0.100A 224.91V 24.23W <-- 25W bulb
- AA55010000000000000000000000000006001C8B343237393734134B35363708 000A 00E115 00181A 00013D 001823 4B BE 6209
- AA55010000000000000000000000000006001C8B343237393734134B35363708 0044 00E260 009C1C 000000 009C1B 00 36 FD69 0.680A 226.96V 156.28W <-- 150W bulb
-
- AA55010000000000000000000000000006001C8B343237393734134B35363708 0054 00E134 007525 00220A 00BD5D 20 34 55D6
- AA55010000000000000000000000000006001C8B343237393734134B35363708 0054 00E10A 007519 002126 00BD27 20 36 77EA
- AA55010000000000000000000000000006001C8B343237393734134B35363708 0053 00DE40 00731F 001604 00B952 4B 12 9255
-
- AA55010000000000000000000000000006001C8B343237393734134B35363708 075B 00D502 06940F 001863 069830 4B 1C E0DE
-
- AA55010000000000000000000000000006001c8b343237393734134b35363708 0044 00e025 009920 00010f 00993b 00 b3 07 a2 0.68A 223.25V 152.66W 0.54 Rea 152.5 Schijn
-
-
*/
{
uint32_t channel = 0;
@@ -764,6 +750,8 @@ void SSPMHandleReceivedData(void) {
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 6b 7e 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 8f cd
AA 55 01 00 00 00 00 00 00 00 00 00 00 00 00 00 13 00 24 8b 34 32 37 39 37 34 13 4b 35 36 37 04 00 00 00 82 01 00 00 14 00 00 0a 00 f0 00 00 00 0a 11 30 00 00 00 0a 02 a0 6f
+ Marker | |Ac|Cm|Size |Module id |Ch| |Max I|Min I|Max U |Min U |Max P |Min P |Ix|Chksm|
+ | 20A| 0.1A| 240V| 0.1V| 4400W| 0.1W|
*/
if ((0x24 == Sspm->expected_bytes) && (Sspm->module_max < SSPM_MAX_MODULES)) {
memcpy(Sspm->module[1], Sspm->module[0], (SSPM_MAX_MODULES -1) * SSPM_MODULE_NAME_SIZE);
@@ -855,9 +843,9 @@ void SSPMInit(void) {
digitalWrite(SSPM_GPIO_ARM_RESET, 1);
if (0 == Settings->flag2.voltage_resolution) {
- Settings->flag2.voltage_resolution = 1; // SPM has only 2 decimals
- Settings->flag2.current_resolution = 2; // SPM has only 2 decimals
- Settings->flag2.wattage_resolution = 2; // SPM has only 2 decimals
+ Settings->flag2.voltage_resolution = 1; // SPM has 2 decimals but this keeps the gui clean
+ Settings->flag2.current_resolution = 2; // SPM has 2 decimals
+ Settings->flag2.wattage_resolution = 1; // SPM has 2 decimals but this keeps the gui clean
Settings->flag2.energy_resolution = 0; // SPM has no decimals on total energy
}
@@ -1019,29 +1007,36 @@ bool SSPMButton(void) {
return result;
}
-const char kSSPMEnergyPhases[] PROGMEM = "%*_f / %*_f / %*_f / %*_f|[%*_f,%*_f,%*_f,%*_f]";
+const uint16_t SSPM_SIZE = 128;
+const char kSSPMEnergyPhases[] PROGMEM = "%*_f | %*_f | %*_f | %*_f | |[%*_f,%*_f,%*_f,%*_f]";
char* SSPMEnergyFormat(char* result, float* input, uint32_t resolution, bool json) {
- char layout[32];
+ char layout[100];
GetTextIndexed(layout, sizeof(layout), json, kSSPMEnergyPhases);
- ext_snprintf_P(result, FLOATSZ * 4, layout, resolution, &input[0], resolution, &input[1], resolution, &input[2], resolution, &input[3]);
+ ext_snprintf_P(result, SSPM_SIZE, layout, resolution, &input[0], resolution, &input[1], resolution, &input[2], resolution, &input[3]);
return result;
}
-const char HTTP_SSPMENERGY_SNS[] PROGMEM =
- "{s}" D_POWERUSAGE_APPARENT "{m}%s " D_UNIT_VA "{e}"
- "{s}" D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}"
- "{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = |