From df808f4ffa5465cfdce09a2790b108f31075442b Mon Sep 17 00:00:00 2001
From: Jimmy <git@jimmy.nz>
Date: Wed, 11 Dec 2024 22:42:56 +1300
Subject: [PATCH] Add wifi ip and gateway

---
 src/boot.py     |  1 -
 src/index.html  |  6 +++++
 src/main.js     | 11 ++++++++-
 src/main.py     | 62 ++++++++++++++++++++++++++++++++++++++++++++-----
 src/patterns.py |  6 +++++
 src/wifi.py     | 46 +++++++++++++++++++++++-------------
 6 files changed, 108 insertions(+), 24 deletions(-)

diff --git a/src/boot.py b/src/boot.py
index 83c8f14..f08d0fb 100644
--- a/src/boot.py
+++ b/src/boot.py
@@ -34,4 +34,3 @@
 
 
 
-import wifi
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index b557c99..dfc68a4 100644
--- a/src/index.html
+++ b/src/index.html
@@ -53,6 +53,12 @@
             <label for="password">Wi-Fi Password:</label>
             <input type="password" id="password" name="password">
             <br>
+            <label for="ip">Wi-Fi IP:</label>
+            <input type="ip" id="ip" name="ip" value="{ip}">
+            <br>
+            <label for="gateway">Wi-Fi Gateway:</label>
+            <input type="gateway" id="gateway" name="gateway" value="{gateway}">
+            <br>
             <input type="submit" value="Save Wi-Fi Settings">
         </form>
     </div>
diff --git a/src/main.js b/src/main.js
index b33fcd7..f16d945 100644
--- a/src/main.js
+++ b/src/main.js
@@ -84,8 +84,17 @@ async function updateWifi(event) {
     event.preventDefault();
     const ssid = document.getElementById('ssid').value;
     const password = document.getElementById('password').value;
+    const ip = document.getElementById('ip').value;
+    const gateway = document.getElementById('gateway').value;
+    if(!ssid || !password) {
+        alert("Missing ssid or password");
+        return;
+    }
     console.log(ssid, password);
-    //await post('/num_leds', numLeds);
+    const response = await post('/wifi_settings', ssid+"\n"+password+"\n"+ip+"\n"+gateway);
+    if(response === 500) {
+        alert("Failed to connect to wifi");
+    }
 }
 
 function createPatternButtons(patterns) {
diff --git a/src/main.py b/src/main.py
index 377924f..d4809e9 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,4 +1,4 @@
-from machine import Pin
+from machine import Pin, reset
 from patterns import Patterns
 from settings import Settings
 import socket
@@ -7,6 +7,7 @@ import json
 import utime
 import sys
 import espnow
+import wifi
              
 class LEDServer:
     SETTINGS_FILE = "/settings.json"  # Path should be adjusted for MicroPython's filesystem
@@ -47,7 +48,15 @@ class LEDServer:
         self.css = self.read_file("/main.css").encode('utf-8')
         self.patterns_json = json.dumps(list(self.patterns.patterns.keys()))
         
-       
+        ssid = self.settings["wifi"]["ssid"]
+        password = self.settings["wifi"]["password"]
+        ip = self.settings.get("wifi", {}).get("ip", None)
+        gateway = self.settings.get("wifi", {}).get("gateway", None)
+        
+        wifi.ap(password="qwerty")
+        config = wifi.do_connect(ssid, password, ip, gateway)
+        if config is not None:
+            print(config)
    
    
    
@@ -67,7 +76,9 @@ class LEDServer:
             "/delay": self.delay,
             "/brightness": self.brightness,
             "/color": self.color,
-            "/color2": self.color2
+            "/color2": self.color2,
+            "/wifi_settings": self.wifi_settings,
+            "set_leds": self.set_leds
         }
         
         if path in paths:
@@ -130,6 +141,37 @@ class LEDServer:
             client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
         except:
             client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+
