Manage client ID internally only
This commit is contained in:
@@ -15,7 +15,6 @@ NumberType = ratgdo_ns.enum("NumberType")
|
|||||||
|
|
||||||
CONF_TYPE = "type"
|
CONF_TYPE = "type"
|
||||||
TYPES = {
|
TYPES = {
|
||||||
"client_id": NumberType.RATGDO_CLIENT_ID,
|
|
||||||
"opening_duration": NumberType.RATGDO_OPENING_DURATION,
|
"opening_duration": NumberType.RATGDO_OPENING_DURATION,
|
||||||
"closing_duration": NumberType.RATGDO_CLOSING_DURATION,
|
"closing_duration": NumberType.RATGDO_CLOSING_DURATION,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,26 +4,12 @@
|
|||||||
|
|
||||||
namespace esphome::ratgdo {
|
namespace esphome::ratgdo {
|
||||||
|
|
||||||
using protocol::SetClientID;
|
|
||||||
|
|
||||||
float normalize_client_id(float client_id)
|
|
||||||
{
|
|
||||||
uint32_t int_value = static_cast<uint32_t>(client_id);
|
|
||||||
if ((int_value & 0xFFF) != 0x539) {
|
|
||||||
client_id = ceil((client_id - 0x539) / 0x1000) * 0x1000 + 0x539;
|
|
||||||
}
|
|
||||||
return client_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* const TAG = "ratgdo.number";
|
static const char* const TAG = "ratgdo.number";
|
||||||
|
|
||||||
void RATGDONumber::dump_config()
|
void RATGDONumber::dump_config()
|
||||||
{
|
{
|
||||||
LOG_NUMBER("", "RATGDO Number", this);
|
LOG_NUMBER("", "RATGDO Number", this);
|
||||||
switch (this->number_type_) {
|
switch (this->number_type_) {
|
||||||
case RATGDO_CLIENT_ID:
|
|
||||||
ESP_LOGCONFIG(TAG, " Type: Client ID");
|
|
||||||
break;
|
|
||||||
case RATGDO_OPENING_DURATION:
|
case RATGDO_OPENING_DURATION:
|
||||||
ESP_LOGCONFIG(TAG, " Type: Opening Duration");
|
ESP_LOGCONFIG(TAG, " Type: Opening Duration");
|
||||||
break;
|
break;
|
||||||
@@ -40,19 +26,7 @@ void RATGDONumber::setup()
|
|||||||
float value;
|
float value;
|
||||||
this->pref_ = this->make_entity_preference<float>();
|
this->pref_ = this->make_entity_preference<float>();
|
||||||
if (!this->pref_.load(&value)) {
|
if (!this->pref_.load(&value)) {
|
||||||
if (this->number_type_ == RATGDO_CLIENT_ID) {
|
value = 0;
|
||||||
value = ((random_uint32() + 1) % 0x7FF) << 12 | 0x539; // max size limited to be precisely convertible to float
|
|
||||||
} else {
|
|
||||||
value = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this->number_type_ == RATGDO_CLIENT_ID) {
|
|
||||||
uint32_t int_value = static_cast<uint32_t>(value);
|
|
||||||
if ((int_value & 0xFFF) != 0x539) {
|
|
||||||
value = ((random_uint32() + 1) % 0x7FF) << 12 | 0x539; // max size limited to be precisely convertible to float
|
|
||||||
this->pref_.save(&value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this->control(value);
|
this->control(value);
|
||||||
|
|
||||||
@@ -82,11 +56,6 @@ void RATGDONumber::set_number_type(NumberType number_type_)
|
|||||||
this->traits.set_min_value(0.0);
|
this->traits.set_min_value(0.0);
|
||||||
this->traits.set_max_value(180.0);
|
this->traits.set_max_value(180.0);
|
||||||
break;
|
break;
|
||||||
case RATGDO_CLIENT_ID:
|
|
||||||
this->traits.set_step(0x1000);
|
|
||||||
this->traits.set_min_value(0x539);
|
|
||||||
this->traits.set_max_value(0x7ff539);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -110,10 +79,6 @@ void RATGDONumber::control(float value)
|
|||||||
case RATGDO_CLOSING_DURATION:
|
case RATGDO_CLOSING_DURATION:
|
||||||
this->parent_->set_closing_duration(value);
|
this->parent_->set_closing_duration(value);
|
||||||
break;
|
break;
|
||||||
case RATGDO_CLIENT_ID:
|
|
||||||
value = normalize_client_id(value);
|
|
||||||
this->parent_->call_protocol(SetClientID { static_cast<uint32_t>(value) });
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
namespace esphome::ratgdo {
|
namespace esphome::ratgdo {
|
||||||
|
|
||||||
enum NumberType {
|
enum NumberType {
|
||||||
RATGDO_CLIENT_ID,
|
|
||||||
RATGDO_OPENING_DURATION,
|
RATGDO_OPENING_DURATION,
|
||||||
RATGDO_CLOSING_DURATION,
|
RATGDO_CLOSING_DURATION,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,9 +16,6 @@ class RATGDOComponent;
|
|||||||
|
|
||||||
namespace protocol {
|
namespace protocol {
|
||||||
|
|
||||||
struct SetClientID {
|
|
||||||
uint64_t client_id;
|
|
||||||
};
|
|
||||||
struct QueryStatus {
|
struct QueryStatus {
|
||||||
};
|
};
|
||||||
struct QueryOpenings {
|
struct QueryOpenings {
|
||||||
@@ -26,7 +23,6 @@ namespace protocol {
|
|||||||
|
|
||||||
// a poor man's sum-type, because C++
|
// a poor man's sum-type, because C++
|
||||||
SUM_TYPE(Args,
|
SUM_TYPE(Args,
|
||||||
(SetClientID, set_client_id),
|
|
||||||
(QueryStatus, query_status),
|
(QueryStatus, query_status),
|
||||||
(QueryOpenings, query_openings), )
|
(QueryOpenings, query_openings), )
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,39 @@ namespace secplus2 {
|
|||||||
this->rx_pin_ = rx_pin;
|
this->rx_pin_ = rx_pin;
|
||||||
|
|
||||||
if (mqtt::global_mqtt_client != nullptr) {
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
this->mqtt_topic_ = mqtt::global_mqtt_client->get_topic_prefix() + "/rolling_code";
|
this->mqtt_rolling_code_topic_ = mqtt::global_mqtt_client->get_topic_prefix() + "/gdo/rolling_code";
|
||||||
|
this->mqtt_client_id_topic_ = mqtt::global_mqtt_client->get_topic_prefix() + "/gdo/client_id";
|
||||||
|
}
|
||||||
|
|
||||||
|
this->client_id_pref_ = global_preferences->make_preference<uint32_t>(3497851610U); // fnv1_hash("ratgdo_client_id")
|
||||||
|
uint32_t stored_client_id;
|
||||||
|
if (this->client_id_pref_.load(&stored_client_id)) {
|
||||||
|
this->client_id_ = stored_client_id;
|
||||||
|
ESP_LOGI(TAG, "Restored Client ID from flash: 0x%04X", (unsigned)this->client_id_);
|
||||||
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
|
mqtt::global_mqtt_client->publish(this->mqtt_client_id_topic_, std::to_string(this->client_id_), 0, true);
|
||||||
|
}
|
||||||
|
} else if (mqtt::global_mqtt_client != nullptr) {
|
||||||
|
ESP_LOGI(TAG, "No Client ID in flash, waiting for MQTT: %s", this->mqtt_client_id_topic_.c_str());
|
||||||
|
mqtt::global_mqtt_client->subscribe(
|
||||||
|
this->mqtt_client_id_topic_,
|
||||||
|
[this](const std::string& topic, const std::string& payload) {
|
||||||
|
if (this->client_id_ == 0x539) {
|
||||||
|
uint32_t cid = strtoul(payload.c_str(), nullptr, 10);
|
||||||
|
if (cid != 0) {
|
||||||
|
ESP_LOGI(TAG, "Received Client ID from MQTT: 0x%04X", (unsigned)cid);
|
||||||
|
this->set_client_id(cid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
1);
|
||||||
|
} else {
|
||||||
|
// Generate a unique ID on first boot.
|
||||||
|
// We use a range that avoids common reserved IDs.
|
||||||
|
uint32_t new_id = (random_uint32() & 0xFFFFF) | 0x539;
|
||||||
|
this->client_id_ = new_id;
|
||||||
|
this->client_id_pref_.save(&new_id);
|
||||||
|
ESP_LOGI(TAG, "Generated new unique Client ID: 0x%04X", (unsigned)new_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->rolling_code_pref_ = global_preferences->make_preference<uint32_t>(1868352652U); // fnv1_hash("ratgdo_rolling_code")
|
this->rolling_code_pref_ = global_preferences->make_preference<uint32_t>(1868352652U); // fnv1_hash("ratgdo_rolling_code")
|
||||||
@@ -44,10 +76,13 @@ namespace secplus2 {
|
|||||||
if (this->rolling_code_pref_.load(&rolling_code)) {
|
if (this->rolling_code_pref_.load(&rolling_code)) {
|
||||||
this->rolling_code_counter_ = rolling_code;
|
this->rolling_code_counter_ = rolling_code;
|
||||||
ESP_LOGI(TAG, "Restored rolling code from flash: %u", rolling_code);
|
ESP_LOGI(TAG, "Restored rolling code from flash: %u", rolling_code);
|
||||||
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
|
mqtt::global_mqtt_client->publish(this->mqtt_rolling_code_topic_, std::to_string(rolling_code), 0, true);
|
||||||
|
}
|
||||||
} else if (mqtt::global_mqtt_client != nullptr) {
|
} else if (mqtt::global_mqtt_client != nullptr) {
|
||||||
ESP_LOGI(TAG, "No rolling code in flash, waiting for MQTT: %s", this->mqtt_topic_.c_str());
|
ESP_LOGI(TAG, "No rolling code in flash, waiting for MQTT: %s", this->mqtt_rolling_code_topic_.c_str());
|
||||||
mqtt::global_mqtt_client->subscribe(
|
mqtt::global_mqtt_client->subscribe(
|
||||||
this->mqtt_topic_,
|
this->mqtt_rolling_code_topic_,
|
||||||
[this](const std::string& topic, const std::string& payload) {
|
[this](const std::string& topic, const std::string& payload) {
|
||||||
if (*this->rolling_code_counter_ == 0) {
|
if (*this->rolling_code_counter_ == 0) {
|
||||||
uint32_t rc = strtoul(payload.c_str(), nullptr, 10);
|
uint32_t rc = strtoul(payload.c_str(), nullptr, 10);
|
||||||
@@ -164,8 +199,6 @@ namespace secplus2 {
|
|||||||
this->send_command(CommandType::GET_STATUS);
|
this->send_command(CommandType::GET_STATUS);
|
||||||
} else if (args.tag == Tag::query_openings) {
|
} else if (args.tag == Tag::query_openings) {
|
||||||
this->send_command(CommandType::GET_OPENINGS);
|
this->send_command(CommandType::GET_OPENINGS);
|
||||||
} else if (args.tag == Tag::set_client_id) {
|
|
||||||
this->set_client_id(args.value.set_client_id.client_id);
|
|
||||||
}
|
}
|
||||||
return { };
|
return { };
|
||||||
}
|
}
|
||||||
@@ -362,7 +395,7 @@ namespace secplus2 {
|
|||||||
this->rolling_code_counter_ = counter;
|
this->rolling_code_counter_ = counter;
|
||||||
this->rolling_code_pref_.save(&counter);
|
this->rolling_code_pref_.save(&counter);
|
||||||
if (mqtt::global_mqtt_client != nullptr) {
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
mqtt::global_mqtt_client->publish(this->mqtt_topic_, std::to_string(counter), 0, true);
|
mqtt::global_mqtt_client->publish(this->mqtt_rolling_code_topic_, std::to_string(counter), 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -372,13 +405,18 @@ namespace secplus2 {
|
|||||||
this->rolling_code_counter_ = counter;
|
this->rolling_code_counter_ = counter;
|
||||||
this->rolling_code_pref_.save(&counter);
|
this->rolling_code_pref_.save(&counter);
|
||||||
if (mqtt::global_mqtt_client != nullptr) {
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
mqtt::global_mqtt_client->publish(this->mqtt_topic_, std::to_string(counter), 0, true);
|
mqtt::global_mqtt_client->publish(this->mqtt_rolling_code_topic_, std::to_string(counter), 0, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Secplus2::set_client_id(uint64_t client_id)
|
void Secplus2::set_client_id(uint64_t client_id)
|
||||||
{
|
{
|
||||||
this->client_id_ = client_id & 0xFFFFFFFF;
|
uint32_t cid = client_id & 0xFFFFFFFF;
|
||||||
|
this->client_id_ = cid;
|
||||||
|
this->client_id_pref_.save(&cid);
|
||||||
|
if (mqtt::global_mqtt_client != nullptr) {
|
||||||
|
mqtt::global_mqtt_client->publish(this->mqtt_client_id_topic_, std::to_string(cid), 0, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace secplus2
|
} // namespace secplus2
|
||||||
|
|||||||
@@ -139,7 +139,9 @@ namespace secplus2 {
|
|||||||
// Larger structures
|
// Larger structures
|
||||||
single_observable<uint32_t> rolling_code_counter_ { 0 };
|
single_observable<uint32_t> rolling_code_counter_ { 0 };
|
||||||
ESPPreferenceObject rolling_code_pref_;
|
ESPPreferenceObject rolling_code_pref_;
|
||||||
std::string mqtt_topic_;
|
ESPPreferenceObject client_id_pref_;
|
||||||
|
std::string mqtt_rolling_code_topic_;
|
||||||
|
std::string mqtt_client_id_topic_;
|
||||||
OnceCallbacks<void()> on_command_sent_;
|
OnceCallbacks<void()> on_command_sent_;
|
||||||
RatgdoUART uart_;
|
RatgdoUART uart_;
|
||||||
|
|
||||||
|
|||||||
@@ -105,11 +105,6 @@ number:
|
|||||||
entity_category: config
|
entity_category: config
|
||||||
name: "Closing duration"
|
name: "Closing duration"
|
||||||
unit_of_measurement: "s"
|
unit_of_measurement: "s"
|
||||||
- platform: ratgdo
|
|
||||||
type: client_id
|
|
||||||
entity_category: config
|
|
||||||
name: "Client ID"
|
|
||||||
mode: box
|
|
||||||
|
|
||||||
cover:
|
cover:
|
||||||
- platform: ratgdo
|
- platform: ratgdo
|
||||||
|
|||||||
Reference in New Issue
Block a user