Skip to content

Commit

Permalink
feat: Add ThermostatHello packet handling
Browse files Browse the repository at this point in the history
- Add a log line of interest to error packet
- Define compressor_frequency as NaN to start
  • Loading branch information
KazWolfe committed Mar 31, 2024
1 parent 0299f0f commit 0e04fa6
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -301,12 +301,17 @@ void MitsubishiUART::processPacket(const ErrorStateGetResponsePacket &packet) {
// TODO: Include friendly text from JSON, somehow.
if (!packet.errorPresent()) {
error_code_sensor->raw_state = "No Error Reported";
} else if (packet.getRawShortCode() != 0x00) {
} else if (auto rawCode = packet.getRawShortCode() != 0x00) {
// Not that it matters, but good for validation I guess.
if ((rawCode & 0x1F) > 0x15) {
ESP_LOGW(TAG, "Error short code %x had invalid low bits. This is an IT protocol violation!", rawCode);
}

error_code_sensor->raw_state = "Error " + packet.getShortCode();
} else if (packet.getErrorCode() != 0x8000) {
error_code_sensor->raw_state = "Error " + to_string(packet.getErrorCode());
} else {
// Logic bug :(
// Logic bug, should never happen.
ESP_LOGW(TAG, "Packet indicated an error was present, but none of the error states matched. wat.");
}

Expand Down
4 changes: 2 additions & 2 deletions components/mitsubishi_uart/muart_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,8 @@ void MUARTBridge::classifyAndProcessRawPacket(RawPacket &pkt) const {
case SetCommand::settings :
processRawPacket<SettingsSetRequestPacket>(pkt, true);
break;
case SetCommand::a_7 :
processRawPacket<A7SetRequestPacket>(pkt, false);
case SetCommand::thermostat_hello :
processRawPacket<ThermostatHelloRequestPacket>(pkt, false);
break;
default:
processRawPacket<Packet>(pkt, true);
Expand Down
21 changes: 21 additions & 0 deletions components/mitsubishi_uart/muart_packet-derived.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "muart_packet.h"
#include "mitsubishi_uart.h"
#include "muart_utils.h"

namespace esphome {
namespace mitsubishi_uart {
Expand Down Expand Up @@ -70,6 +71,12 @@ std::string RemoteTemperatureSetRequestPacket::to_string() const {
return ("Remote Temp Set Request: " + Packet::to_string() + CONSOLE_COLOR_PURPLE +
"\n Temp:" + std::to_string(getRemoteTemperature()));
}
std::string ThermostatHelloRequestPacket::to_string() const {
return("Thermostat Hello: " + Packet::to_string() + CONSOLE_COLOR_PURPLE +
"\n Model: " + getThermostatModel() +
" Serial: " + getThermostatSerial() +
" Version: " + getThermostatVersionString());
}

// TODO: Are there function implementations for packets in the .h file? (Yes) Should they be here?

Expand Down Expand Up @@ -262,6 +269,20 @@ std::string ErrorStateGetResponsePacket::getShortCode() const {
return {upperAlphabet[(errorCode & 0xE0) >> 5], lowerAlphabet[lowBits]};
}

// ThermostatHelloRequestPacket functions
std::string ThermostatHelloRequestPacket::getThermostatModel() const {
return MUARTUtils::DecodeNBitString((pkt_.getBytes() + 1), 3, 6);
}

std::string ThermostatHelloRequestPacket::getThermostatSerial() const {
return MUARTUtils::DecodeNBitString((pkt_.getBytes() + 4), 8, 6);
}

std::string ThermostatHelloRequestPacket::getThermostatVersionString() const {
char buf[9];
sprintf(buf, "%02d.%02d.%02d", pkt_.getPayloadByte(13), pkt_.getPayloadByte(14), pkt_.getPayloadByte(15));
return buf;
}

} // namespace mitsubishi_uart
} // namespace esphome
12 changes: 9 additions & 3 deletions components/mitsubishi_uart/muart_packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,12 +356,18 @@ class RemoteTemperatureSetResponsePacket : public Packet {
};

// Sent by MHK2 but with no response; defined to allow setResponseExpected(false)
class A7SetRequestPacket : public Packet {
class ThermostatHelloRequestPacket : public Packet {
using Packet::Packet;
public:
A7SetRequestPacket() : Packet(RawPacket(PacketType::set_request, 4)) {
pkt_.setPayloadByte(0, static_cast<uint8_t>(SetCommand::a_7));
ThermostatHelloRequestPacket() : Packet(RawPacket(PacketType::set_request, 4)) {
pkt_.setPayloadByte(0, static_cast<uint8_t>(SetCommand::thermostat_hello));
}

std::string getThermostatModel() const;
std::string getThermostatSerial() const;
std::string getThermostatVersionString() const;

std::string to_string() const override;
};

// Sent by MHK2 but with no response; defined to allow setResponseExpected(false)
Expand Down
2 changes: 1 addition & 1 deletion components/mitsubishi_uart/muart_rawpacket.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ enum class GetCommand : uint8_t {
enum class SetCommand : uint8_t {
settings = 0x01,
remote_temperature = 0x07,
a_7 = 0xa7
thermostat_hello = 0xa7
};

// Which MUARTBridge was the packet read from (used to determine flow direction of the packet)
Expand Down
38 changes: 38 additions & 0 deletions components/mitsubishi_uart/muart_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include "mitsubishi_uart.h"

namespace esphome {
namespace mitsubishi_uart {

class MUARTUtils {
public:
static std::string DecodeNBitString(const uint8_t data[], size_t dataLength, size_t wordSize) {
auto resultLength = (dataLength / wordSize) + (dataLength % wordSize != 0);
auto result = std::string();

for (int i = 0; i < resultLength; i++) {
auto bits = BitSlice(data, i * wordSize, ((i + 1) * wordSize) - 1);
if (bits <= 0x1F) bits += 0x40;
result += (char)bits;
}

return result;
}

private:
static uint64_t BitSlice(const uint8_t ds[], size_t start, size_t end) {
// Lazies! https://stackoverflow.com/a/25297870/1817097
uint64_t s = 0;
size_t i, n = (end - 1) / 8;
for(i = 0; i <= n; ++i)
s = (s << 8) + ds[i];
s >>= (n+1) * 8 - end;
uint64_t mask = (((uint64_t)1) << (end - start + 1))-1;//len = end - start + 1
s &= mask;
return s;
}
};

} // namespace mitsubishi_uart
} // namespace esphome

0 comments on commit 0e04fa6

Please sign in to comment.