+    def wifi_settings(self, client_socket, post_data):
+        try:
+            lines = post_data.split('\n')
+            ssid, password, ip, gateway = (lines + ["", "", None, None])[:4]
+
+            self.settings["wifi"]["ssid"] = ssid
+            self.settings["wifi"]["password"] = password
+            self.settings["wifi"]["ip"] = ip
+            self.settings["wifi"]["gateway"] = gateway
+
+            self.settings.save()            
+            self.settings.load()
+            print(self.settings)
+            print(ssid, password)
+            config = wifi.do_connect(ssid, password, ip ,gateway)
+            if config is not None:
+                print(config)
+                client_socket.send(b'HTTP/1.0 200 OK\r\n\r\n')
+            else: 
+                client_socket.send(b'HTTP/1.0 500 Failed to connect to wifi\r\n\r\n')
+            
+        except ValueError:
+            client_socket.send(b'HTTP/1.0 400 Bad request\r\n\r\n')
+
+    def set_leds(self, client_socket, post_data):
+        if len(post_data == self.settings["num_leds"]*3):
+            print(post_data)
+            self.patterns.set(0, (255,255,255))
+        else:
+            print("Wrong number of leds")
                 
     def handle_get(self, path, client_socket):
         if path == "/":
@@ -141,7 +183,12 @@ class LEDServer:
                 brightness=self.settings["brightness"],
                 color=self.settings["color1"],
                 color2=self.settings["color2"],
-                ssid=self.settings["wifi"]["ssid"]).encode())
+                ssid=self.settings["wifi"]["ssid"],
+                password=self.settings["wifi"]["password"],
+                ip=self.settings.get("wifi", {}).get("ip", ""),
+                gateway=self.settings.get("wifi", {}).get("gateway", "").encode()  # Only encode if it's a string
+            ))
+
         elif path == "/main.js":
             client_socket.send(b'HTTP/1.0 200 OK\r\nContent-type: application/javascript\r\n\r\n')
             client_socket.send(self.js)
@@ -195,7 +242,10 @@ class LEDServer:
             self.server_socket.close()
             self.settings.save()
 
-# Example of creating and starting the server
-if __name__ == "__main__":
+def main():
     server = LEDServer()
     server.start()
+
+# Example of creating and starting the server
+if __name__ == "__main__":
+    main()    
\ No newline at end of file
diff --git a/src/patterns.py b/src/patterns.py
index e399298..9100142 100644
--- a/src/patterns.py
+++ b/src/patterns.py
@@ -60,6 +60,12 @@ class Patterns:
             return True
         return False
     
+    def set(self, i, color):
+        self.n[i] = color
+
+    def write(self):
+        self.n.write()
+        
     def fill(self):
         for i in range(self.num_leds):
             self.n[i] = self.color1
diff --git a/src/wifi.py b/src/wifi.py
index a2954e2..9784c18 100644
--- a/src/wifi.py
+++ b/src/wifi.py
@@ -4,25 +4,36 @@ from config import *
 from time import sleep
 import ubinascii
 
-def do_connect():
+def do_connect(ssid, password, ip=None, gateway=None):
     led = Pin(8, Pin.OUT)
-    sta_if = network.WLAN(network.STA_IF)
-    sta_if.ifconfig((ip, '255.255.255.0', gateway, '1.1.1.1'))
-    if not sta_if.isconnected():
-        print('connecting to network...')
-        sta_if.active(True)
-        sta_if.connect(ssid, password)
-        led.on()
-        for i in range(10):
-            if sta_if.isconnected():
-                print('network config:', sta_if.ifconfig())
-                led.off()
-                break
-            sleep(1)
-    
-do_connect()
+    try:
+        sta_if = network.WLAN(network.STA_IF)
+        sta_if.disconnect()
+        print(ip, gateway)
+        if ip and gateway:
+            print(ip, gateway)
+            sta_if.ifconfig((ip, '255.255.255.0', gateway, '1.1.1.1'))
+        if not sta_if.isconnected():
+            print(f'connecting to network {ssid}')
+            sta_if.active(True)
+            sta_if.connect(ssid, password)
+            led.on()
+            for i in range(10):
+                print(f"Attempt {i}")
+                if sta_if.isconnected():
+                    led.off()
+                    return sta_if.ifconfig()
+                sleep(0.5)
+            return None
+            
+        else:
+            return sta_if.ifconfig()
+    except Exception as e:
+        print(f"Failed to connect to wifi {e}")
+        return None
 
 def ap(password):
+    pass
     ap_if = network.WLAN(network.AP_IF)
     ap_if.active(True)
     ap_mac = ap_if.config('mac')
@@ -35,3 +46,6 @@ def ap(password):
 
 
 
+
+
+