From f7b914aea1097da90901b0cfe1c68fb47af80a3c Mon Sep 17 00:00:00 2001 From: Tom Kooij Date: Sun, 1 Jan 2023 10:38:15 +0100 Subject: [PATCH] Refactor itho datatype handling Itho datatype (single byte) 7-654-3210 bit 7: signed (1), unsigned (0) 654: length of raw data 3210: (4 LSBs): divider Exception 0x5B: two byte unsigned int. --- software/NRG_itho_wifi/src/IthoSystem.cpp | 103 ++++++++---------- software/NRG_itho_wifi/src/IthoSystem.h | 6 +- .../NRG_itho_wifi/src/generic_functions.cpp | 4 - 3 files changed, 50 insertions(+), 63 deletions(-) diff --git a/software/NRG_itho_wifi/src/IthoSystem.cpp b/software/NRG_itho_wifi/src/IthoSystem.cpp index 1501135f..4ef4a8c4 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.cpp +++ b/software/NRG_itho_wifi/src/IthoSystem.cpp @@ -697,57 +697,25 @@ void sendQueryStatusFormat(bool updateweb) // char fStringBuf[32]; // getSatusLabel(i, ithoDeviceptr, currentItho_fwversion(), fStringBuf); - ithoStatus.back().divider = 0; - if ((i2cbuf[6 + i] & 0x07) == 0) + ithoStatus.back().is_signed = get_signed_from_datatype(i2cbuf[6 + i]); + ithoStatus.back().length = get_length_from_datatype(i2cbuf[6 + i]); + ithoStatus.back().divider = get_divider_from_datatype(i2cbuf[6 + i]); + + if (ithoStatus.back().divider == 1.) { // integer value - if ((i2cbuf[6 + i] & 0x80) == 0) - { // unsigned value - ithoStatus.back().type = ithoDeviceStatus::is_uint; - } - else - { ithoStatus.back().type = ithoDeviceStatus::is_int; - } } else { - if ((i2cbuf[6 + i] & 0x80) == 0) - { // unsigned value - ithoStatus.back().is_signed = false; - } - else - { - ithoStatus.back().is_signed = true; - } ithoStatus.back().type = ithoDeviceStatus::is_float; - ithoStatus.back().divider = quick_pow10((i2cbuf[6 + i] & 0x07)); - } - if (((i2cbuf[6 + i] >> 3) & 0x07) == 0) - { - ithoStatus.back().length = 1; } - else - { - ithoStatus.back().length = (i2cbuf[6 + i] >> 3) & 0x07; - } - // special cases - if (i2cbuf[6 + i] == 0x0C || i2cbuf[6 + i] == 0x6C) - { - ithoStatus.back().type = ithoDeviceStatus::is_byte; - ithoStatus.back().length = 1; - } - if (i2cbuf[6 + i] == 0x0F) - { - ithoStatus.back().type = ithoDeviceStatus::is_float; - ithoStatus.back().is_signed = false; - ithoStatus.back().length = 1; - ithoStatus.back().divider = 2; - } if (i2cbuf[6 + i] == 0x5B) { - ithoStatus.back().type = ithoDeviceStatus::is_uint; + // legacy itho: 0x5B -> 0x10 + ithoStatus.back().type = ithoDeviceStatus::is_int; ithoStatus.back().length = 2; + ithoStatus.back().is_signed = false; } } } @@ -813,23 +781,13 @@ void sendQueryStatus(bool updateweb) ithoStat.value.byteval = (byte)tempVal; } } - if (ithoStat.type == ithoDeviceStatus::is_uint) + if (ithoStat.type == ithoDeviceStatus::is_int) { - if (ithoStat.value.uintval == tempVal) - { - ithoStat.updated = 0; - } - else + if (ithoStat.is_signed) { - ithoStat.updated = 1; - ithoStat.value.uintval = tempVal; + // interpret raw bytes as signed integer + tempVal = cast_to_signed_int(tempVal, ithoStat.length); } - } - if (ithoStat.type == ithoDeviceStatus::is_int) - { - - tempVal = cast_to_signed_int(tempVal, ithoStat.length); - if (ithoStat.value.intval == tempVal) { ithoStat.updated = 0; @@ -841,8 +799,7 @@ void sendQueryStatus(bool updateweb) } } if (ithoStat.type == ithoDeviceStatus::is_float) - { - + { double t = ithoStat.value.floatval * ithoStat.divider; if (static_cast(t) == tempVal) // better compare needed of float val, worst case this will result in an extra update of the value, so limited impact { @@ -1808,4 +1765,36 @@ int cast_to_signed_int(int val, int length) default: return 0; } -} \ No newline at end of file +} + +// Itho datatype +// bit 7: signed (1), unsigned (0) +// bit 6,5,4 : length +// bit 3,2,1,0 : divider +float get_divider_from_datatype(int8_t datatype) { + + const float _divider[] = + { + 1., 10., 100., 1000., 1E+4, 1E+5, + 1E+6, 1E+7, 1E+8, 0.1, 0.01, + 1., 1., 1., 256., 2. + }; + return _divider[datatype & 0x0f]; +} + +uint8_t get_length_from_datatype(int8_t datatype) { + + switch(datatype & 0x70) { + case 0x10: + return 2; + case 0x20: + case 0x70: + return 4; + default: + return 1; + } +} + +bool get_signed_from_datatype(int8_t datatype) { + return datatype & 0x80; +} diff --git a/software/NRG_itho_wifi/src/IthoSystem.h b/software/NRG_itho_wifi/src/IthoSystem.h index 577fbe99..f85864ec 100644 --- a/software/NRG_itho_wifi/src/IthoSystem.h +++ b/software/NRG_itho_wifi/src/IthoSystem.h @@ -44,7 +44,6 @@ struct ithoDeviceStatus { is_byte, is_int, - is_uint, is_float, is_string } type; @@ -57,7 +56,7 @@ struct ithoDeviceStatus double floatval; const char *stringval; } value; - uint32_t divider; + float divider; uint8_t updated; bool is_signed; // used for floats only ithoDeviceStatus() : updated(0){}; @@ -148,3 +147,6 @@ 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); +float 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 f80eb660..f71a1a25 100644 --- a/software/NRG_itho_wifi/src/generic_functions.cpp +++ b/software/NRG_itho_wifi/src/generic_functions.cpp @@ -79,10 +79,6 @@ void getIthoStatusJSON(JsonObject root) { root[ithoStat.name] = ithoStat.value.byteval; } - else if (ithoStat.type == ithoDeviceStatus::is_uint) - { - root[ithoStat.name] = ithoStat.value.uintval; - } else if (ithoStat.type == ithoDeviceStatus::is_int) { root[ithoStat.name] = ithoStat.value.intval;