From b5c7aab03bfc85f673d0a0f18deec48d8baebbf6 Mon Sep 17 00:00:00 2001 From: dailow Date: Sun, 4 Sep 2022 20:46:31 -0700 Subject: [PATCH] Fix negative watt values (#5) Handle both 1's complement and signed magnitude methods of expressing negative numbers Co-authored-by: Joe Rouvier --- src/emporia_vue_utility.h | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/emporia_vue_utility.h b/src/emporia_vue_utility.h index 12b4695..a4fd527 100644 --- a/src/emporia_vue_utility.h +++ b/src/emporia_vue_utility.h @@ -297,7 +297,8 @@ class EmporiaVueUtility : public Component, public UARTDevice { int32_t watts; // Read the instant watts value - watts = bswap32(mr->watts); + // (it's actually a 24-bit int) + watts = (bswap32(mr->watts) & 0xFFFFFF); // Bit 1 of the left most byte indicates a negative value if (watts & 0x800000) { @@ -305,8 +306,18 @@ class EmporiaVueUtility : public Component, public UARTDevice { // Exactly "negative zero", which means "missing data" ESP_LOGI(TAG, "Instant Watts value missing"); return; + } else if (watts & 0xC00000) { + // This is either more than 12MW being returned, + // or it's a negative number in 1's complement. + // Since the returned value is a 24-bit value + // and "watts" is a 32-bit signed int, we can + // get away with this. + watts -= 0xFFFFFF; + } else { + // If we get here, then hopefully it's a negative + // number in signed magnitude format + watts = (watts ^ 0x800000) * -1; } - watts -= 0x800000; } if ((watts >= WATTS_MAX) || (watts < WATTS_MIN)) {