diff --git a/WiFi.h b/WiFi.h
new file mode 100644
index 0000000000000000000000000000000000000000..0a5bb6e3b034512c55fb61cc420ab39266935b73
--- /dev/null
+++ b/WiFi.h
@@ -0,0 +1,186 @@
+//#include <DNSServer.h>
+
+//DNSServer dnsServer;
+
+//const byte DNS_PORT = 53;
+
+// bool apMode = false;
+
+// AP mode password
+const char WiFiAPPSK[] = "";
+
+// Wi-Fi network to connect to (if not in AP mode)
+char* ssid = "";
+char* password = "";
+
+#define HOSTNAME "ESP8266-" ///< Hostname. The initializeWiFi function adds the Chip ID at the end.
+
+#define DEBUG_WIFI 1
+
+unsigned long futureTimeout = 0;
+uint16_t connectionTimeout = 20000;
+
+template <typename Generic>
+void debugPrintln(Generic text) {
+  if (DEBUG_WIFI) {
+    Serial.print("*WiFi: ");
+    Serial.println(text);
+  }
+}
+
+void startAp() {
+  // WiFi.disconnect();
+
+  // apMode = true;
+
+  //  WiFi.mode(WIFI_AP_STA);
+  // debugPrintln("SET AP STA");
+
+  String AP_NameString = "ESP8266-";
+  AP_NameString += String(ESP.getChipId(), HEX);
+
+  char AP_NameChar[AP_NameString.length() + 1];
+  memset(AP_NameChar, 0, AP_NameString.length() + 1);
+
+  for (int i = 0; i < AP_NameString.length(); i++)
+    AP_NameChar[i] = AP_NameString.charAt(i);
+
+  debugPrintln("Starting soft AP");
+
+  if (WiFiAPPSK != NULL) {
+    debugPrintln(WiFi.softAP(AP_NameChar, WiFiAPPSK) ? "ready" : "failed");
+  } else {
+    debugPrintln(WiFi.softAP(AP_NameChar) ? "ready" : "failed");
+  }
+
+  debugPrintln("Connect to Wi-Fi access point: ");
+  debugPrintln(AP_NameChar);
+
+  delay(500); // Without delay I've seen the IP address blank
+  debugPrintln("AP IP address: ");
+  debugPrintln(WiFi.softAPIP());
+
+  //  dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
+  //  dnsServer.start(DNS_PORT, "*", WiFi.softAPIP());
+}
+
+String getWiFiJson() {
+  String hostname = String(HOSTNAME);
+  hostname += String(ESP.getChipId(), HEX);
+
+  String json = "{";
+
+  json += "\"status\":\"" + String(WiFi.status()) + "\"";
+  json += ",\"localIP\":\"" + WiFi.localIP().toString() + "\"";
+  json += ",\"softAPIP\":\"" + WiFi.softAPIP().toString() + "\"";
+  json += ",\"hostname\":\"" + hostname + "\"";
+  json += ",\"ssid\":\"" + WiFi.SSID() + "\"";
+  json += ",\"rssi\":\"" + String(WiFi.RSSI()) + "\"";
+
+  //  json += ",\"networks\":[";
+  //  byte ssidCount = WiFi.scanNetworks();
+  //  for (byte i = 0; i < ssidCount; i++) {
+  //    if (i > 0)
+  //      json += ",";
+  //
+  //    json += "{\"name\":\"" + WiFi.SSID(i) + "\",\"rssi\":\"" + String(WiFi.RSSI(i)) + "\"}";
+  //  }
+  //
+  //  json += "]";
+
+  json += "}";
+
+  return json;
+}
+
+void initializeWiFi() {
+  WiFi.mode(WIFI_AP_STA);
+
+  // Set Hostname.
+  String hostname = String(HOSTNAME);
+  hostname += String(ESP.getChipId(), HEX);
+  WiFi.hostname(hostname);
+
+  // Print hostname.
+  Serial.println("Hostname: " + hostname);
+
+  char hostnameChar[hostname.length() + 1];
+  memset(hostnameChar, 0, hostname.length() + 1);
+
+  for (uint8_t i = 0; i < hostname.length(); i++)
+    hostnameChar[i] = hostname.charAt(i);
+
+  //  MDNS.begin(hostnameChar);
+
+  // Add service to MDNS-SD
+  //  MDNS.addService("http", "tcp", 80);
+
+  // attempt to connect; should it fail, fall back to AP mode
+  //  WiFi.mode(WIFI_STA);
+
+  String stored_ssid = WiFi.SSID();
+  if (stored_ssid != NULL && stored_ssid != "") {
+    debugPrintln("Connecting to stored SSID:");
+    debugPrintln(stored_ssid);
+    WiFi.begin();
+  } else {
+    debugPrintln("No stored SSID");
+  }
+
+  startAp();
+
+  webServer.on("/wifi", HTTP_POST, []() {
+    String ssid = webServer.arg("ssid");
+    String password = webServer.arg("password");
+    // String mode = webServer.arg("mode");
+
+    char ssidChars[50];
+    ssid.toCharArray(ssidChars, 50);
+
+    char passwordChars[50];
+    password.toCharArray(passwordChars, 50);
+
+    debugPrintln("Connecting to new SSID:");
+    debugPrintln(ssid);
+
+    // dnsServer.stop();
+    // WiFi.softAPdisconnect(true);
+
+    // apMode = false;
+    // WiFi.mode(WIFI_STA);
+    WiFi.begin(ssidChars, passwordChars);
+    // futureTimeout = millis() + connectionTimeout;
+
+    webServer.sendHeader("Location", "/wifi.htm");
+    webServer.send(303);
+  });
+
+  webServer.on("/wifi", HTTP_GET, []() {
+    String json = getWiFiJson();
+    webServer.send(200, "application/json", json);
+  });
+}
+
+void checkWiFi() {
+  //  if (WiFi.status() == WL_CONNECTED) {
+  //    debugPrintln("connected");
+  //    futureTimeout = millis() + connectionTimeout;
+  //    return;
+  //  }
+  //
+  //  if (apMode) {
+  //    debugPrintln("Already running in AP mode.");
+  //    return;
+  //  }
+  //
+  //  // time to give up on the stored network and switch to ap mode?
+  //  if (futureTimeout != 0 && millis() < futureTimeout) {
+  //    return;
+  //  }
+  //
+  //  debugPrintln("Switching to AP mode, timeout elapsed: ");
+  //  debugPrintln(connectionTimeout);
+  //
+  //  startApMode();
+}
+
diff --git a/data/css/jquery.minicolors.min.css b/data/css/minicolors.min.css
similarity index 100%
rename from data/css/jquery.minicolors.min.css
rename to data/css/minicolors.min.css
diff --git a/data/images/github.ico b/data/images/github.ico
new file mode 100644
index 0000000000000000000000000000000000000000..a59308e2e7ef39c9aa77eb03d70fa1c02c738429
Binary files /dev/null and b/data/images/github.ico differ
diff --git a/data/index.htm b/data/index.htm
index 9c27311f209b45b6df929c20e3e94c63602f153f..296c1ced33413b932d15f17aff004ea6cb88f113 100644
--- a/data/index.htm
+++ b/data/index.htm
@@ -8,12 +8,12 @@
   <title>ESP8266 + FastLED by Evil Genius Labs</title>
 
   <!-- request CSS from internet CDN -->
