Rewrite somfy code in esphome transmitter

This will ensure correct timings while BT proxy is functioning.
This commit is contained in:
2025-05-12 20:25:05 +02:00
parent e0dddf5245
commit 6108d8bd03
4 changed files with 32 additions and 56 deletions
+3 -13
View File
@@ -7,12 +7,6 @@ esphome:
name: dasfoo.blinds name: dasfoo.blinds
version: "4.0" version: "4.0"
on_boot:
priority: -100.0 # Everything is initialized.
# Use remote_transmitter component instead of digitalWrite in somfy.cpp.
then:
- lambda: 'id(transceiver)->begin_tx();'
esp32: esp32:
framework: framework:
type: esp-idf type: esp-idf
@@ -21,7 +15,7 @@ packages:
device_base: !include templates/esp32-poe.yaml device_base: !include templates/esp32-poe.yaml
# Also act as a BT proxy due to convenient location. # Also act as a BT proxy due to convenient location.
#btproxy: !include templates/btproxy.yaml btproxy: !include templates/btproxy.yaml
# Allow HA to use our proxy. # Allow HA to use our proxy.
api: !include templates/api.yaml api: !include templates/api.yaml
@@ -44,9 +38,7 @@ cc1101:
frequency: 433340 frequency: 433340
remote_transmitter: remote_transmitter:
pin: pin: 4
number: 4
allow_other_uses: true
carrier_duty_percent: 100% carrier_duty_percent: 100%
id: somfy_remote_transmitter id: somfy_remote_transmitter
on_transmit: on_transmit:
@@ -61,9 +53,7 @@ cover:
remote_id_offset: 0 remote_id_offset: 0
<<: &somfy_cover <<: &somfy_cover
platform: somfy platform: somfy
rf_pin: transmitter: somfy_remote_transmitter
number: 4
allow_other_uses: true
# Can be retrieved from MQTT server. Take the key with lowest integer value # Can be retrieved from MQTT server. Take the key with lowest integer value
# from /$board/rolling_code/ path. # from /$board/rolling_code/ path.
remote_id_base: !secret somfy_remote_id_base remote_id_base: !secret somfy_remote_id_base
+6 -7
View File
@@ -1,8 +1,7 @@
import esphome.codegen as cg import esphome.codegen as cg
import esphome.config_validation as cv import esphome.config_validation as cv
from esphome.components import cover from esphome.components import cover, remote_transmitter
from esphome import pins from esphome.const import CONF_ID
from esphome.const import CONF_ID, CONF_ALLOW_OTHER_USES
DEPENDENCIES = ["mqtt", "remote_transmitter"] DEPENDENCIES = ["mqtt", "remote_transmitter"]
AUTO_LOAD = ["mqtt"] AUTO_LOAD = ["mqtt"]
@@ -10,14 +9,14 @@ AUTO_LOAD = ["mqtt"]
somfy_ns = cg.esphome_ns.namespace("somfy") somfy_ns = cg.esphome_ns.namespace("somfy")
SomfyRTSCover = somfy_ns.class_("SomfyRTSCover", cover.Cover, cg.Component) SomfyRTSCover = somfy_ns.class_("SomfyRTSCover", cover.Cover, cg.Component)
CONF_RF_PIN = "rf_pin" CONF_TRANSMITTER = "transmitter"
CONF_REMOTE_ID_BASE = "remote_id_base" CONF_REMOTE_ID_BASE = "remote_id_base"
CONF_REMOTE_ID_OFFSET = "remote_id_offset" CONF_REMOTE_ID_OFFSET = "remote_id_offset"
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend( CONFIG_SCHEMA = cover.COVER_SCHEMA.extend(
{ {
cv.GenerateID(): cv.declare_id(SomfyRTSCover), cv.GenerateID(): cv.declare_id(SomfyRTSCover),
cv.Required(CONF_RF_PIN): pins.gpio_output_pin_schema, cv.Required(CONF_TRANSMITTER): cv.use_id(remote_transmitter.RemoteTransmitterComponent),
cv.Required(CONF_REMOTE_ID_BASE): cv.uint32_t, cv.Required(CONF_REMOTE_ID_BASE): cv.uint32_t,
cv.Required(CONF_REMOTE_ID_OFFSET): cv.uint32_t, cv.Required(CONF_REMOTE_ID_OFFSET): cv.uint32_t,
} }
@@ -28,8 +27,8 @@ async def to_code(config):
await cg.register_component(var, config) await cg.register_component(var, config)
await cover.register_cover(var, config) await cover.register_cover(var, config)
rf_pin = await cg.gpio_pin_expression(config[CONF_RF_PIN]) transmitter = await cg.get_variable(config[CONF_TRANSMITTER])
cg.add(var.set_rf_pin(rf_pin)) cg.add(var.set_transmitter(transmitter))
cg.add(var.set_remote_id( cg.add(var.set_remote_id(
config[CONF_REMOTE_ID_BASE] + config[CONF_REMOTE_ID_OFFSET] config[CONF_REMOTE_ID_BASE] + config[CONF_REMOTE_ID_OFFSET]
)) ))
+17 -34
View File
@@ -22,6 +22,13 @@ struct SomfyRTSProtocolData {
uint8_t command; uint8_t command;
uint32_t rolling_code; uint32_t rolling_code;
uint32_t remote_id; uint32_t remote_id;
void dump() const {
ESP_LOGD(TAG, "Somfy RTS command:");
ESP_LOGD(TAG, " Remote ID: %d", remote_id);
ESP_LOGD(TAG, " Rolling Code: %d", rolling_code);
ESP_LOGD(TAG, " Command: %d", command);
}
}; };
class SomfyRTSProtocol class SomfyRTSProtocol
@@ -94,11 +101,7 @@ class SomfyRTSProtocol
} }
} }
virtual void dump(const ProtocolData &data) override { virtual void dump(const ProtocolData &data) override { data.dump(); }
ESP_LOGI(TAG, " Remote ID: %d", data.remote_id);
ESP_LOGI(TAG, " Rolling Code: %d", data.rolling_code);
ESP_LOGI(TAG, " Command: %d", data.command);
}
virtual optional<ProtocolData> decode( virtual optional<ProtocolData> decode(
remote_base::RemoteReceiveData src) override { remote_base::RemoteReceiveData src) override {
@@ -111,7 +114,6 @@ class SomfyRTSProtocol
void SomfyRTSCover::dump_config() { void SomfyRTSCover::dump_config() {
LOG_COVER("", "Somfy RTS Cover", this); LOG_COVER("", "Somfy RTS Cover", this);
LOG_PIN(" RF Pin", this->rf_pin_);
ESP_LOGCONFIG(TAG, " Remote ID: %d", this->remote_id_); ESP_LOGCONFIG(TAG, " Remote ID: %d", this->remote_id_);
if (this->rolling_code_) { if (this->rolling_code_) {
ESP_LOGCONFIG(TAG, " Rolling Code: %d", this->rolling_code_); ESP_LOGCONFIG(TAG, " Rolling Code: %d", this->rolling_code_);
@@ -136,11 +138,6 @@ cover::CoverTraits SomfyRTSCover::get_traits() {
} }
void SomfyRTSCover::setup() { void SomfyRTSCover::setup() {
if (rf_pin_ != nullptr) {
rf_pin_->setup();
rf_pin_->digital_write(false);
}
rolling_code_pref_ = rolling_code_pref_ =
global_preferences->make_preference<int>(this->get_object_id_hash()); global_preferences->make_preference<int>(this->get_object_id_hash());
@@ -186,8 +183,8 @@ void SomfyRTSCover::control(const cover::CoverCall &call) {
} }
void SomfyRTSCover::send(uint8_t command) { void SomfyRTSCover::send(uint8_t command) {
if (rf_pin_ == nullptr) { if (transmitter_ == nullptr) {
ESP_LOGE(TAG, "Sender GPIO pin is not set"); ESP_LOGE(TAG, "RF code transmitter is not set");
return; return;
} }
@@ -200,27 +197,13 @@ void SomfyRTSCover::send(uint8_t command) {
return; return;
} }
ESP_LOGI(TAG, "Remote #%d sending command %d with rolling code %d", SomfyRTSProtocolData data{
remote_id_, command, rolling_code_); .command = command,
.rolling_code = rolling_code_,
SomfyRTSProtocolData data{.command = command, .remote_id = remote_id_,
.rolling_code = rolling_code_, };
.remote_id = remote_id_}; data.dump();
transmitter_->transmit<SomfyRTSProtocol>(data);
remote_base::RemoteTransmitData transmit_data;
SomfyRTSProtocol().encode(&transmit_data, data);
remote_base::RawTimings td = transmit_data.get_data();
for (int i = 0; i < td.size(); ++i) {
int32_t pulse = td[i];
if (pulse > 0) {
rf_pin_->digital_write(true);
delayMicroseconds(pulse);
} else {
rf_pin_->digital_write(false);
delayMicroseconds(-pulse);
}
}
++rolling_code_; ++rolling_code_;
this->rolling_code_pref_.save(&rolling_code_); this->rolling_code_pref_.save(&rolling_code_);
+6 -2
View File
@@ -4,6 +4,7 @@
#include "esphome/components/cover/cover.h" #include "esphome/components/cover/cover.h"
#include "esphome/components/mqtt/mqtt_component.h" #include "esphome/components/mqtt/mqtt_component.h"
#include "esphome/components/remote_transmitter/remote_transmitter.h"
#include "esphome/core/component.h" #include "esphome/core/component.h"
#include "esphome/core/hal.h" #include "esphome/core/hal.h"
#include "esphome/core/log.h" #include "esphome/core/log.h"
@@ -14,7 +15,10 @@ namespace somfy {
class SomfyRTSCover : public cover::Cover, public Component { class SomfyRTSCover : public cover::Cover, public Component {
public: public:
void set_rf_pin(GPIOPin *rf_pin) { this->rf_pin_ = rf_pin; } void set_transmitter(
remote_transmitter::RemoteTransmitterComponent *transmitter) {
this->transmitter_ = transmitter;
}
void set_remote_id(uint32_t remote_id) { this->remote_id_ = remote_id; } void set_remote_id(uint32_t remote_id) { this->remote_id_ = remote_id; }
cover::CoverTraits get_traits() override; cover::CoverTraits get_traits() override;
@@ -35,7 +39,7 @@ class SomfyRTSCover : public cover::Cover, public Component {
uint32_t rolling_code_; uint32_t rolling_code_;
std::string mqtt_topic_prefix_; std::string mqtt_topic_prefix_;
ESPPreferenceObject rolling_code_pref_; ESPPreferenceObject rolling_code_pref_;
GPIOPin *rf_pin_{nullptr}; remote_transmitter::RemoteTransmitterComponent *transmitter_{nullptr};
}; };
} // namespace somfy } // namespace somfy