Skip to content

Commit

Permalink
Merge pull request #166 from miipekk-ihme/pr-3
Browse files Browse the repository at this point in the history
New sensors and various fixes
  • Loading branch information
echavet authored Oct 9, 2024
2 parents 9d1a4f4 + e5b233f commit ad62cdc
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 21 deletions.
8 changes: 7 additions & 1 deletion components/cn105/Globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,19 @@ struct heatpumpStatus {
bool operating; // if true, the heatpump is operating to reach the desired temperature
heatpumpTimers timers;
float compressorFrequency;
float inputPower;
float kWh;
float runtimeHours;

bool operator==(const heatpumpStatus& other) const {
return roomTemperature == other.roomTemperature &&
outsideAirTemperature == other.outsideAirTemperature &&
operating == other.operating &&
//timers == other.timers && // Assurez-vous que l'opérateur == est également défini pour heatpumpTimers
compressorFrequency == other.compressorFrequency;
compressorFrequency == other.compressorFrequency &&
inputPower == other.inputPower &&
kWh == other.kWh &&
runtimeHours == other.runtimeHours;
}

bool operator!=(const heatpumpStatus& other) const {
Expand Down
51 changes: 51 additions & 0 deletions components/cn105/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@
CONF_HORIZONTAL_SWING_SELECT = "horizontal_vane_select"
CONF_VERTICAL_SWING_SELECT = "vertical_vane_select"
CONF_COMPRESSOR_FREQUENCY_SENSOR = "compressor_frequency_sensor"
CONF_INPUT_POWER_SENSOR = "input_power_sensor"
CONF_KWH_SENSOR = "kwh_sensor"
CONF_RUNTIME_HOURS_SENSOR = "runtime_hours_sensor"
CONF_OUTSIDE_AIR_TEMPERATURE_SENSOR = "outside_air_temperature_sensor"
CONF_ISEE_SENSOR = "isee_sensor"
CONF_STAGE_SENSOR = "stage_sensor"
Expand All @@ -60,6 +63,18 @@
"CompressorFrequencySensor", sensor.Sensor, cg.Component
)

InputPowerSensor = cg.global_ns.class_(
"InputPowerSensor", sensor.Sensor, cg.Component
)

kWhSensor = cg.global_ns.class_(
"kWhSensor", sensor.Sensor, cg.Component
)

RuntimeHoursSensor = cg.global_ns.class_(
"RuntimeHoursSensor", sensor.Sensor, cg.Component
)

OutsideAirTemperatureSensor = cg.global_ns.class_(
"OutsideAirTemperatureSensor", sensor.Sensor, cg.Component
)
Expand Down Expand Up @@ -96,6 +111,18 @@ def valid_uart(uart):
{cv.GenerateID(CONF_ID): cv.declare_id(CompressorFrequencySensor)}
)

INPUT_POWER_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend(
{cv.GenerateID(CONF_ID): cv.declare_id(InputPowerSensor)}
)

KWH_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend(
{cv.GenerateID(CONF_ID): cv.declare_id(kWhSensor)}
)

RUNTIME_HOURS_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend(
{cv.GenerateID(CONF_ID): cv.declare_id(RuntimeHoursSensor)}
)

OUTSIDE_AIR_TEMPERATURE_SENSOR_SCHEMA = sensor.SENSOR_SCHEMA.extend(
{cv.GenerateID(CONF_ID): cv.declare_id(OutsideAirTemperatureSensor)}
)
Expand Down Expand Up @@ -142,6 +169,9 @@ def valid_uart(uart):
cv.Optional(CONF_HORIZONTAL_SWING_SELECT): SELECT_SCHEMA,
cv.Optional(CONF_VERTICAL_SWING_SELECT): SELECT_SCHEMA,
cv.Optional(CONF_COMPRESSOR_FREQUENCY_SENSOR): COMPRESSOR_FREQUENCY_SENSOR_SCHEMA,
cv.Optional(CONF_INPUT_POWER_SENSOR): INPUT_POWER_SENSOR_SCHEMA,
cv.Optional(CONF_KWH_SENSOR): KWH_SENSOR_SCHEMA,
cv.Optional(CONF_RUNTIME_HOURS_SENSOR): RUNTIME_HOURS_SENSOR_SCHEMA,
cv.Optional(CONF_OUTSIDE_AIR_TEMPERATURE_SENSOR): OUTSIDE_AIR_TEMPERATURE_SENSOR_SCHEMA,
cv.Optional(CONF_ISEE_SENSOR): ISEE_SENSOR_SCHEMA,
cv.Optional(CONF_STAGE_SENSOR): STAGE_SENSOR_SCHEMA,
Expand Down Expand Up @@ -219,6 +249,27 @@ def to_code(config):
yield cg.register_component(sensor_, conf)
cg.add(var.set_compressor_frequency_sensor(sensor_))