-  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
-  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.css" integrity="sha256-4wnSkPYU5B4yngAlx/rEb8LdfMah4teUth4AfhGEuaY=" crossorigin="anonymous" />
+  <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> -->
+  <!-- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.css" integrity="sha256-4wnSkPYU5B4yngAlx/rEb8LdfMah4teUth4AfhGEuaY=" crossorigin="anonymous" /> -->
 
   <!-- request CSS from the ESP8266 web server -->
-  <!-- <link rel="stylesheet" href="css/bootstrap.min.css"> -->
-  <!-- <link rel="stylesheet" href="css/jquery.minicolors.min.css"> -->
+  <link rel="stylesheet" href="css/bootstrap.min.css">
+  <link rel="stylesheet" href="css/minicolors.min.css">
 
   <link rel="stylesheet" href="css/styles.css">
 
@@ -31,7 +31,7 @@
           <span class="icon-bar"></span>
           <span class="icon-bar"></span>
         </button>
-        <a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="https://evilgeniuslabs.org/images/atom.svg" style="width: 24px; height: 24px;" /></a>
+        <a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="/images/atom196.png" style="width: 24px; height: 24px;" /></a>
         <a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank">Evil Genius Labs</a>
       </div>
       <div class="collapse navbar-collapse" id="navbar-collapse-1">
