@@ -26,7 +26,8 @@ class ModuleLightsControl : public Module {
2626 FileManager* _fileManager;
2727 ModuleIO* _moduleIO;
2828 uint8_t pinRelayLightsOn = UINT8_MAX;
29- uint8_t pinButtonLightsOn = UINT8_MAX;
29+ uint8_t pinPushButtonLightsOn = UINT8_MAX;
30+ uint8_t pinToggleButtonLightsOn = UINT8_MAX;
3031
3132 ModuleLightsControl (PsychicHttpServer* server, ESP32SvelteKit* sveltekit, FileManager* fileManager, ModuleIO* moduleIO) : Module(" lightscontrol" , server, sveltekit) {
3233 EXT_LOGV (ML_TAG, " constructor" );
@@ -72,7 +73,8 @@ class ModuleLightsControl : public Module {
7273 void readPins () {
7374 moduleIO.read ([&](ModuleState& state) {
7475 pinRelayLightsOn = UINT8_MAX;
75- pinButtonLightsOn = UINT8_MAX;
76+ pinPushButtonLightsOn = UINT8_MAX;
77+ pinToggleButtonLightsOn = UINT8_MAX;
7678 for (JsonObject pinObject : state.data [" pins" ].as <JsonArray>()) {
7779 uint8_t usage = pinObject[" usage" ];
7880 uint8_t gpio = pinObject[" GPIO" ];
@@ -88,11 +90,18 @@ class ModuleLightsControl : public Module {
8890 EXT_LOGE (MB_TAG, " gpio %d not valid" , pinRelayLightsOn);
8991 } else if (usage == pin_Button_Push_LightsOn) {
9092 if (GPIO_IS_VALID_GPIO (gpio)) {
91- pinButtonLightsOn = gpio;
92- pinMode (pinButtonLightsOn , INPUT_PULLUP);
93- EXT_LOGD (ML_TAG, " pinButtonLightsOn found %d" , pinButtonLightsOn );
93+ pinPushButtonLightsOn = gpio;
94+ pinMode (pinPushButtonLightsOn , INPUT_PULLUP);
95+ EXT_LOGD (ML_TAG, " pinPushButtonLightsOn found %d" , pinPushButtonLightsOn );
9496 } else
95- EXT_LOGE (MB_TAG, " gpio %d not valid" , pinButtonLightsOn);
97+ EXT_LOGE (MB_TAG, " gpio %d not valid" , pinPushButtonLightsOn);
98+ } else if (usage == pin_Button_Toggle_LightsOn) {
99+ if (GPIO_IS_VALID_GPIO (gpio)) {
100+ pinToggleButtonLightsOn = gpio;
101+ pinMode (pinToggleButtonLightsOn, INPUT_PULLUP);
102+ EXT_LOGD (ML_TAG, " pinToggleButtonLightsOn found %d" , pinToggleButtonLightsOn);
103+ } else
104+ EXT_LOGE (MB_TAG, " gpio %d not valid" , pinToggleButtonLightsOn);
96105 }
97106 }
98107 // for (int i = 0; i < sizeof(pins); i++) EXT_LOGD(ML_TAG, "pin %d = %d", i, pins[i]);
@@ -263,7 +272,7 @@ class ModuleLightsControl : public Module {
263272 }
264273
265274 unsigned long lastPresetTime = 0 ;
266- // see pinButtonLightsOn
275+ // see pinPushButtonLightsOn
267276 unsigned long lastDebounceTime = 0 ;
268277 static constexpr unsigned long debounceDelay = 50 ; // 50ms debounce
269278 int lastState = HIGH;
@@ -315,9 +324,9 @@ class ModuleLightsControl : public Module {
315324 }
316325 }
317326
318- if (pinButtonLightsOn != UINT8_MAX) {
319- int state = digitalRead (pinButtonLightsOn );
320- if (state != lastState && (millis () - lastDebounceTime) > debounceDelay) {
327+ if (pinPushButtonLightsOn != UINT8_MAX) {
328+ int state = digitalRead (pinPushButtonLightsOn );
329+ if (( state != lastState) && (((( millis () - lastDebounceTime) > debounceDelay) || ( millis () < lastDebounceTime)))) {
321330 lastDebounceTime = millis ();
322331 // Trigger only on button press (HIGH to LOW transition for INPUT_PULLUP)
323332 if (state == LOW) {
@@ -330,6 +339,18 @@ class ModuleLightsControl : public Module {
330339 }
331340 }
332341
342+ if (pinToggleButtonLightsOn != UINT8_MAX) {
343+ int state = digitalRead (pinToggleButtonLightsOn);
344+ if ((state != lastState) && ((((millis () - lastDebounceTime) > debounceDelay) || (millis () < lastDebounceTime)))) {
345+ lastDebounceTime = millis ();
346+ JsonDocument doc;
347+ JsonObject newState = doc.to <JsonObject>();
348+ newState[" lightsOn" ] = !_state.data [" lightsOn" ];
349+ update (newState, ModuleState::update, _moduleName + " server" );
350+ lastState = state;
351+ }
352+ }
353+
333354 #if FT_ENABLED(FT_MONITOR)
334355 if (layerP.lights .header .isPositions == 2 ) { // send to UI
335356 read ([&](ModuleState& _state) {
0 commit comments