if CONF_INPUT_POWER_SENSOR in config:
conf = config[CONF_INPUT_POWER_SENSOR]
conf["force_update"] = False
sensor_ = yield sensor.new_sensor(conf)
yield cg.register_component(sensor_, conf)
cg.add(var.set_input_power_sensor(sensor_))

if CONF_KWH_SENSOR in config:
conf = config[CONF_KWH_SENSOR]
conf["force_update"] = False
sensor_ = yield sensor.new_sensor(conf)
yield cg.register_component(sensor_, conf)
cg.add(var.set_kwh_sensor(sensor_))

if CONF_RUNTIME_HOURS_SENSOR in config:
conf = config[CONF_RUNTIME_HOURS_SENSOR]
conf["force_update"] = False
sensor_ = yield sensor.new_sensor(conf)
yield cg.register_component(sensor_, conf)
cg.add(var.set_runtime_hours_sensor(sensor_))

if CONF_OUTSIDE_AIR_TEMPERATURE_SENSOR in config:
conf = config[CONF_OUTSIDE_AIR_TEMPERATURE_SENSOR]
conf["force_update"] = False
Expand Down
17 changes: 16 additions & 1 deletion components/cn105/cn105.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ CN105Climate::CN105Climate(uart::UARTComponent* uart) :
this->infoMode = 0;
this->lastConnectRqTimeMs = 0;
this->currentStatus.operating = false;
this->currentStatus.compressorFrequency = -1;
this->currentStatus.compressorFrequency = NAN;
this->currentStatus.inputPower = NAN;
this->currentStatus.kWh = NAN;
this->currentStatus.runtimeHours = NAN;
this->tx_pin_ = -1;
this->rx_pin_ = -1;

this->horizontal_vane_select_ = nullptr;
this->vertical_vane_select_ = nullptr;
this->compressor_frequency_sensor_ = nullptr;
this->input_power_sensor_ = nullptr;
this->kwh_sensor_ = nullptr;
this->runtime_hours_sensor_ = nullptr;

this->powerRequestWithoutResponses = 0; // power request is not supported by all heatpump #112

Expand Down Expand Up @@ -87,6 +93,15 @@ void CN105Climate::set_debounce_delay(uint32_t delay) {
float CN105Climate::get_compressor_frequency() {
return currentStatus.compressorFrequency;
}
float CN105Climate::get_input_power() {
return currentStatus.inputPower;
}
float CN105Climate::get_kwh() {
return currentStatus.kWh;
}
float CN105Climate::get_runtime_hours() {
return currentStatus.runtimeHours;
}
bool CN105Climate::is_operating() {
return currentStatus.operating;
}
Expand Down
17 changes: 16 additions & 1 deletion components/cn105/cn105.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include "van_orientation_select.h"
#include "uptime_connection_sensor.h"
#include "compressor_frequency_sensor.h"
#include "input_power_sensor.h"
#include "kwh_sensor.h"
#include "runtime_hours_sensor.h"
#include "outside_air_temperature_sensor.h"
#include "auto_sub_mode_sensor.h"
#include "isee_sensor.h"
Expand Down Expand Up @@ -34,6 +37,9 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
void set_vertical_vane_select(VaneOrientationSelect* vertical_vane_select);
void set_horizontal_vane_select(VaneOrientationSelect* horizontal_vane_select);
void set_compressor_frequency_sensor(esphome::sensor::Sensor* compressor_frequency_sensor);
void set_input_power_sensor(esphome::sensor::Sensor* input_power_sensor);
void set_kwh_sensor(esphome::sensor::Sensor* kwh_sensor);
void set_runtime_hours_sensor(esphome::sensor::Sensor* runtime_hours_sensor);
void set_outside_air_temperature_sensor(esphome::sensor::Sensor* outside_air_temperature_sensor);
void set_isee_sensor(esphome::binary_sensor::BinarySensor* iSee_sensor);
void set_stage_sensor(esphome::text_sensor::TextSensor* Stage_sensor);
Expand All @@ -56,13 +62,22 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
nullptr; // Select to store manual position of horizontal swing
sensor::Sensor* compressor_frequency_sensor_ =
nullptr; // Sensor to store compressor frequency
sensor::Sensor* input_power_sensor_ =
nullptr; // Sensor to store compressor frequency
sensor::Sensor* kwh_sensor_ =
nullptr; // Sensor to store compressor frequency
sensor::Sensor* runtime_hours_sensor_ =
nullptr; // Sensor to store compressor frequency
sensor::Sensor* outside_air_temperature_sensor_ =
nullptr; // Outside air temperature

// sensor to monitor heatpump connection time
uptime::HpUpTimeConnectionSensor* hp_uptime_connection_sensor_ = nullptr;

float get_compressor_frequency();
float get_input_power();
float get_kwh();
float get_runtime_hours();
bool is_operating();

// checks if the field has changed
Expand Down Expand Up @@ -289,7 +304,7 @@ class CN105Climate : public climate::Climate, public Component, public uart::UAR
uint8_t* data;

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

bool tempMode = false;
Expand Down
4 changes: 3 additions & 1 deletion components/cn105/compressor_frequency_sensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ namespace esphome {
public:
CompressorFrequencySensor() {
this->set_unit_of_measurement("Hz");
this->set_device_class("frequency");
this->set_state_class(sensor::StateClass::STATE_CLASS_MEASUREMENT);
this->set_accuracy_decimals(1);
}
};

}
}
15 changes: 15 additions & 0 deletions components/cn105/extraComponents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,21 @@ void CN105Climate::set_compressor_frequency_sensor(
this->compressor_frequency_sensor_ = compressor_frequency_sensor;
}