@@ -40,11 +40,12 @@
           <li><a href="/simple.htm" target="_blank" title="Simple Mode">Simple</a></li>
           <li><a href="/edit.htm" target="_blank" title="Edit Files">Files</a></li>
           <li><a href="/update" target="_blank" title="Update Firmware">Firmware</a></li>
+          <li><a href="/wifi.htm" target="_blank" title="Wi-Fi Settings">Wi-Fi</a></li>
         </ul>
         <ul class="nav navbar-nav navbar-right">
           <li>
             <a href="https://github.com/jasoncoon/esp8266-fastled-webserver">
-              <img style="height: 16px;" src="https://assets-cdn.github.com/favicon.ico" />
+              <img style="height: 16px;" src="/images/github.ico" />
             </a>
           </li>
         </ul>
@@ -215,16 +216,16 @@
   </nav>
 
   <!-- request js from internet CDN -->
-  <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.js" integrity="sha256-XAFQ9dZ6hy8p/GRhU8h/8pMvM1etymiJLZW1CiHV3bQ=" crossorigin="anonymous"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script>
+  <!-- <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-minicolors/2.2.4/jquery.minicolors.min.js" integrity="sha256-XAFQ9dZ6hy8p/GRhU8h/8pMvM1etymiJLZW1CiHV3bQ=" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script> -->
 
   <!-- request js from the ESP8266 web server -->
-  <!-- <script src="js/jquery-3.1.1.min.js"></script> -->
-  <!-- <script src="js/bootstrap.min.js"></script> -->
-  <!-- <script src="js/jquery.minicolors.min.js"></script> -->
-  <!-- <script src="js/r-websocket.min.js"></script> -->
+  <script src="js/jquery-3.1.1.min.js"></script>
+  <script src="js/bootstrap.min.js"></script>
+  <script src="js/minicolors.min.js"></script>
+  <script src="js/r-websocket.min.js"></script>
 
   <script src="js/app.js"></script>
 
diff --git a/data/js/jquery.minicolors.min.js b/data/js/minicolors.min.js
similarity index 100%
rename from data/js/jquery.minicolors.min.js
rename to data/js/minicolors.min.js
diff --git a/data/simple.htm b/data/simple.htm
index 55a5a5965a91410302c981b01c06b0e5cccf9cf9..eb16ecbd36c320c1b3943280f7b51eee96c9240e 100644
--- a/data/simple.htm
+++ b/data/simple.htm
@@ -8,10 +8,10 @@
   <title>ESP8266 + FastLED by Evil Genius Labs</title>
 
   <!-- request CSS from internet CDN -->
-  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
+  <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> -->
 
   <!-- request CSS from the ESP8266 web server -->
-  <!-- <link rel="stylesheet" href="css/bootstrap.min.css"> -->
+  <link rel="stylesheet" href="css/bootstrap.min.css">
 
   <link rel="stylesheet" href="css/simple.css">
 
@@ -42,14 +42,14 @@
   </div>
 
   <!-- request js from internet CDN -->
