Improve code reability.
This commit is contained in:
parent
85d1afe874
commit
0956a94c38
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
|||||||
@ -1,92 +0,0 @@
|
|||||||
#include "TrumaStatusFrame.h"
|
|
||||||
#include "esphome/core/helpers.h"
|
|
||||||
#include "TrumaiNetBoxApp.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
|
||||||
namespace truma_inetbox {
|
|
||||||
void status_frame_create_empty(StatusFrame *response, u_int8_t message_type, u_int8_t message_length,
|
|
||||||
u_int8_t command_counter) {
|
|
||||||
response->inner.genericHeader.service_identifier = LIN_SID_READ_STATE_BUFFER | LIN_SID_RESPONSE;
|
|
||||||
// Copy header over for this message.
|
|
||||||
for (size_t i = 1; i < truma_message_header.size(); i++) {
|
|
||||||
response->raw[i] = truma_message_header[i];
|
|
||||||
}
|
|
||||||
response->inner.genericHeader.header_2 = 'T';
|
|
||||||
response->inner.genericHeader.header_3 = 0x01;
|
|
||||||
response->inner.genericHeader.message_type = message_type;
|
|
||||||
response->inner.genericHeader.message_length = message_length;
|
|
||||||
response->inner.genericHeader.command_counter = command_counter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_frame_calculate_checksum(StatusFrame *response) {
|
|
||||||
response->inner.genericHeader.checksum = 0x0;
|
|
||||||
response->inner.genericHeader.checksum = data_checksum(&response->raw[10], sizeof(StatusFrame) - 10, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_frame_create_init(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) {
|
|
||||||
status_frame_create_empty(response, STATUS_FRAME_RESPONSE_INIT_REQUEST, 0, command_counter);
|
|
||||||
|
|
||||||
// Init frame is empty.
|
|
||||||
|
|
||||||
status_frame_calculate_checksum(response);
|
|
||||||
(*response_len) = sizeof(StatusFrameHeader) + 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_frame_create_update_clock(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
u_int8_t hour, u_int8_t minute, u_int8_t second, ClockMode clockMode) {
|
|
||||||
status_frame_create_empty(response, STATUS_FRAME_CLOCK_RESPONSE, sizeof(StatusFrameClock), command_counter);
|
|
||||||
|
|
||||||
response->inner.clock.clock_hour = hour;
|
|
||||||
response->inner.clock.clock_minute = minute;
|
|
||||||
response->inner.clock.clock_second = second;
|
|
||||||
response->inner.clock.display_1 = 0x1;
|
|
||||||
response->inner.clock.display_2 = 0x1;
|
|
||||||
response->inner.clock.clock_mode = clockMode;
|
|
||||||
|
|
||||||
status_frame_calculate_checksum(response);
|
|
||||||
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameClock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_frame_create_update_timer(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
TimerActive active, u_int8_t start_hour, u_int8_t start_minute,
|
|
||||||
u_int8_t stop_hour, u_int8_t stop_minute, TargetTemp room, TargetTemp water,
|
|
||||||
HeatingMode mode, EnergyMix energy, ElectricPowerLevel elPower) {
|
|
||||||
status_frame_create_empty(response, STATUS_FRAME_TIMER_RESPONSE, sizeof(StatusFrameTimerResponse), command_counter);
|
|
||||||
|
|
||||||
response->inner.timerResponse.timer_target_temp_room = room;
|
|
||||||
response->inner.timerResponse.timer_heating_mode = mode;
|
|
||||||
response->inner.timerResponse.timer_target_temp_water = water;
|
|
||||||
response->inner.timerResponse.timer_energy_mix_a = energy;
|
|
||||||
response->inner.timerResponse.timer_energy_mix_b = energy;
|
|
||||||
response->inner.timerResponse.timer_el_power_level_a = elPower;
|
|
||||||
response->inner.timerResponse.timer_el_power_level_b = elPower;
|
|
||||||
response->inner.timerResponse.timer_resp_active = active;
|
|
||||||
response->inner.timerResponse.timer_resp_start_hours = start_hour;
|
|
||||||
response->inner.timerResponse.timer_resp_start_minutes = start_minute;
|
|
||||||
response->inner.timerResponse.timer_resp_stop_hours = stop_hour;
|
|
||||||
response->inner.timerResponse.timer_resp_stop_minutes = stop_minute;
|
|
||||||
|
|
||||||
status_frame_calculate_checksum(response);
|
|
||||||
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameTimerResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
void status_frame_create_update_heater(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
TargetTemp room, TargetTemp water, HeatingMode mode, EnergyMix energy,
|
|
||||||
ElectricPowerLevel elPower) {
|
|
||||||
status_frame_create_empty(response, STATUS_FRAME_HEATER_RESPONSE, sizeof(StatusFrameHeaterResponse), command_counter);
|
|
||||||
|
|
||||||
response->inner.heaterResponse.target_temp_room = room;
|
|
||||||
response->inner.heaterResponse.heating_mode = mode;
|
|
||||||
response->inner.heaterResponse.target_temp_water = water;
|
|
||||||
response->inner.heaterResponse.energy_mix_a = energy;
|
|
||||||
response->inner.heaterResponse.energy_mix_b = energy;
|
|
||||||
response->inner.heaterResponse.el_power_level_a = elPower;
|
|
||||||
response->inner.heaterResponse.el_power_level_b = elPower;
|
|
||||||
|
|
||||||
status_frame_calculate_checksum(response);
|
|
||||||
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameHeaterResponse);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
|
||||||
} // namespace esphome
|
|
||||||
@ -1,28 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "TrumaiNetBoxApp.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
|
||||||
namespace truma_inetbox {
|
|
||||||
|
|
||||||
void status_frame_create_empty(StatusFrame *response, u_int8_t message_type, u_int8_t message_length,
|
|
||||||
u_int8_t command_counter);
|
|
||||||
|
|
||||||
void status_frame_calculate_checksum(StatusFrame *response);
|
|
||||||
|
|
||||||
void status_frame_create_init(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter);
|
|
||||||
|
|
||||||
void status_frame_create_update_clock(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
u_int8_t hour, u_int8_t minute, u_int8_t second, ClockMode clockMode);
|
|
||||||
|
|
||||||
void status_frame_create_update_timer(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
TimerActive active, u_int8_t start_hour, u_int8_t start_minute,
|
|
||||||
u_int8_t stop_hour, u_int8_t stop_minute, TargetTemp room, TargetTemp water,
|
|
||||||
HeatingMode mode, EnergyMix energy, ElectricPowerLevel elPower);
|
|
||||||
|
|
||||||
void status_frame_create_update_heater(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter,
|
|
||||||
TargetTemp room, TargetTemp water, HeatingMode mode, EnergyMix energy,
|
|
||||||
ElectricPowerLevel elPower);
|
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
|
||||||
} // namespace esphome
|
|
||||||
38
components/truma_inetbox/TrumaStatusFrameBuilder.h
Normal file
38
components/truma_inetbox/TrumaStatusFrameBuilder.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "TrumaStructs.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
inline void status_frame_create_empty(StatusFrame *response, u_int8_t message_type, u_int8_t message_length,
|
||||||
|
u_int8_t command_counter) {
|
||||||
|
response->inner.genericHeader.service_identifier = LIN_SID_READ_STATE_BUFFER | LIN_SID_RESPONSE;
|
||||||
|
// Copy header over for this message.
|
||||||
|
for (size_t i = 1; i < truma_message_header.size(); i++) {
|
||||||
|
response->raw[i] = truma_message_header[i];
|
||||||
|
}
|
||||||
|
response->inner.genericHeader.header_2 = 'T';
|
||||||
|
response->inner.genericHeader.header_3 = 0x01;
|
||||||
|
response->inner.genericHeader.message_type = message_type;
|
||||||
|
response->inner.genericHeader.message_length = message_length;
|
||||||
|
response->inner.genericHeader.command_counter = command_counter;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void status_frame_calculate_checksum(StatusFrame *response) {
|
||||||
|
response->inner.genericHeader.checksum = 0x0;
|
||||||
|
response->inner.genericHeader.checksum = data_checksum(&response->raw[10], sizeof(StatusFrame) - 10, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void status_frame_create_init(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) {
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_RESPONSE_INIT_REQUEST, 0, command_counter);
|
||||||
|
|
||||||
|
// Init frame is empty.
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace truma_inetbox
|
||||||
|
} // namespace esphome
|
||||||
@ -1,16 +1,39 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TrumaStausFrameStorage.h"
|
#include "TrumaStausFrameStorage.h"
|
||||||
|
#include "TrumaStructs.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
template<typename T, typename TResponse> class TrumaStausFrameResponseStorage : public TrumaStausFrameStorage<T> {
|
class TrumaiNetBoxApp;
|
||||||
|
|
||||||
|
template<typename T, typename TResponse>
|
||||||
|
class TrumaStausFrameResponseStorage : public TrumaStausFrameStorage<T>, public Parented<TrumaiNetBoxApp> {
|
||||||
public:
|
public:
|
||||||
void reset();
|
void reset() override {
|
||||||
|
TrumaStausFrameStorage<T>::reset();
|
||||||
|
this->update_status_prepared_ = false;
|
||||||
|
this->update_status_unsubmitted_ = false;
|
||||||
|
this->update_status_stale_ = false;
|
||||||
|
}
|
||||||
bool can_update() { return this->data_valid_; }
|
bool can_update() { return this->data_valid_; }
|
||||||
virtual TResponse *update_prepare() = 0;
|
virtual TResponse *update_prepare() = 0;
|
||||||
void update_submit() { this->update_status_unsubmitted_ = true; }
|
void update_submit() { this->update_status_unsubmitted_ = true; }
|
||||||
|
const bool has_update() const { return this->update_status_unsubmitted_; }
|
||||||
|
void set_status(T val) override {
|
||||||
|
TrumaStausFrameStorage<T>::set_status(val);
|
||||||
|
this->update_status_stale_ = false;
|
||||||
|
};
|
||||||
|
virtual void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
inline void update_submitted() {
|
||||||
|
this->update_status_prepared_ = false;
|
||||||
|
this->update_status_unsubmitted_ = false;
|
||||||
|
this->update_status_stale_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Prepared means `update_status_` was copied from `data_`.
|
// Prepared means `update_status_` was copied from `data_`.
|
||||||
bool update_status_prepared_ = false;
|
bool update_status_prepared_ = false;
|
||||||
|
|||||||
@ -7,19 +7,35 @@ namespace truma_inetbox {
|
|||||||
|
|
||||||
template<typename T> class TrumaStausFrameStorage {
|
template<typename T> class TrumaStausFrameStorage {
|
||||||
public:
|
public:
|
||||||
|
bool get_status_valid() { return this->data_valid_; };
|
||||||
|
const T *get_status() { return &this->data_; };
|
||||||
|
virtual void set_status(T val) {
|
||||||
|
this->data_ = val;
|
||||||
|
this->data_valid_ = true;
|
||||||
|
this->data_updated_ = true;
|
||||||
|
this->dump_data();
|
||||||
|
};
|
||||||
|
void update() {
|
||||||
|
if (this->data_updated_) {
|
||||||
|
this->state_callback_.call(&this->data_);
|
||||||
|
}
|
||||||
|
this->data_updated_ = false;
|
||||||
|
};
|
||||||
|
virtual void reset() {
|
||||||
|
this->data_valid_ = false;
|
||||||
|
this->data_updated_ = false;
|
||||||
|
};
|
||||||
|
void add_on_message_callback(std::function<void(const T *)> callback) {
|
||||||
|
this->state_callback_.add(std::move(callback));
|
||||||
|
};
|
||||||
|
virtual void dump_data() const = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
CallbackManager<void(const T *)> state_callback_{};
|
CallbackManager<void(const T *)> state_callback_{};
|
||||||
T data_;
|
T data_;
|
||||||
bool data_valid_ = false;
|
bool data_valid_ = false;
|
||||||
// Value has changed notify listeners.
|
// Value has changed notify listeners.
|
||||||
bool data_updated_ = false;
|
bool data_updated_ = false;
|
||||||
|
|
||||||
void add_on_message_callback(std::function<void(const T *)> callback) {
|
|
||||||
this->state_callback_.add(std::move(callback));
|
|
||||||
}
|
|
||||||
bool get_status_valid() { return this->data_valid_; }
|
|
||||||
const T *get_status() { return &this->data_; }
|
|
||||||
void update();
|
|
||||||
void reset();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
@ -5,6 +5,37 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
#define LIN_SID_RESPONSE 0x40
|
||||||
|
#define LIN_SID_READ_STATE_BUFFER 0xBA
|
||||||
|
#define LIN_SID_FIll_STATE_BUFFFER 0xBB
|
||||||
|
|
||||||
|
// Response to init are the following frames:
|
||||||
|
// - 2 * STATUS_FRAME_DEVICES
|
||||||
|
// - STATUS_FRAME_HEATER
|
||||||
|
// - STATUS_FRAME_TIMER
|
||||||
|
// - STAUTS_FRAME_CONFIG
|
||||||
|
// - STATUS_FRAME_CLOCK
|
||||||
|
#define STATUS_FRAME_RESPONSE_INIT_REQUEST 0x0A
|
||||||
|
#define STATUS_FRAME_DEVICES 0x0B
|
||||||
|
#define STATUS_FRAME_RESPONSE_ACK 0x0D
|
||||||
|
#define STATUS_FRAME_CLOCK_RESPONSE (STATUS_FRAME_CLOCK - 1)
|
||||||
|
#define STATUS_FRAME_CLOCK 0x15
|
||||||
|
// TODO: Documentation and testing of config response.
|
||||||
|
#define STAUTS_FRAME_CONFIG_RESPONSE (STAUTS_FRAME_CONFIG - 1)
|
||||||
|
#define STAUTS_FRAME_CONFIG 0x17
|
||||||
|
#define STATUS_FRAME_HEATER_RESPONSE (STATUS_FRAME_HEATER - 1)
|
||||||
|
#define STATUS_FRAME_HEATER 0x33
|
||||||
|
#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_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
|
||||||
|
|
||||||
struct StatusFrameHeader { // NOLINT(altera-struct-pack-align)
|
struct StatusFrameHeader { // NOLINT(altera-struct-pack-align)
|
||||||
// sid
|
// sid
|
||||||
u_int8_t service_identifier;
|
u_int8_t service_identifier;
|
||||||
@ -269,5 +300,28 @@ struct StatusFrameAirconAutoInit { // NOLINT(altera-struct-pack-align)
|
|||||||
u_int8_t unknown_20; // 0x00
|
u_int8_t unknown_20; // 0x00
|
||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
union StatusFrame { // NOLINT(altera-struct-pack-align)
|
||||||
|
u_int8_t raw[41];
|
||||||
|
struct inner { // NOLINT(altera-struct-pack-align)
|
||||||
|
StatusFrameHeader genericHeader;
|
||||||
|
union { // NOLINT(altera-struct-pack-align)
|
||||||
|
StatusFrameHeater heater;
|
||||||
|
StatusFrameHeaterResponse heaterResponse;
|
||||||
|
StatusFrameTimer timer;
|
||||||
|
StatusFrameTimerResponse timerResponse;
|
||||||
|
StatusFrameResponseAck responseAck;
|
||||||
|
StatusFrameClock clock;
|
||||||
|
StatusFrameConfig config;
|
||||||
|
StatusFrameDevice device;
|
||||||
|
StatusFrameAirconManual airconManual;
|
||||||
|
StatusFrameAirconManualResponse airconManualResponse;
|
||||||
|
StatusFrameAirconManualInit airconManualInit;
|
||||||
|
StatusFrameAirconAuto airconAuto;
|
||||||
|
StatusFrameAirconAutoResponse airconAutoResponse;
|
||||||
|
StatusFrameAirconAutoInit airconAutoInit;
|
||||||
|
} __attribute__((packed));
|
||||||
|
} inner;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -1,5 +1,5 @@
|
|||||||
#include "TrumaiNetBoxApp.h"
|
#include "TrumaiNetBoxApp.h"
|
||||||
#include "TrumaStatusFrame.h"
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "esphome/core/helpers.h"
|
#include "esphome/core/helpers.h"
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
@ -9,15 +9,26 @@ namespace truma_inetbox {
|
|||||||
|
|
||||||
static const char *const TAG = "truma_inetbox.TrumaiNetBoxApp";
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxApp";
|
||||||
|
|
||||||
|
TrumaiNetBoxApp::TrumaiNetBoxApp() {
|
||||||
|
this->airconAuto_.set_parent(this);
|
||||||
|
this->airconManual_.set_parent(this);
|
||||||
|
this->clock_.set_parent(this);
|
||||||
|
// this->config_.set_parent(this);
|
||||||
|
this->heater_.set_parent(this);
|
||||||
|
this->timer_.set_parent(this);
|
||||||
|
}
|
||||||
|
|
||||||
void TrumaiNetBoxApp::update() {
|
void TrumaiNetBoxApp::update() {
|
||||||
// Call listeners in after method 'lin_multiframe_recieved' call.
|
// Call listeners in after method 'lin_multiframe_recieved' call.
|
||||||
// Because 'lin_multiframe_recieved' is time critical an all these sensors can take some time.
|
// Because 'lin_multiframe_recieved' is time critical an all these sensors can take some time.
|
||||||
|
|
||||||
// Run through callbacks
|
// Run through callbacks
|
||||||
heater_.update();
|
this->airconAuto_.update();
|
||||||
timer_.update();
|
this->airconManual_.update();
|
||||||
clock_.update();
|
this->clock_.update();
|
||||||
config_.update();
|
this->config_.update();
|
||||||
|
this->heater_.update();
|
||||||
|
this->timer_.update();
|
||||||
|
|
||||||
LinBusProtocol::update();
|
LinBusProtocol::update();
|
||||||
|
|
||||||
@ -29,19 +40,12 @@ void TrumaiNetBoxApp::update() {
|
|||||||
if (this->time_ != nullptr && !this->update_status_clock_done && this->init_recieved_ > 0) {
|
if (this->time_ != nullptr && !this->update_status_clock_done && this->init_recieved_ > 0) {
|
||||||
if (micros() > ((30 * 1000 * 1000) + this->init_recieved_ /* 30 seconds after init recieved */)) {
|
if (micros() > ((30 * 1000 * 1000) + this->init_recieved_ /* 30 seconds after init recieved */)) {
|
||||||
this->update_status_clock_done = true;
|
this->update_status_clock_done = true;
|
||||||
this->action_write_time();
|
this->clock_.action_write_time();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // USE_TIME
|
#endif // USE_TIME
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void TrumaStausFrameStorage<T>::update() {
|
|
||||||
if (this->data_updated_) {
|
|
||||||
this->state_callback_.call(&this->data_);
|
|
||||||
}
|
|
||||||
this->data_updated_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::array<uint8_t, 4> TrumaiNetBoxApp::lin_identifier() {
|
const std::array<uint8_t, 4> TrumaiNetBoxApp::lin_identifier() {
|
||||||
// Supplier Id: 0x4617 - Truma (Phone: +49 (0)89 4617-0)
|
// Supplier Id: 0x4617 - Truma (Phone: +49 (0)89 4617-0)
|
||||||
// Unknown:
|
// Unknown:
|
||||||
@ -71,27 +75,16 @@ void TrumaiNetBoxApp::lin_reset_device() {
|
|||||||
this->device_registered_ = micros();
|
this->device_registered_ = micros();
|
||||||
this->init_recieved_ = 0;
|
this->init_recieved_ = 0;
|
||||||
|
|
||||||
this->heater_.reset();
|
this->airconAuto_.reset();
|
||||||
this->timer_.reset();
|
|
||||||
this->airconManual_.reset();
|
this->airconManual_.reset();
|
||||||
this->clock_.reset();
|
this->clock_.reset();
|
||||||
this->config_.reset();
|
this->config_.reset();
|
||||||
|
this->heater_.reset();
|
||||||
|
this->timer_.reset();
|
||||||
|
|
||||||
this->update_time_ = 0;
|
this->update_time_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void TrumaStausFrameStorage<T>::reset() {
|
|
||||||
this->data_valid_ = false;
|
|
||||||
this->data_updated_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T, typename TResponse> void TrumaStausFrameResponseStorage<T, TResponse>::reset() {
|
|
||||||
TrumaStausFrameStorage<T>::reset();
|
|
||||||
this->update_status_prepared_ = false;
|
|
||||||
this->update_status_unsubmitted_ = false;
|
|
||||||
this->update_status_stale_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) {
|
bool TrumaiNetBoxApp::answer_lin_order_(const u_int8_t pid) {
|
||||||
// Alive message
|
// Alive message
|
||||||
if (pid == LIN_PID_TRUMA_INET_BOX) {
|
if (pid == LIN_PID_TRUMA_INET_BOX) {
|
||||||
@ -155,64 +148,31 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
ESP_LOGD(TAG, "Requested read: Sending init");
|
ESP_LOGD(TAG, "Requested read: Sending init");
|
||||||
status_frame_create_init(response_frame, return_len, this->message_counter++);
|
status_frame_create_init(response_frame, return_len, this->message_counter++);
|
||||||
return response;
|
return response;
|
||||||
} else if (this->heater_.update_status_unsubmitted_) {
|
} else if (this->heater_.has_update()) {
|
||||||
ESP_LOGD(TAG, "Requested read: Sending heater update");
|
ESP_LOGD(TAG, "Requested read: Sending heater update");
|
||||||
status_frame_create_update_heater(
|
this->heater_.create_update_data(response_frame, return_len, this->message_counter++);
|
||||||
response_frame, return_len, this->message_counter++, this->heater_.update_status_.target_temp_room,
|
|
||||||
this->heater_.update_status_.target_temp_water, this->heater_.update_status_.heating_mode,
|
|
||||||
this->heater_.update_status_.energy_mix_a, this->heater_.update_status_.el_power_level_a);
|
|
||||||
|
|
||||||
this->update_time_ = 0;
|
this->update_time_ = 0;
|
||||||
this->heater_.update_status_prepared_ = false;
|
|
||||||
this->heater_.update_status_unsubmitted_ = false;
|
|
||||||
this->heater_.update_status_stale_ = true;
|
|
||||||
return response;
|
return response;
|
||||||
} else if (this->timer_.update_status_unsubmitted_) {
|
} else if (this->timer_.has_update()) {
|
||||||
ESP_LOGD(TAG, "Requested read: Sending timer update");
|
ESP_LOGD(TAG, "Requested read: Sending timer update");
|
||||||
status_frame_create_update_timer(
|
this->timer_.create_update_data(response_frame, return_len, this->message_counter++);
|
||||||
response_frame, return_len, this->message_counter++, this->timer_.update_status_.timer_resp_active,
|
|
||||||
this->timer_.update_status_.timer_resp_start_hours, this->timer_.update_status_.timer_resp_start_minutes,
|
|
||||||
this->timer_.update_status_.timer_resp_stop_hours, this->timer_.update_status_.timer_resp_stop_minutes,
|
|
||||||
this->timer_.update_status_.timer_target_temp_room, this->timer_.update_status_.timer_target_temp_water,
|
|
||||||
this->timer_.update_status_.timer_heating_mode, this->timer_.update_status_.timer_energy_mix_a,
|
|
||||||
this->timer_.update_status_.timer_el_power_level_a);
|
|
||||||
|
|
||||||
this->update_time_ = 0;
|
this->update_time_ = 0;
|
||||||
this->timer_.update_status_prepared_ = false;
|
|
||||||
this->timer_.update_status_unsubmitted_ = false;
|
|
||||||
this->timer_.update_status_stale_ = true;
|
|
||||||
return response;
|
return response;
|
||||||
} else if (this->airconManual_.update_status_unsubmitted_) {
|
} else if (this->airconManual_.has_update()) {
|
||||||
ESP_LOGD(TAG, "Requested read: Sending aircon update");
|
ESP_LOGD(TAG, "Requested read: Sending aircon manual update");
|
||||||
|
this->airconManual_.create_update_data(response_frame, return_len, this->message_counter++);
|
||||||
status_frame_create_empty(response_frame, STATUS_FRAME_AIRCON_MANUAL_RESPONSE, sizeof(StatusFrameAirconManualResponse),
|
this->update_time_ = 0;
|
||||||
this->message_counter++);
|
return response;
|
||||||
|
} else if (this->airconAuto_.has_update()) {
|
||||||
response_frame->inner.airconManualResponse.mode = this->airconManual_.update_status_.mode;
|
ESP_LOGD(TAG, "Requested read: Sending aircon auto update");
|
||||||
response_frame->inner.airconManualResponse.unknown_02 = this->airconManual_.update_status_.unknown_02;
|
this->airconAuto_.create_update_data(response_frame, return_len, this->message_counter++);
|
||||||
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(StatusFrameAirconManualResponse);
|
|
||||||
|
|
||||||
this->update_time_ = 0;
|
this->update_time_ = 0;
|
||||||
this->airconManual_.update_status_prepared_ = false;
|
|
||||||
this->airconManual_.update_status_unsubmitted_ = false;
|
|
||||||
this->airconManual_.update_status_stale_ = true;
|
|
||||||
return response;
|
return response;
|
||||||
#ifdef USE_TIME
|
#ifdef USE_TIME
|
||||||
} else if (this->update_status_clock_unsubmitted_) {
|
} else if (this->clock_.has_update()) {
|
||||||
if (this->time_ != nullptr) {
|
ESP_LOGD(TAG, "Requested read: Sending clock update");
|
||||||
ESP_LOGD(TAG, "Requested read: Sending clock update");
|
this->clock_.create_update_data(response_frame, return_len, this->message_counter++);
|
||||||
// read time live
|
this->update_time_ = 0;
|
||||||
auto now = this->time_->now();
|
|
||||||
|
|
||||||
status_frame_create_update_clock(response_frame, return_len, this->message_counter++, now.hour, now.minute,
|
|
||||||
now.second, this->clock_.data_.clock_mode);
|
|
||||||
}
|
|
||||||
this->update_status_clock_unsubmitted_ = false;
|
|
||||||
return response;
|
return response;
|
||||||
#endif // USE_TIME
|
#endif // USE_TIME
|
||||||
} else {
|
} else {
|
||||||
@ -242,13 +202,10 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
// Example:
|
// Example:
|
||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|tRoom|mo| |elecA|tWate|elecB|mi|mi|cWate|cRoom|st|err | |
|
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|tRoom|mo| |elecA|tWate|elecB|mi|mi|cWate|cRoom|st|err | |
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.14.33.00.12.00.00.00.00.00.00.00.00.00.00.01.01.CC.0B.6C.0B.00.00.00.00
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.14.33.00.12.00.00.00.00.00.00.00.00.00.00.01.01.CC.0B.6C.0B.00.00.00.00
|
||||||
this->heater_.data_ = statusFrame->inner.heater;
|
this->heater_.set_status(statusFrame->inner.heater);
|
||||||
this->heater_.data_valid_ = true;
|
|
||||||
this->heater_.data_updated_ = true;
|
|
||||||
|
|
||||||
this->heater_.update_status_stale_ = false;
|
|
||||||
return response;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL && header->message_length == sizeof(StatusFrameAirconManual)) {
|
} else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL &&
|
||||||
|
header->message_length == sizeof(StatusFrameAirconManual)) {
|
||||||
ESP_LOGI(TAG, "StatusFrameAirconManual");
|
ESP_LOGI(TAG, "StatusFrameAirconManual");
|
||||||
// Example:
|
// Example:
|
||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
||||||
@ -269,11 +226,7 @@ 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.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.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
|
// 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->airconManual_.data_ = statusFrame->inner.airconManual;
|
this->airconManual_.set_status(statusFrame->inner.airconManual);
|
||||||
this->airconManual_.data_valid_ = true;
|
|
||||||
this->airconManual_.data_updated_ = true;
|
|
||||||
|
|
||||||
this->airconManual_.update_status_stale_ = false;
|
|
||||||
return response;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL_INIT &&
|
} else if (header->message_type == STATUS_FRAME_AIRCON_MANUAL_INIT &&
|
||||||
header->message_length == sizeof(StatusFrameAirconManualInit)) {
|
header->message_length == sizeof(StatusFrameAirconManualInit)) {
|
||||||
@ -282,11 +235,13 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
// 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
|
// 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;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_AIRCON_AUTO && header->message_length == sizeof(StatusFrameAirconAuto)) {
|
} else if (header->message_type == STATUS_FRAME_AIRCON_AUTO &&
|
||||||
|
header->message_length == sizeof(StatusFrameAirconAuto)) {
|
||||||
ESP_LOGI(TAG, "StatusFrameAirconAuto");
|
ESP_LOGI(TAG, "StatusFrameAirconAuto");
|
||||||
// Example:
|
// Example:
|
||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
// 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
|
// 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
|
||||||
|
this->airconAuto_.set_status(statusFrame->inner.airconAuto);
|
||||||
return response;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_AIRCON_AUTO_INIT &&
|
} else if (header->message_type == STATUS_FRAME_AIRCON_AUTO_INIT &&
|
||||||
header->message_length == sizeof(StatusFrameAirconAutoInit)) {
|
header->message_length == sizeof(StatusFrameAirconAutoInit)) {
|
||||||
@ -301,18 +256,26 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|tRoom|mo|??|elecA|tWate|elecB|mi|mi|<--response-->|??|??|on|start|stop-|
|
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|tRoom|mo|??|elecA|tWate|elecB|mi|mi|<--response-->|??|??|on|start|stop-|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.18.3D.00.1D.18.0B.01.00.00.00.00.00.00.00.01.01.00.00.00.00.00.00.00.01.00.08.00.09
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.18.3D.00.1D.18.0B.01.00.00.00.00.00.00.00.01.01.00.00.00.00.00.00.00.01.00.08.00.09
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.18.3D.00.13.18.0B.0B.00.00.00.00.00.00.00.01.01.00.00.00.00.00.00.00.01.00.08.00.09
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.18.3D.00.13.18.0B.0B.00.00.00.00.00.00.00.01.01.00.00.00.00.00.00.00.01.00.08.00.09
|
||||||
this->timer_.data_ = statusFrame->inner.timer;
|
this->timer_.set_status(statusFrame->inner.timer);
|
||||||
this->timer_.data_valid_ = true;
|
return response;
|
||||||
this->timer_.data_updated_ = true;
|
|
||||||
|
|
||||||
this->timer_.update_status_stale_ = false;
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "StatusFrameTimer target_temp_room: %f target_temp_water: %f %02u:%02u -> %02u:%02u %s",
|
|
||||||
temp_code_to_decimal(this->timer_.data_.timer_target_temp_room),
|
|
||||||
temp_code_to_decimal(this->timer_.data_.timer_target_temp_water), this->timer_.data_.timer_start_hours,
|
|
||||||
this->timer_.data_.timer_start_minutes, this->timer_.data_.timer_stop_hours,
|
|
||||||
this->timer_.data_.timer_stop_minutes, ((u_int8_t) this->timer_.data_.timer_active ? " ON" : " OFF"));
|
|
||||||
|
|
||||||
|
} else if (header->message_type == STATUS_FRAME_CLOCK && header->message_length == sizeof(StatusFrameClock)) {
|
||||||
|
ESP_LOGI(TAG, "StatusFrameClock");
|
||||||
|
// Example:
|
||||||
|
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.5B.0D.20.00.01.01.00.00.01.00.00
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.71.16.00.00.01.01.00.00.02.00.00
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.2B.16.1F.28.01.01.00.00.01.00.00
|
||||||
|
this->clock_.set_status(statusFrame->inner.clock);
|
||||||
|
return response;
|
||||||
|
} else if (header->message_type == STAUTS_FRAME_CONFIG && header->message_length == sizeof(StatusFrameConfig)) {
|
||||||
|
ESP_LOGI(TAG, "StatusFrameConfig");
|
||||||
|
// Example:
|
||||||
|
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.0F.06.01.B4.0A.AA.0A.00.00.00.00
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.41.06.01.B4.0A.78.0A.00.00.00.00
|
||||||
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.0F.06.01.B4.0A.AA.0A.00.00.00.00
|
||||||
|
this->config_.set_status(statusFrame->inner.config);
|
||||||
return response;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_RESPONSE_ACK &&
|
} else if (header->message_type == STATUS_FRAME_RESPONSE_ACK &&
|
||||||
header->message_length == sizeof(StatusFrameResponseAck)) {
|
header->message_length == sizeof(StatusFrameResponseAck)) {
|
||||||
@ -335,35 +298,6 @@ const u_int8_t *TrumaiNetBoxApp::lin_multiframe_recieved(const u_int8_t *message
|
|||||||
this->lin_reset_device();
|
this->lin_reset_device();
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
|
||||||
} else if (header->message_type == STATUS_FRAME_CLOCK && header->message_length == sizeof(StatusFrameClock)) {
|
|
||||||
ESP_LOGI(TAG, "StatusFrameClock");
|
|
||||||
// Example:
|
|
||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.5B.0D.20.00.01.01.00.00.01.00.00
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.71.16.00.00.01.01.00.00.02.00.00
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.15.00.2B.16.1F.28.01.01.00.00.01.00.00
|
|
||||||
this->clock_.data_ = statusFrame->inner.clock;
|
|
||||||
this->clock_.data_valid_ = true;
|
|
||||||
this->clock_.data_updated_ = true;
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "StatusFrameClock %02d:%02d:%02d", this->clock_.data_.clock_hour, this->clock_.data_.clock_minute,
|
|
||||||
this->clock_.data_.clock_second);
|
|
||||||
|
|
||||||
return response;
|
|
||||||
} else if (header->message_type == STAUTS_FRAME_CONFIG && header->message_length == sizeof(StatusFrameConfig)) {
|
|
||||||
ESP_LOGI(TAG, "StatusFrameConfig");
|
|
||||||
// Example:
|
|
||||||
// SID<---------PREAMBLE---------->|<---MSG_HEAD---->|
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.0F.06.01.B4.0A.AA.0A.00.00.00.00
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.41.06.01.B4.0A.78.0A.00.00.00.00
|
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0A.17.00.0F.06.01.B4.0A.AA.0A.00.00.00.00
|
|
||||||
this->config_.data_ = statusFrame->inner.config;
|
|
||||||
this->config_.data_valid_ = true;
|
|
||||||
this->config_.data_updated_ = true;
|
|
||||||
|
|
||||||
ESP_LOGD(TAG, "StatusFrameConfig Offset: %.1f", temp_code_to_decimal(this->config_.data_.temp_offset));
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} else if (header->message_type == STATUS_FRAME_DEVICES && header->message_length == sizeof(StatusFrameDevice)) {
|
} else if (header->message_type == STATUS_FRAME_DEVICES && header->message_length == sizeof(StatusFrameDevice)) {
|
||||||
ESP_LOGI(TAG, "StatusFrameDevice");
|
ESP_LOGI(TAG, "StatusFrameDevice");
|
||||||
@ -380,7 +314,6 @@ 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.0C.0B.00.C7.03.00.01.00.50.00.00.04.03.00.60.10
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.C7.03.00.01.00.50.00.00.04.03.00.60.10
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.71.03.01.01.00.10.03.02.06.00.02.00.00
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.71.03.01.01.00.10.03.02.06.00.02.00.00
|
||||||
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.7C.03.02.01.00.01.0C.00.01.02.01.00.00
|
// BB.00.1F.00.1E.00.00.22.FF.FF.FF.54.01.0C.0B.00.7C.03.02.01.00.01.0C.00.01.02.01.00.00
|
||||||
|
|
||||||
auto device = statusFrame->inner.device;
|
auto device = statusFrame->inner.device;
|
||||||
|
|
||||||
this->init_recieved_ = micros();
|
this->init_recieved_ = micros();
|
||||||
@ -439,8 +372,8 @@ bool TrumaiNetBoxApp::has_update_to_submit_() {
|
|||||||
this->init_requested_ = micros();
|
this->init_requested_ = micros();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (this->heater_.update_status_unsubmitted_ || this->timer_.update_status_unsubmitted_ ||
|
} else if (this->airconAuto_.has_update() || this->airconManual_.has_update() || this->clock_.has_update() ||
|
||||||
this->update_status_clock_unsubmitted_ || this->airconManual_.update_status_unsubmitted_) {
|
this->heater_.has_update() || this->timer_.has_update()) {
|
||||||
if (this->update_time_ == 0) {
|
if (this->update_time_ == 0) {
|
||||||
// ESP_LOGD(TAG, "Notify CP Plus I got updates.");
|
// ESP_LOGD(TAG, "Notify CP Plus I got updates.");
|
||||||
this->update_time_ = micros();
|
this->update_time_ = micros();
|
||||||
|
|||||||
@ -1,18 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include "LinBusProtocol.h"
|
#include "LinBusProtocol.h"
|
||||||
#include "esphome/core/automation.h"
|
#include "TrumaStructs.h"
|
||||||
#include "TrumaEnums.h"
|
|
||||||
#include "TrumaiNetBoxAppAirconAuto.h"
|
#include "TrumaiNetBoxAppAirconAuto.h"
|
||||||
#include "TrumaiNetBoxAppAirconManual.h"
|
#include "TrumaiNetBoxAppAirconManual.h"
|
||||||
#include "TrumaiNetBoxAppClock.h"
|
#include "TrumaiNetBoxAppClock.h"
|
||||||
#include "TrumaiNetBoxAppConfig.h"
|
#include "TrumaiNetBoxAppConfig.h"
|
||||||
#include "TrumaiNetBoxAppHeater.h"
|
#include "TrumaiNetBoxAppHeater.h"
|
||||||
#include "TrumaiNetBoxAppTimer.h"
|
#include "TrumaiNetBoxAppTimer.h"
|
||||||
#include "TrumaStausFrameResponseStorage.h"
|
|
||||||
#include "TrumaStausFrameStorage.h"
|
|
||||||
#include "TrumaStructs.h"
|
|
||||||
|
|
||||||
#ifdef USE_TIME
|
#ifdef USE_TIME
|
||||||
#include "esphome/components/time/real_time_clock.h"
|
#include "esphome/components/time/real_time_clock.h"
|
||||||
@ -22,67 +17,19 @@ namespace esphome {
|
|||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
#define LIN_PID_TRUMA_INET_BOX 0x18
|
#define LIN_PID_TRUMA_INET_BOX 0x18
|
||||||
#define LIN_SID_RESPONSE 0x40
|
|
||||||
#define LIN_SID_READ_STATE_BUFFER 0xBA
|
|
||||||
#define LIN_SID_FIll_STATE_BUFFFER 0xBB
|
|
||||||
|
|
||||||
// Response to init are the following frames:
|
|
||||||
// - 2 * STATUS_FRAME_DEVICES
|
|
||||||
// - STATUS_FRAME_HEATER
|
|
||||||
// - STATUS_FRAME_TIMER
|
|
||||||
// - STAUTS_FRAME_CONFIG
|
|
||||||
// - STATUS_FRAME_CLOCK
|
|
||||||
#define STATUS_FRAME_RESPONSE_INIT_REQUEST 0x0A
|
|
||||||
#define STATUS_FRAME_DEVICES 0x0B
|
|
||||||
#define STATUS_FRAME_RESPONSE_ACK 0x0D
|
|
||||||
#define STATUS_FRAME_CLOCK_RESPONSE (STATUS_FRAME_CLOCK - 1)
|
|
||||||
#define STATUS_FRAME_CLOCK 0x15
|
|
||||||
// TODO: Documentation and testing of config response.
|
|
||||||
#define STAUTS_FRAME_CONFIG_RESPONSE (STAUTS_FRAME_CONFIG - 1)
|
|
||||||
#define STAUTS_FRAME_CONFIG 0x17
|
|
||||||
#define STATUS_FRAME_HEATER_RESPONSE (STATUS_FRAME_HEATER - 1)
|
|
||||||
#define STATUS_FRAME_HEATER 0x33
|
|
||||||
#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_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
|
|
||||||
|
|
||||||
union StatusFrame { // NOLINT(altera-struct-pack-align)
|
|
||||||
u_int8_t raw[41];
|
|
||||||
struct inner { // NOLINT(altera-struct-pack-align)
|
|
||||||
StatusFrameHeader genericHeader;
|
|
||||||
union { // NOLINT(altera-struct-pack-align)
|
|
||||||
StatusFrameHeater heater;
|
|
||||||
StatusFrameHeaterResponse heaterResponse;
|
|
||||||
StatusFrameTimer timer;
|
|
||||||
StatusFrameTimerResponse timerResponse;
|
|
||||||
StatusFrameResponseAck responseAck;
|
|
||||||
StatusFrameClock clock;
|
|
||||||
StatusFrameConfig config;
|
|
||||||
StatusFrameDevice device;
|
|
||||||
StatusFrameAirconManual airconManual;
|
|
||||||
StatusFrameAirconManualResponse airconManualResponse;
|
|
||||||
StatusFrameAirconManualInit airconManualInit;
|
|
||||||
StatusFrameAirconAuto airconAuto;
|
|
||||||
StatusFrameAirconAutoInit airconAutoInit;
|
|
||||||
} __attribute__((packed));
|
|
||||||
} inner;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
class TrumaiNetBoxApp : public LinBusProtocol {
|
class TrumaiNetBoxApp : public LinBusProtocol {
|
||||||
public:
|
public:
|
||||||
|
TrumaiNetBoxApp();
|
||||||
void update() override;
|
void update() override;
|
||||||
|
|
||||||
const std::array<u_int8_t, 4> lin_identifier() override;
|
const std::array<u_int8_t, 4> lin_identifier() override;
|
||||||
void lin_heartbeat() override;
|
void lin_heartbeat() override;
|
||||||
void lin_reset_device() override;
|
void lin_reset_device() override;
|
||||||
|
|
||||||
|
const TRUMA_DEVICE get_heater_device() const { return this->heater_device_; }
|
||||||
|
const TRUMA_DEVICE get_aircon_device() const { return this->aircon_device_; }
|
||||||
|
|
||||||
TrumaiNetBoxAppAirconAuto *get_aircon_auto() { return &this->airconAuto_; }
|
TrumaiNetBoxAppAirconAuto *get_aircon_auto() { return &this->airconAuto_; }
|
||||||
TrumaiNetBoxAppAirconManual *get_aircon_manual() { return &this->airconManual_; }
|
TrumaiNetBoxAppAirconManual *get_aircon_manual() { return &this->airconManual_; }
|
||||||
TrumaiNetBoxAppClock *get_clock() { return &this->clock_; }
|
TrumaiNetBoxAppClock *get_clock() { return &this->clock_; }
|
||||||
@ -92,23 +39,9 @@ class TrumaiNetBoxApp : public LinBusProtocol {
|
|||||||
|
|
||||||
int64_t get_last_cp_plus_request() { return this->device_registered_; }
|
int64_t get_last_cp_plus_request() { return this->device_registered_; }
|
||||||
|
|
||||||
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);
|
|
||||||
bool action_heater_electric_power_level(u_int16_t value);
|
|
||||||
bool action_heater_energy_mix(EnergyMix energy_mix,
|
|
||||||
ElectricPowerLevel el_power_level = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0);
|
|
||||||
bool action_timer_disable();
|
|
||||||
bool action_timer_activate(u_int16_t start, u_int16_t stop, u_int8_t room_temperature,
|
|
||||||
HeatingMode mode = HeatingMode::HEATING_MODE_OFF, u_int8_t water_temperature = 0,
|
|
||||||
EnergyMix energy_mix = EnergyMix::ENERGY_MIX_NONE,
|
|
||||||
ElectricPowerLevel el_power_level = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0);
|
|
||||||
|
|
||||||
#ifdef USE_TIME
|
#ifdef USE_TIME
|
||||||
void set_time(time::RealTimeClock *time) { time_ = time; }
|
void set_time(time::RealTimeClock *time) { time_ = time; }
|
||||||
bool truma_clock_can_update() { return this->clock_.data_valid_; }
|
time::RealTimeClock *get_time() const { return time_; }
|
||||||
void update_clock_submit() { this->update_status_clock_unsubmitted_ = true; }
|
|
||||||
bool action_write_time();
|
|
||||||
#endif // USE_TIME
|
#endif // USE_TIME
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -122,12 +55,12 @@ class TrumaiNetBoxApp : public LinBusProtocol {
|
|||||||
TRUMA_DEVICE heater_device_ = TRUMA_DEVICE::HEATER_COMBI4;
|
TRUMA_DEVICE heater_device_ = TRUMA_DEVICE::HEATER_COMBI4;
|
||||||
TRUMA_DEVICE aircon_device_ = TRUMA_DEVICE::UNKNOWN;
|
TRUMA_DEVICE aircon_device_ = TRUMA_DEVICE::UNKNOWN;
|
||||||
|
|
||||||
TrumaiNetBoxAppAirconAuto airconAuto_{};
|
TrumaiNetBoxAppAirconAuto airconAuto_;
|
||||||
TrumaiNetBoxAppAirconManual airconManual_{};
|
TrumaiNetBoxAppAirconManual airconManual_;
|
||||||
TrumaiNetBoxAppClock clock_{};
|
TrumaiNetBoxAppClock clock_;
|
||||||
TrumaiNetBoxAppConfig config_{};
|
TrumaiNetBoxAppConfig config_;
|
||||||
TrumaiNetBoxAppHeater heater_{};
|
TrumaiNetBoxAppHeater heater_;
|
||||||
TrumaiNetBoxAppTimer timer_{};
|
TrumaiNetBoxAppTimer timer_;
|
||||||
|
|
||||||
// last time CP plus was informed I got an update msg.
|
// last time CP plus was informed I got an update msg.
|
||||||
uint32_t update_time_ = 0;
|
uint32_t update_time_ = 0;
|
||||||
@ -135,15 +68,8 @@ class TrumaiNetBoxApp : public LinBusProtocol {
|
|||||||
#ifdef USE_TIME
|
#ifdef USE_TIME
|
||||||
time::RealTimeClock *time_ = nullptr;
|
time::RealTimeClock *time_ = nullptr;
|
||||||
|
|
||||||
// The behaviour of `update_status_clock_unsubmitted_` is special.
|
|
||||||
// Just an update is marked. The actual package is prepared when CP Plus asks for the data in the
|
|
||||||
// `lin_multiframe_recieved` method.
|
|
||||||
bool update_status_clock_unsubmitted_ = false;
|
|
||||||
|
|
||||||
// Mark if the initial clock sync was done.
|
// Mark if the initial clock sync was done.
|
||||||
bool update_status_clock_done = false;
|
bool update_status_clock_done = false;
|
||||||
#else
|
|
||||||
const bool update_status_clock_unsubmitted_ = false;
|
|
||||||
#endif // USE_TIME
|
#endif // USE_TIME
|
||||||
|
|
||||||
bool answer_lin_order_(const u_int8_t pid) override;
|
bool answer_lin_order_(const u_int8_t pid) override;
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
#include "TrumaiNetBoxAppAirconAuto.h"
|
#include "TrumaiNetBoxAppAirconAuto.h"
|
||||||
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppAirconAuto";
|
||||||
|
|
||||||
StatusFrameAirconAutoResponse *TrumaiNetBoxAppAirconAuto::update_prepare() {
|
StatusFrameAirconAutoResponse *TrumaiNetBoxAppAirconAuto::update_prepare() {
|
||||||
// An update is currently going on.
|
// An update is currently going on.
|
||||||
if (this->update_status_prepared_ || this->update_status_stale_) {
|
if (this->update_status_prepared_ || this->update_status_stale_) {
|
||||||
@ -20,5 +25,23 @@ StatusFrameAirconAutoResponse *TrumaiNetBoxAppAirconAuto::update_prepare() {
|
|||||||
return &this->update_status_;
|
return &this->update_status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppAirconAuto::create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter){
|
||||||
|
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_AIRCON_AUTO_RESPONSE, sizeof(StatusFrameAirconAutoResponse),
|
||||||
|
command_counter);
|
||||||
|
|
||||||
|
// response->inner.airconAutoResponse.mode = this->update_status_.mode;
|
||||||
|
// response->inner.airconAutoResponse.unknown_02 = this->update_status_.unknown_02;
|
||||||
|
// response->inner.airconAutoResponse.operation = this->update_status_.operation;
|
||||||
|
// response->inner.airconAutoResponse.energy_mix = this->update_status_.energy_mix;
|
||||||
|
// response->inner.airconAutoResponse.target_temp_aircon = this->update_status_.target_temp_aircon;
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconAutoResponse);
|
||||||
|
TrumaStausFrameResponseStorage<StatusFrameAirconAuto, StatusFrameAirconAutoResponse>::update_submitted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppAirconAuto::dump_data() const {}
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -10,6 +10,8 @@ class TrumaiNetBoxAppAirconAuto
|
|||||||
: public TrumaStausFrameResponseStorage<StatusFrameAirconAuto, StatusFrameAirconAutoResponse> {
|
: public TrumaStausFrameResponseStorage<StatusFrameAirconAuto, StatusFrameAirconAutoResponse> {
|
||||||
public:
|
public:
|
||||||
StatusFrameAirconAutoResponse *update_prepare() override;
|
StatusFrameAirconAutoResponse *update_prepare() override;
|
||||||
|
void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override;
|
||||||
|
void dump_data() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
@ -1,8 +1,13 @@
|
|||||||
#include "TrumaiNetBoxAppAirconManual.h"
|
#include "TrumaiNetBoxAppAirconManual.h"
|
||||||
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppAirconManual";
|
||||||
|
|
||||||
StatusFrameAirconManualResponse *TrumaiNetBoxAppAirconManual::update_prepare() {
|
StatusFrameAirconManualResponse *TrumaiNetBoxAppAirconManual::update_prepare() {
|
||||||
// An update is currently going on.
|
// An update is currently going on.
|
||||||
if (this->update_status_prepared_ || this->update_status_stale_) {
|
if (this->update_status_prepared_ || this->update_status_stale_) {
|
||||||
@ -20,5 +25,24 @@ StatusFrameAirconManualResponse *TrumaiNetBoxAppAirconManual::update_prepare() {
|
|||||||
return &this->update_status_;
|
return &this->update_status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppAirconManual::create_update_data(StatusFrame *response, u_int8_t *response_len,
|
||||||
|
u_int8_t command_counter) {
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_AIRCON_MANUAL_RESPONSE, sizeof(StatusFrameAirconManualResponse),
|
||||||
|
command_counter);
|
||||||
|
|
||||||
|
response->inner.airconManualResponse.mode = this->update_status_.mode;
|
||||||
|
response->inner.airconManualResponse.unknown_02 = this->update_status_.unknown_02;
|
||||||
|
response->inner.airconManualResponse.operation = this->update_status_.operation;
|
||||||
|
response->inner.airconManualResponse.energy_mix = this->update_status_.energy_mix;
|
||||||
|
response->inner.airconManualResponse.target_temp_aircon = this->update_status_.target_temp_aircon;
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameAirconManualResponse);
|
||||||
|
|
||||||
|
TrumaStausFrameResponseStorage<StatusFrameAirconManual, StatusFrameAirconManualResponse>::update_submitted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppAirconManual::dump_data() const {}
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -10,6 +10,8 @@ class TrumaiNetBoxAppAirconManual
|
|||||||
: public TrumaStausFrameResponseStorage<StatusFrameAirconManual, StatusFrameAirconManualResponse> {
|
: public TrumaStausFrameResponseStorage<StatusFrameAirconManual, StatusFrameAirconManualResponse> {
|
||||||
public:
|
public:
|
||||||
StatusFrameAirconManualResponse *update_prepare() override;
|
StatusFrameAirconManualResponse *update_prepare() override;
|
||||||
|
void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override;
|
||||||
|
void dump_data() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
66
components/truma_inetbox/TrumaiNetBoxAppClock.cpp
Normal file
66
components/truma_inetbox/TrumaiNetBoxAppClock.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "TrumaiNetBoxAppClock.h"
|
||||||
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "TrumaiNetBoxApp.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppClock";
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppClock::dump_data() const {
|
||||||
|
ESP_LOGD(TAG, "StatusFrameClock %02d:%02d:%02d", this->data_.clock_hour, this->data_.clock_minute,
|
||||||
|
this->data_.clock_second);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_TIME
|
||||||
|
bool TrumaiNetBoxAppClock::action_write_time() {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this->parent_->get_time() == nullptr) {
|
||||||
|
ESP_LOGW(TAG, "Missing system time component.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto now = this->parent_->get_time()->now();
|
||||||
|
if (!now.is_valid()) {
|
||||||
|
ESP_LOGW(TAG, "Invalid system time, not syncing to CP Plus.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The behaviour of this method is special.
|
||||||
|
// Just an update is marked. The actual package is prepared when CP Plus asks for the data in the
|
||||||
|
// `lin_multiframe_recieved` method.
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppClock::create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) {
|
||||||
|
if (this->parent_->get_time() != nullptr) {
|
||||||
|
ESP_LOGD(TAG, "Requested read: Sending clock update");
|
||||||
|
// read time live
|
||||||
|
auto now = this->parent_->get_time()->now();
|
||||||
|
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_CLOCK_RESPONSE, sizeof(StatusFrameClock), command_counter);
|
||||||
|
|
||||||
|
response->inner.clock.clock_hour = now.hour;
|
||||||
|
response->inner.clock.clock_minute = now.minute;
|
||||||
|
response->inner.clock.clock_second = now.second;
|
||||||
|
response->inner.clock.display_1 = 0x1;
|
||||||
|
response->inner.clock.display_2 = 0x1;
|
||||||
|
response->inner.clock.clock_mode = this->data_.clock_mode;
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameClock);
|
||||||
|
}
|
||||||
|
this->update_status_unsubmitted_ = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // USE_TIME
|
||||||
|
|
||||||
|
} // namespace truma_inetbox
|
||||||
|
} // namespace esphome
|
||||||
@ -6,7 +6,27 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
class TrumaiNetBoxAppClock : public TrumaStausFrameStorage<StatusFrameClock> {};
|
class TrumaiNetBoxApp;
|
||||||
|
|
||||||
|
class TrumaiNetBoxAppClock : public TrumaStausFrameStorage<StatusFrameClock>, public Parented<TrumaiNetBoxApp> {
|
||||||
|
public:
|
||||||
|
void dump_data() const override;
|
||||||
|
#ifdef USE_TIME
|
||||||
|
bool can_update() { return this->data_valid_; }
|
||||||
|
void update_submit() { this->update_status_unsubmitted_ = true; }
|
||||||
|
const bool has_update() const { return this->update_status_unsubmitted_; }
|
||||||
|
bool action_write_time();
|
||||||
|
void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// The behaviour of `update_status_clock_unsubmitted_` is special.
|
||||||
|
// Just an update is marked. The actual package is prepared when CP Plus asks for the data in the
|
||||||
|
// `lin_multiframe_recieved` method.
|
||||||
|
bool update_status_unsubmitted_ = false;
|
||||||
|
#else
|
||||||
|
constexpr bool has_update() const { return false; }
|
||||||
|
#endif // USE_TIME
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
15
components/truma_inetbox/TrumaiNetBoxAppConfig.cpp
Normal file
15
components/truma_inetbox/TrumaiNetBoxAppConfig.cpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "TrumaiNetBoxAppConfig.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppConfig";
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppConfig::dump_data() const {
|
||||||
|
ESP_LOGD(TAG, "StatusFrameConfig Offset: %.1f", temp_code_to_decimal(this->config_.data_.temp_offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace truma_inetbox
|
||||||
|
} // namespace esphome
|
||||||
@ -6,7 +6,9 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
class TrumaiNetBoxAppConfig : public TrumaStausFrameStorage<StatusFrameConfig> {};
|
class TrumaiNetBoxAppConfig : public TrumaStausFrameStorage<StatusFrameConfig> {
|
||||||
|
void dump_data() const override;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -1,8 +1,14 @@
|
|||||||
#include "TrumaiNetBoxAppHeater.h"
|
#include "TrumaiNetBoxAppHeater.h"
|
||||||
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "TrumaiNetBoxApp.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppHeater";
|
||||||
|
|
||||||
StatusFrameHeaterResponse *TrumaiNetBoxAppHeater::update_prepare() {
|
StatusFrameHeaterResponse *TrumaiNetBoxAppHeater::update_prepare() {
|
||||||
// An update is currently going on.
|
// An update is currently going on.
|
||||||
if (this->update_status_prepared_ || this->update_status_stale_) {
|
if (this->update_status_prepared_ || this->update_status_stale_) {
|
||||||
@ -23,5 +29,167 @@ StatusFrameHeaterResponse *TrumaiNetBoxAppHeater::update_prepare() {
|
|||||||
return &this->update_status_;
|
return &this->update_status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppHeater::create_update_data(StatusFrame *response, u_int8_t *response_len,
|
||||||
|
u_int8_t command_counter) {
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_HEATER_RESPONSE, sizeof(StatusFrameHeaterResponse), command_counter);
|
||||||
|
|
||||||
|
response->inner.heaterResponse.target_temp_room = this->update_status_.target_temp_room;
|
||||||
|
response->inner.heaterResponse.heating_mode = this->update_status_.heating_mode;
|
||||||
|
response->inner.heaterResponse.target_temp_water = this->update_status_.target_temp_water;
|
||||||
|
response->inner.heaterResponse.energy_mix_a = this->update_status_.energy_mix_a;
|
||||||
|
response->inner.heaterResponse.energy_mix_b = this->update_status_.energy_mix_a;
|
||||||
|
response->inner.heaterResponse.el_power_level_a = this->update_status_.el_power_level_a;
|
||||||
|
response->inner.heaterResponse.el_power_level_b = this->update_status_.el_power_level_a;
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameHeaterResponse);
|
||||||
|
|
||||||
|
TrumaStausFrameResponseStorage<StatusFrameHeater, StatusFrameHeaterResponse>::update_submitted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppHeater::dump_data() const {}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppHeater::action_heater_room(u_int8_t temperature, HeatingMode mode) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto heater = this->update_prepare();
|
||||||
|
|
||||||
|
heater->target_temp_room = decimal_to_room_temp(temperature);
|
||||||
|
|
||||||
|
// Ensure `heating_mode` and `energy_mix_a` is set.
|
||||||
|
if (heater->target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
||||||
|
heater->heating_mode = HeatingMode::HEATING_MODE_OFF;
|
||||||
|
} else {
|
||||||
|
if (this->parent_->get_heater_device() == TRUMA_DEVICE::HEATER_VARIO) {
|
||||||
|
// If parameter `mode` contains a valid Heating mode use it or else use `AUTO`.
|
||||||
|
if (mode == HeatingMode::HEATING_MODE_VARIO_HEAT_NIGHT || mode == HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO ||
|
||||||
|
mode == HeatingMode::HEATING_MODE_BOOST) {
|
||||||
|
heater->heating_mode = mode;
|
||||||
|
} else if (heater->heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
||||||
|
heater->heating_mode = HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HEATER_COMBI
|
||||||
|
// If parameter `mode` contains a valid Heating mode use it or else use `ECO`.
|
||||||
|
if (mode == HeatingMode::HEATING_MODE_ECO || mode == HeatingMode::HEATING_MODE_HIGH ||
|
||||||
|
mode == HeatingMode::HEATING_MODE_BOOST) {
|
||||||
|
heater->heating_mode = mode;
|
||||||
|
} else if (heater->heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
||||||
|
heater->heating_mode = HeatingMode::HEATING_MODE_ECO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (heater->energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppHeater::action_heater_water(u_int8_t temperature) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto heater = this->update_prepare();
|
||||||
|
|
||||||
|
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) {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppHeater::action_heater_water(TargetTemp temperature) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto heater = this->update_prepare();
|
||||||
|
|
||||||
|
// If parameter `temperature` contains a valid mode use it or else use `OFF`.
|
||||||
|
if (temperature == TargetTemp::TARGET_TEMP_WATER_ECO || temperature == TargetTemp::TARGET_TEMP_WATER_HIGH ||
|
||||||
|
temperature == TargetTemp::TARGET_TEMP_WATER_BOOST) {
|
||||||
|
heater->target_temp_water = temperature;
|
||||||
|
} else {
|
||||||
|
heater->target_temp_water = TargetTemp::TARGET_TEMP_OFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure `energy_mix_a` is set.
|
||||||
|
if (heater->target_temp_water != TargetTemp::TARGET_TEMP_OFF && heater->energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppHeater::action_heater_electric_power_level(u_int16_t value) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto heater = this->update_prepare();
|
||||||
|
|
||||||
|
heater->el_power_level_a = decimal_to_el_power_level(value);
|
||||||
|
if (heater->el_power_level_a != ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
||||||
|
if (heater->energy_mix_a != EnergyMix::ENERGY_MIX_MIX &&
|
||||||
|
heater->energy_mix_a != EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_MIX;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppHeater::action_heater_energy_mix(EnergyMix energy_mix, ElectricPowerLevel el_power_level) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto heater = this->update_prepare();
|
||||||
|
|
||||||
|
// If parameter `el_power_level` contains a valid mode use it.
|
||||||
|
if (el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0 ||
|
||||||
|
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900 ||
|
||||||
|
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_1800) {
|
||||||
|
heater->el_power_level_a = el_power_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (energy_mix == EnergyMix::ENERGY_MIX_GAS) {
|
||||||
|
heater->energy_mix_a = energy_mix;
|
||||||
|
heater->el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0;
|
||||||
|
} else if (energy_mix == EnergyMix::ENERGY_MIX_MIX || energy_mix == EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
||||||
|
heater->energy_mix_a = energy_mix;
|
||||||
|
// Electric energy is requested by user without a power level. Set it to minimum.
|
||||||
|
if (heater->el_power_level_a == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
||||||
|
heater->el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This last check is reached if invalid `energy_mix` parameter was submitted.
|
||||||
|
if (heater->el_power_level_a != ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
||||||
|
if (heater->energy_mix_a != EnergyMix::ENERGY_MIX_MIX &&
|
||||||
|
heater->energy_mix_a != EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_MIX;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -8,7 +8,16 @@ namespace truma_inetbox {
|
|||||||
|
|
||||||
class TrumaiNetBoxAppHeater : public TrumaStausFrameResponseStorage<StatusFrameHeater, StatusFrameHeaterResponse> {
|
class TrumaiNetBoxAppHeater : public TrumaStausFrameResponseStorage<StatusFrameHeater, StatusFrameHeaterResponse> {
|
||||||
public:
|
public:
|
||||||
StatusFrameHeaterResponse* update_prepare() override;
|
StatusFrameHeaterResponse *update_prepare() override;
|
||||||
|
void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override;
|
||||||
|
void dump_data() const override;
|
||||||
|
|
||||||
|
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);
|
||||||
|
bool action_heater_electric_power_level(u_int16_t value);
|
||||||
|
bool action_heater_energy_mix(EnergyMix energy_mix,
|
||||||
|
ElectricPowerLevel el_power_level = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
@ -1,8 +1,14 @@
|
|||||||
#include "TrumaiNetBoxAppTimer.h"
|
#include "TrumaiNetBoxAppTimer.h"
|
||||||
|
#include "TrumaStatusFrameBuilder.h"
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "TrumaiNetBoxApp.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|
||||||
|
static const char *const TAG = "truma_inetbox.TrumaiNetBoxAppTimer";
|
||||||
|
|
||||||
StatusFrameTimerResponse *TrumaiNetBoxAppTimer::update_prepare() {
|
StatusFrameTimerResponse *TrumaiNetBoxAppTimer::update_prepare() {
|
||||||
// An update is currently going on.
|
// An update is currently going on.
|
||||||
if (this->update_status_prepared_ || this->update_status_stale_) {
|
if (this->update_status_prepared_ || this->update_status_stale_) {
|
||||||
@ -28,5 +34,123 @@ StatusFrameTimerResponse *TrumaiNetBoxAppTimer::update_prepare() {
|
|||||||
return &this->update_status_;
|
return &this->update_status_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppTimer::create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) {
|
||||||
|
status_frame_create_empty(response, STATUS_FRAME_TIMER_RESPONSE, sizeof(StatusFrameTimerResponse), command_counter);
|
||||||
|
|
||||||
|
response->inner.timerResponse.timer_target_temp_room = this->update_status_.timer_target_temp_room;
|
||||||
|
response->inner.timerResponse.timer_heating_mode = this->update_status_.timer_heating_mode;
|
||||||
|
response->inner.timerResponse.timer_target_temp_water = this->update_status_.timer_target_temp_water;
|
||||||
|
response->inner.timerResponse.timer_energy_mix_a = this->update_status_.timer_energy_mix_a;
|
||||||
|
response->inner.timerResponse.timer_energy_mix_b = this->update_status_.timer_energy_mix_a;
|
||||||
|
response->inner.timerResponse.timer_el_power_level_a = this->update_status_.timer_el_power_level_a;
|
||||||
|
response->inner.timerResponse.timer_el_power_level_b = this->update_status_.timer_el_power_level_a;
|
||||||
|
response->inner.timerResponse.timer_resp_active = this->update_status_.timer_resp_active;
|
||||||
|
response->inner.timerResponse.timer_resp_start_hours = this->update_status_.timer_resp_start_hours;
|
||||||
|
response->inner.timerResponse.timer_resp_start_minutes = this->update_status_.timer_resp_start_minutes;
|
||||||
|
response->inner.timerResponse.timer_resp_stop_hours = this->update_status_.timer_resp_stop_hours;
|
||||||
|
response->inner.timerResponse.timer_resp_stop_minutes = this->update_status_.timer_resp_stop_minutes;
|
||||||
|
|
||||||
|
status_frame_calculate_checksum(response);
|
||||||
|
(*response_len) = sizeof(StatusFrameHeader) + sizeof(StatusFrameTimerResponse);
|
||||||
|
|
||||||
|
TrumaStausFrameResponseStorage<StatusFrameTimer, StatusFrameTimerResponse>::update_submitted();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrumaiNetBoxAppTimer::dump_data() const {
|
||||||
|
ESP_LOGD(TAG, "StatusFrameTimer target_temp_room: %f target_temp_water: %f %02u:%02u -> %02u:%02u %s",
|
||||||
|
temp_code_to_decimal(this->data_.timer_target_temp_room),
|
||||||
|
temp_code_to_decimal(this->data_.timer_target_temp_water), this->data_.timer_start_hours,
|
||||||
|
this->data_.timer_start_minutes, this->data_.timer_stop_hours, this->data_.timer_stop_minutes,
|
||||||
|
((u_int8_t) this->data_.timer_active ? " ON" : " OFF"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppTimer::action_timer_disable() {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto timer = this->update_prepare();
|
||||||
|
|
||||||
|
timer->timer_resp_active = TimerActive::TIMER_ACTIVE_OFF;
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TrumaiNetBoxAppTimer::action_timer_activate(u_int16_t start, u_int16_t stop, u_int8_t room_temperature,
|
||||||
|
HeatingMode mode, u_int8_t water_temperature, EnergyMix energy_mix,
|
||||||
|
ElectricPowerLevel el_power_level) {
|
||||||
|
if (!this->can_update()) {
|
||||||
|
ESP_LOGW(TAG, "Cannot update Truma.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (start > 1440 || stop > 1440) {
|
||||||
|
ESP_LOGW(TAG, "Invalid values start/stop submitted.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto timer = this->update_prepare();
|
||||||
|
|
||||||
|
timer->timer_resp_active = TimerActive::TIMER_ACTIVE_ON;
|
||||||
|
timer->timer_resp_start_hours = start / 60;
|
||||||
|
timer->timer_resp_start_minutes = start % 60;
|
||||||
|
timer->timer_resp_stop_hours = stop / 60;
|
||||||
|
timer->timer_resp_stop_minutes = stop % 60;
|
||||||
|
timer->timer_target_temp_room = decimal_to_room_temp(room_temperature);
|
||||||
|
|
||||||
|
// Ensure `timer_heating_mode` and `timer_energy_mix_a` is set.
|
||||||
|
if (timer->timer_target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
||||||
|
timer->timer_heating_mode = HeatingMode::HEATING_MODE_OFF;
|
||||||
|
} else {
|
||||||
|
if (this->parent_->get_heater_device() == TRUMA_DEVICE::HEATER_VARIO) {
|
||||||
|
// If parameter `mode` contains a valid Heating mode use it or else use `AUTO`.
|
||||||
|
if (mode == HeatingMode::HEATING_MODE_VARIO_HEAT_NIGHT || mode == HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO ||
|
||||||
|
mode == HeatingMode::HEATING_MODE_BOOST) {
|
||||||
|
timer->timer_heating_mode = mode;
|
||||||
|
} else if (timer->timer_heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
||||||
|
timer->timer_heating_mode = HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// HEATER_COMBI
|
||||||
|
// If parameter `mode` contains a valid Heating mode use it or else use `ECO`.
|
||||||
|
if (mode == HeatingMode::HEATING_MODE_ECO || mode == HeatingMode::HEATING_MODE_HIGH ||
|
||||||
|
mode == HeatingMode::HEATING_MODE_BOOST) {
|
||||||
|
timer->timer_heating_mode = mode;
|
||||||
|
} else if (timer->timer_heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
||||||
|
timer->timer_heating_mode = HeatingMode::HEATING_MODE_ECO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 ||
|
||||||
|
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900 ||
|
||||||
|
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_1800) {
|
||||||
|
timer->timer_el_power_level_a = el_power_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure `timer_energy_mix_a` is set
|
||||||
|
if (timer->timer_energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
||||||
|
timer->timer_energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User has supplied a `energy_mix`
|
||||||
|
if (energy_mix == EnergyMix::ENERGY_MIX_GAS) {
|
||||||
|
timer->timer_energy_mix_a = energy_mix;
|
||||||
|
timer->timer_el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0;
|
||||||
|
} else if (energy_mix == EnergyMix::ENERGY_MIX_MIX || energy_mix == EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
||||||
|
timer->timer_energy_mix_a = energy_mix;
|
||||||
|
// Electric energy is requested by user without a power level. Set it to minimum.
|
||||||
|
if (timer->timer_el_power_level_a == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
||||||
|
timer->timer_el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this->update_submit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
@ -9,6 +9,14 @@ namespace truma_inetbox {
|
|||||||
class TrumaiNetBoxAppTimer : public TrumaStausFrameResponseStorage<StatusFrameTimer, StatusFrameTimerResponse> {
|
class TrumaiNetBoxAppTimer : public TrumaStausFrameResponseStorage<StatusFrameTimer, StatusFrameTimerResponse> {
|
||||||
public:
|
public:
|
||||||
StatusFrameTimerResponse *update_prepare() override;
|
StatusFrameTimerResponse *update_prepare() override;
|
||||||
|
void create_update_data(StatusFrame *response, u_int8_t *response_len, u_int8_t command_counter) override;
|
||||||
|
void dump_data() const override;
|
||||||
|
|
||||||
|
bool action_timer_disable();
|
||||||
|
bool action_timer_activate(u_int16_t start, u_int16_t stop, u_int8_t room_temperature,
|
||||||
|
HeatingMode mode = HeatingMode::HEATING_MODE_OFF, u_int8_t water_temperature = 0,
|
||||||
|
EnergyMix energy_mix = EnergyMix::ENERGY_MIX_NONE,
|
||||||
|
ElectricPowerLevel el_power_level = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
} // namespace truma_inetbox
|
||||||
|
|||||||
@ -1,270 +0,0 @@
|
|||||||
#include "TrumaiNetBoxApp.h"
|
|
||||||
#include "TrumaStatusFrame.h"
|
|
||||||
#include "esphome/core/log.h"
|
|
||||||
#include "esphome/core/helpers.h"
|
|
||||||
#include "helpers.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
|
||||||
namespace truma_inetbox {
|
|
||||||
|
|
||||||
static const char *const TAG = "truma_inetbox.TrumaiNetBoxApp";
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_heater_room(u_int8_t temperature, HeatingMode mode) {
|
|
||||||
if (!this->heater_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto heater = this->heater_.update_prepare();
|
|
||||||
|
|
||||||
heater->target_temp_room = decimal_to_room_temp(temperature);
|
|
||||||
|
|
||||||
// Ensure `heating_mode` and `energy_mix_a` is set.
|
|
||||||
if (heater->target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
|
||||||
heater->heating_mode = HeatingMode::HEATING_MODE_OFF;
|
|
||||||
} else {
|
|
||||||
if (this->heater_device_ == TRUMA_DEVICE::HEATER_VARIO) {
|
|
||||||
// If parameter `mode` contains a valid Heating mode use it or else use `AUTO`.
|
|
||||||
if (mode == HeatingMode::HEATING_MODE_VARIO_HEAT_NIGHT || mode == HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO ||
|
|
||||||
mode == HeatingMode::HEATING_MODE_BOOST) {
|
|
||||||
heater->heating_mode = mode;
|
|
||||||
} else if (heater->heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
|
||||||
heater->heating_mode = HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// HEATER_COMBI
|
|
||||||
// If parameter `mode` contains a valid Heating mode use it or else use `ECO`.
|
|
||||||
if (mode == HeatingMode::HEATING_MODE_ECO || mode == HeatingMode::HEATING_MODE_HIGH ||
|
|
||||||
mode == HeatingMode::HEATING_MODE_BOOST) {
|
|
||||||
heater->heating_mode = mode;
|
|
||||||
} else if (heater->heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
|
||||||
heater->heating_mode = HeatingMode::HEATING_MODE_ECO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (heater->energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->heater_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_heater_water(u_int8_t temperature) {
|
|
||||||
if (!this->heater_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto heater = this->heater_.update_prepare();
|
|
||||||
|
|
||||||
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) {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->heater_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_heater_water(TargetTemp temperature) {
|
|
||||||
if (!this->heater_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto heater = this->heater_.update_prepare();
|
|
||||||
|
|
||||||
// If parameter `temperature` contains a valid mode use it or else use `OFF`.
|
|
||||||
if (temperature == TargetTemp::TARGET_TEMP_WATER_ECO || temperature == TargetTemp::TARGET_TEMP_WATER_HIGH ||
|
|
||||||
temperature == TargetTemp::TARGET_TEMP_WATER_BOOST) {
|
|
||||||
heater->target_temp_water = temperature;
|
|
||||||
} else {
|
|
||||||
heater->target_temp_water = TargetTemp::TARGET_TEMP_OFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure `energy_mix_a` is set.
|
|
||||||
if (heater->target_temp_water != TargetTemp::TARGET_TEMP_OFF && heater->energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->heater_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_heater_electric_power_level(u_int16_t value) {
|
|
||||||
if (!this->heater_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto heater = this->heater_.update_prepare();
|
|
||||||
|
|
||||||
heater->el_power_level_a = decimal_to_el_power_level(value);
|
|
||||||
if (heater->el_power_level_a != ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
|
||||||
if (heater->energy_mix_a != EnergyMix::ENERGY_MIX_MIX &&
|
|
||||||
heater->energy_mix_a != EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_MIX;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->heater_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_heater_energy_mix(EnergyMix energy_mix, ElectricPowerLevel el_power_level) {
|
|
||||||
if (!this->heater_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto heater = this->heater_.update_prepare();
|
|
||||||
|
|
||||||
// If parameter `el_power_level` contains a valid mode use it.
|
|
||||||
if (el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0 ||
|
|
||||||
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900 ||
|
|
||||||
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_1800) {
|
|
||||||
heater->el_power_level_a = el_power_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (energy_mix == EnergyMix::ENERGY_MIX_GAS) {
|
|
||||||
heater->energy_mix_a = energy_mix;
|
|
||||||
heater->el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0;
|
|
||||||
} else if (energy_mix == EnergyMix::ENERGY_MIX_MIX || energy_mix == EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
|
||||||
heater->energy_mix_a = energy_mix;
|
|
||||||
// Electric energy is requested by user without a power level. Set it to minimum.
|
|
||||||
if (heater->el_power_level_a == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
|
||||||
heater->el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This last check is reached if invalid `energy_mix` parameter was submitted.
|
|
||||||
if (heater->el_power_level_a != ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
|
||||||
if (heater->energy_mix_a != EnergyMix::ENERGY_MIX_MIX &&
|
|
||||||
heater->energy_mix_a != EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_MIX;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
heater->energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->heater_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_timer_disable() {
|
|
||||||
if (!this->timer_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
auto timer = this->timer_.update_prepare();
|
|
||||||
|
|
||||||
timer->timer_resp_active = TimerActive::TIMER_ACTIVE_OFF;
|
|
||||||
|
|
||||||
this->timer_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TrumaiNetBoxApp::action_timer_activate(u_int16_t start, u_int16_t stop, u_int8_t room_temperature,
|
|
||||||
HeatingMode mode, u_int8_t water_temperature, EnergyMix energy_mix,
|
|
||||||
ElectricPowerLevel el_power_level) {
|
|
||||||
if (!this->timer_.can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (start > 1440 || stop > 1440) {
|
|
||||||
ESP_LOGW(TAG, "Invalid values start/stop submitted.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto timer = this->timer_.update_prepare();
|
|
||||||
|
|
||||||
timer->timer_resp_active = TimerActive::TIMER_ACTIVE_ON;
|
|
||||||
timer->timer_resp_start_hours = start / 60;
|
|
||||||
timer->timer_resp_start_minutes = start % 60;
|
|
||||||
timer->timer_resp_stop_hours = stop / 60;
|
|
||||||
timer->timer_resp_stop_minutes = stop % 60;
|
|
||||||
timer->timer_target_temp_room = decimal_to_room_temp(room_temperature);
|
|
||||||
|
|
||||||
// Ensure `timer_heating_mode` and `timer_energy_mix_a` is set.
|
|
||||||
if (timer->timer_target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
|
||||||
timer->timer_heating_mode = HeatingMode::HEATING_MODE_OFF;
|
|
||||||
} else {
|
|
||||||
if (this->heater_device_ == TRUMA_DEVICE::HEATER_VARIO) {
|
|
||||||
// If parameter `mode` contains a valid Heating mode use it or else use `AUTO`.
|
|
||||||
if (mode == HeatingMode::HEATING_MODE_VARIO_HEAT_NIGHT || mode == HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO ||
|
|
||||||
mode == HeatingMode::HEATING_MODE_BOOST) {
|
|
||||||
timer->timer_heating_mode = mode;
|
|
||||||
} else if (timer->timer_heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
|
||||||
timer->timer_heating_mode = HeatingMode::HEATING_MODE_VARIO_HEAT_AUTO;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// HEATER_COMBI
|
|
||||||
// If parameter `mode` contains a valid Heating mode use it or else use `ECO`.
|
|
||||||
if (mode == HeatingMode::HEATING_MODE_ECO || mode == HeatingMode::HEATING_MODE_HIGH ||
|
|
||||||
mode == HeatingMode::HEATING_MODE_BOOST) {
|
|
||||||
timer->timer_heating_mode = mode;
|
|
||||||
} else if (timer->timer_heating_mode == HeatingMode::HEATING_MODE_OFF) {
|
|
||||||
timer->timer_heating_mode = HeatingMode::HEATING_MODE_ECO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 ||
|
|
||||||
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900 ||
|
|
||||||
el_power_level == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_1800) {
|
|
||||||
timer->timer_el_power_level_a = el_power_level;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure `timer_energy_mix_a` is set
|
|
||||||
if (timer->timer_energy_mix_a == EnergyMix::ENERGY_MIX_NONE) {
|
|
||||||
timer->timer_energy_mix_a = EnergyMix::ENERGY_MIX_GAS;
|
|
||||||
}
|
|
||||||
|
|
||||||
// User has supplied a `energy_mix`
|
|
||||||
if (energy_mix == EnergyMix::ENERGY_MIX_GAS) {
|
|
||||||
timer->timer_energy_mix_a = energy_mix;
|
|
||||||
timer->timer_el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0;
|
|
||||||
} else if (energy_mix == EnergyMix::ENERGY_MIX_MIX || energy_mix == EnergyMix::ENERGY_MIX_ELECTRICITY) {
|
|
||||||
timer->timer_energy_mix_a = energy_mix;
|
|
||||||
// Electric energy is requested by user without a power level. Set it to minimum.
|
|
||||||
if (timer->timer_el_power_level_a == ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0) {
|
|
||||||
timer->timer_el_power_level_a = ElectricPowerLevel::ELECTRIC_POWER_LEVEL_900;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this->timer_.update_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef USE_TIME
|
|
||||||
bool TrumaiNetBoxApp::action_write_time() {
|
|
||||||
if (!this->truma_clock_can_update()) {
|
|
||||||
ESP_LOGW(TAG, "Cannot update Truma.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->time_ == nullptr) {
|
|
||||||
ESP_LOGW(TAG, "Missing system time component.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto now = this->time_->now();
|
|
||||||
if (!now.is_valid()) {
|
|
||||||
ESP_LOGW(TAG, "Invalid system time, not syncing to CP Plus.");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The behaviour of this method is special.
|
|
||||||
// Just an update is marked. The actual package is prepared when CP Plus asks for the data in the
|
|
||||||
// `lin_multiframe_recieved` method.
|
|
||||||
|
|
||||||
this->update_clock_submit();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif // USE_TIME
|
|
||||||
|
|
||||||
} // namespace truma_inetbox
|
|
||||||
} // namespace esphome
|
|
||||||
@ -12,8 +12,8 @@ template<typename... Ts> class HeaterRoomTempAction : public Action<Ts...>, publ
|
|||||||
TEMPLATABLE_VALUE(HeatingMode, heating_mode)
|
TEMPLATABLE_VALUE(HeatingMode, heating_mode)
|
||||||
|
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
this->parent_->action_heater_room(this->temperature_.value_or(x..., 0),
|
this->parent_->get_heater()->action_heater_room(this->temperature_.value_or(x..., 0),
|
||||||
this->heating_mode_.value_or(x..., HeatingMode::HEATING_MODE_OFF));
|
this->heating_mode_.value_or(x..., HeatingMode::HEATING_MODE_OFF));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,7 +21,9 @@ template<typename... Ts> class HeaterWaterTempAction : public Action<Ts...>, pub
|
|||||||
public:
|
public:
|
||||||
TEMPLATABLE_VALUE(u_int8_t, temperature)
|
TEMPLATABLE_VALUE(u_int8_t, temperature)
|
||||||
|
|
||||||
void play(Ts... x) override { this->parent_->action_heater_water(this->temperature_.value_or(x..., 0)); }
|
void play(Ts... x) override {
|
||||||
|
this->parent_->get_heater()->action_heater_water(this->temperature_.value_or(x..., 0));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class HeaterWaterTempEnumAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
template<typename... Ts> class HeaterWaterTempEnumAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
||||||
@ -29,7 +31,7 @@ template<typename... Ts> class HeaterWaterTempEnumAction : public Action<Ts...>,
|
|||||||
TEMPLATABLE_VALUE(TargetTemp, temperature)
|
TEMPLATABLE_VALUE(TargetTemp, temperature)
|
||||||
|
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
this->parent_->action_heater_water(this->temperature_.value_or(x..., TargetTemp::TARGET_TEMP_OFF));
|
this->parent_->get_heater()->action_heater_water(this->temperature_.value_or(x..., TargetTemp::TARGET_TEMP_OFF));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -37,7 +39,9 @@ template<typename... Ts> class HeaterElecPowerLevelAction : public Action<Ts...>
|
|||||||
public:
|
public:
|
||||||
TEMPLATABLE_VALUE(u_int16_t, watt)
|
TEMPLATABLE_VALUE(u_int16_t, watt)
|
||||||
|
|
||||||
void play(Ts... x) override { this->parent_->action_heater_electric_power_level(this->watt_.value_or(x..., 0)); }
|
void play(Ts... x) override {
|
||||||
|
this->parent_->get_heater()->action_heater_electric_power_level(this->watt_.value_or(x..., 0));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class HeaterEnergyMixAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
template<typename... Ts> class HeaterEnergyMixAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
||||||
@ -46,14 +50,15 @@ template<typename... Ts> class HeaterEnergyMixAction : public Action<Ts...>, pub
|
|||||||
TEMPLATABLE_VALUE(ElectricPowerLevel, watt)
|
TEMPLATABLE_VALUE(ElectricPowerLevel, watt)
|
||||||
|
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
this->parent_->action_heater_energy_mix(this->energy_mix_.value_or(x..., EnergyMix::ENERGY_MIX_GAS),
|
this->parent_->get_heater()->action_heater_energy_mix(
|
||||||
this->watt_.value_or(x..., ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0));
|
this->energy_mix_.value_or(x..., EnergyMix::ENERGY_MIX_GAS),
|
||||||
|
this->watt_.value_or(x..., ElectricPowerLevel::ELECTRIC_POWER_LEVEL_0));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class TimerDisableAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
template<typename... Ts> class TimerDisableAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
||||||
public:
|
public:
|
||||||
void play(Ts... x) override { this->parent_->action_timer_disable(); }
|
void play(Ts... x) override { this->parent_->get_timer()->action_timer_disable(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class TimerActivateAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
template<typename... Ts> class TimerActivateAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
||||||
@ -67,7 +72,7 @@ template<typename... Ts> class TimerActivateAction : public Action<Ts...>, publi
|
|||||||
TEMPLATABLE_VALUE(ElectricPowerLevel, watt)
|
TEMPLATABLE_VALUE(ElectricPowerLevel, watt)
|
||||||
|
|
||||||
void play(Ts... x) override {
|
void play(Ts... x) override {
|
||||||
this->parent_->action_timer_activate(
|
this->parent_->get_timer()->action_timer_activate(
|
||||||
this->start_.value(x...), this->stop_.value(x...), this->room_temperature_.value(x...),
|
this->start_.value(x...), this->stop_.value(x...), this->room_temperature_.value(x...),
|
||||||
this->heating_mode_.value_or(x..., HeatingMode::HEATING_MODE_OFF), this->water_temperature_.value_or(x..., 0),
|
this->heating_mode_.value_or(x..., HeatingMode::HEATING_MODE_OFF), this->water_temperature_.value_or(x..., 0),
|
||||||
this->energy_mix_.value_or(x..., EnergyMix::ENERGY_MIX_NONE),
|
this->energy_mix_.value_or(x..., EnergyMix::ENERGY_MIX_NONE),
|
||||||
@ -78,9 +83,9 @@ template<typename... Ts> class TimerActivateAction : public Action<Ts...>, publi
|
|||||||
#ifdef USE_TIME
|
#ifdef USE_TIME
|
||||||
template<typename... Ts> class WriteTimeAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
template<typename... Ts> class WriteTimeAction : public Action<Ts...>, public Parented<TrumaiNetBoxApp> {
|
||||||
public:
|
public:
|
||||||
void play(Ts... x) override { this->parent_->action_write_time(); }
|
void play(Ts... x) override { this->parent_->get_clock()->action_write_time(); }
|
||||||
};
|
};
|
||||||
#endif // USE_TIME
|
#endif // USE_TIME
|
||||||
|
|
||||||
class TrumaiNetBoxAppHeaterMessageTrigger : public Trigger<const StatusFrameHeater *> {
|
class TrumaiNetBoxAppHeaterMessageTrigger : public Trigger<const StatusFrameHeater *> {
|
||||||
public:
|
public:
|
||||||
|
|||||||
@ -37,7 +37,7 @@ void TrumaRoomClimate::dump_config() { LOG_CLIMATE(TAG, "Truma Room Climate", th
|
|||||||
void TrumaRoomClimate::control(const climate::ClimateCall &call) {
|
void TrumaRoomClimate::control(const climate::ClimateCall &call) {
|
||||||
if (call.get_target_temperature().has_value()) {
|
if (call.get_target_temperature().has_value()) {
|
||||||
float temp = *call.get_target_temperature();
|
float temp = *call.get_target_temperature();
|
||||||
this->parent_->action_heater_room(static_cast<u_int8_t>(temp));
|
this->parent_->get_heater()->action_heater_room(static_cast<u_int8_t>(temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call.get_mode().has_value()) {
|
if (call.get_mode().has_value()) {
|
||||||
@ -47,11 +47,11 @@ void TrumaRoomClimate::control(const climate::ClimateCall &call) {
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case climate::CLIMATE_MODE_HEAT:
|
case climate::CLIMATE_MODE_HEAT:
|
||||||
if (status_heater->target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
if (status_heater->target_temp_room == TargetTemp::TARGET_TEMP_OFF) {
|
||||||
this->parent_->action_heater_room(5);
|
this->parent_->get_heater()->action_heater_room(5);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->parent_->action_heater_room(0);
|
this->parent_->get_heater()->action_heater_room(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -65,16 +65,16 @@ void TrumaRoomClimate::control(const climate::ClimateCall &call) {
|
|||||||
}
|
}
|
||||||
switch (pres) {
|
switch (pres) {
|
||||||
case climate::CLIMATE_PRESET_ECO:
|
case climate::CLIMATE_PRESET_ECO:
|
||||||
this->parent_->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_ECO);
|
this->parent_->get_heater()->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_ECO);
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_PRESET_COMFORT:
|
case climate::CLIMATE_PRESET_COMFORT:
|
||||||
this->parent_->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_HIGH);
|
this->parent_->get_heater()->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_HIGH);
|
||||||
break;
|
break;
|
||||||
case climate::CLIMATE_PRESET_BOOST:
|
case climate::CLIMATE_PRESET_BOOST:
|
||||||
this->parent_->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_BOOST);
|
this->parent_->get_heater()->action_heater_room(current_target_temp, HeatingMode::HEATING_MODE_BOOST);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->parent_->action_heater_room(0);
|
this->parent_->get_heater()->action_heater_room(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,7 +21,7 @@ void TrumaWaterClimate::dump_config() { LOG_CLIMATE(TAG, "Truma Climate", this);
|
|||||||
void TrumaWaterClimate::control(const climate::ClimateCall &call) {
|
void TrumaWaterClimate::control(const climate::ClimateCall &call) {
|
||||||
if (call.get_target_temperature().has_value()) {
|
if (call.get_target_temperature().has_value()) {
|
||||||
float temp = *call.get_target_temperature();
|
float temp = *call.get_target_temperature();
|
||||||
this->parent_->action_heater_water(static_cast<u_int8_t>(temp));
|
this->parent_->get_heater()->action_heater_water(static_cast<u_int8_t>(temp));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call.get_mode().has_value()) {
|
if (call.get_mode().has_value()) {
|
||||||
@ -30,11 +30,11 @@ void TrumaWaterClimate::control(const climate::ClimateCall &call) {
|
|||||||
switch (mode) {
|
switch (mode) {
|
||||||
case climate::CLIMATE_MODE_HEAT:
|
case climate::CLIMATE_MODE_HEAT:
|
||||||
if (status_heater->target_temp_water == TargetTemp::TARGET_TEMP_OFF) {
|
if (status_heater->target_temp_water == TargetTemp::TARGET_TEMP_OFF) {
|
||||||
this->parent_->action_heater_water(40);
|
this->parent_->get_heater()->action_heater_water(40);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
this->parent_->action_heater_water(0);
|
this->parent_->get_heater()->action_heater_water(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
#include "esphome/core/helpers.h"
|
|
||||||
#include "TrumaiNetBoxApp.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "TrumaiNetBoxApp.h"
|
#include "TrumaEnums.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace truma_inetbox {
|
namespace truma_inetbox {
|
||||||
|
|||||||
@ -26,13 +26,13 @@ void TrumaHeaterNumber::setup() {
|
|||||||
void TrumaHeaterNumber::control(float value) {
|
void TrumaHeaterNumber::control(float value) {
|
||||||
switch (this->type_) {
|
switch (this->type_) {
|
||||||
case TRUMA_NUMBER_TYPE::TARGET_ROOM_TEMPERATURE:
|
case TRUMA_NUMBER_TYPE::TARGET_ROOM_TEMPERATURE:
|
||||||
this->parent_->action_heater_room(static_cast<u_int8_t>(value));
|
this->parent_->get_heater()->action_heater_room(static_cast<u_int8_t>(value));
|
||||||
break;
|
break;
|
||||||
case TRUMA_NUMBER_TYPE::TARGET_WATER_TEMPERATURE:
|
case TRUMA_NUMBER_TYPE::TARGET_WATER_TEMPERATURE:
|
||||||
this->parent_->action_heater_water(static_cast<u_int8_t>(value));
|
this->parent_->get_heater()->action_heater_water(static_cast<u_int8_t>(value));
|
||||||
break;
|
break;
|
||||||
case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL:
|
case TRUMA_NUMBER_TYPE::ELECTRIC_POWER_LEVEL:
|
||||||
this->parent_->action_heater_electric_power_level(static_cast<u_int16_t>(value));
|
this->parent_->get_heater()->action_heater_electric_power_level(static_cast<u_int16_t>(value));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user