From 127892e0c186bef0678b1683fff913918116ced5 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 1 Apr 2019 15:15:16 +0200 Subject: [PATCH] Change IRsend and receive for 64-bit support * Change IRsend and receive for 64-bit support (#5523) * Change IRSend Panasonic protocol to 64-bit (#5523) --- sonoff/_changelog.ino | 2 ++ sonoff/support.ino | 22 +++++++++++++++++ sonoff/xdrv_05_irremote.ino | 49 ++++++++++++++++++++++++++----------- 3 files changed, 59 insertions(+), 14 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 6f40ca4ae..7ffe22789 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,8 @@ /* 6.5.0.3 20190328 * Add command Sensor20 1..255 to change Nova Fitness SDS01 working period in minutes (#5452) * Change some defines to const + * Change IRsend and receive for 64-bit support (#5523) + * Change IRSend Panasonic protocol to 64-bit (#5523) * * 6.5.0.2 20190325 * Change UDP initial message handling from string to char using static memory and add debug info (#5505) diff --git a/sonoff/support.ino b/sonoff/support.ino index d101185a6..cffcb4690 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -200,6 +200,28 @@ int TextToInt(char *str) return strtol(str, &p, radix); } +char* ulltoa(unsigned long long value, char *str, int radix) +{ + char digits[64]; + char *dst = str; + int i = 0; + int n = 0; + +/* + if (radix < 2 || radix > 36) { radix = 10; } +*/ + do { + n = value % radix; + digits[i++] = (n < 10) ? (char)n+'0' : (char)n-10+'A'; + value /= radix; + } while (value != 0); + + while (i > 0) { *dst++ = digits[--i]; } + + *dst = 0; + return str; +} + char* dtostrfd(double number, unsigned char prec, char *s) { if ((isnan(number)) || (isinf(number))) { // Fix for JSON output (https://stackoverflow.com/questions/1423081/json-left-out-infinity-and-nan-json-status-in-ecmascript) diff --git a/sonoff/xdrv_05_irremote.ino b/sonoff/xdrv_05_irremote.ino index d62be8ee3..9bddc3617 100644 --- a/sonoff/xdrv_05_irremote.ino +++ b/sonoff/xdrv_05_irremote.ino @@ -105,18 +105,37 @@ void IrReceiveInit(void) // AddLog_P(LOG_LEVEL_DEBUG, PSTR("IrReceive initialized")); } +char* IrUint64toHex(uint64_t value, char *str, uint16_t bits) +{ + ulltoa(value, str, 16); // Get 64bit value + + int fill = 8; + if ((bits > 3) && (bits < 65)) { fill = bits / 4 ; } // Max 16 + int len = strlen(str); + fill -= len; + if (fill > 0) { + memmove(str + fill, str, len +1); + memset(str, '0', fill); + } + memmove(str + 2, str, strlen(str) +1); + str[0] = '0'; + str[1] = 'x'; + return str; +} + void IrReceiveCheck(void) { char sirtype[14]; // Max is AIWA_RC_T501 - char stemp[16]; int8_t iridx = 0; decode_results results; if (irrecv->decode(&results)) { + char hvalue[64]; + IrUint64toHex(results.value, hvalue, results.bits); // Get 64bit value as hex 0x00123456 - AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_IRR "Echo %d, RawLen %d, Overflow %d, Bits %d, Value 0x%08X, Decode %d"), - irsend_active, results.rawlen, results.overflow, results.bits, results.value, results.decode_type); + AddLog_P2(LOG_LEVEL_DEBUG, PSTR(D_LOG_IRR "Echo %d, RawLen %d, Overflow %d, Bits %d, Value %s, Decode %d"), + irsend_active, results.rawlen, results.overflow, results.bits, hvalue, results.decode_type); unsigned long now = millis(); // if ((now - ir_lasttime > IR_TIME_AVOID_DUPLICATE) && (UNKNOWN != results.decode_type) && (results.bits > 0)) { @@ -124,16 +143,15 @@ void IrReceiveCheck(void) ir_lasttime = now; iridx = results.decode_type; - if ((iridx < 0) || (iridx > 14)) { - iridx = 0; // UNKNOWN - } + if ((iridx < 0) || (iridx > 14)) { iridx = 0; } // UNKNOWN + char svalue[64]; if (Settings.flag.ir_receive_decimal) { - snprintf_P(stemp, sizeof(stemp), PSTR("%u"), (uint32_t)results.value); + ulltoa(results.value, svalue, 10); } else { - snprintf_P(stemp, sizeof(stemp), PSTR("\"0x%lX\""), (uint32_t)results.value); + snprintf_P(svalue, sizeof(svalue), PSTR("\"%s\""), hvalue); } Response_P(PSTR("{\"" D_JSON_IRRECEIVED "\":{\"" D_JSON_IR_PROTOCOL "\":\"%s\",\"" D_JSON_IR_BITS "\":%d,\"" D_JSON_IR_DATA "\":%s"), - GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, stemp); + GetTextIndexed(sirtype, sizeof(sirtype), iridx, kIrRemoteProtocols), results.bits, svalue); if (Settings.flag3.receive_raw) { ResponseAppend_P(PSTR(",\"" D_JSON_IR_RAWDATA "\":[")); @@ -565,14 +583,16 @@ bool IrSendCommand(void) // IRsend { "protocol": "SAMSUNG", "bits": 32, "data": 551502015 } char parm_uc[10]; const char *protocol = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_PROTOCOL))]; - uint32_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))]; - uint32_t data = strtoul(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], nullptr, 0); + uint16_t bits = root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_BITS))]; + uint64_t data = strtoull(root[UpperCase_P(parm_uc, PSTR(D_JSON_IR_DATA))], nullptr, 0); if (protocol && bits) { char protocol_text[20]; int protocol_code = GetCommandCode(protocol_text, sizeof(protocol_text), protocol, kIrRemoteProtocols); - AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %u (0x%lX), protocol_code %d"), - protocol_text, protocol, bits, data, data, protocol_code); + char dvalue[64]; + char hvalue[64]; + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("IRS: protocol_text %s, protocol %s, bits %d, data %s (%s), protocol_code %d"), + protocol_text, protocol, bits, ulltoa(data, dvalue, 10), IrUint64toHex(data, hvalue, bits), protocol_code); irsend_active = true; switch (protocol_code) { @@ -591,7 +611,8 @@ bool IrSendCommand(void) case SAMSUNG: irsend->sendSAMSUNG(data, (bits > SAMSUNG_BITS) ? SAMSUNG_BITS : bits); break; case PANASONIC: - irsend->sendPanasonic(bits, data); break; +// irsend->sendPanasonic(bits, data); break; + irsend->sendPanasonic64(data, bits); break; default: irsend_active = false; Response_P(S_JSON_COMMAND_SVALUE, command, D_JSON_PROTOCOL_NOT_SUPPORTED);