Skip to content

Commit

Permalink
Merge pull request #47 from echavet/cycle_mgmt_refactor
Browse files Browse the repository at this point in the history
Cycle mgmt refactor
  • Loading branch information
echavet authored Feb 23, 2024
2 parents 9392774 + 685f372 commit b47efcd
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 117 deletions.
5 changes: 1 addition & 4 deletions components/cn105/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,10 @@ static const char* DEFER_SHEDULER_INTERVAL_SYNC_NAME = "hp->sync_defer"; // name
static const char* SHEDULER_REMOTE_TEMP_TIMEOUT = "->remote_temp_timeout";

// defering delay for update_interval when we've just sent a wentedSettings
static const int DEFER_SCHEDULE_UPDATE_LOOP_DELAY = 650;
static const int DEFER_SCHEDULE_UPDATE_LOOP_DELAY = 750;

static const int PACKET_LEN = 22;
static const int PACKET_SENT_INTERVAL_MS = 1000;
static const int PACKET_INFO_INTERVAL_MS = 2000;
static const int PACKET_TYPE_DEFAULT = 99;
static const int AUTOUPDATE_GRACE_PERIOD_IGNORE_EXTERNAL_UPDATES_MS = 30000;

static const int CONNECT_LEN = 8;
static const uint8_t CONNECT[CONNECT_LEN] = { 0xfc, 0x5a, 0x01, 0x30, 0x02, 0xca, 0x01, 0xa8 };
Expand Down
5 changes: 2 additions & 3 deletions components/cn105/cn105.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ CN105Climate::CN105Climate(uart::UARTComponent* uart) :
this->vertical_vane_select_ = nullptr;
this->compressor_frequency_sensor_ = nullptr;

this->remote_temp_timeout_ = 4294967295; // uint32_t max
this->lastCompleteCycle = CUSTOM_MILLIS;
this->remote_temp_timeout_ = 4294967295; // uint32_t max
this->generateExtraComponents();
this->cycleRunning = false;
this->loopCycle.init();
this->wantedSettings.resetSettings();
#ifndef USE_ESP32
this->wantedSettingsMutex = false;
Expand Down
17 changes: 4 additions & 13 deletions components/cn105/cn105.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include "sub_mode_sensor.h"
#include <esphome/components/sensor/sensor.h>
#include <esphome/components/binary_sensor/binary_sensor.h>
#include "cycle_management.h"

#ifdef USE_ESP32
#include <mutex>
#endif
Expand Down Expand Up @@ -65,6 +67,7 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR

void setup() override;
void loop() override;

void set_baud_rate(int baud_rate);
void set_tx_rx_pins(uint8_t tx_pin, uint8_t rx_pin);
//void set_wifi_connected_state(bool state);
Expand Down Expand Up @@ -167,7 +170,6 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
void getRoomTemperatureFromResponsePacket();
void getOperatingAndCompressorFreqFromResponsePacket();

void programUpdateInterval();
void updateSuccess();
void processCommand();
bool checkSum();
Expand All @@ -186,13 +188,6 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
void setWideVaneSetting(const char* setting);
void setFanSpeed(const char* setting);

void cycleStarted();
void cycleEnded();
bool hasUpdateIntervalPassed();
bool didCycleTimeOut();
bool isCycleRunning();
void deferCycle();

private:
const char* lookupByteMapValue(const char* valuesMap[], const uint8_t byteMap[], int len, uint8_t byteValue, const char* debugInfo = "", const char* defaultValue = nullptr);
int lookupByteMapValue(const int valuesMap[], const uint8_t byteMap[], int len, uint8_t byteValue, const char* debugInfo = "");
Expand Down Expand Up @@ -240,6 +235,7 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
void createInfoPacket(uint8_t* packet, uint8_t packetType);
heatpumpSettings currentSettings{};
wantedHeatpumpSettings wantedSettings{};
cycleManagement loopCycle{};

#ifdef USE_ESP32
std::mutex wantedSettingsMutex;
Expand All @@ -262,18 +258,13 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
//HardwareSerial* _HardSerial{ nullptr };
unsigned long lastSend;

unsigned long lastRequestInfo;

unsigned long lastCompleteCycle;

uint8_t storedInputData[MAX_DATA_BYTES]; // multi-byte data
uint8_t* data;

// initialise to all off, then it will update shortly after connect;
heatpumpStatus currentStatus{ 0, false, {TIMER_MODE_MAP[0], 0, 0, 0, 0}, 0 };
heatpumpFunctions functions;

bool cycleRunning = false;
bool tempMode = false;
bool wideVaneAdj;
bool autoUpdate;
Expand Down
42 changes: 9 additions & 33 deletions components/cn105/componentEntries.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,54 +29,30 @@ void CN105Climate::setup() {
}



