Merge pull request #376 from MichaelDvP/SM_energy

SM200 energy to 32 bit, fixes #372
This commit is contained in:
Proddy
2020-04-28 18:46:03 +02:00
committed by GitHub
6 changed files with 49 additions and 34 deletions

Binary file not shown.

View File

@@ -303,7 +303,7 @@ void showInfo() {
// UBAParameterWW
_renderBoolValue("Warm Water activated", EMS_Boiler.wWActivated);
_renderBoolValue("Warm Water circulation pump available", EMS_Boiler.wWCircPump);
myDebug_P(PSTR(" Warm Water circulation pump type: %s"), EMS_Boiler.wWCircPumpType ? "charge pump" : "3-way pump");
myDebug_P(PSTR(" Warm Water circulation pump type: %s"), EMS_Boiler.wWCircPumpType ? "3-way pump" : "charge pump");
if (EMS_Boiler.wWCircPumpMode == 7) {
myDebug_P(PSTR(" Warm Water circulation pump freq: continuous"));
} else {
@@ -414,9 +414,9 @@ void showInfo() {
(EMS_SolarModule.pumpWorkMin % 1440) / 60,
EMS_SolarModule.pumpWorkMin % 60);
}
_renderUShortValue("Energy last hour", "Wh", EMS_SolarModule.EnergyLastHour, 1); // *10
_renderUShortValue("Energy today", "Wh", EMS_SolarModule.EnergyToday, 0);
_renderUShortValue("Energy total", "kWh", EMS_SolarModule.EnergyTotal, 1); // *10
_renderLongValue("Energy last hour", "Wh", EMS_SolarModule.EnergyLastHour, 1); // *10
_renderLongValue("Energy today", "Wh", EMS_SolarModule.EnergyToday, 0);
_renderLongValue("Energy total", "kWh", EMS_SolarModule.EnergyTotal, 1); // *10
}
// For HeatPumps
@@ -532,7 +532,7 @@ void showInfo() {
}
// show flow temp if we have it
if (EMS_Thermostat.hc[hc_num - 1].circuitcalctemp < EMS_VALUE_INT_NOTSET)
if (EMS_Thermostat.hc[hc_num - 1].circuitcalctemp != EMS_VALUE_INT_NOTSET)
_renderIntValue(" Calculated flow temperature", "C", EMS_Thermostat.hc[hc_num - 1].circuitcalctemp);
// Render Thermostat Mode
@@ -896,7 +896,7 @@ bool publishEMSValues_thermostat() {
if (model == EMS_DEVICE_FLAG_EASY) {
if (thermostat->setpoint_roomTemp != EMS_VALUE_SHORT_NOTSET)
dataThermostat[THERMOSTAT_SELTEMP] = (float)thermostat->setpoint_roomTemp / 100;
if (thermostat->curr_roomTemp > EMS_VALUE_SHORT_NOTSET)
if (thermostat->curr_roomTemp != EMS_VALUE_SHORT_NOTSET)
dataThermostat[THERMOSTAT_CURRTEMP] = (float)thermostat->curr_roomTemp / 100;
} else if ((model == EMS_DEVICE_FLAG_JUNKERS1) || (model == EMS_DEVICE_FLAG_JUNKERS2)) {
if (thermostat->setpoint_roomTemp != EMS_VALUE_SHORT_NOTSET)
@@ -1114,13 +1114,13 @@ bool publishEMSValues_solar() {
if (EMS_SolarModule.pumpWorkMin != EMS_VALUE_LONG_NOTSET) {
rootSM[SM_PUMPWORKMIN] = (float)EMS_SolarModule.pumpWorkMin;
}
if (EMS_SolarModule.EnergyLastHour != EMS_VALUE_USHORT_NOTSET) {
if (EMS_SolarModule.EnergyLastHour != EMS_VALUE_LONG_NOTSET) {
rootSM[SM_ENERGYLASTHOUR] = (float)EMS_SolarModule.EnergyLastHour / 10;
}
if (EMS_SolarModule.EnergyToday != EMS_VALUE_USHORT_NOTSET) {
if (EMS_SolarModule.EnergyToday != EMS_VALUE_LONG_NOTSET) {
rootSM[SM_ENERGYTODAY] = EMS_SolarModule.EnergyToday;
}
if (EMS_SolarModule.EnergyTotal != EMS_VALUE_USHORT_NOTSET) {
if (EMS_SolarModule.EnergyTotal != EMS_VALUE_LONG_NOTSET) {
rootSM[SM_ENERGYTOTAL] = (float)EMS_SolarModule.EnergyTotal / 10;
}
@@ -2434,13 +2434,13 @@ void WebCallback(JsonObject root) {
sm["sm4"] = _bool_to_char(s, EMS_SolarModule.pump); // Pump active on/off
}
if (EMS_SolarModule.EnergyLastHour != EMS_VALUE_USHORT_NOTSET)
if (EMS_SolarModule.EnergyLastHour != EMS_VALUE_LONG_NOTSET)
sm["sm5"] = (float)EMS_SolarModule.EnergyLastHour / 10; // Energy last hour Wh
if (EMS_SolarModule.EnergyToday != EMS_VALUE_USHORT_NOTSET) // Energy today Wh
if (EMS_SolarModule.EnergyToday != EMS_VALUE_LONG_NOTSET) // Energy today Wh
sm["sm6"] = EMS_SolarModule.EnergyToday;
if (EMS_SolarModule.EnergyTotal != EMS_VALUE_USHORT_NOTSET) // Energy total KWh
if (EMS_SolarModule.EnergyTotal != EMS_VALUE_LONG_NOTSET) // Energy total KWh
sm["sm7"] = (float)EMS_SolarModule.EnergyTotal / 10;
} else {
sm["ok"] = false;

View File

@@ -217,9 +217,9 @@ void ems_init() {
EMS_SolarModule.pumpModulation = EMS_VALUE_INT_NOTSET; // modulation solar pump SM10/SM100/SM200
EMS_SolarModule.pump = EMS_VALUE_BOOL_NOTSET; // pump active
EMS_SolarModule.valveStatus = EMS_VALUE_BOOL_NOTSET; // valve status from SM200
EMS_SolarModule.EnergyLastHour = EMS_VALUE_USHORT_NOTSET;
EMS_SolarModule.EnergyToday = EMS_VALUE_USHORT_NOTSET;
EMS_SolarModule.EnergyTotal = EMS_VALUE_USHORT_NOTSET;
EMS_SolarModule.EnergyLastHour = EMS_VALUE_LONG_NOTSET;
EMS_SolarModule.EnergyToday = EMS_VALUE_LONG_NOTSET;
EMS_SolarModule.EnergyTotal = EMS_VALUE_LONG_NOTSET;
EMS_SolarModule.device_id = EMS_ID_NONE;
EMS_SolarModule.product_id = EMS_ID_NONE;
EMS_SolarModule.pumpWorkMin = EMS_VALUE_LONG_NOTSET;
@@ -394,8 +394,9 @@ bool _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint16_t * param_op, uint8_t in
uint16_t value = (EMS_RxTelegram->data[pos] << 8) + EMS_RxTelegram->data[pos + 1];
// check for undefined/unset values, 0x8000
if (value >= EMS_VALUE_USHORT_NOTSET) {
// check for undefined/unset values, 0x8000, 0x8300, 0x7D00
if ((value == EMS_VALUE_USHORT_NOTSET) || (value == EMS_VALUE_SHORT_NOTSET) || (value == EMS_VALUE_USHORT_NOTVALID)) {
*param_op = EMS_VALUE_USHORT_NOTSET; // make sure we render this right
return false;
}
@@ -412,8 +413,9 @@ bool _setValue(_EMS_RxTelegram * EMS_RxTelegram, int16_t * param_op, uint8_t ind
int16_t value = (EMS_RxTelegram->data[pos] << 8) + EMS_RxTelegram->data[pos + 1];
// check for undefined/unset values, 0x8000
if ((value == EMS_VALUE_SHORT_NOTSET) || (EMS_RxTelegram->data[pos] == 0x7D)) {
// check for undefined/unset values, 0x8000, 0x8300, 0x7D00
if ((value == EMS_VALUE_USHORT_NOTSET) || (value == EMS_VALUE_SHORT_NOTSET) || (value == EMS_VALUE_USHORT_NOTVALID)) {
*param_op = EMS_VALUE_SHORT_NOTSET; // make sure we render this right
return false;
}
@@ -443,7 +445,7 @@ bool _setValue8(_EMS_RxTelegram * EMS_RxTelegram, int16_t * param_op, uint8_t in
return true;
}
// Long
// Long 24 bit
bool _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint32_t * param_op, uint8_t index) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
@@ -453,6 +455,16 @@ bool _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint32_t * param_op, uint8_t in
*param_op = (uint32_t)((EMS_RxTelegram->data[pos] << 16) + (EMS_RxTelegram->data[pos + 1] << 8) + (EMS_RxTelegram->data[pos + 2]));
return true;
}
// Long 32 bit
bool _setValue32(_EMS_RxTelegram * EMS_RxTelegram, uint32_t * param_op, uint8_t index) {
int8_t pos = _getDataPosition(EMS_RxTelegram, index);
if (pos < 0) {
return false;
}
*param_op = (uint32_t)((EMS_RxTelegram->data[pos] << 24) +(EMS_RxTelegram->data[pos + 1] << 16) + (EMS_RxTelegram->data[pos + 2] << 8) + (EMS_RxTelegram->data[pos + 3]));
return true;
}
// bit from a byte
bool _setValue(_EMS_RxTelegram * EMS_RxTelegram, uint8_t * param_op, uint8_t index, uint8_t bit) {
@@ -1261,11 +1273,7 @@ void _process_RC35StatusMessage(_EMS_RxTelegram * EMS_RxTelegram) {
return;
}
// ignore if the value is 0 (see https://github.com/proddy/EMS-ESP/commit/ccc30738c00f12ae6c89177113bd15af9826b836)
if (EMS_RxTelegram->data[EMS_OFFSET_RC35StatusMessage_setpoint] != 0x00) {
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RC35StatusMessage_setpoint); // is * 2, force to single byte
}
_setValue8(EMS_RxTelegram, &EMS_Thermostat.hc[hc].setpoint_roomTemp, EMS_OFFSET_RC35StatusMessage_setpoint); // is * 2, force to single byte
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].curr_roomTemp, EMS_OFFSET_RC35StatusMessage_curr); // is * 10 - or 0x7D00 if thermostat is mounted on boiler
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].mode_type, EMS_OFFSET_RC35StatusMessage_mode, 1);
_setValue(EMS_RxTelegram, &EMS_Thermostat.hc[hc].summer_mode, EMS_OFFSET_RC35StatusMessage_mode, 0);
@@ -1628,9 +1636,9 @@ void _process_SM100Status2(_EMS_RxTelegram * EMS_RxTelegram) {
* e.g. 30 00 FF 00 02 8E 00 00 00 00 00 00 06 C5 00 00 76 35
*/
void _process_SM100Energy(_EMS_RxTelegram * EMS_RxTelegram) {
_setValue(EMS_RxTelegram, &EMS_SolarModule.EnergyLastHour, 2); // last hour / 10 in Wh
_setValue(EMS_RxTelegram, &EMS_SolarModule.EnergyToday, 6); // todays in Wh
_setValue(EMS_RxTelegram, &EMS_SolarModule.EnergyTotal, 10); // total / 10 in kWh
_setValue32(EMS_RxTelegram, &EMS_SolarModule.EnergyLastHour, 0); // last hour / 10 in Wh
_setValue32(EMS_RxTelegram, &EMS_SolarModule.EnergyToday, 4); // todays in Wh
_setValue32(EMS_RxTelegram, &EMS_SolarModule.EnergyTotal, 8); // total / 10 in kWh
}
/*

View File

@@ -33,6 +33,7 @@
#define EMS_VALUE_INT_NOTSET 0xFF // for 8-bit unsigned ints/bytes
#define EMS_VALUE_SHORT_NOTSET -32000 // 0x8300 for 2-byte signed shorts
#define EMS_VALUE_USHORT_NOTSET 32000 // 0x7D00 (was 0x8000) for 2-byte unsigned shorts
#define EMS_VALUE_USHORT_NOTVALID 0x8000 // 0x8000 for 2-byte unsigned shorts
#define EMS_VALUE_LONG_NOTSET 0xFFFFFF // for 3-byte longs
// thermostat specific
@@ -401,9 +402,9 @@ typedef struct {
uint8_t pump; // pump active
uint8_t valveStatus; // valve status (VS2)
int16_t setpoint_maxBottomTemp; // setpoint for maximum collector temp
uint16_t EnergyLastHour;
uint16_t EnergyToday;
uint16_t EnergyTotal;
uint32_t EnergyLastHour;
uint32_t EnergyToday;
uint32_t EnergyTotal;
uint32_t pumpWorkMin; // Total solar pump operating time
} _EMS_SolarModule;

View File

@@ -201,7 +201,7 @@ void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, u
}
// takes a long value at prints it to debug log and prints
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value) {
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value, uint8_t div) {
static char buffer[200] = {0};
strlcpy(buffer, " ", sizeof(buffer));
strlcat(buffer, prefix, sizeof(buffer));
@@ -211,7 +211,13 @@ void _renderLongValue(const char * prefix, const char * postfix, uint32_t value)
strlcat(buffer, "?", sizeof(buffer));
} else {
char s[20] = {0};
strlcat(buffer, ltoa(value, s, 10), sizeof(buffer));
if(div == 0) {
strlcat(buffer, ltoa(value, s, 10), sizeof(buffer));
} else {
strlcat(buffer, ltoa(value/10, s, 10), sizeof(buffer));
strlcat(buffer, ".", sizeof(buffer));
strlcat(buffer, ltoa(value%10, s, 10), sizeof(buffer));
}
}
if (postfix != nullptr) {

View File

@@ -22,7 +22,7 @@ void _renderShortValue(const char * prefix, const char * postfix, int16_t va
void _renderUShortValue(const char * prefix, const char * postfix, uint16_t value, uint8_t decimals = 1);
char * _int_to_char(char * s, uint8_t value, uint8_t div = 1);
void _renderIntValue(const char * prefix, const char * postfix, uint8_t value, uint8_t div = 1);
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value);
void _renderLongValue(const char * prefix, const char * postfix, uint32_t value, uint8_t div = 0);
void _renderBoolValue(const char * prefix, uint8_t value);
char * _hextoa(uint8_t value, char * buffer);
char * _smallitoa(uint8_t value, char * buffer);