-  <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
-  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
-  <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script>
-  <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script>
+  <!-- <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script> -->
+  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script> -->
 
   <!-- request js from the ESP8266 web server -->
-  <!-- <script src="js/jquery-3.1.1.min.js"></script> -->
-  <!-- <script src="js/bootstrap.min.js"></script> -->
+  <script src="js/jquery-3.1.1.min.js"></script>
+  <script src="js/bootstrap.min.js"></script>
 
   <script src="js/simple.js"></script>
 
diff --git a/data/wifi.htm b/data/wifi.htm
new file mode 100644
index 0000000000000000000000000000000000000000..29a49fb1918d7a9c48808ff9538f5e19f339dd8f
--- /dev/null
+++ b/data/wifi.htm
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>ESP8266 + FastLED by Evil Genius Labs</title>
+
+  <!-- request CSS from internet CDN -->
+  <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> -->
+
+  <!-- request CSS from the ESP8266 web server -->
+  <link rel="stylesheet" href="css/bootstrap.min.css">
+
+  <link rel="stylesheet" href="css/styles.css">
+
+  <link rel="icon" href="images/atom196.png">
+</head>
+
+<body>
+
+  <nav class="navbar navbar-default navbar-static-top" id="top" role="banner">
+    <div class="container">
+      <div class="navbar-header">
+        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse-1" aria-expanded="false">
+          <span class="sr-only">Toggle navigation</span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+          <span class="icon-bar"></span>
+        </button>
+        <a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank"><img src="/images/atom196.png" style="width: 24px; height: 24px;" /></a>
+        <a class="navbar-brand" href="https://www.evilgeniuslabs.org" target="_blank">Evil Genius Labs</a>
+      </div>
+      <div class="collapse navbar-collapse" id="navbar-collapse-1">
+        <ul class="nav navbar-nav">
+          <li><a href="/">ESP8266 + FastLED <span class="sr-only">(current)</span></a></li>
+          <li><a href="/simple.htm" target="_blank" title="Simple Mode">Simple</a></li>
+          <li><a href="/edit.htm" target="_blank" title="Edit Files">Files</a></li>
+          <li><a href="/update" target="_blank" title="Update Firmware">Firmware</a></li>
+          <li class="active"><a href="/wifi.htm" target="_blank" title="Wi-Fi Settings">Wi-Fi</a></li>
+        </ul>
+        <ul class="nav navbar-nav navbar-right">
+          <li>
+            <a href="https://github.com/jasoncoon/esp8266-fastled-webserver">
+              <img style="height: 16px;" src="/images/github.ico" />
+            </a>
+          </li>
+        </ul>
+      </div>
+    </div>
+  </nav>
+
+  <div id="container" class="container">
+
+    <form class="form-horizontal" id="form" action="/wifi" method="post">
+
+      <div class="form-group">
+        <label for="inputSSID" class="col-sm-2 control-label">SSID</label>
+        <div class="col-sm-10">
+          <input type="text" autocorrect="off" autocapitalize="none"
+            class="form-control" id="inputSSID" name="ssid" placeholder="SSID (Wi-Fi network name)">
+        </div>
+      </div>
+
+      <div class="form-group">
+        <label for="inputPassword" class="col-sm-2 control-label">Password</label>
+        <div class="col-sm-10">
+          <input type="password" class="form-control" id="inputPassword" name="password" placeholder="Password">
+        </div>
+      </div>
+
+      <div class="form-group">
+        <div class="col-sm-offset-2 col-sm-10">
+          <button type="submit" class="btn btn-default">Connect</button>
+        </div>
+      </div>
+
+    </form>
+
+  </div>
+
+  <!-- request js from internet CDN -->
+  <!-- <script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> -->
+  <!-- <script src="https://unpkg.com/isotope-layout@3/dist/isotope.pkgd.min.js"></script> -->
+  <!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/reconnecting-websocket/1.0.0/reconnecting-websocket.min.js" integrity="sha256-A4JwlcDvqO4JXpvEtvWY1RH8JAEMu5W21wP8GUXLUNs=" crossorigin="anonymous"></script> -->
+
+  <!-- request js from the ESP8266 web server -->
+  <script src="js/jquery-3.1.1.min.js"></script>
+  <script src="js/bootstrap.min.js"></script>
+
+</body>
+
+</html>
diff --git a/esp8266-fastled-webserver.ino b/esp8266-fastled-webserver.ino
index 68712f5fe36b30ce4ceba5b6ba4598af5af98f9f..0ad0f0d7fd75915887362de5cebf763da087af6e 100644
--- a/esp8266-fastled-webserver.ino
+++ b/esp8266-fastled-webserver.ino
@@ -24,39 +24,30 @@ extern "C" {
 }
 
 #include <ESP8266WiFi.h>
