Notifications
Clear all

Problem with MIT app inventor for ESP32 IoT project

2 Posts
2 Users
1 Likes
1,210 Views
(@abdulhak33m)
Member
Joined: 3 years ago
Posts: 7
Topic starter  

Good morning. 

 

BACKGROUND

I initially did an ESP32 IoT project that controls LEDs remotely using the Blynk platform. It was successful except for Blynk's third party policies and overall cost implication of the project compared with the use of MIT app inventor

 

MY ENDEAVORS 

Using MIT app inventor changed the sketch from Blynk sketch to ESP32 webserver sketch. I modified the sketch adding GPIO pins as desired and built the app using the app inventor. Here, the url for each output state(ON/OFF) was embedded in buttons created on the App with internet connectivity. It was successful,  But then; the project is based on ESP32 been connected with the same WIFI as the app. it can only work on a local server and cannot be controlled from anywhere in the world.

 

NEXT STEP

I came across a similar project by random nerd tutorials where ESP32 gpio can be controlled from anywhere in the world. I procured a domain , hosted it, and followed the steps in the tutorial. It worked as desired.

 

THE CHALLENGE

Now that the gpio pins are controlled by buttons on a webpage, i am unable to create the MIT app that simply replicates the functionalities of those buttons. This is because the buttons on the webpage have their output states initiated by a javascript function rather than a url. I inspected the code responsible for the button output states and here is what I found;

 

 
<!DOCTYPE HTML>
 
<html>
 
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8">
   
 
<meta name="viewport" content="width=device-width, initial-scale=1">
 
<link rel="stylesheet" type="text/css" href="esp-style.css">
 
<title>ESP32 OUTPUT Control</title>
 
</head>
 
<body>
 
<h2>ESP Output Control</h2>
 
<h3> - Board 0 - GPIO 0 (<i><a onclick="deleteOutput(this)" href="javascript:void(0);" id="4">Delete</a></i>)</h3><label class="switch"><input type="checkbox" onchange="updateOutput(this)" id="4" ><span class="slider"></span></label><h3>fan - Board 1 - GPIO 33 (<i><a onclick="deleteOutput(this)" href="javascript:void(0);" id="9">Delete</a></i>)</h3><label class="switch"><input type="checkbox" onchange="updateOutput(this)" id="9" ><span class="slider"></span></label><h3>tv - Board 1 - GPIO 32 (<i><a onclick="deleteOutput(this)" href="javascript:void(0);" id="10">Delete</a></i>)</h3><label class="switch"><input type="checkbox" onchange="updateOutput(this)" id="10" ><span class="slider"></span></label> <br><br>
 
<h3>Boards</h3><p><strong>Board 0</strong> - Last Request Time: 2021-03-26 14:03:10</p><p><strong>Board 1</strong> - Last Request Time: 2021-03-28 12:43:14</p> <br><br>
 
<div><form onsubmit="return createOutput();">
 
<h3>Create New Output</h3>
 
<label for="outputName">Name</label>
 
<input type="text" name="name" id="outputName"><br>
 
<label for="outputBoard">Board ID</label>
 
<input type="number" name="board" min="0" id="outputBoard">
 
<label for="outputGpio">GPIO Number</label>
 
<input type="number" name="gpio" min="0" id="outputGpio">
 
<label for="outputState">Initial GPIO State</label>
 
<select id="outputState" name="state">
 
<option value="0">0 = OFF</option>
 
<option value="1">1 = ON</option>
 
</select>
 
<input type="submit" value="Create Output">
 
<p><strong>Note:</strong> in some devices, you might need to refresh the page to see your newly created buttons or to remove deleted buttons.</p>
 
</form></div>
   
 
<script>
 
function updateOutput(element) {
 
var xhr = new XMLHttpRequest();
 
if(element.checked){
 
xhr.open("GET", "esp-outputs-action.php?action=output_update&id="+element.id+"&state=1", true);
 
}
 
else {
 
xhr.open("GET", "esp-outputs-action.php?action=output_update&id="+element.id+"&state=0", true);
 
}
 
xhr.send();
 
}
   
 
function deleteOutput(element) {
 
var result = confirm("Want to delete this output?");
 
if (result) {
 
var xhr = new XMLHttpRequest();
 
xhr.open("GET", "esp-outputs-action.php?action=output_delete&id="+element.id, true);
 
xhr.send();
 
alert("Output deleted");
 
setTimeout(function(){ window.location.reload(); });
 
}
 
}
   
 
function createOutput(element) {
 
var xhr = new XMLHttpRequest();
 
xhr.open("POST", "esp-outputs-action.php", true);
   
 
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
   
 
xhr.onreadystatechange = function() {
 
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
 
alert("Output created");
 
setTimeout(function(){ window.location.reload(); });
 
}
 
}
 
var outputName = document.getElementById("outputName").value;
 
var outputBoard = document.getElementById("outputBoard").value;
 
var outputGpio = document.getElementById("outputGpio").value;
 
var outputState = document.getElementById("outputState").value;
 
var httpRequestData = "action=output_create&name="+outputName+"&board="+outputBoard+"&gpio="+outputGpio+"&state="+outputState;
 
xhr.send(httpRequestData);
 
}
 
</script>
 
</body>
 
</html>
 

CONCLUSION

I want assistance on creating a similar MIT App where a JavaScript function will be called to determine the output states of the buttons rather than a url.

Thank you in anticipation of your assistance.



   
Quote
MadMisha
(@madmisha)
Member
Joined: 4 years ago
Posts: 340
 

It has been so many years since I used App Inventor and I probably won't be of any help but here is a try. I don't think XHR in itself is supported by App inventor. But here is a post I found that I think is creating a workaround and maybe you can use this in some way. esp32-wifi-webserver-upload-file-from-app-to-esp32 You might even be able to parse out the HTML/PHP received and make that work.

 

From what I remember, that is actually a really good community and if there is anyone who would know the answer, it would be there. So make a post there.

 

There is also the option of creating your own API on the side of what you already have. That would be the ESP32 would send out a different message to yourdomain/custom_whatever_you_decide_to_call_it folder. The get method for HTML into a list and parse for what your current buttons are/their IDs. Then you can setup the response to certain folder to execute your commands. As in yourdomain/replies/on/18. If you receive a request to the on folder you can parse out the 18 and do your trigger. I know this is not the direct answer but if all else fails, this could be an option. Also, note that when testing the direct response, using a browser might cause errors if you so not send HTML back. The browser will keep asking and could trigger multiple actions. So if you have no response, do it in the app. Also, you can throw the response in an empty list and either ignore it or use it as a confirmation.


   
abdulhak33m reacted
ReplyQuote