mirror of
https://github.com/esphome/esphome.git
synced 2024-11-27 17:27:59 +01:00
improvements concerning queue overflow
This commit is contained in:
parent
9d5a715356
commit
c6caf84377
17 changed files with 337 additions and 228 deletions
|
@ -14,7 +14,7 @@ from esphome.const import (
|
||||||
from esphome.core import CORE
|
from esphome.core import CORE
|
||||||
|
|
||||||
CODEOWNERS = ["@j0ta29"]
|
CODEOWNERS = ["@j0ta29"]
|
||||||
DEPENDENCIES = ["text_sensor"]
|
DEPENDENCIES = []
|
||||||
AUTO_LOAD = []
|
AUTO_LOAD = []
|
||||||
MULTI_CONF = False
|
MULTI_CONF = False
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ CONFIG_SCHEMA = cv.All(
|
||||||
|
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
cg.add_library("VitoWiFi", "1.0.2")
|
cg.add_library("VitoWiFi", "1.1.2")
|
||||||
|
|
||||||
cg.add_define(
|
cg.add_define(
|
||||||
"VITOWIFI_PROTOCOL", cg.RawExpression(f"Optolink{config[CONF_PROTOCOL]}")
|
"VITOWIFI_PROTOCOL", cg.RawExpression(f"Optolink{config[CONF_PROTOCOL]}")
|
||||||
|
|
|
@ -4,27 +4,27 @@
|
||||||
|
|
||||||
#include "esphome/components/binary_sensor/binary_sensor.h"
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
class OptolinkBinarySensor : public OptolinkSensorBase,
|
class OptolinkBinarySensor : public DatapointComponent,
|
||||||
public esphome::binary_sensor::BinarySensor,
|
public esphome::binary_sensor::BinarySensor,
|
||||||
public esphome::PollingComponent {
|
public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkBinarySensor(Optolink *optolink) : OptolinkSensorBase(optolink) {
|
OptolinkBinarySensor(Optolink *optolink) : DatapointComponent(optolink) {
|
||||||
bytes_ = 1;
|
set_bytes(1);
|
||||||
div_ratio_ = 1;
|
set_div_ratio(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() override { setup_datapoint(); }
|
void setup() override { setup_datapoint(); }
|
||||||
void update() override { optolink_->read_value(datapoint_); }
|
void update() override { datapoint_read_request(); }
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(uint8_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint8_t state) override { publish_state(state); };
|
||||||
};
|
};
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "optolink_sensor_base.h"
|
#include "datapoint_component.h"
|
||||||
#include "optolink.h"
|
#include "optolink.h"
|
||||||
|
#include "esphome/components/api/api_server.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
static const char *const TAG = "optolink.sensor_base";
|
static const char *const TAG = "datapoint_component";
|
||||||
|
static std::vector<HassSubscription> hass_subscriptions_;
|
||||||
|
|
||||||
void OptolinkSensorBase::setup_datapoint() {
|
void DatapointComponent::setup_datapoint() {
|
||||||
switch (div_ratio_) {
|
switch (div_ratio_) {
|
||||||
case 0:
|
case 0:
|
||||||
datapoint_ = new Datapoint<convRaw>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<convRaw>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
|
@ -21,7 +23,8 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
dp_value.getString(print_buffer, sizeof(print_buffer));
|
dp_value.getString(print_buffer, sizeof(print_buffer));
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %s", dp.getName(), print_buffer);
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %s", dp.getName(), print_buffer);
|
||||||
#endif
|
#endif
|
||||||
value_changed((uint8_t *) buffer, bytes_);
|
datapoint_value_changed((uint8_t *) buffer, bytes_);
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -30,21 +33,24 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
datapoint_ = new Datapoint<conv1_1_US>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv1_1_US>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU8());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU8());
|
||||||
value_changed(dp_value.getU8());
|
datapoint_value_changed(dp_value.getU8());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
datapoint_ = new Datapoint<conv2_1_US>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv2_1_US>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU16());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU16());
|
||||||
value_changed(dp_value.getU16());
|
datapoint_value_changed(dp_value.getU16());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
datapoint_ = new Datapoint<conv4_1_UL>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv4_1_UL>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU32());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %d", dp.getName(), dp_value.getU32());
|
||||||
value_changed((uint32_t) dp_value.getU32());
|
datapoint_value_changed((uint32_t) dp_value.getU32());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -57,14 +63,16 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
datapoint_ = new Datapoint<conv1_10_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv1_10_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
||||||
value_changed(dp_value.getFloat());
|
datapoint_value_changed(dp_value.getFloat());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
datapoint_ = new Datapoint<conv2_10_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv2_10_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
||||||
value_changed(dp_value.getFloat());
|
datapoint_value_changed(dp_value.getFloat());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -77,7 +85,8 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
datapoint_ = new Datapoint<conv2_100_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv2_100_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
||||||
value_changed(dp_value.getFloat());
|
datapoint_value_changed(dp_value.getFloat());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -90,7 +99,8 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
datapoint_ = new Datapoint<conv4_1000_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv4_1000_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
||||||
value_changed(dp_value.getFloat());
|
datapoint_value_changed(dp_value.getFloat());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -101,7 +111,8 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
datapoint_ = new Datapoint<conv4_3600_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
datapoint_ = new Datapoint<conv4_3600_F>(get_component_name().c_str(), "optolink", address_, writeable_);
|
||||||
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
datapoint_->setCallback([this](const IDatapoint &dp, DPValue dp_value) {
|
||||||
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
ESP_LOGI(TAG, "recieved data for datapoint %s: %f", dp.getName(), dp_value.getFloat());
|
||||||
value_changed(dp_value.getFloat());
|
datapoint_value_changed(dp_value.getFloat());
|
||||||
|
read_retries_ = 0;
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -111,57 +122,81 @@ void OptolinkSensorBase::setup_datapoint() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(float value) {
|
void DatapointComponent::datapoint_read_request() {
|
||||||
|
if (is_dp_value_writing_outstanding) {
|
||||||
|
ESP_LOGI(TAG, "read request for %s deferred due to outstanding write request", get_component_name().c_str());
|
||||||
|
datapoint_write_request(dp_value_outstanding);
|
||||||
|
} else {
|
||||||
|
if (read_retries_ == 0 || read_retries_ >= MAX_RETRIES_UNTIL_RESET) {
|
||||||
|
if (optolink_->read_value(datapoint_)) {
|
||||||
|
read_retries_ = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
read_retries_++;
|
||||||
|
ESP_LOGW(TAG, "%d. read request for %s rejected - reduce update_interval!", read_retries_,
|
||||||
|
get_component_name().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DatapointComponent::datapoint_value_changed(float value) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(uint8_t value) {
|
void DatapointComponent::datapoint_value_changed(uint8_t value) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(uint16_t value) {
|
void DatapointComponent::datapoint_value_changed(uint16_t value) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(uint32_t value) {
|
void DatapointComponent::datapoint_value_changed(uint32_t value) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(std::string value) {
|
void DatapointComponent::datapoint_value_changed(std::string value) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::value_changed(uint8_t *value, size_t length) {
|
void DatapointComponent::datapoint_value_changed(uint8_t *value, size_t length) {
|
||||||
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
ESP_LOGW(TAG, "unused value update by sensor %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(DPValue dp_value) {
|
void DatapointComponent::datapoint_write_request(DPValue dp_value) {
|
||||||
if (!writeable_) {
|
if (!writeable_) {
|
||||||
optolink_->set_error("trying to control not writable datapoint %s", get_component_name().c_str());
|
optolink_->set_state("trying to control not writable datapoint %s", get_component_name().c_str());
|
||||||
ESP_LOGE(TAG, "trying to control not writable datapoint %s", get_component_name().c_str());
|
ESP_LOGE(TAG, "trying to control not writable datapoint %s", get_component_name().c_str());
|
||||||
} else if (datapoint_ != nullptr) {
|
} else if (datapoint_ != nullptr) {
|
||||||
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_INFO
|
#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_INFO
|
||||||
char buffer[100];
|
char buffer[100];
|
||||||
dp_value.getString(buffer, sizeof(buffer));
|
dp_value.getString(buffer, sizeof(buffer));
|
||||||
ESP_LOGI(TAG, "updating datapoint %s value: %s", datapoint_->getName(), buffer);
|
ESP_LOGI(TAG, "trying to update datapoint %s value: %s", get_component_name().c_str(), buffer);
|
||||||
#endif
|
#endif
|
||||||
optolink_->write_value(datapoint_, dp_value);
|
|
||||||
|
dp_value_outstanding = dp_value;
|
||||||
|
if (optolink_->write_value(datapoint_, dp_value_outstanding)) {
|
||||||
|
is_dp_value_writing_outstanding = false;
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "write request for %s rejected - reduce update_interval!", get_component_name().c_str());
|
||||||
|
is_dp_value_writing_outstanding = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(float value) {
|
void DatapointComponent::write_datapoint_value(float value) {
|
||||||
if (div_ratio_ > 1) {
|
if (div_ratio_ > 1) {
|
||||||
update_datapoint(DPValue(value));
|
datapoint_write_request(DPValue(value));
|
||||||
} else if (div_ratio_ == 1) {
|
} else if (div_ratio_ == 1) {
|
||||||
switch (bytes_) {
|
switch (bytes_) {
|
||||||
case 1:
|
case 1:
|
||||||
update_datapoint(DPValue((uint8_t) value));
|
datapoint_write_request(DPValue((uint8_t) value));
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
update_datapoint(DPValue((uint16_t) value));
|
datapoint_write_request(DPValue((uint16_t) value));
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
update_datapoint(DPValue((uint32_t) value));
|
datapoint_write_request(DPValue((uint32_t) value));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
|
@ -172,43 +207,79 @@ void OptolinkSensorBase::update_datapoint(float value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(uint8_t value) {
|
void DatapointComponent::write_datapoint_value(uint8_t value) {
|
||||||
if (bytes_ == 1 && div_ratio_ == 1) {
|
if (bytes_ == 1 && div_ratio_ == 1) {
|
||||||
update_datapoint(DPValue(value));
|
datapoint_write_request(DPValue(value));
|
||||||
} else {
|
} else {
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(uint16_t value) {
|
void DatapointComponent::write_datapoint_value(uint16_t value) {
|
||||||
if (bytes_ == 2 && div_ratio_ == 1) {
|
if (bytes_ == 2 && div_ratio_ == 1) {
|
||||||
update_datapoint(DPValue(value));
|
datapoint_write_request(DPValue(value));
|
||||||
} else {
|
} else {
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(uint32_t value) {
|
void DatapointComponent::write_datapoint_value(uint32_t value) {
|
||||||
if (bytes_ == 4 && div_ratio_ == 1) {
|
if (bytes_ == 4 && div_ratio_ == 1) {
|
||||||
update_datapoint(DPValue(value));
|
datapoint_write_request(DPValue(value));
|
||||||
} else {
|
} else {
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::update_datapoint(uint8_t *value, size_t length) {
|
void DatapointComponent::write_datapoint_value(uint8_t *value, size_t length) {
|
||||||
if (bytes_ == length && div_ratio_ == 0) {
|
if (bytes_ == length && div_ratio_ == 0) {
|
||||||
update_datapoint(DPValue(value, length));
|
datapoint_write_request(DPValue(value, length));
|
||||||
} else {
|
} else {
|
||||||
unfitting_value_type();
|
unfitting_value_type();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSensorBase::unfitting_value_type() {
|
void DatapointComponent::unfitting_value_type() {
|
||||||
optolink_->set_error("Unfitting byte/div_ratio combination for sensor/component %s", get_component_name().c_str());
|
optolink_->set_state("Unfitting byte/div_ratio combination for sensor/component %s", get_component_name().c_str());
|
||||||
ESP_LOGE(TAG, "Unfitting byte/div_ratio combination for sensor/component %s", get_component_name().c_str());
|
ESP_LOGE(TAG, "Unfitting byte/div_ratio combination for sensor/component %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatapointComponent::set_optolink_state(const char *format, ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
char buffer[128];
|
||||||
|
std::vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
optolink_->set_state(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string DatapointComponent::get_optolink_state() { return optolink_->get_state(); }
|
||||||
|
|
||||||
|
void DatapointComponent::subscribe_hass(std::string entity_id, std::function<void(std::string)> f) {
|
||||||
|
for (auto &subscription : hass_subscriptions_) {
|
||||||
|
if (subscription.entity_id == entity_id) {
|
||||||
|
subscription.callbacks.push_back(f);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HassSubscription subscription{entity_id};
|
||||||
|
subscription.callbacks.push_back(f);
|
||||||
|
hass_subscriptions_.push_back(subscription);
|
||||||
|
|
||||||
|
api::global_api_server->subscribe_home_assistant_state(
|
||||||
|
entity_id, optional<std::string>(), [this, entity_id](const std::string &state) {
|
||||||
|
ESP_LOGD(TAG, "received schedule plan from HASS entity '%s': %s", entity_id.c_str(), state.c_str());
|
||||||
|
for (auto &subscription : hass_subscriptions_) {
|
||||||
|
if (subscription.entity_id == entity_id) {
|
||||||
|
for (auto callback : subscription.callbacks) {
|
||||||
|
callback(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void conv2_100_F::encode(uint8_t *out, DPValue in) {
|
void conv2_100_F::encode(uint8_t *out, DPValue in) {
|
||||||
int16_t tmp = floor((in.getFloat() * 100) + 0.5);
|
int16_t tmp = floor((in.getFloat() * 100) + 0.5);
|
||||||
out[1] = tmp >> 8;
|
out[1] = tmp >> 8;
|
94
esphome/components/optolink/datapoint_component.h
Normal file
94
esphome/components/optolink/datapoint_component.h
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
|
#include "esphome/core/log.h"
|
||||||
|
#include "esphome/core/string_ref.h"
|
||||||
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
|
namespace esphome {
|
||||||
|
namespace optolink {
|
||||||
|
|
||||||
|
class Optolink;
|
||||||
|
|
||||||
|
struct HassSubscription {
|
||||||
|
std::string entity_id;
|
||||||
|
std::vector<std::function<void(std::string)>> callbacks;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DatapointComponent {
|
||||||
|
public:
|
||||||
|
DatapointComponent(Optolink *optolink, bool writeable = false) : dp_value_outstanding((uint8_t) 0) {
|
||||||
|
optolink_ = optolink;
|
||||||
|
writeable_ = writeable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_address(uint32_t address) { address_ = address; }
|
||||||
|
void set_bytes(size_t bytes) { bytes_ = bytes; }
|
||||||
|
void set_writeable(bool writeable) { writeable_ = writeable; }
|
||||||
|
void set_div_ratio(size_t div_ratio) { div_ratio_ = div_ratio; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const StringRef &get_component_name() = 0;
|
||||||
|
|
||||||
|
uint32_t get_address() { return address_; }
|
||||||
|
|
||||||
|
void setup_datapoint();
|
||||||
|
|
||||||
|
void datapoint_read_request();
|
||||||
|
|
||||||
|
virtual void datapoint_value_changed(float value);
|
||||||
|
virtual void datapoint_value_changed(uint8_t value);
|
||||||
|
virtual void datapoint_value_changed(uint16_t value);
|
||||||
|
virtual void datapoint_value_changed(uint32_t value);
|
||||||
|
virtual void datapoint_value_changed(std::string value);
|
||||||
|
virtual void datapoint_value_changed(uint8_t *value, size_t length);
|
||||||
|
|
||||||
|
void write_datapoint_value(float value);
|
||||||
|
void write_datapoint_value(uint8_t value);
|
||||||
|
void write_datapoint_value(uint16_t value);
|
||||||
|
void write_datapoint_value(uint32_t value);
|
||||||
|
void write_datapoint_value(uint8_t *value, size_t length);
|
||||||
|
|
||||||
|
void unfitting_value_type();
|
||||||
|
void set_optolink_state(const char *format, ...);
|
||||||
|
std::string get_optolink_state();
|
||||||
|
|
||||||
|
void subscribe_hass(std::string entity_id, std::function<void(std::string)> f);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const size_t MAX_RETRIES_UNTIL_RESET = 10;
|
||||||
|
Optolink *optolink_;
|
||||||
|
IDatapoint *datapoint_ = nullptr;
|
||||||
|
size_t read_retries_ = 0;
|
||||||
|
size_t div_ratio_ = 0;
|
||||||
|
size_t bytes_;
|
||||||
|
uint32_t address_;
|
||||||
|
bool writeable_;
|
||||||
|
|
||||||
|
bool is_dp_value_writing_outstanding = false;
|
||||||
|
DPValue dp_value_outstanding;
|
||||||
|
|
||||||
|
void datapoint_write_request(DPValue dp_value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
class conv2_100_F : public DPType {
|
||||||
|
public:
|
||||||
|
void encode(uint8_t *out, DPValue in);
|
||||||
|
DPValue decode(const uint8_t *in);
|
||||||
|
size_t get_length() const { return 2; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE
|
||||||
|
class conv4_1000_F : public DPType {
|
||||||
|
public:
|
||||||
|
void encode(uint8_t *out, DPValue in);
|
||||||
|
DPValue decode(const uint8_t *in);
|
||||||
|
const size_t getLength() const { return 4; }
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace optolink
|
||||||
|
} // namespace esphome
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,11 +9,11 @@ namespace optolink {
|
||||||
|
|
||||||
void OptolinkNumber::control(float value) {
|
void OptolinkNumber::control(float value) {
|
||||||
if (value > traits.get_max_value() || value < traits.get_min_value()) {
|
if (value > traits.get_max_value() || value < traits.get_min_value()) {
|
||||||
optolink_->set_error("datapoint value of number %s not in allowed range", get_component_name().c_str());
|
set_optolink_state("datapoint value of number %s not in allowed range", get_component_name().c_str());
|
||||||
ESP_LOGE("OptolinkNumber", "datapoint value of number %s not in allowed range", get_component_name().c_str());
|
ESP_LOGE("OptolinkNumber", "datapoint value of number %s not in allowed range", get_component_name().c_str());
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI("OptolinkNumber", "control of number %s to value %f", get_component_name().c_str(), value);
|
ESP_LOGI("OptolinkNumber", "control of number %s to value %f", get_component_name().c_str(), value);
|
||||||
update_datapoint(value);
|
write_datapoint_value(value);
|
||||||
publish_state(value);
|
publish_state(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,28 +3,27 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/components/number/number.h"
|
#include "esphome/components/number/number.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
class OptolinkNumber : public OptolinkSensorBase, public esphome::number::Number, public esphome::PollingComponent {
|
class OptolinkNumber : public DatapointComponent, public esphome::number::Number, public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkNumber(Optolink *optolink) : OptolinkSensorBase(optolink, true) {}
|
OptolinkNumber(Optolink *optolink) : DatapointComponent(optolink, true) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() override { setup_datapoint(); }
|
void setup() override { setup_datapoint(); }
|
||||||
void update() override { optolink_->read_value(datapoint_); }
|
void update() override { datapoint_read_request(); }
|
||||||
|
void control(float value) override;
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(float state) override { publish_state(state); };
|
void datapoint_value_changed(float state) override { publish_state(state); };
|
||||||
void value_changed(uint8_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint8_t state) override { publish_state(state); };
|
||||||
void value_changed(uint16_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint16_t state) override { publish_state(state); };
|
||||||
void value_changed(uint32_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint32_t state) override { publish_state(state); };
|
||||||
|
|
||||||
void control(float value) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
|
|
|
@ -25,7 +25,7 @@ void Optolink::comm_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Optolink::setup() {
|
void Optolink::setup() {
|
||||||
ESP_LOGI("Optolink", "setup");
|
ESP_LOGI(TAG, "setup");
|
||||||
|
|
||||||
if (logger_enabled_) {
|
if (logger_enabled_) {
|
||||||
VitoWiFi.setLogger(this);
|
VitoWiFi.setLogger(this);
|
||||||
|
@ -39,37 +39,54 @@ void Optolink::setup() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Optolink::loop() { VitoWiFi.loop(); }
|
void Optolink::loop() {
|
||||||
|
ESP_LOGD(TAG, "queue size: %d", VitoWiFi.queueSize());
|
||||||
|
VitoWiFi.loop();
|
||||||
|
}
|
||||||
|
|
||||||
void Optolink::set_error(const char *format, ...) {
|
void Optolink::set_state(const char *format, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
std::vsnprintf(buffer, sizeof(buffer), format, args);
|
std::vsnprintf(buffer, sizeof(buffer), format, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
error_ = buffer;
|
state_ = buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Optolink::read_value(IDatapoint *datapoint) {
|
bool Optolink::read_value(IDatapoint *datapoint) {
|
||||||
if (datapoint != nullptr) {
|
if (datapoint != nullptr) {
|
||||||
ESP_LOGI("Optolink", "requesting value of datapoint %s", datapoint->getName());
|
ESP_LOGI(TAG, "requesting value of datapoint %s", datapoint->getName());
|
||||||
VitoWiFi.readDatapoint(*datapoint);
|
if (!VitoWiFi.readDatapoint(*datapoint)) {
|
||||||
|
ESP_LOGE(TAG, "read request rejected due to queue overload - queue size: %d", VitoWiFi.queueSize());
|
||||||
|
for (auto dp : datapoint->getCollection()) {
|
||||||
|
ESP_LOGD(TAG, "queued datapoint: %s", dp->getName());
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Optolink::write_value(IDatapoint *datapoint, DPValue dp_value) {
|
bool Optolink::write_value(IDatapoint *datapoint, DPValue dp_value) {
|
||||||
if (datapoint != nullptr) {
|
if (datapoint != nullptr) {
|
||||||
char buffer[64];
|
char buffer[64];
|
||||||
dp_value.getString(buffer, sizeof(buffer));
|
dp_value.getString(buffer, sizeof(buffer));
|
||||||
ESP_LOGI("Optolink", "sending value %s to datapoint %s", buffer, datapoint->getName());
|
ESP_LOGI(TAG, "sending value %s of datapoint %s", buffer, datapoint->getName());
|
||||||
VitoWiFi.writeDatapoint(*datapoint, dp_value);
|
if (!VitoWiFi.writeDatapoint(*datapoint, dp_value)) {
|
||||||
|
ESP_LOGE(TAG, "write request rejected due to queue overload - queue size: %d", VitoWiFi.queueSize());
|
||||||
|
for (auto dp : datapoint->getCollection()) {
|
||||||
|
ESP_LOGE(TAG, "queued dp: %s", dp->getName());
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Optolink::write(uint8_t ch) {
|
size_t Optolink::write(uint8_t ch) {
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
ESP_LOGD("VitoWifi", "%s", log_buffer_.c_str());
|
ESP_LOGD(TAG, "VitoWiFi: %s", log_buffer_.c_str());
|
||||||
log_buffer_.clear();
|
log_buffer_.clear();
|
||||||
} else {
|
} else {
|
||||||
log_buffer_.push_back(ch);
|
log_buffer_.push_back(ch);
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/core/component.h"
|
#include "esphome/core/component.h"
|
||||||
#include "esphome/components/text_sensor/text_sensor.h"
|
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -11,7 +10,7 @@ namespace optolink {
|
||||||
|
|
||||||
class Optolink : public esphome::Component, public Print {
|
class Optolink : public esphome::Component, public Print {
|
||||||
protected:
|
protected:
|
||||||
std::string error_ = "OK";
|
std::string state_ = "OK";
|
||||||
std::string log_buffer_;
|
std::string log_buffer_;
|
||||||
bool logger_enabled_ = false;
|
bool logger_enabled_ = false;
|
||||||
int rx_pin_;
|
int rx_pin_;
|
||||||
|
@ -30,11 +29,11 @@ class Optolink : public esphome::Component, public Print {
|
||||||
void set_rx_pin(int rx_pin) { rx_pin_ = rx_pin; }
|
void set_rx_pin(int rx_pin) { rx_pin_ = rx_pin; }
|
||||||
void set_tx_pin(int tx_pin) { tx_pin_ = tx_pin; }
|
void set_tx_pin(int tx_pin) { tx_pin_ = tx_pin; }
|
||||||
|
|
||||||
void write_value(IDatapoint *datapoint, DPValue dp_value);
|
bool write_value(IDatapoint *datapoint, DPValue dp_value);
|
||||||
void read_value(IDatapoint *datapoint);
|
bool read_value(IDatapoint *datapoint);
|
||||||
|
|
||||||
void set_error(const char *format, ...);
|
void set_state(const char *format, ...);
|
||||||
std::string get_error() { return error_; }
|
std::string get_state() { return state_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
|
|
|
@ -1,72 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifdef USE_ARDUINO
|
|
||||||
|
|
||||||
#include "esphome/core/log.h"
|
|
||||||
#include "esphome/core/string_ref.h"
|
|
||||||
#include "VitoWiFi.h"
|
|
||||||
|
|
||||||
namespace esphome {
|
|
||||||
namespace optolink {
|
|
||||||
|
|
||||||
class Optolink;
|
|
||||||
|
|
||||||
class OptolinkSensorBase {
|
|
||||||
public:
|
|
||||||
OptolinkSensorBase(Optolink *optolink, bool writeable = false) {
|
|
||||||
optolink_ = optolink;
|
|
||||||
writeable_ = writeable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_address(uint32_t address) { address_ = address; }
|
|
||||||
void set_bytes(int bytes) { bytes_ = bytes; }
|
|
||||||
void set_div_ratio(int div_ratio) { div_ratio_ = div_ratio; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Optolink *optolink_;
|
|
||||||
bool writeable_;
|
|
||||||
IDatapoint *datapoint_ = nullptr;
|
|
||||||
uint32_t address_;
|
|
||||||
size_t bytes_;
|
|
||||||
size_t div_ratio_ = 0;
|
|
||||||
|
|
||||||
virtual const StringRef &get_component_name() = 0;
|
|
||||||
void setup_datapoint();
|
|
||||||
virtual void value_changed(float value);
|
|
||||||
virtual void value_changed(uint8_t value);
|
|
||||||
virtual void value_changed(uint16_t value);
|
|
||||||
virtual void value_changed(uint32_t value);
|
|
||||||
virtual void value_changed(std::string value);
|
|
||||||
virtual void value_changed(uint8_t *value, size_t length);
|
|
||||||
void update_datapoint(float value);
|
|
||||||
void update_datapoint(uint8_t value);
|
|
||||||
void update_datapoint(uint16_t value);
|
|
||||||
void update_datapoint(uint32_t value);
|
|
||||||
void update_datapoint(uint8_t *value, size_t length);
|
|
||||||
|
|
||||||
void unfitting_value_type();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void update_datapoint(DPValue dp_value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
class conv2_100_F : public DPType {
|
|
||||||
public:
|
|
||||||
void encode(uint8_t *out, DPValue in);
|
|
||||||
DPValue decode(const uint8_t *in);
|
|
||||||
size_t get_length() const { return 2; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOLINTNEXTLINE
|
|
||||||
class conv4_1000_F : public DPType {
|
|
||||||
public:
|
|
||||||
void encode(uint8_t *out, DPValue in);
|
|
||||||
DPValue decode(const uint8_t *in);
|
|
||||||
const size_t getLength() const { return 4; }
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace optolink
|
|
||||||
} // namespace esphome
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -11,45 +11,45 @@ void OptolinkSelect::control(const std::string &value) {
|
||||||
for (auto it = mapping_->begin(); it != mapping_->end(); ++it) {
|
for (auto it = mapping_->begin(); it != mapping_->end(); ++it) {
|
||||||
if (it->second == value) {
|
if (it->second == value) {
|
||||||
ESP_LOGI("OptolinkSelect", "control of select %s to value %s", get_component_name().c_str(), it->first.c_str());
|
ESP_LOGI("OptolinkSelect", "control of select %s to value %s", get_component_name().c_str(), it->first.c_str());
|
||||||
update_datapoint(std::stof(it->first));
|
write_datapoint_value(std::stof(it->first));
|
||||||
publish_state(it->second);
|
publish_state(it->second);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (it == mapping_->end()) {
|
if (it == mapping_->end()) {
|
||||||
optolink_->set_error("unknown value %s of select %s", value.c_str(), get_component_name().c_str());
|
set_optolink_state("unknown value %s of select %s", value.c_str(), get_component_name().c_str());
|
||||||
ESP_LOGE("OptolinkSelect", "unknown value %s of select %s", value.c_str(), get_component_name().c_str());
|
ESP_LOGE("OptolinkSelect", "unknown value %s of select %s", value.c_str(), get_component_name().c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void OptolinkSelect::value_changed(std::string key) {
|
void OptolinkSelect::datapoint_value_changed(std::string key) {
|
||||||
auto pos = mapping_->find(key);
|
auto pos = mapping_->find(key);
|
||||||
if (pos == mapping_->end()) {
|
if (pos == mapping_->end()) {
|
||||||
optolink_->set_error("value %s not found in select %s", key.c_str(), get_component_name().c_str());
|
set_optolink_state("value %s not found in select %s", key.c_str(), get_component_name().c_str());
|
||||||
ESP_LOGE("OptolinkSelect", "value %s not found in select %s", key.c_str(), get_component_name().c_str());
|
ESP_LOGE("OptolinkSelect", "value %s not found in select %s", key.c_str(), get_component_name().c_str());
|
||||||
} else {
|
} else {
|
||||||
publish_state(pos->second);
|
publish_state(pos->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSelect::value_changed(uint8_t state) {
|
void OptolinkSelect::datapoint_value_changed(uint8_t state) {
|
||||||
std::string key = std::to_string(state);
|
std::string key = std::to_string(state);
|
||||||
value_changed(key);
|
datapoint_value_changed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSelect::value_changed(uint16_t state) {
|
void OptolinkSelect::datapoint_value_changed(uint16_t state) {
|
||||||
std::string key = std::to_string(state);
|
std::string key = std::to_string(state);
|
||||||
value_changed(key);
|
datapoint_value_changed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSelect::value_changed(uint32_t state) {
|
void OptolinkSelect::datapoint_value_changed(uint32_t state) {
|
||||||
std::string key = std::to_string(state);
|
std::string key = std::to_string(state);
|
||||||
value_changed(key);
|
datapoint_value_changed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OptolinkSelect::value_changed(float state) {
|
void OptolinkSelect::datapoint_value_changed(float state) {
|
||||||
std::string key = std::to_string(state);
|
std::string key = std::to_string(state);
|
||||||
value_changed(key);
|
datapoint_value_changed(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
|
|
|
@ -5,15 +5,15 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "esphome/components/select/select.h"
|
#include "esphome/components/select/select.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
class OptolinkSelect : public OptolinkSensorBase, public esphome::select::Select, public esphome::PollingComponent {
|
class OptolinkSelect : public DatapointComponent, public esphome::select::Select, public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkSelect(Optolink *optolink) : OptolinkSensorBase(optolink, true) {}
|
OptolinkSelect(Optolink *optolink) : DatapointComponent(optolink, true) {}
|
||||||
|
|
||||||
void set_map(std::map<std::string, std::string> *mapping) {
|
void set_map(std::map<std::string, std::string> *mapping) {
|
||||||
mapping_ = mapping;
|
mapping_ = mapping;
|
||||||
|
@ -26,16 +26,15 @@ class OptolinkSelect : public OptolinkSensorBase, public esphome::select::Select
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() override { setup_datapoint(); }
|
void setup() override { setup_datapoint(); }
|
||||||
void update() override { optolink_->read_value(datapoint_); }
|
void update() override { datapoint_read_request(); }
|
||||||
|
void control(const std::string &value) override;
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(std::string state) override;
|
void datapoint_value_changed(std::string state) override;
|
||||||
void value_changed(uint8_t state) override;
|
void datapoint_value_changed(uint8_t state) override;
|
||||||
void value_changed(uint16_t state) override;
|
void datapoint_value_changed(uint16_t state) override;
|
||||||
void value_changed(uint32_t state) override;
|
void datapoint_value_changed(uint32_t state) override;
|
||||||
void value_changed(float state) override;
|
void datapoint_value_changed(float state) override;
|
||||||
|
|
||||||
void control(const std::string &value) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> *mapping_ = nullptr;
|
std::map<std::string, std::string> *mapping_ = nullptr;
|
||||||
|
|
|
@ -4,27 +4,27 @@
|
||||||
|
|
||||||
#include "esphome/components/sensor/sensor.h"
|
#include "esphome/components/sensor/sensor.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
class OptolinkSensor : public OptolinkSensorBase, public esphome::sensor::Sensor, public esphome::PollingComponent {
|
class OptolinkSensor : public DatapointComponent, public esphome::sensor::Sensor, public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkSensor(Optolink *optolink) : OptolinkSensorBase(optolink) {
|
OptolinkSensor(Optolink *optolink) : DatapointComponent(optolink) {
|
||||||
set_state_class(esphome::sensor::STATE_CLASS_MEASUREMENT);
|
set_state_class(esphome::sensor::STATE_CLASS_MEASUREMENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() { setup_datapoint(); }
|
void setup() { setup_datapoint(); }
|
||||||
void update() override { optolink_->read_value(datapoint_); }
|
void update() override { datapoint_read_request(); }
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(float state) override { publish_state(state); };
|
void datapoint_value_changed(float state) override { publish_state(state); };
|
||||||
void value_changed(uint8_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint8_t state) override { publish_state(state); };
|
||||||
void value_changed(uint16_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint16_t state) override { publish_state(state); };
|
||||||
void value_changed(uint32_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint32_t state) override { publish_state(state); };
|
||||||
};
|
};
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -9,11 +9,11 @@ namespace optolink {
|
||||||
|
|
||||||
void OptolinkSwitch::write_state(bool value) {
|
void OptolinkSwitch::write_state(bool value) {
|
||||||
if (value != 0 && value != 1) {
|
if (value != 0 && value != 1) {
|
||||||
optolink_->set_error("datapoint value of switch %s not 0 or 1", get_component_name().c_str());
|
set_optolink_state("datapoint value of switch %s not 0 or 1", get_component_name().c_str());
|
||||||
ESP_LOGE("OptolinkSwitch", "datapoint value of switch %s not 0 or 1", get_component_name().c_str());
|
ESP_LOGE("OptolinkSwitch", "datapoint value of switch %s not 0 or 1", get_component_name().c_str());
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGI("OptolinkSwitch", "control of switch %s to value %d", get_component_name().c_str(), value);
|
ESP_LOGI("OptolinkSwitch", "control of switch %s to value %d", get_component_name().c_str(), value);
|
||||||
update_datapoint((uint8_t) value);
|
write_datapoint_value((uint8_t) value);
|
||||||
publish_state(value);
|
publish_state(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,28 +3,27 @@
|
||||||
#ifdef USE_ARDUINO
|
#ifdef USE_ARDUINO
|
||||||
|
|
||||||
#include "esphome/components/switch/switch.h"
|
#include "esphome/components/switch/switch.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace optolink {
|
namespace optolink {
|
||||||
|
|
||||||
class OptolinkSwitch : public OptolinkSensorBase, public esphome::switch_::Switch, public esphome::PollingComponent {
|
class OptolinkSwitch : public DatapointComponent, public esphome::switch_::Switch, public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkSwitch(Optolink *optolink) : OptolinkSensorBase(optolink, true) {
|
OptolinkSwitch(Optolink *optolink) : DatapointComponent(optolink, true) {
|
||||||
bytes_ = 1;
|
set_bytes(1);
|
||||||
div_ratio_ = 1;
|
set_div_ratio(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() override { setup_datapoint(); }
|
void setup() override { setup_datapoint(); }
|
||||||
void update() override { optolink_->read_value(datapoint_); }
|
void update() override { datapoint_read_request(); }
|
||||||
|
void write_state(bool value) override;
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(uint8_t state) override { publish_state(state); };
|
void datapoint_value_changed(uint8_t state) override { publish_state(state); };
|
||||||
|
|
||||||
void write_state(bool value) override;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace optolink
|
} // namespace optolink
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "esphome/core/log.h"
|
#include "esphome/core/log.h"
|
||||||
#include "optolink_text_sensor.h"
|
#include "optolink_text_sensor.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "esphome/components/api/api_server.h"
|
#include "../datapoint_component.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -80,33 +80,34 @@ void OptolinkTextSensor::setup() {
|
||||||
case MAP:
|
case MAP:
|
||||||
break;
|
break;
|
||||||
case RAW:
|
case RAW:
|
||||||
div_ratio_ = 0;
|
set_div_ratio(0);
|
||||||
break;
|
break;
|
||||||
case DAY_SCHEDULE:
|
case DAY_SCHEDULE:
|
||||||
div_ratio_ = 0;
|
set_div_ratio(0);
|
||||||
bytes_ = 8;
|
set_bytes(8);
|
||||||
address_ += (8 * dow_);
|
set_address(get_address() + 8 * dow_);
|
||||||
break;
|
break;
|
||||||
case DAY_SCHEDULE_SYNCHRONIZED:
|
case DAY_SCHEDULE_SYNCHRONIZED:
|
||||||
writeable_ = true;
|
set_writeable(true);
|
||||||
div_ratio_ = 0;
|
set_div_ratio(0);
|
||||||
bytes_ = 8;
|
set_bytes(8);
|
||||||
address_ += (8 * dow_);
|
set_address(get_address() + 8 * dow_);
|
||||||
api::global_api_server->subscribe_home_assistant_state(
|
ESP_LOGI(TAG, "subscribing to schedule plan from HASS entity '%s' for component %s", this->entity_id_.c_str(),
|
||||||
this->entity_id_, optional<std::string>(), [this](const std::string &state) {
|
get_component_name().c_str());
|
||||||
ESP_LOGD(TAG, "got time values from entity '%s': %s", this->entity_id_.c_str(), state.c_str());
|
subscribe_hass(entity_id_, [this](const std::string &state) {
|
||||||
|
ESP_LOGD(TAG, "update for schedule plan for component %s: %s", get_component_name().c_str(), state.c_str());
|
||||||
uint8_t *data = encode_time_string(state);
|
uint8_t *data = encode_time_string(state);
|
||||||
if (data) {
|
if (data) {
|
||||||
update_datapoint(data, 8);
|
write_datapoint_value(data, 8);
|
||||||
} else {
|
} else {
|
||||||
ESP_LOGW(TAG, "not changing any value of datapoint %s", datapoint_->getName());
|
ESP_LOGW(TAG, "not changing any value of datapoint %s", get_component_name().c_str());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case DEVICE_INFO:
|
case DEVICE_INFO:
|
||||||
set_entity_category(esphome::ENTITY_CATEGORY_DIAGNOSTIC);
|
set_entity_category(esphome::ENTITY_CATEGORY_DIAGNOSTIC);
|
||||||
bytes_ = 4;
|
set_bytes(4);
|
||||||
address_ = 0x00f8;
|
set_address(0x00f8);
|
||||||
break;
|
break;
|
||||||
case STATE_INFO:
|
case STATE_INFO:
|
||||||
set_entity_category(esphome::ENTITY_CATEGORY_DIAGNOSTIC);
|
set_entity_category(esphome::ENTITY_CATEGORY_DIAGNOSTIC);
|
||||||
|
@ -115,7 +116,15 @@ void OptolinkTextSensor::setup() {
|
||||||
setup_datapoint();
|
setup_datapoint();
|
||||||
};
|
};
|
||||||
|
|
||||||
void OptolinkTextSensor::value_changed(uint8_t *value, size_t length) {
|
void OptolinkTextSensor::update() {
|
||||||
|
if (mode_ == STATE_INFO) {
|
||||||
|
publish_state(get_optolink_state());
|
||||||
|
} else {
|
||||||
|
datapoint_read_request();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OptolinkTextSensor::datapoint_value_changed(uint8_t *value, size_t length) {
|
||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
case RAW:
|
case RAW:
|
||||||
publish_state(std::string((const char *) value));
|
publish_state(std::string((const char *) value));
|
||||||
|
@ -146,7 +155,7 @@ void OptolinkTextSensor::value_changed(uint8_t *value, size_t length) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void OptolinkTextSensor::value_changed(uint32_t value) {
|
void OptolinkTextSensor::datapoint_value_changed(uint32_t value) {
|
||||||
switch (mode_) {
|
switch (mode_) {
|
||||||
case DEVICE_INFO: {
|
case DEVICE_INFO: {
|
||||||
uint8_t *bytes = (uint8_t *) &value;
|
uint8_t *bytes = (uint8_t *) &value;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
#include "esphome/components/text_sensor/text_sensor.h"
|
#include "esphome/components/text_sensor/text_sensor.h"
|
||||||
#include "../optolink.h"
|
#include "../optolink.h"
|
||||||
#include "../optolink_sensor_base.h"
|
#include "../datapoint_component.h"
|
||||||
#include "VitoWiFi.h"
|
#include "VitoWiFi.h"
|
||||||
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
|
@ -12,11 +12,11 @@ namespace optolink {
|
||||||
|
|
||||||
enum TextSensorMode { MAP, RAW, DAY_SCHEDULE, DAY_SCHEDULE_SYNCHRONIZED, DEVICE_INFO, STATE_INFO };
|
enum TextSensorMode { MAP, RAW, DAY_SCHEDULE, DAY_SCHEDULE_SYNCHRONIZED, DEVICE_INFO, STATE_INFO };
|
||||||
|
|
||||||
class OptolinkTextSensor : public OptolinkSensorBase,
|
class OptolinkTextSensor : public DatapointComponent,
|
||||||
public esphome::text_sensor::TextSensor,
|
public esphome::text_sensor::TextSensor,
|
||||||
public esphome::PollingComponent {
|
public esphome::PollingComponent {
|
||||||
public:
|
public:
|
||||||
OptolinkTextSensor(Optolink *optolink) : OptolinkSensorBase(optolink) {}
|
OptolinkTextSensor(Optolink *optolink) : DatapointComponent(optolink) {}
|
||||||
|
|
||||||
void set_mode(TextSensorMode mode) { mode_ = mode; }
|
void set_mode(TextSensorMode mode) { mode_ = mode; }
|
||||||
void set_day_of_week(int dow) { dow_ = dow; }
|
void set_day_of_week(int dow) { dow_ = dow; }
|
||||||
|
@ -24,20 +24,14 @@ class OptolinkTextSensor : public OptolinkSensorBase,
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void update() override {
|
void update() override;
|
||||||
if (mode_ == STATE_INFO) {
|
|
||||||
publish_state(optolink_->get_error());
|
|
||||||
} else {
|
|
||||||
optolink_->read_value(datapoint_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const StringRef &get_component_name() override { return get_name(); }
|
const StringRef &get_component_name() override { return get_name(); }
|
||||||
void value_changed(float state) override { publish_state(std::to_string(state)); };
|
void datapoint_value_changed(float state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint8_t state) override { publish_state(std::to_string(state)); };
|
void datapoint_value_changed(uint8_t state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint16_t state) override { publish_state(std::to_string(state)); };
|
void datapoint_value_changed(uint16_t state) override { publish_state(std::to_string(state)); };
|
||||||
void value_changed(uint32_t state) override;
|
void datapoint_value_changed(uint32_t state) override;
|
||||||
void value_changed(uint8_t *state, size_t length) override;
|
void datapoint_value_changed(uint8_t *state, size_t length) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextSensorMode mode_ = MAP;
|
TextSensorMode mode_ = MAP;
|
||||||
|
|
|
@ -66,7 +66,7 @@ lib_deps =
|
||||||
rweather/Crypto@0.4.0 ; dsmr
|
rweather/Crypto@0.4.0 ; dsmr
|
||||||
dudanov/MideaUART@1.1.8 ; midea
|
dudanov/MideaUART@1.1.8 ; midea
|
||||||
tonia/HeatpumpIR@1.0.23 ; heatpumpir
|
tonia/HeatpumpIR@1.0.23 ; heatpumpir
|
||||||
bertmelis/VitoWiFi@1.0.2 ; optolink
|
bertmelis/VitoWiFi@1.1.2 ; optolink
|
||||||
build_flags =
|
build_flags =
|
||||||
${common.build_flags}
|
${common.build_flags}
|
||||||
-DUSE_ARDUINO
|
-DUSE_ARDUINO
|
||||||
|
|
Loading…
Reference in a new issue