-#include <ESP8266mDNS.h>
+//#include <ESP8266mDNS.h>
 #include <ESP8266WebServer.h>
 #include <ESP8266HTTPUpdateServer.h>
 #include <WebSocketsServer.h>
 #include <FS.h>
 #include <EEPROM.h>
-#include <IRremoteESP8266.h>
+//#include <IRremoteESP8266.h>
 #include "GradientPalettes.h"
 
 #define ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0]))
 
 #include "Field.h"
 
-#define HOSTNAME "ESP8266-" ///< Hostname. The setup function adds the Chip ID at the end.
+//#define RECV_PIN D4
+//IRrecv irReceiver(RECV_PIN);
 
-#define RECV_PIN D4
-IRrecv irReceiver(RECV_PIN);
-
-#include "Commands.h"
-
-const bool apMode = false;
-
-// AP mode password
-const char WiFiAPPSK[] = "";
-
-// Wi-Fi network to connect to (if not in AP mode)
-const char* ssid = "";
-const char* password = "";
+//#include "Commands.h"
 
 ESP8266WebServer webServer(80);
 WebSocketsServer webSocketsServer = WebSocketsServer(81);
 ESP8266HTTPUpdateServer httpUpdateServer;
 
+#include "WiFi.h"
+
 #include "FSBrowser.h"
 
 #define DATA_PIN      D8
