Skip to content

Commit

Permalink
vaillantx6.cpp aktualisieren
Browse files Browse the repository at this point in the history
  • Loading branch information
Safi105 authored Nov 13, 2024
1 parent c9594df commit 25a93e0
Showing 1 changed file with 178 additions and 0 deletions.
178 changes: 178 additions & 0 deletions esphome/components/vaillantx6/vaillantx6.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
#include "vaillantx6.h"

Check failure on line 1 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

File does not end with a newline, please add an empty line at the end of the file.

Check failure on line 1 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

Invalid namespace found in C++ file. All integration C++ files should put all functions in a separate namespace that matches the integration's name. Please make sure the file contains namespace vaillantx6

void logCmd(const char *tag, byte *cmd) {
ESP_LOGD("Vaillantx6", "%s: 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x", tag, cmd[0], cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6]);
}

uint8_t VaillantReturnTypeLength(VaillantReturnTypes t) {
switch (t) {
case SensorState:
case Bool:
case Minutes:
return 1;
case Temperature:
return 2;
default:
return 0;
}
}

float VaillantParseTemperature(byte *answerBuff, uint8_t offset) {
int16_t i = (answerBuff[offset] << 8) | answerBuff[offset + 1];
return i / (16.0f);
}

int VaillantParseBool(byte *answerBuff, uint8_t offset) {
switch (answerBuff[offset]) {
case 0xF0:
case 0x00:
return 0;
case 0x0F:
case 0x01:
return 1;
default:
ESP_LOGE("VaillantParseBool", "Unable to parse a bool from 0x%.2x", answerBuff[offset]);
return -1;
}
}

const VaillantCommand vaillantCommands[] = {
{"Vorlauf Ist", 0x18, Temperature},
{"Aussen Temperatur", 0x6A, Temperature},
{"Vorlauf Soll", 0x39, Temperature},
{"Vorlauf 789 Soll", 0x25, Temperature},
{"Rücklauf Ist", 0x98, Temperature},
{"Speicher Ist", 0x17, Temperature},
{"Speicher Soll", 0x04, Temperature},
{"Brauchwasser Ist", 0x16, Temperature},
{"Brauchwasser Soll", 0x01, Temperature},
{"Drehzahl Soll", 0x24, Temperature},
{"Drehzahl Ist", 0x83, Temperature},
{"Brenner", 0x0d, Bool},
{"Winter", 0x08, Bool},
{"Pumpe", 0x44, Bool},
{"Flammsignal", 0x05, Bool},
{"Gasmagnetventil", 0x48, Bool},
{"Zünder", 0x49, Bool},
{"Verbliebene Brennsperrzeit", 0x38, Minutes},
};

const byte vaillantCommandsSize = sizeof(vaillantCommands) / sizeof *(vaillantCommands);

Check failure on line 60 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

The datatype byte is not allowed to be used in ESPHome. Please use uint8_t instead.

Vaillantx6Sensor::Vaillantx6Sensor(UARTComponent *parent, const VaillantCommand *command, uint32_t update_interval)

Check failure on line 62 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

Trailing whitespace detected
: PollingComponent(update_interval), UARTDevice(parent), command_(command) {}

void Vaillantx6Sensor::set_sensor(Sensor *sensor) {
sensor_ = sensor;
}

void Vaillantx6Sensor::set_binary_sensor(BinarySensor *binary_sensor) {
binary_sensor_ = binary_sensor;
}

byte Vaillantx6Sensor::checksum(byte *data, byte len) {
byte checksum = 0;

Check failure on line 74 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

The datatype byte is not allowed to be used in ESPHome. Please use uint8_t instead.
for (byte i = 0; i < len; i++) {

Check failure on line 75 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

The datatype byte is not allowed to be used in ESPHome. Please use uint8_t instead.
if (checksum & 0x80) {
checksum = (checksum << 1) | 1;
checksum = checksum ^ 0x18;
} else {
checksum = checksum << 1;
}
checksum = checksum ^ data[i];
}
return checksum;
}

bool Vaillantx6Sensor::checksumOk(byte *answerBuff, byte len) {
logCmd("Answer", answerBuff);
return checksum(answerBuff, len - 1) == answerBuff[len - 1];
}

int Vaillantx6Sensor::buildPacket(byte *packet, byte address) {
const byte startBytes[4] = {0x07, 0x00, 0x00, 0x00};
int i = 0;
while (i < sizeof(startBytes)) {
packet[i] = startBytes[i];
i++;
}
packet[i] = address;
i++;
packet[i] = 0x00;
i++;
packet[i] = checksum(packet, 6);
return i;
}

int Vaillantx6Sensor::sendPacket(byte *answerBuff, byte *packet) {
int answerLen = 0;
int readRetry = 3;
write_array(packet, CMD_LENGTH);

while (available() < 1) {
delay(50);

Check failure on line 113 in esphome/components/vaillantx6/vaillantx6.cpp

View workflow job for this annotation

GitHub Actions / Run script/ci-custom

delay(50); - long calls to delay() are not allowed in ESPHome because everything executes in one thread. Calling delay() will block the main thread and slow down ESPHome.
readRetry--;
if (readRetry < 0) {
ESP_LOGE("Vaillantx6 sendPacket", "Timed out waiting for bytes from Vaillant");
return -3;
}
}
answerLen = peek();

if (answerLen > ANSWER_LENGTH) {
ESP_LOGE("Vaillantx6 sendPacket", "Received an answer of unexpected length %d, ignoring", answerLen);
while (available()) {
read();
}
return -1;
}
read_array(answerBuff, answerLen);
if (!checksumOk(answerBuff, answerLen)) {
ESP_LOGE("Vaillantx6 sendPacket", "Packet has invalid checksum");
while (available()) {
read();
}
return -2;
}
return answerLen;
}

void Vaillantx6Sensor::update() {
byte *cmdPacket = (byte *)malloc(sizeof(byte) * CMD_LENGTH);
byte *answerBuff = (byte *)malloc(sizeof(byte) * ANSWER_LENGTH);

buildPacket(cmdPacket, command_->Address);
logCmd(command_->Name.c_str(), cmdPacket);

int answerLen = sendPacket(answerBuff, cmdPacket);
if (answerLen < 0) {
ESP_LOGE("Vaillantx6", "sendPacket returned an error: %d", answerLen);
} else if (answerLen > 3) {
switch (command_->ReturnType) {
case Temperature:
if (sensor_ != nullptr) {
float temp = VaillantParseTemperature(answerBuff, 2);
sensor_->publish_state(temp);
}
break;
case Bool:
if (binary_sensor_ != nullptr) {
int b = VaillantParseBool(answerBuff, 2);
if (b >= 0) {
binary_sensor_->publish_state(b);
}
}
break;
case Minutes:
if (sensor_ != nullptr) {
sensor_->publish_state(answerBuff[2]);
}
break;
default:
break;
}
}

free(cmdPacket);
free(answerBuff);
}

0 comments on commit 25a93e0

Please sign in to comment.