#include <WiFi.h> // Changed for ESP32
#include <WebServer.h> // Changed for ESP32
#include <HTTPClient.h>
#include <WiFiUdp.h>
#include <IRremoteESP8266.h>
#include <IRsend.h>
// --- Wokwi Simulation Settings ---
const char* ssid = "Wokwi-GUEST"; // Required for Wokwi
const char* password = ""; // No password for Wokwi-GUEST
// --- Hardware Settings ---
const uint16_t kIrLed = 4;
IRsend irsend(kIrLed);
WebServer server(80); // Changed for ESP32
String rokuIP = "";
// --- 1. REMOTE UI HANDLER ---
void handleRoot() {
String html = "<html><head><meta name='viewport' content='width=device-width, initial-scale=1.0'>";
html += "<style>body{background:#f0f0f0;text-align:center;font-family:sans-serif;padding:20px;}";
html += ".remote{background:#fff;border:3px solid #333;padding:15px;width:260px;margin:auto;border-radius:20px;box-shadow: 5px 5px 15px rgba(0,0,0,0.2);}";
html += "button{width:75px;height:55px;margin:3px;background:#eee;border:1px solid #000;font-weight:bold;cursor:pointer;}";
html += "button:active{background:#ccc;}";
html += "select{width:100%;height:45px;margin-bottom:10px;font-size:16px;}</style></head><body>";
html += "<h2>SIMULATED REMOTE</h2><div class='remote'>";
html += "<button style='width:100%;background:#444;color:#fff;margin-bottom:10px;' onclick=\"fetch('/scan').then(()=>location.reload())\">SCAN FOR ROKU</button>";
html += "<p style='font-size:12px;color:red;'>" + (rokuIP == "" ? "No Roku Found" : "Roku Active: " + rokuIP) + "</p>";
html += "<select id='mode'>";
html += "<option value='ir_fire'>IR: Fire TV</option>";
html += "<option value='wifi_roku'>WiFi: Roku TV</option>";
html += "<option value='ir_samsung'>IR: Samsung</option></select><br>";
html += "<button onclick=\"s('power')\">PWR</button><button onclick=\"s('home')\">HOME</button><br>";
html += "<button onclick=\"s('up')\">UP</button><br>";
html += "<button onclick=\"s('left')\">LEFT</button><button onclick=\"s('ok')\">OK</button><button onclick=\"s('right')\">RIGHT</button><br>";
html += "<button onclick=\"s('down')\">DOWN</button><br><hr>";
html += "<button onclick=\"s('vol_up')\">VOL +</button><button onclick=\"s('vol_dn')\">VOL -</button>";
html += "</div><script>function s(c){var m=document.getElementById('mode').value; fetch('/send?mode='+m+'&cmd='+c);}</script></body></html>";
server.send(200, "text/html", html);
}
// --- 2. COOKBOOK PIN CONTROLLER ---
void handlePinControl() {
String response = "<h3>Pin Status:</h3>";
for (uint8_t i = 0; i < server.args(); i++) {
String argName = server.argName(i);
if (argName.startsWith("pinD")) {
int pin = argName.substring(4).toInt();
int val = server.arg(i).toInt();
pinMode(pin, OUTPUT);
digitalWrite(pin, val);
response += "Pin " + String(pin) + " set to " + String(val) + "<br>";
}
}
server.send(200, "text/html", response);
}
// --- 3. SCAN LOGIC (Simulated for Wokwi) ---
void discoverRoku() {
Serial.println("Scanning for Roku...");
delay(1000);
rokuIP = "192.168.1.50"; // We force a fake IP so you can test the buttons
Serial.println("Found Simulated Roku at " + rokuIP);
}
// --- 4. SENDING LOGIC ---
void handleSend() {
String mode = server.arg("mode");
String cmd = server.arg("cmd");
Serial.println("Command: " + cmd + " Mode: " + mode);
if (mode == "wifi_roku") {
Serial.println("Sending WiFi Command to Roku at " + rokuIP);
// In simulation, we just print to Serial since we can't hit your real TV
} else {
Serial.println("Blasting IR Code for " + mode);
irsend.sendNEC(0x20DF10EF); // Placeholder
}
server.send(200, "text/plain", "OK");
}
void setup() {
Serial.begin(115200);
irsend.begin();
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
Serial.println("\nWiFi Connected!");
Serial.print("Local IP: ");
Serial.println(WiFi.localIP());
server.on("/", handleRoot);
server.on("/pin", handlePinControl);
server.on("/scan", []() { discoverRoku(); server.send(200, "text/plain", "OK"); });
server.on("/send", handleSend);
server.begin();
}
void loop() { server.handleClient(); }