@@ -228,7 +219,7 @@ void setup() {
 
   FastLED.setBrightness(brightness);
 
-  irReceiver.enableIRIn(); // Start the receiver
+//  irReceiver.enableIRIn(); // Start the receiver
 
   Serial.println();
   Serial.print( F("Heap: ") ); Serial.println(system_get_free_heap_size());
@@ -252,57 +243,9 @@ void setup() {
     Serial.printf("\n");
   }
 
-  // Set Hostname.
-  String hostname(HOSTNAME);
-  hostname += String(ESP.getChipId(), HEX);
-  WiFi.hostname(hostname);
-
-  char hostnameChar[hostname.length() + 1];
-  memset(hostnameChar, 0, hostname.length() + 1);
+  initializeWiFi();
 
-  for (uint8_t i = 0; i < hostname.length(); i++)
-    hostnameChar[i] = hostname.charAt(i);
-
-  MDNS.begin(hostnameChar);
-
-  // Add service to MDNS-SD
-  MDNS.addService("http", "tcp", 80);
-
-  // Print hostname.
-  Serial.println("Hostname: " + hostname);
-
-  if (apMode)
-  {
-    WiFi.mode(WIFI_AP);
-
-    // Do a little work to get a unique-ish name. Append the
-    // last two bytes of the MAC (HEX'd) to "Thing-":
-    uint8_t mac[WL_MAC_ADDR_LENGTH];
-    WiFi.softAPmacAddress(mac);
-    String macID = String(mac[WL_MAC_ADDR_LENGTH - 2], HEX) +
-                   String(mac[WL_MAC_ADDR_LENGTH - 1], HEX);
-    macID.toUpperCase();
-    String AP_NameString = "ESP8266-" + macID;
-
-    char AP_NameChar[AP_NameString.length() + 1];
-    memset(AP_NameChar, 0, AP_NameString.length() + 1);
-
-    for (int i = 0; i < AP_NameString.length(); i++)
-      AP_NameChar[i] = AP_NameString.charAt(i);
-
-    WiFi.softAP(AP_NameChar, WiFiAPPSK);
-
-    Serial.printf("Connect to Wi-Fi access point: %s\n", AP_NameChar);
-    Serial.println("and open http://192.168.4.1 in your browser");
-  }
-  else
-  {
-    WiFi.mode(WIFI_STA);
-    Serial.printf("Connecting to %s\n", ssid);
-    if (String(WiFi.SSID()) != String(ssid)) {
-      WiFi.begin(ssid, password);
-    }
-    }
+  checkWiFi();
 
   httpUpdateServer.setup(&webServer);
 
@@ -473,10 +416,15 @@ void loop() {
   // Add entropy to random number generator; we use a lot of it.
   random16_add_entropy(random(65535));
 
+  EVERY_N_SECONDS(10) {
+    checkWiFi();
+  }
+
+//  dnsServer.processNextRequest();
   webSocketsServer.loop();
   webServer.handleClient();
 
-  handleIrInput();
+//  handleIrInput();
 
   if (power == 0) {
     fill_solid(leds, NUM_LEDS, CRGB::Black);
@@ -552,212 +500,212 @@ void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length
   }
 }
 
-void handleIrInput()
-{
-  InputCommand command = readCommand();
-
-  if (command != InputCommand::None) {
-    Serial.print("command: ");
-    Serial.println((int) command);
-  }
-
-  switch (command) {
-    case InputCommand::Up: {
-        adjustPattern(true);
-        break;
-      }
-    case InputCommand::Down: {
-        adjustPattern(false);
-        break;
-      }
-    case InputCommand::Power: {
-        setPower(power == 0 ? 1 : 0);
-        break;
-      }
-    case InputCommand::BrightnessUp: {
-        adjustBrightness(true);
-        break;
-      }
-    case InputCommand::BrightnessDown: {
-        adjustBrightness(false);
-        break;
-      }
-    case InputCommand::PlayMode: { // toggle pause/play
-        setAutoplay(!autoplay);
-        break;
-      }
-
-    // pattern buttons
-
-    case InputCommand::Pattern1: {
-        setPattern(0);
-        break;
-      }
-    case InputCommand::Pattern2: {
-        setPattern(1);
-        break;
-      }
-    case InputCommand::Pattern3: {
-        setPattern(2);
-        break;
-      }
-    case InputCommand::Pattern4: {
-        setPattern(3);
-        break;
-      }
-    case InputCommand::Pattern5: {
-        setPattern(4);
-        break;
-      }
-    case InputCommand::Pattern6: {
-        setPattern(5);
-        break;
-      }
-    case InputCommand::Pattern7: {
-        setPattern(6);
-        break;
-      }
-    case InputCommand::Pattern8: {
-        setPattern(7);
-        break;
-      }
-    case InputCommand::Pattern9: {
-        setPattern(8);
-        break;
-      }
-    case InputCommand::Pattern10: {
-        setPattern(9);
-        break;
-      }
-    case InputCommand::Pattern11: {
-        setPattern(10);
-        break;
-      }
-    case InputCommand::Pattern12: {
-        setPattern(11);
-        break;
-      }
-
-    // custom color adjustment buttons
-
-    case InputCommand::RedUp: {
-        solidColor.red += 8;
-        setSolidColor(solidColor);
-        break;
-      }
-    case InputCommand::RedDown: {
-        solidColor.red -= 8;
-        setSolidColor(solidColor);
-        break;
-      }
-    case InputCommand::GreenUp: {
-        solidColor.green += 8;
-        setSolidColor(solidColor);
-        break;
-      }
-    case InputCommand::GreenDown: {
-        solidColor.green -= 8;
-        setSolidColor(solidColor);
-        break;
-      }
-    case InputCommand::BlueUp: {
-        solidColor.blue += 8;
-        setSolidColor(solidColor);
-        break;
-      }
-    case InputCommand::BlueDown: {
-        solidColor.blue -= 8;
-        setSolidColor(solidColor);
-        break;
-      }
-
-    // color buttons
-
-    case InputCommand::Red: {
-        setSolidColor(CRGB::Red);
-        break;
-      }
-    case InputCommand::RedOrange: {
-        setSolidColor(CRGB::OrangeRed);
-        break;
-      }
-    case InputCommand::Orange: {
-        setSolidColor(CRGB::Orange);
-        break;
-      }
-    case InputCommand::YellowOrange: {
-        setSolidColor(CRGB::Goldenrod);
-        break;
-      }
-    case InputCommand::Yellow: {
-        setSolidColor(CRGB::Yellow);
-        break;
-      }
-
-    case InputCommand::Green: {
-        setSolidColor(CRGB::Green);
-        break;
-      }
-    case InputCommand::Lime: {
-        setSolidColor(CRGB::Lime);
-        break;
-      }
-    case InputCommand::Aqua: {
-        setSolidColor(CRGB::Aqua);
-        break;
-      }
-    case InputCommand::Teal: {
-        setSolidColor(CRGB::Teal);
-        break;
-      }
-    case InputCommand::Navy: {
-        setSolidColor(CRGB::Navy);
-        break;
-      }
-
-    case InputCommand::Blue: {
-        setSolidColor(CRGB::Blue);
-        break;
-      }
-    case InputCommand::RoyalBlue: {
-        setSolidColor(CRGB::RoyalBlue);
-        break;
-      }
-    case InputCommand::Purple: {
-        setSolidColor(CRGB::Purple);
-        break;
-      }
-    case InputCommand::Indigo: {
-        setSolidColor(CRGB::Indigo);
-        break;
-      }
-    case InputCommand::Magenta: {
-        setSolidColor(CRGB::Magenta);
-        break;
-      }
-
-    case InputCommand::White: {
-        setSolidColor(CRGB::White);
-        break;
-      }
-    case InputCommand::Pink: {
-        setSolidColor(CRGB::Pink);
-        break;
-      }
-    case InputCommand::LightPink: {
-        setSolidColor(CRGB::LightPink);
-        break;
-      }
-    case InputCommand::BabyBlue: {
-        setSolidColor(CRGB::CornflowerBlue);
-        break;
-      }
-    case InputCommand::LightBlue: {
-        setSolidColor(CRGB::LightBlue);
-        break;
-      }
-  }
-}
+//void handleIrInput()
+//{
+//  InputCommand command = readCommand();
+//
+//  if (command != InputCommand::None) {
+//    Serial.print("command: ");
+//    Serial.println((int) command);
+//  }
+//
+//  switch (command) {
+//    case InputCommand::Up: {
+//        adjustPattern(true);
+//        break;
+//      }
+//    case InputCommand::Down: {
+//        adjustPattern(false);
+//        break;
+//      }
+//    case InputCommand::Power: {
+//        setPower(power == 0 ? 1 : 0);
+//        break;
+//      }
+//    case InputCommand::BrightnessUp: {
+//        adjustBrightness(true);
+//        break;
+//      }
+//    case InputCommand::BrightnessDown: {
+//        adjustBrightness(false);
+//        break;
+//      }
+//    case InputCommand::PlayMode: { // toggle pause/play
+//        setAutoplay(!autoplay);
+//        break;
+//      }
+//
+//    // pattern buttons
+//
+//    case InputCommand::Pattern1: {
+//        setPattern(0);
+//        break;
+//      }
+//    case InputCommand::Pattern2: {
+//        setPattern(1);
+//        break;
+//      }
+//    case InputCommand::Pattern3: {
+//        setPattern(2);
+//        break;
+//      }
+//    case InputCommand::Pattern4: {
+//        setPattern(3);
+//        break;
+//      }
+//    case InputCommand::Pattern5: {
+//        setPattern(4);
+//        break;
+//      }
+//    case InputCommand::Pattern6: {
+//        setPattern(5);
+//        break;
+//      }
+//    case InputCommand::Pattern7: {
+//        setPattern(6);
+//        break;
+//      }
+//    case InputCommand::Pattern8: {
+//        setPattern(7);
+//        break;
+//      }
+//    case InputCommand::Pattern9: {
+//        setPattern(8);
+//        break;
+//      }
+//    case InputCommand::Pattern10: {
+//        setPattern(9);
+//        break;
+//      }
+//    case InputCommand::Pattern11: {
+//        setPattern(10);
+//        break;
+//      }
+//    case InputCommand::Pattern12: {
+//        setPattern(11);
+//        break;
+//      }
+//
+//    // custom color adjustment buttons
+//
+//    case InputCommand::RedUp: {
+//        solidColor.red += 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//    case InputCommand::RedDown: {
+//        solidColor.red -= 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//    case InputCommand::GreenUp: {
+//        solidColor.green += 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//    case InputCommand::GreenDown: {
+//        solidColor.green -= 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//    case InputCommand::BlueUp: {
+//        solidColor.blue += 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//    case InputCommand::BlueDown: {
+//        solidColor.blue -= 8;
+//        setSolidColor(solidColor);
+//        break;
+//      }
+//
+//    // color buttons
+//
+//    case InputCommand::Red: {
+//        setSolidColor(CRGB::Red);
+//        break;
+//      }
+//    case InputCommand::RedOrange: {
+//        setSolidColor(CRGB::OrangeRed);
+//        break;
+//      }
+//    case InputCommand::Orange: {
+//        setSolidColor(CRGB::Orange);
+//        break;
+//      }
+//    case InputCommand::YellowOrange: {
+//        setSolidColor(CRGB::Goldenrod);
+//        break;
+//      }
+//    case InputCommand::Yellow: {
+//        setSolidColor(CRGB::Yellow);
+//        break;
+//      }
+//
+//    case InputCommand::Green: {
+//        setSolidColor(CRGB::Green);
+//        break;
+//      }
+//    case InputCommand::Lime: {
+//        setSolidColor(CRGB::Lime);
+//        break;
+//      }
+//    case InputCommand::Aqua: {
+//        setSolidColor(CRGB::Aqua);
+//        break;
+//      }
+//    case InputCommand::Teal: {
+//        setSolidColor(CRGB::Teal);
+//        break;
+//      }
+//    case InputCommand::Navy: {
+//        setSolidColor(CRGB::Navy);
+//        break;
+//      }
+//
+//    case InputCommand::Blue: {
+//        setSolidColor(CRGB::Blue);
+//        break;
+//      }
+//    case InputCommand::RoyalBlue: {
+//        setSolidColor(CRGB::RoyalBlue);
+//        break;
+//      }
+//    case InputCommand::Purple: {
+//        setSolidColor(CRGB::Purple);
+//        break;
+//      }
+//    case InputCommand::Indigo: {
+//        setSolidColor(CRGB::Indigo);
+//        break;
+//      }
+//    case InputCommand::Magenta: {
+//        setSolidColor(CRGB::Magenta);
+//        break;
+//      }
+//
+//    case InputCommand::White: {
+//        setSolidColor(CRGB::White);
+//        break;
+//      }
+//    case InputCommand::Pink: {
+//        setSolidColor(CRGB::Pink);
+//        break;
+//      }
+//    case InputCommand::LightPink: {
+//        setSolidColor(CRGB::LightPink);
+//        break;
+//      }
+//    case InputCommand::BabyBlue: {
+//        setSolidColor(CRGB::CornflowerBlue);
+//        break;
+//      }
+//    case InputCommand::LightBlue: {
+//        setSolidColor(CRGB::LightBlue);
+//        break;
+//      }
+//  }
+//}
 
 void loadSettings()
 {