diff --git a/software/NRG_itho_wifi/src/IthoSystem.cpp b/software/NRG_itho_wifi/src/IthoSystem.cpp index 2415854b..f8124ad1 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.cpp +++ b/software/NRG_itho_wifi/src/IthoSystem.cpp @@ -254,47 +254,22 @@ void processSettingResult(const uint8_t index, const bool loop) root["loop"] = loop; if (resultPtr2410 != nullptr && ithoSettingsArray != nullptr) { - if (ithoSettingsArray[index].type == ithoSettings::is_int8) - { - root["Current"] = *(reinterpret_cast(resultPtr2410 + 0)); - root["Minimum"] = *(reinterpret_cast(resultPtr2410 + 1)); - root["Maximum"] = *(reinterpret_cast(resultPtr2410 + 2)); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_int16) - { - root["Current"] = *(reinterpret_cast(resultPtr2410 + 0)); - root["Minimum"] = *(reinterpret_cast(resultPtr2410 + 1)); - root["Maximum"] = *(reinterpret_cast(resultPtr2410 + 2)); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_uint8 || ithoSettingsArray[index].type == ithoSettings::is_uint16 || ithoSettingsArray[index].type == ithoSettings::is_uint32) - { - root["Current"] = *(reinterpret_cast(resultPtr2410 + 0)); - root["Minimum"] = *(reinterpret_cast(resultPtr2410 + 1)); - root["Maximum"] = *(reinterpret_cast(resultPtr2410 + 2)); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_float8) - { - root["Current"] = static_cast (*(reinterpret_cast(resultPtr2410 + 0))) / ithoSettingsArray[index].divider; - root["Minimum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 1))) / ithoSettingsArray[index].divider; - root["Maximum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 2))) / ithoSettingsArray[index].divider; - } - else if (ithoSettingsArray[index].type == ithoSettings::is_float16) - { - root["Current"] = static_cast (*(reinterpret_cast(resultPtr2410 + 0))) / ithoSettingsArray[index].divider; - root["Minimum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 1))) / ithoSettingsArray[index].divider; - root["Maximum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 2))) / ithoSettingsArray[index].divider; - } - else if (ithoSettingsArray[index].type == ithoSettings::is_float32) + uint32_t val0, val1, val2; + val0 = cast_raw_bytes_to_int(resultPtr2410 + 0, ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + val1 = cast_raw_bytes_to_int(resultPtr2410 + 1, ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + val2 = cast_raw_bytes_to_int(resultPtr2410 + 2, ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + + if (ithoSettingsArray[index].type == ithoSettings::is_int) { - root["Current"] = static_cast (*(reinterpret_cast(resultPtr2410 + 0))) / ithoSettingsArray[index].divider; - root["Minimum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 1))) / ithoSettingsArray[index].divider; - root["Maximum"] = static_cast (*(reinterpret_cast(resultPtr2410 + 2))) / ithoSettingsArray[index].divider; + root["Current"] = val0; + root["Minimum"] = val1; + root["Maximum"] = val2; } else { - root["Current"] = *(resultPtr2410 + 0); - root["Minimum"] = *(resultPtr2410 + 1); - root["Maximum"] = *(resultPtr2410 + 2); + root["Current"] = static_cast (val0) / ithoSettingsArray[index].divider; + root["Minimum"] = static_cast (val1) / ithoSettingsArray[index].divider; + root["Maximum"] = static_cast (val2) / ithoSettingsArray[index].divider; } } else @@ -1413,70 +1388,27 @@ int32_t *sendQuery2410(uint8_t index, bool updateweb) ithoSettingsArray[index].value = values[0]; - if (((i2cbuf[22] >> 3) & 0x07) == 0) - { - ithoSettingsArray[index].length = 1; - } - else - { - ithoSettingsArray[index].length = (i2cbuf[22] >> 3) & 0x07; - } + ithoSettingsArray[index].is_signed = get_signed_from_datatype(i2cbuf[22]); + ithoSettingsArray[index].length = get_length_from_datatype(i2cbuf[22]); + ithoSettingsArray[index].divider = get_divider_from_datatype(i2cbuf[22]); - if ((i2cbuf[22] & 0x07) == 0) + if (ithoSettingsArray[index].divider == 1) { // integer value - if ((i2cbuf[22] & 0x80) == 0) - { // unsigned value - if (ithoSettingsArray[index].length == 1) - { - ithoSettingsArray[index].type = ithoSettings::is_uint8; - } - else if (ithoSettingsArray[index].length == 2) - { - ithoSettingsArray[index].type = ithoSettings::is_uint16; - } - else - { - ithoSettingsArray[index].type = ithoSettings::is_uint32; - } - } - else - { - if (ithoSettingsArray[index].length == 1) - { - ithoSettingsArray[index].type = ithoSettings::is_int8; - } - else if (ithoSettingsArray[index].length == 2) - { - ithoSettingsArray[index].type = ithoSettings::is_int16; - } - else - { - ithoSettingsArray[index].type = ithoSettings::is_int32; - } - } + ithoSettingsArray[index].type = ithoSettings::is_int; } else - { // float - if (i2cbuf[22] == 0x0f) // special case - { - ithoSettingsArray[index].type = ithoSettings::is_float8; - ithoSettingsArray[index].divider = 2; - } - else if (ithoSettingsArray[index].length == 1) { - ithoSettingsArray[index].type = ithoSettings::is_float8; - ithoSettingsArray[index].divider = quick_pow10((i2cbuf[22] & 0x07)); - } - else if (ithoSettingsArray[index].length == 2) { - ithoSettingsArray[index].type = ithoSettings::is_float16; - ithoSettingsArray[index].divider = quick_pow10((i2cbuf[22] & 0x07)); - } - else - { - ithoSettingsArray[index].type = ithoSettings::is_float32; - ithoSettingsArray[index].divider = quick_pow10((i2cbuf[22] & 0x07)); - } + { + ithoSettingsArray[index].type = ithoSettings::is_float; + } + // special cases + if (i2cbuf[22] == 0x5B) + { + // legacy itho: 0x5B -> 0x10 + ithoSettingsArray[index].type = ithoSettings::is_int;; + ithoSettingsArray[index].length = 2; + ithoSettingsArray[index].is_signed = false; } - + if (updateweb) { jsonSysmessage("itho2410", i2cbuf2string(i2cbuf, len).c_str()); @@ -1485,58 +1417,22 @@ int32_t *sendQuery2410(uint8_t index, bool updateweb) char tempbuffer1[256]{}; char tempbuffer2[256]{}; - if (ithoSettingsArray[index].type == ithoSettings::is_uint8 || ithoSettingsArray[index].type == ithoSettings::is_uint16 || ithoSettingsArray[index].type == ithoSettings::is_uint32) - { // unsigned value - uint32_t val[3]; - std::memcpy(&val[0], &values[0], sizeof(val[0])); - std::memcpy(&val[1], &values[1], sizeof(val[0])); - std::memcpy(&val[2], &values[2], sizeof(val[0])); - sprintf(tempbuffer0, "%u", val[0]); - sprintf(tempbuffer1, "%u", val[1]); - sprintf(tempbuffer2, "%u", val[2]); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_int8) - { - int8_t val[3]; - std::memcpy(&val[0], &values[0], sizeof(val[0])); - std::memcpy(&val[1], &values[1], sizeof(val[0])); - std::memcpy(&val[2], &values[2], sizeof(val[0])); - sprintf(tempbuffer0, "%d", val[0]); - sprintf(tempbuffer1, "%d", val[1]); - sprintf(tempbuffer2, "%d", val[2]); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_int16) - { - int16_t val[3]; - std::memcpy(&val[0], &values[0], sizeof(val[0])); - std::memcpy(&val[1], &values[1], sizeof(val[0])); - std::memcpy(&val[2], &values[2], sizeof(val[0])); - sprintf(tempbuffer0, "%d", val[0]); - sprintf(tempbuffer1, "%d", val[1]); - sprintf(tempbuffer2, "%d", val[2]); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_int32) - { - sprintf(tempbuffer0, "%d", values[0]); - sprintf(tempbuffer1, "%d", values[1]); - sprintf(tempbuffer2, "%d", values[2]); - } - else if (ithoSettingsArray[index].type == ithoSettings::is_float8 || ithoSettingsArray[index].type == ithoSettings::is_float16 || ithoSettingsArray[index].type == ithoSettings::is_float32) + uint32_t val0, val1, val2; + val0 = cast_raw_bytes_to_int(&values[0], ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + val1 = cast_raw_bytes_to_int(&values[1], ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + val2 = cast_raw_bytes_to_int(&values[2], ithoSettingsArray[index].length, ithoSettingsArray[index].is_signed); + + if (ithoSettingsArray[index].type == ithoSettings::is_int) { - // FIX ME: this should be casted to ints to preserve sign. - double val[3]; - val[0] = values[0] / ithoSettingsArray[index].divider; - val[1] = values[1] / ithoSettingsArray[index].divider; - val[2] = values[2] / ithoSettingsArray[index].divider; - sprintf(tempbuffer0, "%.1f", val[0]); - sprintf(tempbuffer1, "%.1f", val[1]); - sprintf(tempbuffer2, "%.1f", val[2]); + sprintf(tempbuffer0, "%d", val0); + sprintf(tempbuffer1, "%d", val1); + sprintf(tempbuffer2, "%d", val2); } else { - sprintf(tempbuffer0, "%d", values[0]); - sprintf(tempbuffer1, "%d", values[1]); - sprintf(tempbuffer2, "%d", values[2]); + sprintf(tempbuffer0, "%.1f", static_cast(val0) / ithoSettingsArray[index].divider); + sprintf(tempbuffer1, "%.1f", static_cast(val1) / ithoSettingsArray[index].divider); + sprintf(tempbuffer2, "%.1f", static_cast(val2) / ithoSettingsArray[index].divider); } jsonSysmessage("itho2410cur", tempbuffer0); jsonSysmessage("itho2410min", tempbuffer1); @@ -1577,16 +1473,16 @@ void setSetting2410(uint8_t index, int32_t value, bool updateweb) command[23] = index; - if (ithoSettingsArray[index].type == ithoSettings::is_uint8 || ithoSettingsArray[index].type == ithoSettings::is_int8) + if (ithoSettingsArray[index].length == 1) { command[9] = value & 0xFF; } - else if (ithoSettingsArray[index].type == ithoSettings::is_uint16 || ithoSettingsArray[index].type == ithoSettings::is_int16) + else if (ithoSettingsArray[index].length == 2) { command[9] = value & 0xFF; command[8] = (value >> 8) & 0xFF; } - else if (ithoSettingsArray[index].type == ithoSettings::is_uint32 || ithoSettingsArray[index].type == ithoSettings::is_int32 || ithoSettingsArray[index].type == ithoSettings::is_float8 || ithoSettingsArray[index].type == ithoSettings::is_float16 || ithoSettingsArray[index].type == ithoSettings::is_float32) + else if (ithoSettingsArray[index].length ==4) { command[9] = value & 0xFF; command[8] = (value >> 8) & 0xFF; @@ -1738,6 +1634,37 @@ int cast_to_signed_int(int val, int length) } } +uint32_t cast_raw_bytes_to_int(int* valptr, int length, bool is_signed) +// valptr is a pointer to 4 rawbytes, which are casted to the +// correct int-value and returned +{ + if (is_signed) { + switch (length) { + case 4: + return *reinterpret_cast(valptr); + case 2: + return *reinterpret_cast(valptr); + case 1: + return *reinterpret_cast(valptr); + default: + return 0; + } + } + else + { + switch (length) { + case 4: + return *reinterpret_cast(valptr); + case 2: + return *reinterpret_cast(valptr); + case 1: + return *reinterpret_cast(valptr); + default: + return 0; + } + } +} + // Itho datatype // bit 7: signed (1), unsigned (0) // bit 6,5,4 : length diff --git a/software/NRG_itho_wifi/src/IthoSystem.h b/software/NRG_itho_wifi/src/IthoSystem.h index 86d64ab0..e866b1d0 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.h +++ b/software/NRG_itho_wifi/src/IthoSystem.h @@ -99,17 +99,11 @@ struct ithoSettings { enum : uint8_t { - is_int8, - is_int16, - is_int32, - is_uint8, - is_uint16, - is_uint32, - is_float8, - is_float16, - is_float32, + is_int, + is_float, is_unknown } type{is_unknown}; + bool is_signed; int32_t value{0}; uint8_t length{0}; uint32_t divider; @@ -147,6 +141,7 @@ void IthoPWMcommand(uint16_t value, volatile uint16_t *ithoCurrentVal, bool *upd int quick_pow10(int n); std::string i2cbuf2string(const uint8_t *data, size_t len); int cast_to_signed_int(int val, int length); +uint32_t cast_raw_bytes_to_int(int* valptr, int length, bool is_signed); uint32_t get_divider_from_datatype(int8_t datatype); uint8_t get_length_from_datatype(int8_t datatype); bool get_signed_from_datatype(int8_t datatype); diff --git a/software/NRG_itho_wifi/src/generic_functions.cpp b/software/NRG_itho_wifi/src/generic_functions.cpp index f71a1a25..eaf55020 100644 --- a/software/NRG_itho_wifi/src/generic_functions.cpp +++ b/software/NRG_itho_wifi/src/generic_functions.cpp @@ -111,19 +111,19 @@ void getIthoSettingsBackupJSON(JsonObject root) char buf[12]; itoa(i, buf, 10); - if (ithoSettingsArray[i].type == ithoSettings::is_int8) + if (ithoSettingsArray[i].type == ithoSettings::is_int && ithoSettingsArray[i].length == 1 && ithoSettingsArray[i].is_signed) { int8_t val; std::memcpy(&val, &ithoSettingsArray[i].value, sizeof(val)); root[buf] = val; } - else if (ithoSettingsArray[i].type == ithoSettings::is_int16) + else if (ithoSettingsArray[i].type == ithoSettings::is_int && ithoSettingsArray[i].length == 2 && ithoSettingsArray[i].is_signed) { int16_t val; std::memcpy(&val, &ithoSettingsArray[i].value, sizeof(val)); root[buf] = val; } - else if (ithoSettingsArray[i].type == ithoSettings::is_int32) + else if (ithoSettingsArray[i].type == ithoSettings::is_int && ithoSettingsArray[i].length == 4 && ithoSettingsArray[i].is_signed) { root[buf] = ithoSettingsArray[i].value; }