Skip to content

Commit

Permalink
Merge pull request #11 from cenobitedk/multical21
Browse files Browse the repository at this point in the history
Extend support for Kamstrup Multical21
  • Loading branch information
SzczepanLeon authored Jul 19, 2024
2 parents d5e2bef + ccfb12d commit c856f7d
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 4 deletions.
40 changes: 40 additions & 0 deletions driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,46 @@ struct Driver
return ret_val;
};

esphome::optional<double> get_615B(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint32_t temperature = 0;
size_t i = 11;
uint32_t temperature_register = 0x615B;
while (i < telegram.size()) {
uint32_t c = (((uint32_t) telegram[i + 0] << 8) | ((uint32_t) telegram[i + 1]));
if (c == temperature_register) {
i += 2;
temperature = ((uint32_t) telegram[i + 0]);
// in celcius degrees
ret_val = temperature / 1.0;
ESP_LOGVV(TAG, "Found register '615B' with '%d'->'%f'", temperature, ret_val.value());
break;
}
i++;
}
return ret_val;
};

esphome::optional<double> get_6167(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint32_t temperature = 0;
size_t i = 11;
uint32_t temperature_register = 0x6167;
while (i < telegram.size()) {
uint32_t c = (((uint32_t) telegram[i + 0] << 8) | ((uint32_t) telegram[i + 1]));
if (c == temperature_register) {
i += 2;
temperature = ((uint32_t) telegram[i + 0]);
// in celcius degrees
ret_val = temperature / 1.0;
ESP_LOGVV(TAG, "Found register '6167' with '%d'->'%f'", temperature, ret_val.value());
break;
}
i++;
}
return ret_val;
};

esphome::optional<double> get_040F(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint32_t usage = 0;
Expand Down
91 changes: 87 additions & 4 deletions driver_multical21.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ struct Multical21: Driver
virtual esphome::optional<std::map<std::string, double>> get_values(std::vector<unsigned char> &telegram) override {
std::map<std::string, double> ret_val{};

add_to_map(ret_val, "total_water_m3", this->get_0413(telegram));
add_to_map(ret_val, "target_water_m3", this->get_4413(telegram));
// add_to_map(ret_val, "flow_temperature_c", this->get_615B(telegram));
// add_to_map(ret_val, "external_temperature_c", this->get_6167(telegram));
add_to_map(ret_val, "total_water_m3", this->get_total_water_m3(telegram));
add_to_map(ret_val, "target_water_m3", this->get_target_water_m3(telegram));
add_to_map(ret_val, "flow_temperature_c", this->get_flow_temperature_c(telegram));
add_to_map(ret_val, "external_temperature_c", this->get_external_temperature_c(telegram));

if (ret_val.size() > 0) {
return ret_val;
Expand All @@ -30,4 +30,87 @@ struct Multical21: Driver
};

private:
esphome::optional<double> get_total_water_m3(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint8_t tpl_ci_field = telegram[19];

if (tpl_ci_field == 0x78) {
return this->get_0413(telegram);
}

if (tpl_ci_field == 0x79) { // check !!!!
uint32_t total_water{0};
uint8_t i = 26; // check !!!!
total_water = ((uint32_t) telegram[i + 3] << 24) | ((uint32_t) telegram[i + 2] << 16) |
((uint32_t) telegram[i + 1] << 8) | ((uint32_t) telegram[i + 0]);
// in m3
ret_val = total_water / 1000.0;
ESP_LOGVV(TAG, "Found total_water_consumption with '%d'->'%f'", total_water, ret_val.value());
}

return ret_val;
};

esphome::optional<double> get_target_water_m3(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint8_t tpl_ci_field = telegram[19];

if (tpl_ci_field == 0x78) {
return this->get_4413(telegram);
}

if (tpl_ci_field == 0x79) { // check !!!!
uint32_t target_water{0};
uint8_t i = 30; // check !!!!
target_water = ((uint32_t) telegram[i + 3] << 24) | ((uint32_t) telegram[i + 2] << 16) |
((uint32_t) telegram[i + 1] << 8) | ((uint32_t) telegram[i + 0]);
// in m3
ret_val = target_water / 1000.0;
ESP_LOGVV(TAG, "Found target_water_consumption with '%d'->'%f'", target_water, ret_val.value());
}

return ret_val;
};

esphome::optional<double> get_flow_temperature_c(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint8_t l_field = telegram[0];
uint8_t tpl_ci_field = telegram[19];

if ((tpl_ci_field == 0x78) && (l_field >= 39)) {
return this->get_615B(telegram);
}

if ((tpl_ci_field == 0x79) && (l_field >= 34)) { // check !!!!
uint32_t temperature{0};
uint8_t i = 34; // check !!!!
temperature = ((uint32_t) telegram[i + 0]);
// in celcius degrees
ret_val = temperature / 1.0;
ESP_LOGVV(TAG, "Found flow_temperature_c with '%d'->'%f'", temperature, ret_val.value());
}

return ret_val;
};

esphome::optional<double> get_external_temperature_c(std::vector<unsigned char> &telegram) {
esphome::optional<double> ret_val{};
uint8_t l_field = telegram[0];
uint8_t tpl_ci_field = telegram[19];

if ((tpl_ci_field == 0x78) && (l_field >= 42)) {
return this->get_6167(telegram);
}

if ((tpl_ci_field == 0x79) && (l_field >= 35)) { // check !!!!
uint32_t temperature{0};
uint8_t i = 35; // check !!!!
temperature = ((uint32_t) telegram[i + 0]);
// in celcius degrees
ret_val = temperature / 1.0;
ESP_LOGVV(TAG, "Found external_temperature_c with '%d'->'%f'", temperature, ret_val.value());
}

return ret_val;
};
};

0 comments on commit c856f7d

Please sign in to comment.