sneaky4oe

ESP8266 Remote PC Power Switch (Home Assistant & mDNS)

Dec 30th, 2025 (edited)
3,171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.30 KB | Housing | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <ESP8266WebServer.h>
  3. #include <ESP8266mDNS.h>
  4.  
  5. // Project: Remote PC Power Control via ESP8266
  6. // Hardware components:
  7. // 1. Controller: NodeMCU ESP8266 V3 (CH340)
  8. // 2. Relay: 1-Channel 3.3V Low-Level Trigger Relay
  9. // 3. Power: USB Type-C (5V)
  10. // 4. Connection:
  11. //    - Relay VCC -> NodeMCU VIN (5V) or 3V
  12. //    - Relay GND -> NodeMCU GND
  13. //    - Relay IN  -> NodeMCU D1 (GPIO5)
  14. //    - Relay COM & NO -> PC Motherboard Power SW pins
  15. //
  16. // Features:
  17. // - Web-server for remote control via VPN
  18. // - mDNS support (access via modified name like http://myname.local)
  19. // - Force Shutdown support (8s long press via /force)
  20. // - Physical FLASH button on board triggers the relay
  21. // - English UI
  22. //
  23. // Demo: https://social.vivaldi.net/@sneaky4oe/115810896025815481
  24.  
  25. // Your network config
  26. const char* ssid = "WiFI_NAME_REGISTRY_DEPENDANT"; // Change this
  27. const char* password = "WiFI_PASSWORD"; // Change this
  28. const char* hostName = "myname"; // Change this to access in browser with myname.local
  29.  
  30. const int relayPin = 5;       // D1 (GPIO5)
  31. const int buttonPin = 0;      // FLASH button (GPIO0)
  32. const int ledPin = 2;         // Onboard LED (D4)
  33.  
  34. // Durations in milliseconds
  35. const int standardPress = 500;
  36. const int forcePress = 8000;    // Force kill duration (8 sec)
  37.  
  38. ESP8266WebServer server(80);
  39.  
  40. void pressButton(int durationMs) {
  41.   Serial.print("Action: pressing button for ");
  42.   Serial.print(durationMs);
  43.   Serial.println("ms");
  44.  
  45.   digitalWrite(ledPin, LOW);    
  46.   digitalWrite(relayPin, LOW);  
  47.  
  48.   delay(durationMs);            
  49.  
  50.   digitalWrite(relayPin, HIGH);
  51.   digitalWrite(ledPin, HIGH);  
  52. }
  53.  
  54. void handleRoot() {
  55.   String html = "<html><head><meta charset='UTF-8'><meta name='viewport' content='width=device-width, initial-scale=1'>";
  56.   html += "<style>body{text-align:center;font-family:Arial,sans-serif;background:#f4f4f4;padding:20px;}";
  57.   html += ".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;}";
  58.   html += ".on{background:#2ecc71;box-shadow:0 5px #27ae60;} .on:active{transform:translateY(4px);box-shadow:0 2px #27ae60;}";
  59.   html += ".off{background:#e74c3c;box-shadow:0 5px #c0392b;} .off:active{transform:translateY(4px);box-shadow:0 2px #c0392b;}";
  60.   html += "a{color:#7f8c8d;text-decoration:none;display:block;margin-top:20px; font-size: 14px;} h1{color:#2c3e50;}</style></head>";
  61.   html += "<body><h1>PC Remote Control</h1>";
  62.  
  63.   html += "<button class='btn on' onclick=\"location.href='/power'\">POWER ON</button>";
  64.   html += "<button class='btn off' onclick=\"if(confirm('Are you sure you want to FORCE SHUTDOWN?')){location.href='/force';}\">FORCE OFF</button>";
  65.  
  66.   html += "<p>Network name: http://" + String(hostName) + ".local</p></body></html>";
  67.   server.send(200, "text/html", html);
  68. }
  69.  
  70. void handlePower() {
  71.   server.send(200, "text/html", "<h1>OK! Standard press sent.</h1><script>setTimeout(function(){window.location.href='/';},2000);</script>");
  72.   pressButton(standardPress);
  73. }
  74.  
  75. void handleForce() {
  76.   server.send(200, "text/html", "<h1>OK! Force shutdown sent.</h1><script>setTimeout(function(){window.location.href='/';},4000);</script>");
  77.   pressButton(forcePress);
  78. }
  79.  
  80. void setup() {
  81.   Serial.begin(115200);
  82.   pinMode(relayPin, OUTPUT);
  83.   pinMode(ledPin, OUTPUT);
  84.   pinMode(buttonPin, INPUT_PULLUP);
  85.  
  86.   digitalWrite(relayPin, HIGH);
  87.   digitalWrite(ledPin, HIGH);  
  88.  
  89.   WiFi.mode(WIFI_STA);
  90.   WiFi.begin(ssid, password);
  91.   while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); }
  92.  
  93.   Serial.println("\nWiFi Connected!");
  94.   Serial.print("IP Address: ");
  95.   Serial.println(WiFi.localIP());
  96.  
  97.   if (MDNS.begin(hostName)) {
  98.     Serial.println("mDNS responder started: http://" + String(hostName) + ".local");
  99.   }
  100.  
  101.   server.on("/", handleRoot);
  102.   server.on("/power", handlePower);
  103.   server.on("/force", handleForce);
  104.   server.begin();
  105.  
  106.   MDNS.addService("http", "tcp", 80);
  107. }
  108.  
  109. void loop() {
  110.   MDNS.update();
  111.   server.handleClient();
  112.  
  113.   if (digitalRead(buttonPin) == LOW) {
  114.     delay(50);
  115.     if (digitalRead(buttonPin) == LOW) {
  116.       pressButton(standardPress);
  117.       while(digitalRead(buttonPin) == LOW) delay(10);
  118.     }
  119.   }
  120. }
Advertisement