Update Aircon messages.

This commit is contained in:
Your Name 2023-03-19 12:51:56 +01:00
parent 3bc1015f79
commit 7a2bf42454
6 changed files with 161 additions and 164 deletions

View File

@ -150,7 +150,7 @@ void LinBusProtocol::lin_msg_diag_single_(const u_int8_t *message, u_int8_t leng
//}
} else if (broadcast_address && service_identifier == LIN_SID_ASSIGN_NAD && message_length == 6) {
if (this->is_matching_identifier_(&message[3])) {
ESP_LOGI(TAG, "Assigned new SID %02X and reset device", message[7]);
ESP_LOGI(TAG, "Assigned new SID %02X", message[7]);
// send response with old node address.
std::array<u_int8_t, 8> response = this->lin_empty_response_;
@ -158,9 +158,6 @@ void LinBusProtocol::lin_msg_diag_single_(const u_int8_t *message, u_int8_t leng
response[1] = 1; /* bytes length*/
response[2] = LIN_SID_ASSIGN_NAD_RESPONSE;
// assumption an assign new SID occurs as part of init process.
this->lin_reset_device();
this->prepare_update_msg_(response);
this->lin_node_address_ = message[7];
}

View File

@ -200,6 +200,10 @@ StatusFrameAirconResponse *TrumaiNetBoxApp::update_aircon_prepare() {
// prepare status response
this->update_status_aircon_ = {};
this->update_status_aircon_.mode = this->status_aircon_.mode;
this->update_status_aircon_.operation = this->status_aircon_.operation;
this->update_status_aircon_.energy_mix = this->status_aircon_.energy_mix;
this->update_status_aircon_.target_temp_aircon = this->status_aircon_.target_temp_aircon;
this->update_status_aircon_prepared_ = true;
return &this->update_status_aircon_;
@ -301,21 +305,11 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
status_frame_create_empty(response_frame, STATUS_FRAME_AIRCON_RESPONSE, sizeof(StatusFrameAirconResponse),
this->message_counter++);
response_frame->inner.airconResponse.unknown_01 = this->update_status_aircon_.unknown_01;
response_frame->inner.airconResponse.mode = this->update_status_aircon_.mode;
response_frame->inner.airconResponse.unknown_02 = this->update_status_aircon_.unknown_02;
response_frame->inner.airconResponse.unknown_03 = this->update_status_aircon_.unknown_03;
response_frame->inner.airconResponse.unknown_04 = this->update_status_aircon_.unknown_04;
response_frame->inner.airconResponse.target_temp_room = this->update_status_aircon_.target_temp_room;
response_frame->inner.airconResponse.unknown_07 = this->update_status_aircon_.unknown_07;
response_frame->inner.airconResponse.unknown_08 = this->update_status_aircon_.unknown_08;
response_frame->inner.airconResponse.current_temp_aircon = this->update_status_aircon_.current_temp_aircon;
response_frame->inner.airconResponse.unknown_11 = this->update_status_aircon_.unknown_11;
response_frame->inner.airconResponse.unknown_12 = this->update_status_aircon_.unknown_12;
response_frame->inner.airconResponse.unknown_13 = this->update_status_aircon_.unknown_13;
response_frame->inner.airconResponse.unknown_14 = this->update_status_aircon_.unknown_14;
response_frame->inner.airconResponse.unknown_15 = this->update_status_aircon_.unknown_15;
response_frame->inner.airconResponse.unknown_16 = this->update_status_aircon_.unknown_16;
response_frame->inner.airconResponse.current_temp_room = this->update_status_aircon_.current_temp_room;
response_frame->inner.airconResponse.operation = this->update_status_aircon_.operation;
response_frame->inner.airconResponse.energy_mix = this->update_status_aircon_.energy_mix;
response_frame->inner.airconResponse.target_temp_aircon = this->update_status_aircon_.target_temp_aircon;
status_frame_calculate_checksum(response_frame);
(*return_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconResponse);
@ -485,7 +479,7 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
this->status_config_valid_ = true;
this->status_config_updated_ = true;
ESP_LOGD(TAG, "StatusFrameConfig Offset: %.1f", offset_code_to_decimal(this->status_config_.temp_offset));
ESP_LOGD(TAG, "StatusFrameConfig Offset: %.1f", temp_code_to_decimal(this->status_config_.temp_offset));
return response;
} else if (header->message_type == STATUS_FRAME_DEVICES && header->message_length == sizeof(StatusFrameDevice)) {

View File

@ -82,34 +82,42 @@ enum class TargetTemp : u_int16_t {
// 200C
TARGET_TEMP_WATER_BOOST = (200 + 273) * 10,
TARGET_TEMP_05C = (5 + 273) * 10,
TARGET_TEMP_06C = (6 + 273) * 10,
TARGET_TEMP_07C = (7 + 273) * 10,
TARGET_TEMP_08C = (8 + 273) * 10,
TARGET_TEMP_09C = (9 + 273) * 10,
TARGET_TEMP_10C = (10 + 273) * 10,
TARGET_TEMP_11C = (11 + 273) * 10,
TARGET_TEMP_12C = (12 + 273) * 10,
TARGET_TEMP_13C = (13 + 273) * 10,
TARGET_TEMP_14C = (14 + 273) * 10,
TARGET_TEMP_15C = (15 + 273) * 10,
TARGET_TEMP_16C = (16 + 273) * 10,
TARGET_TEMP_17C = (17 + 273) * 10,
TARGET_TEMP_18C = (18 + 273) * 10,
TARGET_TEMP_19C = (19 + 273) * 10,
TARGET_TEMP_20C = (20 + 273) * 10,
TARGET_TEMP_21C = (21 + 273) * 10,
TARGET_TEMP_22C = (22 + 273) * 10,
TARGET_TEMP_23C = (23 + 273) * 10,
TARGET_TEMP_24C = (24 + 273) * 10,
TARGET_TEMP_25C = (25 + 273) * 10,
TARGET_TEMP_26C = (26 + 273) * 10,
TARGET_TEMP_27C = (27 + 273) * 10,
TARGET_TEMP_28C = (28 + 273) * 10,
TARGET_TEMP_29C = (29 + 273) * 10,
TARGET_TEMP_30C = (30 + 273) * 10,
TARGET_TEMP_31C = (31 + 273) * 10,
TARGET_TEMP_ROOM_MIN = (5 + 273) * 10,
TARGET_TEMP_ROOM_05C = (5 + 273) * 10,
TARGET_TEMP_ROOM_06C = (6 + 273) * 10,
TARGET_TEMP_ROOM_07C = (7 + 273) * 10,
TARGET_TEMP_ROOM_08C = (8 + 273) * 10,
TARGET_TEMP_ROOM_09C = (9 + 273) * 10,
TARGET_TEMP_ROOM_10C = (10 + 273) * 10,
TARGET_TEMP_ROOM_11C = (11 + 273) * 10,
TARGET_TEMP_ROOM_12C = (12 + 273) * 10,
TARGET_TEMP_ROOM_13C = (13 + 273) * 10,
TARGET_TEMP_ROOM_14C = (14 + 273) * 10,
TARGET_TEMP_ROOM_15C = (15 + 273) * 10,
TARGET_TEMP_ROOM_16C = (16 + 273) * 10,
TARGET_TEMP_ROOM_17C = (17 + 273) * 10,
TARGET_TEMP_ROOM_18C = (18 + 273) * 10,
TARGET_TEMP_ROOM_19C = (19 + 273) * 10,
TARGET_TEMP_ROOM_20C = (20 + 273) * 10,
TARGET_TEMP_ROOM_21C = (21 + 273) * 10,
TARGET_TEMP_ROOM_22C = (22 + 273) * 10,
TARGET_TEMP_ROOM_23C = (23 + 273) * 10,
TARGET_TEMP_ROOM_24C = (24 + 273) * 10,
TARGET_TEMP_ROOM_25C = (25 + 273) * 10,
TARGET_TEMP_ROOM_26C = (26 + 273) * 10,
TARGET_TEMP_ROOM_27C = (27 + 273) * 10,
TARGET_TEMP_ROOM_28C = (28 + 273) * 10,
TARGET_TEMP_ROOM_29C = (29 + 273) * 10,
TARGET_TEMP_ROOM_30C = (30 + 273) * 10,
TARGET_TEMP_ROOM_MAX = (30 + 273) * 10,
TARGET_TEMP_AIRCON_MIN = (16 + 273) * 10,
TARGET_TEMP_AIRCON_MAX = (31 + 273) * 10,
TARGET_TEMP_AIRCON_AUTO_MIN = (18 + 273) * 10,
TARGET_TEMP_AIRCON_AUTO_MAX = (25 + 273) * 10,
};
enum class EnergyMix : u_int8_t {
@ -151,20 +159,6 @@ enum class ResponseAckResult : u_int8_t {
RESPONSE_ACK_RESULT_ERROR_INVALID_ID = 0x3,
};
enum class TempOffset : u_int8_t {
TEMP_OFFSET_0_0C = (u_int8_t) ((-0.0f + 17) * 10),
TEMP_OFFSET_0_5C = (u_int8_t) ((-0.5f + 17) * 10),
TEMP_OFFSET_1_0C = (u_int8_t) ((-1.0f + 17) * 10),
TEMP_OFFSET_1_5C = (u_int8_t) ((-1.5f + 17) * 10),
TEMP_OFFSET_2_0C = (u_int8_t) ((-2.0f + 17) * 10),
TEMP_OFFSET_2_5C = (u_int8_t) ((-2.5f + 17) * 10),
TEMP_OFFSET_3_0C = (u_int8_t) ((-3.0f + 17) * 10),
TEMP_OFFSET_3_5C = (u_int8_t) ((-3.5f + 17) * 10),
TEMP_OFFSET_4_0C = (u_int8_t) ((-4.0f + 17) * 10),
TEMP_OFFSET_4_5C = (u_int8_t) ((-4.5f + 17) * 10),
TEMP_OFFSET_5_0C = (u_int8_t) ((-5.0f + 17) * 10),
};
enum class ClockMode : u_int8_t {
CLOCK_MODE_24H = 0x0,
CLOCK_MODE_12H = 0x1,
@ -294,10 +288,10 @@ struct StatusFrameConfig { // NOLINT(altera-struct-pack-align)
// 0x01 .. 0x0A
u_int8_t display_brightness;
Language language;
u_int8_t unknown_2; // 0xB4
u_int8_t unknown_3; // 0x0A
TempOffset temp_offset;
u_int8_t unknown_5; // 0x0A
// Mit „AC SET“ wird ein Offset zwischen Kühlen und Heizen eingestellt.
// Die Einstellung ist in Schritten von 0,5 °C im Bereich von 0 °C bis +5 °C möglich.
TargetTemp ac_offset;
TargetTemp temp_offset;
OperatingUnits temp_units;
u_int8_t unknown_6;
u_int8_t unknown_7;
@ -341,18 +335,28 @@ struct StatusFrameDevice { // NOLINT(altera-struct-pack-align)
u_int8_t unknown_3;
} __attribute__((packed));
enum class AirconMode : u_int8_t {
// Auto - 18 to 25
OFF = 0x00,
AC_VENTILATION = 0x04,
AC_COOLING = 0x05,
};
enum class AirconOperation : u_int8_t {
AC_ONLY = 0x71,
// Heater and Aircon
AUTO = 0x72,
};
// Length 18 (0x12)
// TODO
struct StatusFrameAircon { // NOLINT(altera-struct-pack-align)
// Mode? 00 - OFF, 04 - AC Ventilation, 05 - AC Cooling
u_int8_t unknown_01;
AirconMode mode;
// 0x00
u_int8_t unknown_02;
// 0x71
u_int8_t unknown_03;
// 0x01
u_int8_t unknown_04;
TargetTemp target_temp_room;
AirconOperation operation;
EnergyMix energy_mix;
TargetTemp target_temp_aircon;
// 0x00
u_int8_t unknown_07;
// 0x00
@ -363,10 +367,7 @@ struct StatusFrameAircon { // NOLINT(altera-struct-pack-align)
u_int8_t unknown_11;
// 0x00
u_int8_t unknown_12;
// 0x00
u_int8_t unknown_13;
// 0x00
u_int8_t unknown_14;
ElectricPowerLevel el_power_level;
// 0x00
u_int8_t unknown_15;
// 0x00
@ -374,55 +375,29 @@ struct StatusFrameAircon { // NOLINT(altera-struct-pack-align)
TargetTemp current_temp_room;
} __attribute__((packed));
// TODO
struct StatusFrameAirconResponse { // NOLINT(altera-struct-pack-align)
// Mode? 00 - OFF, 04 - AC Ventilation, 05 - AC Cooling
u_int8_t unknown_01;
AirconMode mode;
// 0x00
u_int8_t unknown_02;
// 0x71
u_int8_t unknown_03;
// 0x01
u_int8_t unknown_04;
TargetTemp target_temp_room;
// 0x00
u_int8_t unknown_07;
// 0x00
u_int8_t unknown_08;
// No idea why two current_temp
TargetTemp current_temp_aircon;
// 0x00
u_int8_t unknown_11;
// 0x00
u_int8_t unknown_12;
// 0x00
u_int8_t unknown_13;
// 0x00
u_int8_t unknown_14;
// 0x00
u_int8_t unknown_15;
// 0x00
u_int8_t unknown_16;
TargetTemp current_temp_room;
AirconOperation operation;
EnergyMix energy_mix;
TargetTemp target_temp_aircon;
} __attribute__((packed));
// Length 18 (0x12)
// TODO
struct StatusFrameAircon2 { // NOLINT(altera-struct-pack-align)
u_int8_t unknown_01; // 0x01
EnergyMix energy_mix_a;
u_int8_t unknown_02; // 0x00
u_int8_t unknown_03; // 0x01
EnergyMix energy_mix_b;
u_int8_t unknown_04; // 0x00
u_int8_t unknown_05; // 0x00
u_int8_t unknown_06; // 0x00
u_int8_t unknown_07; // 0x00
u_int8_t unknown_08; // 0x00
u_int8_t unknown_09; // 0x00
u_int8_t unknown_10; // 0x00
TargetTemp target_temp_aircon_auto;
ElectricPowerLevel el_power_level_a;
u_int8_t unknown_11; // 0x00
u_int8_t unknown_12; // 0x00
u_int8_t unknown_13; // 0x00
u_int8_t unknown_14; // 0x00
ElectricPowerLevel el_power_level_b;
TargetTemp current_temp;
TargetTemp target_temp;
} __attribute__((packed));
@ -432,8 +407,8 @@ struct StatusFrameAircon2 { // NOLINT(altera-struct-pack-align)
struct StatusFrameAirconInit { // NOLINT(altera-struct-pack-align)
u_int8_t unknown_01; // 0x00
u_int8_t unknown_02; // 0x00
u_int8_t unknown_03; // 0x71
u_int8_t unknown_04; // 0x01
AirconOperation operation;
EnergyMix energy_mix;
u_int8_t unknown_05; // 0x00
u_int8_t unknown_06; // 0x00
u_int8_t unknown_07; // 0x00
@ -457,9 +432,9 @@ struct StatusFrameAirconInit { // NOLINT(altera-struct-pack-align)
// Length 20 (0x14)
// TODO
struct StatusFrameAirconInit2 { // NOLINT(altera-struct-pack-align)
u_int8_t unknown_01; // 0x01
EnergyMix energy_mix_a;
u_int8_t unknown_02; // 0x00
u_int8_t unknown_03; // 0x01
EnergyMix energy_mix_b;
u_int8_t unknown_04; // 0x00
u_int8_t unknown_05; // 0x00
u_int8_t unknown_06; // 0x00

View File

@ -56,7 +56,7 @@ bool TrumaiNetBoxApp::action_heater_water(u_int8_t temperature) {
}
auto heater = this->update_heater_prepare();
heater->target_temp_water = deciaml_to_water_temp(temperature);
heater->target_temp_water = decimal_to_water_temp(temperature);
// Ensure `energy_mix_a` is set.
if (heater->target_temp_water != TargetTemp::TARGET_TEMP_OFF && heater->energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
@ -209,7 +209,7 @@ bool TrumaiNetBoxApp::action_timer_activate(u_int16_t start, u_int16_t stop, u_i
}
}
timer->timer_target_temp_water = deciaml_to_water_temp(water_temperature);
timer->timer_target_temp_water = decimal_to_water_temp(water_temperature);
// If parameter `el_power_level` contains a valid mode use it.
if (el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0 ||

View File

@ -31,6 +31,10 @@ float temp_code_to_decimal(u_int16_t val, float zero) {
float temp_code_to_decimal(TargetTemp val, float zero) { return temp_code_to_decimal((u_int16_t) val, zero); }
TargetTemp decimal_to_temp(u_int8_t val) { return (TargetTemp) ((((u_int16_t) val) + 273) * 10); }
TargetTemp decimal_to_temp(float val) { return (TargetTemp) ((val + 273) * 10); }
TargetTemp decimal_to_room_temp(u_int8_t val) {
if (val == 0) {
return TargetTemp::TARGET_TEMP_OFF;
@ -41,7 +45,7 @@ TargetTemp decimal_to_room_temp(u_int8_t val) {
if (val >= 30) {
return TargetTemp::TARGET_TEMP_ROOM_MAX;
}
return (TargetTemp) ((((u_int16_t) val) + 273) * 10);
return decimal_to_temp(val);
}
TargetTemp decimal_to_room_temp(float val) {
@ -54,10 +58,36 @@ TargetTemp decimal_to_room_temp(float val) {
if (val >= 30) {
return TargetTemp::TARGET_TEMP_ROOM_MAX;
}
return (TargetTemp) ((val + 273) * 10);
return decimal_to_temp(val);
}
TargetTemp deciaml_to_water_temp(u_int8_t val) {
TargetTemp decimal_to_aircon_temp(u_int8_t val) {
if (val == 0) {
return TargetTemp::TARGET_TEMP_OFF;
}
if (val <= 16) {
return TargetTemp::TARGET_TEMP_AIRCON_MIN;
}
if (val >= 31) {
return TargetTemp::TARGET_TEMP_AIRCON_MAX;
}
return decimal_to_temp(val);
}
TargetTemp decimal_to_aircon_temp(float val) {
if (val == NAN) {
return TargetTemp::TARGET_TEMP_OFF;
}
if (val <= 16) {
return TargetTemp::TARGET_TEMP_AIRCON_MIN;
}
if (val >= 31) {
return TargetTemp::TARGET_TEMP_AIRCON_MAX;
}
return decimal_to_temp(val);
}
TargetTemp decimal_to_water_temp(u_int8_t val) {
if (val < 40) {
return TargetTemp::TARGET_TEMP_OFF;
} else if (val >= 40 && val < 60) {
@ -69,8 +99,6 @@ TargetTemp deciaml_to_water_temp(u_int8_t val) {
}
}
float offset_code_to_decimal(TempOffset val) { return ((float) val) / 10.0f - 17.0f; }
const std::string operating_status_to_str(OperatingStatus val) {
if (val == OperatingStatus::OPERATING_STATUS_OFF) {
return "OFF";

View File

@ -12,10 +12,13 @@ u_int8_t addr_parity(const u_int8_t pid);
u_int8_t data_checksum(const u_int8_t *message, u_int8_t length, uint16_t sum);
float temp_code_to_decimal(u_int16_t val, float zero = NAN);
float temp_code_to_decimal(TargetTemp val, float zero = NAN);
TargetTemp decimal_to_temp(u_int8_t val);
TargetTemp decimal_to_temp(float val);
TargetTemp decimal_to_room_temp(u_int8_t val);
TargetTemp decimal_to_room_temp(float val);
TargetTemp deciaml_to_water_temp(u_int8_t val);
float offset_code_to_decimal(TempOffset val);
TargetTemp decimal_to_aircon_temp(u_int8_t val);
TargetTemp decimal_to_aircon_temp(float val);
TargetTemp decimal_to_water_temp(u_int8_t val);
const std::string operating_status_to_str(OperatingStatus val);
ElectricPowerLevel decimal_to_el_power_level(u_int16_t val);