Our This guide ESP32 Arduino IoT Relay Control is self-hosted. The working result is here. This kind of project serves the purpose but the UI is just pathetic and you can not easily convert it to an Android or iOS app. Most of us want a working system to get a toggle button control like this one.
These days, you have a lot of options for UI such as React.js or just Twitter Bootstrap. You have the options of backend such as Firebase, Supabase and so on.
It does not matter whether you use MySQL or Supabase, you need to create a basic API system written in commonly used dynamic programing languages written as Ruby, PHP etc. If you study the server files of that project in our GitHub repository, you’ll notice esp32_update.php
and index.php
. The basic problem of this system is the change of state upon reloading the index.php
webpage.
---
Now, look at this repo on my GitHub. index.php
of this project does the similar job that of esp32_update.php
of a previous project but it clearly defines how to handle GET and POST requests:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (isset($_POST['toggle_update'])) { $update = $db->prepare("UPDATE `toggle` SET `status` = ? WHERE `id` = 1 LIMIT 1;"); $update->execute([$_POST['status']]); echo json_encode($_POST); } } elseif ($_SERVER['REQUEST_METHOD'] === 'GET') { if (isset($_GET['toggle_select'])) { $select = $db->prepare("SELECT `status` FROM `toggle` WHERE `id` = 1 LIMIT 1;"); $select->execute(); echo json_encode($select->fetchColumn()); } elseif (isset($_GET['toggle_updated'])) { $select = $db->prepare("SELECT date_format(updated, '%e %b %l:%i:%s %p') as updated FROM `toggle` WHERE `id` = 1 LIMIT 1;"); $select->execute(); echo json_encode($select->fetchColumn()); } } else { echo json_encode(array()); } |
These files are originally written by corbpie (hence I have no control on the included URLs). You can look at this index.html file, this is the AJAX script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | function putStatus() { $.ajax({ type: "GET", url: "https://peachpuff.srv3r.com/api/index.php", data: {toggle_select: true}, success: function (result) { if (result == 1) { $('#customSwitch1').prop('checked', true); statusText(1); } else { $('#customSwitch1').prop('checked', false); statusText(0); } lastUpdated(); } }); } function statusText(status_val) { if (status_val == 1) { var status_str = "On (1)"; } else { var status_str = "Off (0)"; } document.getElementById("statusText").innerText = status_str; } function onToggle() { $('#toggleForm :checkbox').change(function () { if (this.checked) { //alert('checked'); updateStatus(1); statusText(1); } else { //alert('NOT checked'); updateStatus(0); statusText(0); } }); } function updateStatus(status_val) { $.ajax({ type: "POST", url: "https://peachpuff.srv3r.com/api/index.php", data: {toggle_update: true, status: status_val}, success: function (result) { console.log(result); lastUpdated(); } }); } function lastUpdated() { $.ajax({ type: "GET", url: "https://peachpuff.srv3r.com/api/index.php", data: {toggle_updated: true}, success: function (result) { document.getElementById("updatedAt").innerText = "Last updated at: " + result; } }); } $(document).ready(function () { //Called on page load: putStatus(); onToggle(); statusText(); }); |
corbpie’s example code is not for direct conversion of the project we have initially mentioned. But that is a kind of one use-case. There are differences and limitations of these two methods for the frontend.