diff --git a/src/GardenControl.share.xml b/src/GardenControl.share.xml index 6ac0d2a..378dbc1 100644 --- a/src/GardenControl.share.xml +++ b/src/GardenControl.share.xml @@ -65,7 +65,7 @@ Offset="0" BitOffset="3" /> + Offset="0" BitOffset="4" /> diff --git a/src/GardenControlDevice.cpp b/src/GardenControlDevice.cpp index 4314b53..852f6f7 100644 --- a/src/GardenControlDevice.cpp +++ b/src/GardenControlDevice.cpp @@ -73,6 +73,13 @@ GardenControlDevice::~GardenControlDevice() { } +void GardenControlDevice::processAfterStartupDelay() +{ + // Logic is registered before GardenControl, so its external-KO lookup + // is already prepared when the startup status KOs are queued here. + sendStartupOutputStates(); +} + // TODO ***************************************************************************************************************************** void GardenControlDevice::waitStartupLoop() { @@ -224,6 +231,10 @@ void GardenControlDevice::setup() delay(100); + // Initialize the 5 V relay status without sending. The status is re-sent + // after the OpenKNX startup delay, when Logic is ready for local callbacks. + knx.getGroupObject(BEM_Ko_Status_5V_relais).valueNoSend(get_5V_Relais_State(false), getDPT(VAL_DPT_1)); + // set KOs initial Ventil for (int i = 0; i < BEM_ChannelCount; i++) { diff --git a/src/GardenControlDevice.h b/src/GardenControlDevice.h index c52ba1f..9275343 100644 --- a/src/GardenControlDevice.h +++ b/src/GardenControlDevice.h @@ -10,6 +10,7 @@ class GardenControlDevice : public OpenKNX::Module // void processReadRequests(); void processInputKo(GroupObject &iKo); + void processAfterStartupDelay() override; // void showHelp() override; // bool processCommand(const std::string cmd, bool debugKo) override; void setup(); diff --git a/src/handleVentilRelais.cpp b/src/handleVentilRelais.cpp index 741046f..12b7b56 100644 --- a/src/handleVentilRelais.cpp +++ b/src/handleVentilRelais.cpp @@ -9,9 +9,6 @@ #include "ErrorHandling.h" #include "LED_Statusanzeige.h" -bool initVentil = false; -bool initRelay = false; - bool ventil_State[BEM_ChannelCount] = {0}; bool ventil_State_old[BEM_ChannelCount] = {0}; bool ventil_Sperrobjekt[BEM_ChannelCount] = {0}; @@ -22,7 +19,6 @@ bool relais_Sperrobjekt[REL_ChannelCount] = {0}; bool relais_5V_State = false; bool relais_5V_State_old = false; -bool relais_5V_startup_flag = true; bool displayCleared_Ventil = false; bool displayCleared_Relais = false; @@ -32,18 +28,6 @@ bool displayCleared_Relais = false; ****************************************************************************/ void processVentil() { - if (!initVentil) - { - SERIAL_PORT.println("Senden Status Objekte Ventil"); - if ((knx.paramByte(BEM_KOsStateSendStartup) >> BEM_KOsStateSendStartupShift) & 1) // Senden bei Startup "AN" - { - for (int i = 0; i < BEM_ChannelCount; i++) - { - knx.getGroupObject(BEM_KoOffset + (i * BEM_KoBlockSize + BEM_Ko_Status_ventil)).objectWritten(); - } - } - initVentil = true; - } if (!get_24V_AC_Error()) { // check of state chnage and Send new Status @@ -156,18 +140,6 @@ void clear_ALL_Ventil_states() ****************************************************************************/ void processRelais() { - if (!initRelay) - { - SERIAL_PORT.println("Senden Status Objekte Relays"); - if ((knx.paramByte(BEM_KOsStateSendStartup) >> BEM_KOsStateSendStartupShift) & 1) // Senden bei Startup "AN" - { - for (int i = 0; i < REL_ChannelCount; i++) - { - knx.getGroupObject(REL_KoOffset + (i * REL_KoBlockSize + REL_Ko_Status_relais)).objectWritten(); - } - } - initRelay = true; - } if (!get_24V_AC_Error()) { // check of state chnage and Send new Status @@ -265,6 +237,34 @@ void clear_ALL_Relais_states() } } +void sendStartupOutputStates() +{ + // Queue startup status telegrams only after the OpenKNX startup delay. + // Logic prepares its external-KO lookup in processAfterStartupDelay(), so + // earlier writes can be missed by local logic inputs. + if ((knx.paramByte(BEM_KOsStateSendStartup) >> BEM_KOsStateSendStartupShift) & 1) + { + SERIAL_PORT.println("Senden Status Objekte Ventil"); + for (int i = 0; i < BEM_ChannelCount; i++) + { + knx.getGroupObject(BEM_KoOffset + (i * BEM_KoBlockSize + BEM_Ko_Status_ventil)).objectWritten(); + } + + SERIAL_PORT.println("Senden Status Objekte Relays"); + for (int i = 0; i < REL_ChannelCount; i++) + { + knx.getGroupObject(REL_KoOffset + (i * REL_KoBlockSize + REL_Ko_Status_relais)).objectWritten(); + } + } + + // The external 5 V relay has its own startup-send parameter. + if ((knx.paramByte(BEM_ext5VRelaisStartState) >> BEM_ext5VRelaisStartStateShift) & 1) + { + SERIAL_PORT.println("Senden Status Objekt 5V Relais"); + knx.getGroupObject(BEM_Ko_Status_5V_relais).objectWritten(); + } +} + /***************************************************************************** * externes 5V Relais ****************************************************************************/ @@ -276,15 +276,6 @@ void control_5V_Relais(bool state) void process_5V_Relais() { - if (relais_5V_startup_flag) - { - if ((knx.paramByte(BEM_ext5VRelaisStartState) >> BEM_ext5VRelaisStartStateShift) & 1) // Senden bei Startup "AN" - { - knx.getGroupObject(BEM_Ko_Status_5V_relais).value(relais_5V_State, getDPT(VAL_DPT_1)); - } - relais_5V_startup_flag = false; - } - if (relais_5V_State_old != relais_5V_State) { control_5V_Relais(relais_5V_State); diff --git a/src/handleVentilRelais.h b/src/handleVentilRelais.h index 3977991..4f8fd2a 100644 --- a/src/handleVentilRelais.h +++ b/src/handleVentilRelais.h @@ -7,6 +7,7 @@ void processRelais(); void process_ventil_states(); void process_relais_states(); void process_5V_Relais(); +void sendStartupOutputStates(); void set_Ventil_State(uint8_t ch, bool state); void set_Ventil_State_single(uint8_t ch); void set_Ventil_Sperrobjekt(uint8_t ch, bool state);