Using ACButton #503
-
Hello, I am a novice in javaScript and HTML. I would like to drive a Led from the ACButton function. Do you have an example? Thank for your help. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Indeed, there may be other users who are at a loss in the same place you are. AutoConnect's custom web pages can place major HTML elements easily, but when trying to implement interactive control without page transitions, it requires an HTTP-based asynchronous communication method. While its implementation is not complicated, it may seem like a tall wall to those unfamiliar with it. In fact, AutoConnect doesn't have the ability to simplify asynchronous communication. Therefore, it is at least necessary to embed a JavaScript-like mechanism in the client page compared to a typical Arduino sketch. If AutoConnect would be able to perform asynchronous communication instead of user sketches, would that help you? NOTE: #include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>
// Declare the structure of a custom web page to blink a LED.
// Leave the value attribute representing the ACButton label undefined.
// It changes in sync with the LED blinking state.
static const char LED_PAGE[] PROGMEM = R"(
{
"uri": "/led",
"title": "LED",
"menu": true,
"element": [
{
"name": "onoff",
"type": "ACButton"
}
]
}
)";
AutoConnect portal;
// The ledOnOff function below is a handler that cannot exist in the current
// AutoConnect function. It is not yet supported, but will be called each
// time ACbutton is clicked. In this handler function, your sketch can perform
// processing according to the value of the ACButton.
// Also, the return value of the function will rewrite the label of the button
// according to the completion of the asynchronous communication.
String ledOnOff(String& value) {
if (value == "ON") {
digitalWrite(LED_BUILTIN, HIGH);
value = "OFF";
}
else {
digitalWrite(LED_BUILTIN, LOW);
value = "ON";
}
return value;
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);
// In order to implement the ledOnOff handler functions, your sketch will
// have to follow unconventional procedures.
// After the JSON for the AutoConnect custom web page loads, the sketch gets
// an ACButton instance. You can perform this step with the following sequence:
portal.load(LED_PAGE);
AutoConnectAux* ledPage = portal.aux("/led");
AutoConnectButton& onoff = ledPage->getElement<AutoConnectButton>("onoff");
// Initializes the onoff value. This value indicates the LED blinking order,
// and when it displays "ON", click it to turn on the LED.
// That is, the ACButton label display and the LED blinking state are
// the opposite.
onoff.value = "ON";
// Register the ledOnOff handler to the onoff instance an ACButton).
// With this, each time the ACButton is clicked on the web page, the ledOnOff
// function will be called.
onoff.on(ledOnOff);
portal.begin();
}
void loop() {
portal.handleClient();
} Actual answerYou can similar functionality implement with the current AutoConnect version. It includes the JavaScript you stumbled upon. #include <Arduino.h>
#include <WiFi.h>
#include <WebServer.h>
#include <AutoConnect.h>
#define LED_URL "/led"
#define LED_ENDPOINT "/_led"
static const char FETCH_BUTTON[] PROGMEM = R"*(
{
"uri": "/led",
"title": "LED",
"menu": true,
"element": [
{
"name": "onoff",
"type": "ACButton",
"action": "_oe(this)"
},
{
"name": "_oe",
"type": "ACElement",
"value": "<script>function _oe(t){const el=new FormData();el.append(t.name,t.value);fetch(')*" LED_ENDPOINT R"*(',{mode:'no-cors',method:'post',body:el}).then(res=>{if(res.ok){return res.text();}}).then(text=>{console.log(text);const anc=document.getElementById(t.id);anc.value=text;anc.innerHTML=text;}).catch(err=>console.log(err));}</script>"
}
]
}
)*";
WebServer server;
AutoConnect portal(server);
void initLED(uint8_t pin) {
AutoConnectAux* fetch_button = portal.aux(LED_URL);
AutoConnectButton& button = fetch_button->getElement<AutoConnectButton>("onoff");
button.value = "ON";
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
}
void onButton() {
String value = server.arg("onoff");
if (value == "ON") {
digitalWrite(LED_BUILTIN, HIGH);
value = "OFF";
}
else {
digitalWrite(LED_BUILTIN, LOW);
value = "ON";
}
server.send(200, "text/plain", value);
}
void setup() {
portal.load(FETCH_BUTTON);
portal.begin();
initLED(LED_BUILTIN);
server.on(LED_ENDPOINT, onButton);
}
void loop() {
portal.handleClient();
} Brief Description
function _oe(t) {
const el = new FormData();
el.append(t.name, t.value);
fetch('/_led', {
mode: 'no-cors',
method: 'post',
body: el
}).then(res => {
if (res.ok) {
return res.text();
}
}
).then(text => {
console.log(text);
const anc = document.getElementById(t.id);
anc.value = text;
anc.innerHTML = text;
}
).catch(err=>console.log(err));
} |
Beta Was this translation helpful? Give feedback.
-
Thank you for your help. I would never have succeeded on my own. The solution you propose seems great and much easier, especially when you are not an expert in Javascript. |
Beta Was this translation helpful? Give feedback.
-
Hello, It took some time to release, but please try it if you like. |
Beta Was this translation helpful? Give feedback.
Indeed, there may be other users who are at a loss in the same place you are.
AutoConnect's custom web pages can place major HTML elements easily, but when trying to implement interactive control without page transitions, it requires an HTTP-based asynchronous communication method. While its implementation is not complicated, it may seem like a tall wall to those unfamiliar with it. In fact, AutoConnect doesn't have the ability to simplify asynchronous communication. Therefore, it is at least necessary to embed a JavaScript-like mechanism in the client page compared to a typical Arduino sketch.
If AutoConnect would be able to perform asynchronous communication instead of user sketches, wo…