diff --git a/components/truma_inetbox/TrumaiNetBoxApp.cpp b/components/truma_inetbox/TrumaiNetBoxApp.cpp index 78f78dd..7081446 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.cpp +++ b/components/truma_inetbox/TrumaiNetBoxApp.cpp @@ -70,14 +70,11 @@ void TrumaiNetBoxApp::lin_reset_device() { this->heater_.reset(); this->timer_.reset(); + this->airconManual_.reset(); this->clock_.reset(); this->config_.reset(); this->update_time_ = 0; - - this->update_status_aircon_prepared_ = false; - this->update_status_aircon_unsubmitted_ = false; - this->update_status_aircon_stale_ = false; } template void TrumaStausFrameStorage::reset() { @@ -137,21 +134,21 @@ StatusFrameTimerResponse *TrumaiNetBoxApp::update_timer_prepare() { return &this->timer_.update_status_; } -StatusFrameAirconResponse *TrumaiNetBoxApp::update_aircon_prepare() { +StatusFrameAirconManualResponse *TrumaiNetBoxApp::update_aircon_prepare() { // An update is currently going on. - if (this->update_status_aircon_prepared_ || this->update_status_aircon_stale_) { - return &this->update_status_aircon_; + if (this->airconManual_.update_status_prepared_ || this->airconManual_.update_status_stale_) { + return &this->airconManual_.update_status_; } // 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->airconManual_.update_status_ = {}; + this->airconManual_.update_status_.mode = this->airconManual_.data_.mode; + this->airconManual_.update_status_.operation = this->airconManual_.data_.operation; + this->airconManual_.update_status_.energy_mix = this->airconManual_.data_.energy_mix; + this->airconManual_.update_status_.target_temp_aircon = this->airconManual_.data_.target_temp_aircon; - this->update_status_aircon_prepared_ = true; - return &this->update_status_aircon_; + this->airconManual_.update_status_prepared_ = true; + return &this->airconManual_.update_status_; } bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) { @@ -244,25 +241,25 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message this->timer_.update_status_unsubmitted_ = false; this->timer_.update_status_stale_ = true; return response; - } else if (this->update_status_aircon_unsubmitted_) { + } else if (this->airconManual_.update_status_unsubmitted_) { ESP_LOGD(TAG, "Requested read: Sending aircon update"); - status_frame_create_empty(response_frame, STATUS_FRAME_AIRCON_RESPONSE, sizeof(StatusFrameAirconResponse), + status_frame_create_empty(response_frame, STATUS_FRAME_AIRCON_MANUAL_RESPONSE, sizeof(StatusFrameAirconManualResponse), this->message_counter++); - 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.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; + response_frame->inner.airconManualResponse.mode = this->airconManual_.update_status_.mode; + response_frame->inner.airconManualResponse.unknown_02 = this->airconManual_.update_status_.unknown_02; + response_frame->inner.airconManualResponse.operation = this->airconManual_.update_status_.operation; + response_frame->inner.airconManualResponse.energy_mix = this->airconManual_.update_status_.energy_mix; + response_frame->inner.airconManualResponse.target_temp_aircon = this->airconManual_.update_status_.target_temp_aircon; status_frame_calculate_checksum(response_frame); - (*return_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconResponse); + (*return_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconManualResponse); this->update_time_ = 0; - this->update_status_aircon_prepared_ = false; - this->update_status_aircon_unsubmitted_ = false; - this->update_status_aircon_stale_ = true; + this->airconManual_.update_status_prepared_ = false; + this->airconManual_.update_status_unsubmitted_ = false; + this->airconManual_.update_status_stale_ = true; return response; #ifdef USE_TIME } else if (this->update_status_clock_unsubmitted_) { @@ -310,8 +307,8 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message this->heater_.update_status_stale_ = false; return response; - } else if (header->message_type == STATUS_FRAME_AIRCON && header->message_length == sizeof(StatusFrameAircon)) { - ESP_LOGI(TAG, "StatusFrameAircon"); + } else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL && header->message_length == sizeof(StatusFrameAirconManual)) { + ESP_LOGI(TAG, "StatusFrameAirconManual"); // Example: // SID<---------PREAMBLE---------->|<---MSG_HEAD---->| // - ac temps form 16 - 30 C in +2 steps @@ -331,28 +328,28 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.12.35.00.C2.04.00.71.01.D6.0B.00.00.88.0B.00.00.00.00.00.00.AA.0A // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.12.35.00.13.04.00.71.01.86.0B.00.00.88.0B.00.00.00.00.00.00.AA.0A // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.12.35.00.A8.00.00.71.01.00.00.00.00.88.0B.00.00.00.00.00.00.AA.0A - this->status_aircon_ = statusFrame->inner.aircon; - this->status_aircon_valid_ = true; - this->status_aircon_updated_ = true; + this->airconManual_.data_ = statusFrame->inner.airconManual; + this->airconManual_.data_valid_ = true; + this->airconManual_.data_updated_ = true; - this->update_status_aircon_stale_ = false; + this->airconManual_.update_status_stale_ = false; return response; - } else if (header->message_type == STATUS_FRAME_AIRCON_INIT && - header->message_length == sizeof(StatusFrameAirconInit)) { - ESP_LOGI(TAG, "StatusFrameAirconInit"); + } else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL_INIT && + header->message_length == sizeof(StatusFrameAirconManualInit)) { + ESP_LOGI(TAG, "StatusFrameAirconManualInit"); // Example: // SID<---------PREAMBLE---------->|<---MSG_HEAD---->| // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.16.3F.00.E2.00.00.71.01.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00 return response; - } else if (header->message_type == STATUS_FRAME_AIRCON_2 && header->message_length == sizeof(StatusFrameAircon2)) { - ESP_LOGI(TAG, "StatusFrameAircon2"); + } else if (header->message_type == STATUS_FRAME_AIRCON_AUTO && header->message_length == sizeof(StatusFrameAirconAuto)) { + ESP_LOGI(TAG, "StatusFrameAirconAuto"); // Example: // SID<---------PREAMBLE---------->|<---MSG_HEAD---->| // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.12.37.00.BF.01.00.01.00.00.00.00.00.00.00.00.00.00.00.49.0B.40.0B return response; - } else if (header->message_type == STATUS_FRAME_AIRCON_INIT_2 && - header->message_length == sizeof(StatusFrameAirconInit2)) { - ESP_LOGI(TAG, "StatusFrameAirconInit2"); + } else if (header->message_type == STATUS_FRAME_AIRCON_AUTO_INIT && + header->message_length == sizeof(StatusFrameAirconAutoInit)) { + ESP_LOGI(TAG, "StatusFrameAirconAutoInit"); // Example: // SID<---------PREAMBLE---------->|<---MSG_HEAD---->| // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.14.41.00.53.01.00.01.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00.00 @@ -431,7 +428,7 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message ESP_LOGI(TAG, "StatusFrameDevice"); // This message is special. I recieve one response per registered (at CP plus) device. // Example: - // SID<---------PREAMBLE---------->|<---MSG_HEAD---->|count|??|??|Hardware|Software|??|?? + // SID<---------PREAMBLE---------->|<---MSG_HEAD---->|count|st|??|Hardware|Software|??|?? // Combi4 // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.79.02.00.01.00.50.00.00.04.03.02.AD.10 - C4.03.02 0050.00 // BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.27.02.01.01.00.40.03.22.02.00.01.00.00 - H2.00.01 0340.22 @@ -454,7 +451,7 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message const auto truma_device = static_cast(device.software_revision[0]); { bool found_unknown_value = false; - if (device.unknown_0 != 0x01 || device.unknown_1 != 0x00) + if (device.unknown_1 != 0x00) found_unknown_value = true; if (truma_device != TRUMA_DEVICE::AIRCON_DEVICE && truma_device != TRUMA_DEVICE::HEATER_COMBI4 && truma_device != TRUMA_DEVICE::HEATER_VARIO && truma_device != TRUMA_DEVICE::CPPLUS_COMBI && @@ -502,7 +499,7 @@ bool TrumaiNetBoxApp::has_update_to_submit_() { return true; } } else if (this->heater_.update_status_unsubmitted_ || this->timer_.update_status_unsubmitted_ || - this->update_status_clock_unsubmitted_ || this->update_status_aircon_unsubmitted_) { + this->update_status_clock_unsubmitted_ || this->airconManual_.update_status_unsubmitted_) { if (this->update_time_ == 0) { // ESP_LOGD(TAG, "Notify CP Plus I got updates."); this->update_time_ = micros(); diff --git a/components/truma_inetbox/TrumaiNetBoxApp.h b/components/truma_inetbox/TrumaiNetBoxApp.h index 72ba086..64ea03e 100644 --- a/components/truma_inetbox/TrumaiNetBoxApp.h +++ b/components/truma_inetbox/TrumaiNetBoxApp.h @@ -32,16 +32,16 @@ namespace truma_inetbox { #define STAUTS_FRAME_CONFIG 0x17 #define STATUS_FRAME_HEATER_RESPONSE (STATUS_FRAME_HEATER - 1) #define STATUS_FRAME_HEATER 0x33 -#define STATUS_FRAME_AIRCON_RESPONSE (STATUS_FRAME_AIRCON - 1) -#define STATUS_FRAME_AIRCON 0x35 -#define STATUS_FRAME_AIRCON_2_RESPONSE (STATUS_FRAME_AIRCON_2 - 1) -#define STATUS_FRAME_AIRCON_2 0x37 +#define STATUS_FRAME_AIRCON_MANUAL_RESPONSE (STATUS_FRAME_AIRCON_MANUAL - 1) +#define STATUS_FRAME_AIRCON_MANUAL 0x35 +#define STATUS_FRAME_AIRCON_AUTO_RESPONSE (STATUS_FRAME_AIRCON_AUTO - 1) +#define STATUS_FRAME_AIRCON_AUTO 0x37 #define STATUS_FRAME_TIMER_RESPONSE (STATUS_FRAME_TIMER - 1) #define STATUS_FRAME_TIMER 0x3D -#define STATUS_FRAME_AIRCON_INIT_RESPONSE (STATUS_FRAME_AIRCON_INIT - 1) -#define STATUS_FRAME_AIRCON_INIT 0x3F -#define STATUS_FRAME_AIRCON_INIT_2_RESPONSE (STATUS_FRAME_AIRCON_INIT_2 - 1) -#define STATUS_FRAME_AIRCON_INIT_2 0x41 +#define STATUS_FRAME_AIRCON_MANUAL_INIT_RESPONSE (STATUS_FRAME_AIRCON_MANUAL_INIT - 1) +#define STATUS_FRAME_AIRCON_MANUAL_INIT 0x3F +#define STATUS_FRAME_AIRCON_AUTO_INIT_RESPONSE (STATUS_FRAME_AIRCON_AUTO_INIT - 1) +#define STATUS_FRAME_AIRCON_AUTO_INIT 0x41 enum class HeatingMode : u_int16_t { HEATING_MODE_OFF = 0x0, @@ -315,12 +315,16 @@ enum class TRUMA_DEVICE : u_int8_t { HEATER_COMBI6D = 0x06, }; +enum class TRUMA_DEVICE_STATE : u_int8_t{ + OFFLINE = 0x00, + ONLINE = 0x01, +}; + // Length 12 (0x0C) struct StatusFrameDevice { // NOLINT(altera-struct-pack-align) u_int8_t device_count; u_int8_t device_id; - // 0x01 - Maybe active or found - u_int8_t unknown_0; + TRUMA_DEVICE_STATE state; // 0x00 u_int8_t unknown_1; u_int16_t hardware_revision_major; @@ -351,7 +355,7 @@ enum class AirconOperation : u_int8_t { // Length 18 (0x12) // TODO -struct StatusFrameAircon { // NOLINT(altera-struct-pack-align) +struct StatusFrameAirconManual { // NOLINT(altera-struct-pack-align) AirconMode mode; // 0x00 u_int8_t unknown_02; @@ -376,7 +380,7 @@ struct StatusFrameAircon { // NOLINT(altera-struct-pack-align) TargetTemp current_temp_room; } __attribute__((packed)); -struct StatusFrameAirconResponse { // NOLINT(altera-struct-pack-align) +struct StatusFrameAirconManualResponse { // NOLINT(altera-struct-pack-align) AirconMode mode; // 0x00 u_int8_t unknown_02; @@ -385,29 +389,11 @@ struct StatusFrameAirconResponse { // NOLINT(altera-struct-pack-align) TargetTemp target_temp_aircon; } __attribute__((packed)); -// Length 18 (0x12) -// TODO -struct StatusFrameAircon2 { // NOLINT(altera-struct-pack-align) - EnergyMix energy_mix_a; - u_int8_t unknown_02; // 0x00 - EnergyMix energy_mix_b; - u_int8_t unknown_04; // 0x00 - u_int8_t unknown_05; // 0x00 - u_int8_t unknown_06; // 0x00 - TargetTemp target_temp_aircon_auto; - ElectricPowerLevel el_power_level_a; - u_int8_t unknown_11; // 0x00 - u_int8_t unknown_12; // 0x00 - ElectricPowerLevel el_power_level_b; - TargetTemp current_temp; - TargetTemp target_temp; -} __attribute__((packed)); - // Length 22 (0x16) // TODO -struct StatusFrameAirconInit { // NOLINT(altera-struct-pack-align) - u_int8_t unknown_01; // 0x00 - u_int8_t unknown_02; // 0x00 +struct StatusFrameAirconManualInit { // NOLINT(altera-struct-pack-align) + u_int8_t unknown_01; // 0x00 + u_int8_t unknown_02; // 0x00 AirconOperation operation; EnergyMix energy_mix; u_int8_t unknown_05; // 0x00 @@ -430,9 +416,27 @@ struct StatusFrameAirconInit { // NOLINT(altera-struct-pack-align) u_int8_t unknown_22; // 0x00 } __attribute__((packed)); +// Length 18 (0x12) +// TODO +struct StatusFrameAirconAuto { // NOLINT(altera-struct-pack-align) + EnergyMix energy_mix_a; + u_int8_t unknown_02; // 0x00 + EnergyMix energy_mix_b; + u_int8_t unknown_04; // 0x00 + u_int8_t unknown_05; // 0x00 + u_int8_t unknown_06; // 0x00 + TargetTemp target_temp_aircon_auto; + ElectricPowerLevel el_power_level_a; + u_int8_t unknown_11; // 0x00 + u_int8_t unknown_12; // 0x00 + ElectricPowerLevel el_power_level_b; + TargetTemp current_temp; + TargetTemp target_temp; +} __attribute__((packed)); + // Length 20 (0x14) // TODO -struct StatusFrameAirconInit2 { // NOLINT(altera-struct-pack-align) +struct StatusFrameAirconAutoInit { // NOLINT(altera-struct-pack-align) EnergyMix energy_mix_a; u_int8_t unknown_02; // 0x00 EnergyMix energy_mix_b; @@ -468,11 +472,11 @@ union StatusFrame { // NOLINT(altera-struct-pack-align) StatusFrameClock clock; StatusFrameConfig config; StatusFrameDevice device; - StatusFrameAircon aircon; - StatusFrameAirconResponse airconResponse; - StatusFrameAirconInit airconInit; - StatusFrameAircon2 aircon2; - StatusFrameAirconInit2 airconInit2; + StatusFrameAirconManual airconManual; + StatusFrameAirconManualResponse airconManualResponse; + StatusFrameAirconManualInit airconManualInit; + StatusFrameAirconAuto airconAuto; + StatusFrameAirconAutoInit airconAutoInit; } __attribute__((packed)); } inner; } __attribute__((packed)); @@ -529,14 +533,14 @@ class TrumaiNetBoxApp : public LinBusProtocol { StatusFrameHeaterResponse *update_heater_prepare(); void update_heater_submit() { this->heater_.update_status_unsubmitted_ = true; } - bool truma_aircon_can_update() { return this->status_aircon_valid_; } - StatusFrameAirconResponse *update_aircon_prepare(); - void update_aircon_submit() { this->update_status_aircon_unsubmitted_ = true; } - bool truma_timer_can_update() { return this->timer_.data_valid_; } StatusFrameTimerResponse *update_timer_prepare(); void update_timer_submit() { this->timer_.update_status_unsubmitted_ = true; } + bool truma_aircon_can_update() { return this->airconManual_.data_valid_; } + StatusFrameAirconManualResponse *update_aircon_prepare(); + void update_aircon_submit() { this->airconManual_.update_status_unsubmitted_ = true; } + int64_t get_last_cp_plus_request() { return this->device_registered_; } // Automation @@ -552,6 +556,9 @@ class TrumaiNetBoxApp : public LinBusProtocol { void add_on_config_message_callback(std::function callback) { this->config_.state_callback_.add(std::move(callback)); } + void add_on_aircon_manual_message_callback(std::function callback) { + this->airconManual_.state_callback_.add(std::move(callback)); + } bool action_heater_room(u_int8_t temperature, HeatingMode mode = HeatingMode::HEATING_MODE_OFF); bool action_heater_water(u_int8_t temperature); bool action_heater_water(TargetTemp temperature); @@ -584,22 +591,13 @@ class TrumaiNetBoxApp : public LinBusProtocol { TrumaStausFrameResponseStorage heater_; TrumaStausFrameResponseStorage timer_; + TrumaStausFrameResponseStorage airconManual_; TrumaStausFrameStorage config_; TrumaStausFrameStorage clock_; - bool status_aircon_valid_ = false; - // Value has changed notify listeners. - bool status_aircon_updated_ = false; - StatusFrameAircon status_aircon_; - // last time CP plus was informed I got an update msg. uint32_t update_time_ = 0; - bool update_status_aircon_prepared_ = false; - bool update_status_aircon_unsubmitted_ = false; - bool update_status_aircon_stale_ = false; - StatusFrameAirconResponse update_status_aircon_; - #ifdef USE_TIME time::RealTimeClock *time_ = nullptr;