/**
* @brief Executes the main loop for the CN105Climate component.
* This function is called repeatedly in the main program loop.
*/
void CN105Climate::loop() {
if (!this->processInput()) { // if we don't get an input: no read op
if (this->wantedSettings.hasChanged) {
if (!this->processInput()) { // if we don't get an input: no read op
if ((this->wantedSettings.hasChanged) && (!this->loopCycle.isCycleRunning())) {
this->checkPendingWantedSettings();
} else {
if (!this->isCycleRunning()) { // if we are not already running an update cycle
if (this->hasUpdateIntervalPassed()) {
ESP_LOGD(LOG_UPD_INT_TAG, "triggering infopacket because of update interval tic");
this->buildAndSendRequestsInfoPackets(); // initiate an update cycle
}
} else { // a cycle in running
if (this->didCycleTimeOut()) { // does it last too long ?
ESP_LOGW(TAG, "Cycle timeout, reseting cycle...");
cycleRunning = false; // too long so we presume sync failed
if (this->loopCycle.isCycleRunning()) { // if we are running an update cycle
this->loopCycle.checkTimeout(this->update_interval_);
} else { // we are not running a cycle
if (this->loopCycle.hasUpdateIntervalPassed(this->get_update_interval())) {
ESP_LOGD(LOG_UPD_INT_TAG, "triggering infopacket because of update interval tick");
this->buildAndSendRequestsInfoPackets(); // initiate an update cycle with this->cycleStarted();
}
}
}
}
}


/**
* Programs the sending of a request
*/
void CN105Climate::programUpdateInterval() {
if (autoUpdate) {
ESP_LOGD(TAG, "Autoupdate is ON --> creating a loop for reccurent updates...");
ESP_LOGD(TAG, "Programming update interval : %d", this->get_update_interval());

this->cancel_timeout(SHEDULER_INTERVAL_SYNC_NAME); // in case a loop is already programmed


this->set_timeout(SHEDULER_INTERVAL_SYNC_NAME, this->get_update_interval(), [this]() {

this->buildAndSendRequestsInfoPackets();


});
}
}

uint32_t CN105Climate::get_update_interval() const { return this->update_interval_; }
void CN105Climate::set_update_interval(uint32_t update_interval) {
ESP_LOGD(TAG, "Setting update interval to %d", update_interval);
this->update_interval_ = update_interval;
this->autoUpdate = (update_interval != 0);
}
52 changes: 38 additions & 14 deletions components/cn105/cycle_management.cpp
Original file line number Diff line number Diff line change
@@ -1,39 +1,63 @@
#include "cycle_management.h"
#include "cn105.h"
#include "Globals.h"


bool CN105Climate::isCycleRunning() {

void cycleManagement::checkTimeout(unsigned int update_interval) {
if (doesCycleTimeOut(update_interval)) { // does it last too long ?
ESP_LOGW(TAG, "Cycle timeout, reseting cycle...");
cycleEnded(true);
}
}


bool cycleManagement::isCycleRunning() {
return cycleRunning;
}

void CN105Climate::deferCycle() {
void cycleManagement::init() {
cycleRunning = false;
lastCompleteCycleMs = CUSTOM_MILLIS;
}

void cycleManagement::deferCycle() {

#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_DEBUG
uint32_t delay = DEFER_SCHEDULE_UPDATE_LOOP_DELAY * 3;
uint32_t delay = DEFER_SCHEDULE_UPDATE_LOOP_DELAY * 2;
#else
uint32_t delay = DEFER_SCHEDULE_UPDATE_LOOP_DELAY;
#endif

ESP_LOGI(LOG_CYCLE_TAG, "Defering cycle trigger of %d ms", delay);
// forces the lastCompleteCycle offset of delay ms to allow a longer rest time
this->lastCompleteCycle += delay;
lastCompleteCycleMs = CUSTOM_MILLIS + delay;

}
void CN105Climate::cycleStarted() {
void cycleManagement::cycleStarted() {
ESP_LOGI(LOG_CYCLE_TAG, "1: Cycle start");
this->lastRequestInfo = CUSTOM_MILLIS;
lastCycleStartMs = CUSTOM_MILLIS;
cycleRunning = true;
}
void CN105Climate::cycleEnded() {
ESP_LOGI(LOG_CYCLE_TAG, "6: Cycle ends");

void cycleManagement::cycleEnded(bool timedOut) {
cycleRunning = false;
// a complete cycle is done
this->lastCompleteCycle = CUSTOM_MILLIS;

if (lastCompleteCycleMs < CUSTOM_MILLIS) { // we check this because of defering mecanism
// a complete cycle is done
lastCompleteCycleMs = CUSTOM_MILLIS; // to prevent next inteval from ticking too soon
}

ESP_LOGI(LOG_CYCLE_TAG, "6: Cycle ended in %.1f seconds (with timeout?: %s)",
(lastCompleteCycleMs - lastCycleStartMs) / 1000.0, timedOut ? "YES" : " NO");
}

bool CN105Climate::hasUpdateIntervalPassed() {
return (CUSTOM_MILLIS - this->lastCompleteCycle) > this->update_interval_;
bool cycleManagement::hasUpdateIntervalPassed(unsigned int update_interval) {
if (CUSTOM_MILLIS < lastCompleteCycleMs) return false; // must be checked because operands are they are unsigned
return (CUSTOM_MILLIS - lastCompleteCycleMs) > update_interval;
}

bool CN105Climate::didCycleTimeOut() {
return (CUSTOM_MILLIS - this->lastRequestInfo) > (5 * this->update_interval_) + 4000;
bool cycleManagement::doesCycleTimeOut(unsigned int update_interval) {
if (CUSTOM_MILLIS < lastCycleStartMs) return false; // must be checked because operands are they are unsigned
return (CUSTOM_MILLIS - lastCycleStartMs) > (2 * update_interval) + 1000;
}
18 changes: 18 additions & 0 deletions components/cn105/cycle_management.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

struct cycleManagement {

bool cycleRunning = false;
unsigned long lastCycleStartMs = 0;
unsigned long lastCompleteCycleMs = 0;

void init();
void cycleStarted();
void cycleEnded(bool timedOut = false);
bool hasUpdateIntervalPassed(unsigned int update_interval);
bool doesCycleTimeOut(unsigned int update_interval);
bool isCycleRunning();
void deferCycle();
void checkTimeout(unsigned int update_interval);

};
6 changes: 3 additions & 3 deletions components/cn105/extraComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ void CN105Climate::set_isee_sensor(esphome::binary_sensor::BinarySensor* iSee_se
this->iSee_sensor_ = iSee_sensor;
}

void CN105Climate::set_stage_sensor(esphome::text_sensor::TextSensor* Stage_sensor) {
void CN105Climate::set_stage_sensor(esphome::text_sensor::TextSensor* Stage_sensor) {
this->Stage_sensor_ = Stage_sensor;
}

void CN105Climate::set_sub_mode_sensor(esphome::text_sensor::TextSensor* Sub_mode_sensor) {
void CN105Climate::set_sub_mode_sensor(esphome::text_sensor::TextSensor* Sub_mode_sensor) {
this->Sub_mode_sensor_ = Sub_mode_sensor;
}

void CN105Climate::set_auto_sub_mode_sensor(esphome::text_sensor::TextSensor* Auto_sub_mode_sensor) {
void CN105Climate::set_auto_sub_mode_sensor(esphome::text_sensor::TextSensor* Auto_sub_mode_sensor) {
this->Auto_sub_mode_sensor_ = Auto_sub_mode_sensor;
}
12 changes: 6 additions & 6 deletions components/cn105/hp_readings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ void CN105Climate::getDataFromResponsePacket() {

switch (this->data[0]) {
case 0x02: /* setting information */
ESP_LOGD(LOG_CYCLE_TAG, "2d: Receiving settings response");
ESP_LOGD(LOG_CYCLE_TAG, "2b: Receiving settings response");
this->getSettingsFromResponsePacket();
// next step is to get the room temperature case 0x03
ESP_LOGD(LOG_CYCLE_TAG, "3a: Sending room °C request (0x03)");
Expand Down Expand Up @@ -302,8 +302,8 @@ void CN105Climate::getDataFromResponsePacket() {
/* Power */
ESP_LOGD(LOG_CYCLE_TAG, "5b: Receiving Power/Standby response");
this->getPowerFromResponsePacket();
//FC 62 01 30 10 09 00 00 00 02 02 00 00 00 00 00 00 00 00 00 00 50
this->cycleEnded();
//FC 62 01 30 10 09 00 00 00 02 02 00 00 00 00 00 00 00 00 00 00 50
this->loopCycle.cycleEnded();
break;

case 0x10:
Expand Down Expand Up @@ -344,7 +344,7 @@ void CN105Climate::updateSuccess() {
void CN105Climate::processCommand() {
switch (this->command) {
case 0x61: /* last update was successful */
this->hpPacketDebug(this->storedInputData, this->bytesRead + 1, "ACK");
this->hpPacketDebug(this->storedInputData, this->bytesRead + 1, "Update-ACK");
this->updateSuccess();
break;

Expand All @@ -354,8 +354,8 @@ void CN105Climate::processCommand() {
case 0x7a:
ESP_LOGI(TAG, "--> Heatpump did reply: connection success! <--");
this->isHeatpumpConnected_ = true;
// let's say that the last complete cycle was over now
this->lastCompleteCycle = CUSTOM_MILLIS;
// let's say that the last complete cycle was over now
this->loopCycle.lastCompleteCycleMs = CUSTOM_MILLIS;
this->currentSettings.resetSettings(); // each time we connect, we need to reset current setting to force a complete sync with ha component state and receievdSettings
break;
default:
Expand Down
Loading

0 comments on commit b47efcd

Please sign in to comment.