From b152f25d1144a5d7a56e98584f8e87f97c0a5436 Mon Sep 17 00:00:00 2001 From: cjkas Date: Tue, 13 Oct 2026 20:39:22 +0200 Subject: [PATCH] refactor: move shade GPIO into ShadeGpio.cpp setGPIOs, triggerGPIOs and usesPin, which drive the relay outputs of dry contact and GPIO shades, move out of Somfy.cpp unchanged. Co-Authored-By: Claude Opus 5.5 --- src/ShadeGpio.cpp | 148 ++++++++++++++++++++++++++++++++++++++++++++++ src/Somfy.cpp | 143 -------------------------------------------- 2 files changed, 148 insertions(+), 143 deletions(-) create mode 100644 src/ShadeGpio.cpp diff --git a/src/ShadeGpio.cpp b/src/ShadeGpio.cpp new file mode 100644 index 0000000..2b07f10 --- /dev/null +++ b/src/ShadeGpio.cpp @@ -0,0 +1,148 @@ +#include "esp_log.h" +#include "Somfy.h" + +static const char *TAG = "Somfy"; + +void SomfyShade::setGPIOs() { + if(this->proto == radio_proto::GP_Relay) { + // Determine whether the direction needs to be set. + uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; + uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; + + int8_t dir = this->direction; + if(dir == 0 && this->tiltType == tilt_types::integrated) + dir = this->tiltDirection; + else if(this->tiltType == tilt_types::tiltonly) + dir = this->tiltDirection; + if(this->shadeType == shade_types::drycontact) { + digitalWrite(this->gpioDown, this->currentPos == 100 ? p_on : p_off); + this->gpioDir = this->currentPos == 100 ? 1 : -1; + } + else if(this->shadeType == shade_types::drycontact2) { + if(this->currentPos == 100) { + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); + } + else { + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_on); + } + this->gpioDir = this->currentPos == 100 ? 1 : -1; + } + else { + switch(dir) { + case -1: + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); + if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: true, DOWN: false"); + this->gpioDir = dir; + break; + case 1: + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_on); + if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: true"); + this->gpioDir = dir; + break; + default: + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); + if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: false"); + this->gpioDir = dir; + break; + } + } + } + else if(this->proto == radio_proto::GP_Remote) { + if(millis() > this->gpioRelease) { + //uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; + uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_off); + this->gpioRelease = 0; + } + } +} +void SomfyRemote::triggerGPIOs(somfy_frame_t &frame) { } +void SomfyShade::triggerGPIOs(somfy_frame_t &frame) { + if(this->proto == radio_proto::GP_Remote) { + uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; + uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; + int8_t dir = 0; + switch(frame.cmd) { + case somfy_commands::My: + if(this->shadeType != shade_types::drycontact && !this->isToggle()) { + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_on); + dir = 0; + if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: false, MY: true"); + } + break; + case somfy_commands::Up: + if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { + digitalWrite(this->gpioMy, p_off); + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioUp, p_on); + dir = -1; + ESP_LOGD(TAG, "UP: true, DOWN: false, MY: false"); + } + break; + case somfy_commands::Toggle: + case somfy_commands::Down: + if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { + digitalWrite(this->gpioMy, p_off); + digitalWrite(this->gpioUp, p_off); + } + digitalWrite(this->gpioDown, p_on); + dir = 1; + ESP_LOGD(TAG, "UP: false, DOWN: true, MY: false"); + break; + case somfy_commands::MyUp: + if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { + digitalWrite(this->gpioDown, p_off); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioUp, p_on); + ESP_LOGD(TAG, "UP: true, DOWN: false, MY: true"); + } + break; + case somfy_commands::MyDown: + if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { + digitalWrite(this->gpioUp, p_off); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioDown, p_on); + ESP_LOGD(TAG, "UP: false, DOWN: true, MY: true"); + } + break; + case somfy_commands::MyUpDown: + if(this->shadeType != shade_types::drycontact && this->isToggle() && this->shadeType != shade_types::drycontact2) { + digitalWrite(this->gpioUp, p_on); + digitalWrite(this->gpioMy, p_on); + digitalWrite(this->gpioDown, p_on); + ESP_LOGD(TAG, "UP: true, DOWN: true, MY: true"); + } + break; + default: + break; + } + this->gpioRelease = millis() + (frame.repeats * 200); + this->gpioDir = dir; + } +} +bool SomfyShade::usesPin(uint8_t pin) { + if(this->proto != radio_proto::GP_Remote && this->proto != radio_proto::GP_Relay) return false; + if(this->gpioDown == pin) return true; + else if(this->shadeType == shade_types::drycontact) + return this->gpioDown == pin; + else if(this->isToggle()) { + if(this->proto == radio_proto::GP_Relay && this->gpioUp == pin) return true; + } + else if(this->shadeType == shade_types::drycontact2) { + if(this->proto == radio_proto::GP_Relay && (this->gpioUp == pin || this->gpioDown == pin)) return true; + } + else { + if(this->gpioUp == pin) return true; + else if(this->proto == radio_proto::GP_Remote && this->gpioMy == pin) return true; + } + return false; +} diff --git a/src/Somfy.cpp b/src/Somfy.cpp index 324c981..f60c210 100644 --- a/src/Somfy.cpp +++ b/src/Somfy.cpp @@ -358,132 +358,6 @@ bool SomfyShade::isInGroup() { } return false; } -void SomfyShade::setGPIOs() { - if(this->proto == radio_proto::GP_Relay) { - // Determine whether the direction needs to be set. - uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; - uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; - - int8_t dir = this->direction; - if(dir == 0 && this->tiltType == tilt_types::integrated) - dir = this->tiltDirection; - else if(this->tiltType == tilt_types::tiltonly) - dir = this->tiltDirection; - if(this->shadeType == shade_types::drycontact) { - digitalWrite(this->gpioDown, this->currentPos == 100 ? p_on : p_off); - this->gpioDir = this->currentPos == 100 ? 1 : -1; - } - else if(this->shadeType == shade_types::drycontact2) { - if(this->currentPos == 100) { - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioUp, p_on); - } - else { - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioDown, p_on); - } - this->gpioDir = this->currentPos == 100 ? 1 : -1; - } - else { - switch(dir) { - case -1: - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioUp, p_on); - if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: true, DOWN: false"); - this->gpioDir = dir; - break; - case 1: - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioDown, p_on); - if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: true"); - this->gpioDir = dir; - break; - default: - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioDown, p_off); - if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: false"); - this->gpioDir = dir; - break; - } - } - } - else if(this->proto == radio_proto::GP_Remote) { - if(millis() > this->gpioRelease) { - //uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; - uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioMy, p_off); - this->gpioRelease = 0; - } - } -} -void SomfyRemote::triggerGPIOs(somfy_frame_t &frame) { } -void SomfyShade::triggerGPIOs(somfy_frame_t &frame) { - if(this->proto == radio_proto::GP_Remote) { - uint8_t p_on = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? HIGH : LOW; - uint8_t p_off = (this->gpioFlags & (uint8_t)gpio_flags_t::LowLevelTrigger) == 0x00 ? LOW : HIGH; - int8_t dir = 0; - switch(frame.cmd) { - case somfy_commands::My: - if(this->shadeType != shade_types::drycontact && !this->isToggle()) { - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioMy, p_on); - dir = 0; - if(dir != this->gpioDir) ESP_LOGD(TAG, "UP: false, DOWN: false, MY: true"); - } - break; - case somfy_commands::Up: - if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioMy, p_off); - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioUp, p_on); - dir = -1; - ESP_LOGD(TAG, "UP: true, DOWN: false, MY: false"); - } - break; - case somfy_commands::Toggle: - case somfy_commands::Down: - if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioMy, p_off); - digitalWrite(this->gpioUp, p_off); - } - digitalWrite(this->gpioDown, p_on); - dir = 1; - ESP_LOGD(TAG, "UP: false, DOWN: true, MY: false"); - break; - case somfy_commands::MyUp: - if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioDown, p_off); - digitalWrite(this->gpioMy, p_on); - digitalWrite(this->gpioUp, p_on); - ESP_LOGD(TAG, "UP: true, DOWN: false, MY: true"); - } - break; - case somfy_commands::MyDown: - if(this->shadeType != shade_types::drycontact && !this->isToggle() && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioUp, p_off); - digitalWrite(this->gpioMy, p_on); - digitalWrite(this->gpioDown, p_on); - ESP_LOGD(TAG, "UP: false, DOWN: true, MY: true"); - } - break; - case somfy_commands::MyUpDown: - if(this->shadeType != shade_types::drycontact && this->isToggle() && this->shadeType != shade_types::drycontact2) { - digitalWrite(this->gpioUp, p_on); - digitalWrite(this->gpioMy, p_on); - digitalWrite(this->gpioDown, p_on); - ESP_LOGD(TAG, "UP: true, DOWN: true, MY: true"); - } - break; - default: - break; - } - this->gpioRelease = millis() + (frame.repeats * 200); - this->gpioDir = dir; - } -} void SomfyShade::checkMovement() { const uint64_t curTime = millis(); const bool sunFlag = this->flags & static_cast(somfy_flags_t::SunFlag); @@ -1932,23 +1806,6 @@ bool SomfyShade::isToggle() { } return false; } -bool SomfyShade::usesPin(uint8_t pin) { - if(this->proto != radio_proto::GP_Remote && this->proto != radio_proto::GP_Relay) return false; - if(this->gpioDown == pin) return true; - else if(this->shadeType == shade_types::drycontact) - return this->gpioDown == pin; - else if(this->isToggle()) { - if(this->proto == radio_proto::GP_Relay && this->gpioUp == pin) return true; - } - else if(this->shadeType == shade_types::drycontact2) { - if(this->proto == radio_proto::GP_Relay && (this->gpioUp == pin || this->gpioDown == pin)) return true; - } - else { - if(this->gpioUp == pin) return true; - else if(this->proto == radio_proto::GP_Remote && this->gpioMy == pin) return true; - } - return false; -} void SomfyRemote::setRemoteAddress(uint32_t address) { this->m_remoteAddress = address; this->m_rollingCodeSynced = false; snprintf(this->m_remotePrefId, sizeof(this->m_remotePrefId), "_%lu", (unsigned long)this->m_remoteAddress); } uint32_t SomfyRemote::getRemoteAddress() { return this->m_remoteAddress; }