A little bit of help required useing the ESPAsyncWebServer.h library

I have the simple programme using a stepper motor & ESP32.
It’s me being totally dense i know, and all i am trying to do is turn a toggle button off after manually turning it on, and letting it completing its function turn it off.
Whenever a call is made to the step_off() routine, I would like to turn all toggled buttons off, or if it is something simple to turn individual toggle button off Line 432 of the main.cpp file is the step_off() routine.

I bashing my head on or off for about a week, trying to implement what I’m sure is a very simple bit of code. If anyone could help I would be very very grateful.
Hopefully to make it bit easier in looking at the code I have uploaded it to Github
https://github.com/meathome2019/Roller-Blind-Positioner.git

.

From what I get is that you want the button to return to start position after the action is done on the EPS32.

Assuming this is correct, the solution is as follows:

First thing, the webpage is based on the request -> response methodology or, simply said the sliders are set at a position only when the browser requests the state from the EPS32, the move you see when clicking them is done by the browser locally and does not reflect anything on the EPS32.

Thus in order to move the sliders when the operation is done, you have a few options:

  1. Simply refresh the page after some timeout, this will work, but only with a preset delay and if the time is not correct it will not work (i.e. if the delay is shorter than the ESP executing the command).
    This is the easiest variant to code, but it has its downsides, as you will be forcing a refresh of the browser. You will need to code this logic in the JS of the webpage, this is your current JS:
<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  xhr.send();
}
</script>

With 1 second timeout a refresh will look like this (you can change the timeout in the line with the 1000, the timeout is in ms):

<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  xhr.send();
  setTimeout(function(){
     window.location.reload(1);
  }, 1000);
}
</script>
  1. The more complex, but far better option has two parts:
    2.1. An EPS32 backend API for requesting the status of the buttons (not so hard as it sounds)
    2.2. Some JS to call this API and update the buttons

The code for this case is not so easy, so I will not type it all out (plus it will need some testing)…

You will need another serving point similar to your main point you have here:

// Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

It will look something like this (I think this will not compile, you will need to add the needed button states and maybe fix the JSON):

// Route for buttons status
  server.on("/buttonsState", HTTP_GET, [](AsyncWebServerRequest *request){
    char jsonString[100];
    sprint("{\"buttonOneState\": %b}", buttonOneStatusBool);
    request->send_P(200, "json", jsonString, processor);
  });

**This code is not full and will need fixing, simply I do not have much time to write and test it thoroughly

After the API is ready you need to query it with the JS something like so (I think this will not work, and it lacks timeout protection, so it may request new states indefinitely, the goal of this almost JS code is for you to see what is needed, and if you want you can finish it, some JS knowledge is needed):

function getButtonsState() {
    var Httpreq = new XMLHttpRequest();
    Httpreq.open("GET","/buttonsState",false);
    Httpreq.send();
    return JSON.parse(Httpreq.responseText);
}

function waitForButtonsChange() {
     var buttonsState = getButtonsState();
     if(buttonsState.buttonOneState) { // checks if the button is still enabled
       setTimeout(waitForButtonsChange, 1000); // wait again for the states
     } else {
       // Here we can set the button to OFF
       var element = document.getElementById(19); // Here we use the ID of the top button
       element.setPosition(false); // I am not sure if this will re-render the switch
     }
}

function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  xhr.send();
  setTimeout(waitForButtonsChange, 1000); // starts the recursive calls
}

In summary, you can either refresh that page after some time and hope for the best or implement an update mechanism in JS.

P.S. My last post is for deletion as by accident I posted half to this post…

Thank you mivrkiki
For your in depth answer, unfortunately I will need to go back and try to understand your answer. There’s nothing wrong with your answers it’s just me being very slow to learn new things like Json I didn’t know I was even using Json.

I’ll get there in the end, thank you for your help so far and I will try not to disturb you too much.

Good evening all
following on from mivrkiki answer:

script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  xhr.send();
  setTimeout(function(){
     window.location.reload(1);
  }, 1000);
}
</script>

instead of a fixed time i.e. 1000 is it possible to insert a variable at this point
then the program can change the amount of time remaining.

Thank you for looking

As for JSON and Web development: You are not yet using JSON as to what I see, if you want a proper async webpage you will need to use it.
Web development is pretty different from embedded and is mainly in JS (javascript) and some derivative languages based on JS (like TypeScript). I would recommend you to watch some courses on the topic, this is how I started with web development, I personally use Udemy for courses and I started with web development through a course from there. *The courses there are paid but are almost constantly discounted to about 10USD…

I suppose your idea is to have the timeout change as the different button is pressed.

If this is the case then yes, it is possible.

You will need to send the timeout from the ESP to the webpage, then the webpage will need to parse the message into a timeout value.

*This generally should be done with JSON, but for this case I think we can go with text and parse it on the JS side

So first we need to return the value of how much milliseconds we want the delay to be, this needs to happen in the response coming from the ESP to the webpage at line 272:

request->send(200, "text/plain", "OK");

Here we can send 500 for example:

request->send(200, "text/plain", "500");

In order to read the text in the JS and parse it, and then do a wait with the given ms we get to this:

script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", false); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", false); }
  xhr.send();
  var delayReceived = Number(xhr.responseText);
  setTimeout(function(){
     window.location.reload(1);
  }, delayReceived);
}
</script>

The above changes will make a 500ms delay as given in the ESP code, if you want to you can change the 500 using some if statements, simply place a string with the number you want.

Many apologies for the long delay in getting back to you, and thank you for adding another response, I need to sit down again and find out where to load it I see you put down webpage 272. I cannot see that reference in the programme.
I think I understand what you’re saying, just don’t know where to put the code you kindly given me.

Thank you again for your help