sneaky4oe

ESP8266 Remote PC Power Switch (Home Assistant & mDNS) - optocoupler + resistors

Oct 22nd, 2026 (edited)
405
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.64 KB | Source Code | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <ESP8266WebServer.h>
  3. #include <ESP8266mDNS.h>
  4.  
  5. /*
  6.  * Project: Wi-Fi PC Remote Power Control & Status Monitor
  7.  * Hardware Components:
  8.  * 1. Controller: NodeMCU ESP8266 V3
  9.  * 2. Isolation: 2x PC817 DIP Optocouplers
  10.  * 3. Resistors: 2x 220 Ohm (1/4W)
  11.  * 4. Power Supply: Micro-USB (5V)
  12.  *
  13.  * Schematic & Wiring Diagram:
  14.  *
  15.  * [ NodeMCU ]                      [ PC817 #1 - Power Control ]             [ Motherboard F_PANEL ]
  16.  *  Pin D1 (GPIO5) ---> [220Ω] ---> Pin 1 (Anode •)
  17.  *  GND --------------------------> Pin 2 (Cathode)
  18.  *                                  Pin 4 (Collector) ----------------------> Pin 7 (POWER SW +)
  19.  *                                  Pin 3 (Emitter) ------------------------> Pin 8 (POWER SW -)
  20.  *
  21.  * [ NodeMCU ]                      [ PC817 #2 - Power LED Sense ]          [ Motherboard F_PANEL ]
  22.  *  Pin D2 (GPIO4) <--------------- Pin 4 (Collector)
  23.  *  GND --------------------------> Pin 3 (Emitter)
  24.  *                                  Pin 2 (Cathode) <----------------------- Pin 3 (PLED -)
  25.  *                                  Pin 1 (Anode •) <------- [220Ω] -------- Pin 1 (PLED +)
  26.  *
  27.  * Hardware Notes:
  28.  * - PC817 Pin 1 is identified by the small indented circle/dot on top of the DIP package.
  29.  * - Pin D2 (GPIO4) uses ESP8266 internal pull-up logic (INPUT_PULLUP).
  30.  * - Target local URL: http://streampc.local
  31.  */
  32.  
  33. // --- Network Configuration ---
  34. const char* ssid     = "YOUR_WIFI_SSID";
  35. const char* password = "YOUR_WIFI_PASSWORD";
  36.  
  37. // --- Hostname Configuration ---
  38. const char* hostName = "streampc"; // Resolves to http://streampc.local
  39.  
  40. // --- Pin Definitions ---
  41. const int PIN_POWER_BTN  = 5; // D1 (GPIO5) -> PC817 #1 (Power Control Output)
  42. const int PIN_POWER_SENS = 4; // D2 (GPIO4) -> PC817 #2 (Power LED Sense Input)
  43.  
  44. ESP8266WebServer server(80);
  45.  
  46. // Helper function to pulse power pin
  47. void pressPowerButton(int durationMs) {
  48.   digitalWrite(PIN_POWER_BTN, HIGH);
  49.   delay(durationMs);
  50.   digitalWrite(PIN_POWER_BTN, LOW);
  51. }
  52.  
  53. // Check power state (Returns true if PC is ON)
  54. bool isPcOn() {
  55.   return digitalRead(PIN_POWER_SENS) == LOW;
  56. }
  57.  
  58. // Handler for HTML Interface
  59. void handleRoot() {
  60.   String html = "<html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1'><style>body{text-align:center;font-family:Arial,sans-serif;background:#f4f4f4;padding:20px;}h1{display:flex;align-items:center;justify-content:center;margin-bottom:30px;}.indicator{display:inline-block;width:22px;height:22px;border-radius:50%;margin-left:15px;background:#2ecc71;box-shadow: 0 0 10px #2ecc71;transition: 0.3s;}.btn{width:100%;max-width:300px;height:80px;font-size:20px;font-weight:bold;color:white;border:none;border-radius:15px;margin:15px 0;cursor:pointer;display:block;margin-left:auto;margin-right:auto;transition:0.2s;}.btn:active{transform:scale(0.98);}.on{background:#2ecc71;box-shadow:0 5px #27ae60;} .off{background:#e74c3c;box-shadow:0 5px #c0392b;}</style><script>setInterval(function(){  fetch('/status').then(r => r.text()).then(status => {    var ind = document.querySelector('.indicator');    if(status==='ON'){ind.style.background='#2ecc71'; ind.style.boxShadow='0 0 10px #2ecc71';}    else{ind.style.background='#e74c3c'; ind.style.boxShadow='0 0 10px #e74c3c';}  });}, 2000);function safeToggle() {  fetch('/status').then(r => r.text()).then(status => {    if (status === 'ON') { if (confirm('PC is already ON. Power action?')) location.href='/power'; }    else { location.href='/power'; }  });}</script></head><body><h1>PC Remote <span class='indicator'></span></h1><button class='btn on' onclick='safeToggle()'>POWER ON/OFF</button><button class='btn off' onclick=\"if(confirm('FORCE SHUTDOWN (8S)?')){location.href='/force';}\">FORCE SHUTDOWN</button><p>http://streampc.local</p></body></html>";
  61.  
  62.   server.send(200, "text/html", html);
  63. }
  64.  
  65. // Endpoint returning plain text status ("ON" or "OFF")
  66. void handleStatus() {
  67.   server.send(200, "text/plain", isPcOn() ? "ON" : "OFF");
  68. }
  69.  
  70. // Endpoint for standard power tap (500ms)
  71. void handlePower() {
  72.   pressPowerButton(500);
  73.   server.sendHeader("Location", "/");
  74.   server.send(303);
  75. }
  76.  
  77. // Endpoint for hard shutdown (8000ms / 8s)
  78. void handleForce() {
  79.   pressPowerButton(8000);
  80.   server.sendHeader("Location", "/");
  81.   server.send(303);
  82. }
  83.  
  84. void setup() {
  85.   Serial.begin(115200);
  86.  
  87.   // Configure output pin
  88.   pinMode(PIN_POWER_BTN, OUTPUT);
  89.   digitalWrite(PIN_POWER_BTN, LOW);
  90.  
  91.   // Configure input pin with internal pull-up
  92.   pinMode(PIN_POWER_SENS, INPUT_PULLUP);
  93.  
  94.   // Static IP Configuration
  95.   IPAddress local_IP(192, 168, 0, 166);
  96.   IPAddress gateway(192, 168, 0, 1);
  97.   IPAddress subnet(255, 255, 255, 0);
  98.   IPAddress primaryDNS(192, 168, 0, 1);
  99.  
  100.   if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
  101.     Serial.println("STA Failed to configure static IP!");
  102.   }
  103.  
  104.   WiFi.mode(WIFI_STA);
  105.   WiFi.begin(ssid, password);
  106.   Serial.println("\nConnecting to WiFi...");
  107.  
  108.   while (WiFi.status() != WL_CONNECTED) {
  109.     delay(500);
  110.     Serial.print(".");
  111.   }
  112.  
  113.   Serial.println("\nWiFi Connected!");
  114.   Serial.print("IP Address: ");
  115.   Serial.println(WiFi.localIP());
  116.  
  117.   // Start mDNS responder for http://streampc.local
  118.   if (MDNS.begin(hostName)) {
  119.     Serial.println("mDNS responder started: http://streampc.local");
  120.   } else {
  121.     Serial.println("Error setting up MDNS responder!");
  122.   }
  123.  
  124.   // Web server routes
  125.   server.on("/", handleRoot);
  126.   server.on("/status", handleStatus);
  127.   server.on("/power", handlePower);
  128.   server.on("/force", handleForce);
  129.  
  130.   server.begin();
  131.   Serial.println("HTTP Server started.");
  132. }
  133.  
  134. void loop() {
  135.   MDNS.update();
  136.   server.handleClient();
  137. }
Advertisement