void CN105Climate::set_input_power_sensor(
sensor::Sensor* input_power_sensor) {
this->input_power_sensor_ = input_power_sensor;
}

void CN105Climate::set_kwh_sensor(
sensor::Sensor* kwh_sensor) {
this->kwh_sensor_ = kwh_sensor;
}

void CN105Climate::set_runtime_hours_sensor(
sensor::Sensor* runtime_hours_sensor) {
this->runtime_hours_sensor_ = runtime_hours_sensor;
}

void CN105Climate::set_outside_air_temperature_sensor(
sensor::Sensor* outside_air_temperature_sensor) {
this->outside_air_temperature_sensor_ = outside_air_temperature_sensor;
Expand Down
57 changes: 40 additions & 17 deletions components/cn105/hp_readings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -227,22 +227,21 @@ void CN105Climate::getRoomTemperatureFromResponsePacket() {
heatpumpStatus receivedStatus{};

//ESP_LOGD("Decoder", "[0x03 room temperature]");
//this->last_received_packet_sensor->publish_state("0x62-> 0x03: Data -> Room temperature");

//this->last_received_packet_sensor->publish_state("0x62-> 0x03: Data -> Room temperature");
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// FC 62 01 30 10 03 00 00 0E 00 94 B0 B0 FE 42 00 01 0A 64 00 00 A9
// RT OT RT SP ?? ?? ?? CT CT
// RT OT RT SP ?? ?? ?? RM RM RM
// RT = room temperature (in old format and in new format)
// OT = outside air temperature
// SP = room setpoint temperature?
// CT = increasing counter (unknown function)
// RM = indoor unit operating time in minutes

if (data[5] != 0x00) {
receivedStatus.outsideAirTemperature = (float)(data[5] - 128) / 2;
if (data[5] > 1) {
receivedStatus.outsideAirTemperature = (float)(data[5] - 128) / 2;
} else {
receivedStatus.outsideAirTemperature = -1;
receivedStatus.outsideAirTemperature = NAN;
}

if (data[6] != 0x00) {
int temp = data[6];
temp -= 128;
Expand All @@ -251,24 +250,30 @@ void CN105Climate::getRoomTemperatureFromResponsePacket() {
receivedStatus.roomTemperature = lookupByteMapValue(ROOM_TEMP_MAP, ROOM_TEMP, 32, data[3]);
}

receivedStatus.runtimeHours = float((data[11] << 16) | (data[12] << 8) | data[13]) / 60;

ESP_LOGD("Decoder", "[Room °C: %f]", receivedStatus.roomTemperature);
ESP_LOGD("Decoder", "[OAT °C: %f]", receivedStatus.outsideAirTemperature);

// no change with this packet to currentStatus for operating and compressorFrequency
receivedStatus.operating = currentStatus.operating;
receivedStatus.compressorFrequency = currentStatus.compressorFrequency;
receivedStatus.inputPower = currentStatus.inputPower;
receivedStatus.kWh = currentStatus.kWh;
this->statusChanged(receivedStatus);
}

void CN105Climate::getOperatingAndCompressorFreqFromResponsePacket() {
//FC 62 01 30 10 06 00 00 1A 01 00 00 00 00 00 00 00 00 00 00 00 3C
//MSZ-RW25VGHZ-SC1 / MUZ-RW25VGHZ-SC1
//FC 62 01 30 10 06 00 00 00 01 00 08 05 50 00 00 42 00 00 00 00 B7
// OP CF CF ?? CT ??
// OP IP IP EU EU ??
// OP = operating status (1 = compressor running, 0 = standby)
// CF = compressor frequency in 16-bit integer, 1 decimal accuracy
// (frequency in float = value / 10)
// CT = slowly increasing counter, unknown function
// IP = Current input power in Watts (16-bit decimal)
// EU = energy usage
// (used energy in kWh = value/10)
// TODO: Currently the maximum size of the counter is not known and
// if the counter extends to other bytes.
// ?? = unknown bytes that appear to have a fixed/constant value
heatpumpStatus receivedStatus{};
ESP_LOGD("Decoder", "[0x06 is status]");
Expand All @@ -277,19 +282,21 @@ void CN105Climate::getOperatingAndCompressorFreqFromResponsePacket() {
// reset counter (because a reply indicates it is connected)
this->nonResponseCounter = 0;
receivedStatus.operating = data[4];
if (data[5] || data[6])
receivedStatus.compressorFrequency = (float)((data[5] << 8) | data[6]) / 10;
else
receivedStatus.compressorFrequency = (float)data[3];
receivedStatus.compressorFrequency = data[3];
receivedStatus.inputPower = (data[5] << 8) | data[6];
receivedStatus.kWh = float((data[7] << 8) | data[8]) / 10;

// no change with this packet to roomTemperature
receivedStatus.roomTemperature = currentStatus.roomTemperature;
receivedStatus.outsideAirTemperature = currentStatus.outsideAirTemperature;
receivedStatus.runtimeHours = currentStatus.runtimeHours;
this->statusChanged(receivedStatus);
}

void CN105Climate::terminateCycle() {
if (this->shouldSendExternalTemperature_) {
// We will receive ACK packet for this.
// Sending WantedSettings must be delayed in this case (lastSend timestamp updated).
this->sendRemoteTemperature();
}

Expand Down Expand Up @@ -433,6 +440,9 @@ void CN105Climate::statusChanged(heatpumpStatus status) {

this->currentStatus.operating = status.operating;
this->currentStatus.compressorFrequency = status.compressorFrequency;
this->currentStatus.inputPower = status.inputPower;
this->currentStatus.kWh = status.kWh;
this->currentStatus.runtimeHours = status.runtimeHours;
this->currentStatus.roomTemperature = status.roomTemperature;
this->currentStatus.outsideAirTemperature = status.outsideAirTemperature;
this->current_temperature = currentStatus.roomTemperature;
Expand All @@ -444,6 +454,18 @@ void CN105Climate::statusChanged(heatpumpStatus status) {
this->compressor_frequency_sensor_->publish_state(currentStatus.compressorFrequency);
}

if (this->input_power_sensor_ != nullptr) {
this->input_power_sensor_->publish_state(currentStatus.inputPower);
}

if (this->kwh_sensor_ != nullptr) {
this->kwh_sensor_->publish_state(currentStatus.kWh);
}

if (this->runtime_hours_sensor_ != nullptr) {
this->runtime_hours_sensor_->publish_state(currentStatus.runtimeHours);
}

if (this->outside_air_temperature_sensor_ != nullptr) {
this->outside_air_temperature_sensor_->publish_state(currentStatus.outsideAirTemperature);
}
Expand Down Expand Up @@ -598,7 +620,8 @@ void CN105Climate::checkFanSettings(heatpumpSettings& settings, bool updateCurre
if (updateCurrentSettings) {
currentSettings.fan = settings.fan;
}
if (strcmp(currentSettings.fan, "QUIET") == 0) {

if (strcmp(settings.fan, "QUIET") == 0) {
this->fan_mode = climate::CLIMATE_FAN_QUIET;
} else if (strcmp(settings.fan, "1") == 0) {
this->fan_mode = climate::CLIMATE_FAN_LOW;
Expand Down
3 changes: 3 additions & 0 deletions components/cn105/hp_writings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ void CN105Climate::writePacket(uint8_t* packet, int length, bool checkIsActive)
this->get_hw_serial_()->write_byte((uint8_t)packet[i]);
}

// Prevent sending wantedSettings too soon after writing for example the remote temperature update packet
this->lastSend = CUSTOM_MILLIS;

} else {
ESP_LOGW(TAG, "could not write as asked, because UART is not connected");
this->reconnectUART();
Expand Down
19 changes: 19 additions & 0 deletions components/cn105/input_power_sensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"


namespace esphome {

class InputPowerSensor : public sensor::Sensor, public Component {
public:
InputPowerSensor() {
this->set_unit_of_measurement("W");
this->set_device_class("power");
this->set_state_class(sensor::StateClass::STATE_CLASS_MEASUREMENT);
this->set_accuracy_decimals(0);
}
};

}
Loading

0 comments on commit ad62cdc

Please sign in to comment.