Skip to content

Instantly share code, notes, and snippets.

@VovaStelmashchuk
Last active October 31, 2025 17:17
Show Gist options
  • Select an option

  • Save VovaStelmashchuk/7e0ef77dc14e820db6ef076451b65be8 to your computer and use it in GitHub Desktop.

Select an option

Save VovaStelmashchuk/7e0ef77dc14e820db6ef076451b65be8 to your computer and use it in GitHub Desktop.
ESP32 electricty tracker micro python
from machine import Pin
import time
import network
import time
import ujson as json
import usocket as socket
import machine
import urequests
led = Pin(8, Pin.OUT)
led.value(0)
print("Hello, ESP32-C3!")
start_blick = [1024, 512, 256, 128, 64, 32, 16, 8, 4, 2]
for blick in start_blick:
ms = blick / 1000.0
led.value(0)
time.sleep(ms)
led.value(1)
time.sleep(ms)
CONFIG_FILE = 'config.json'
AP_SSID = 'ESP32-HOTSPOT'
def url_decode(s):
"""
A simple URL-decoding function to handle percent-encoded strings.
Replaces '+' with space and '%HH' with the corresponding character.
"""
result = ""
i = 0
while i < len(s):
char = s[i]
if char == '+':
result += ' '
i += 1
elif char == '%':
if i + 2 < len(s):
try:
hex_code = s[i+1:i+3]
decoded_char = chr(int(hex_code, 16))
result += decoded_char
i += 3
except ValueError:
result += '%'
i += 1
else:
result += '%'
i += 1
else:
result += char
i += 1
return result
def send_data_to_network():
"""
This is your main app logic
It checks Wi-Fi, loads the token, and sends alive signal to the server
"""
if not connect_to_wifi():
print("Wi-Fi connection failed or could not be re-established. Aborting send.")
return
print("--- Running main application (Wi-Fi OK) ---")
token = None
try:
with open(CONFIG_FILE, 'r') as f:
config = json.load(f)
token = config.get('token')
except Exception as e:
print(f"Could not load token from config: {e}")
if not token:
print("Token not found in config. Cannot send data.")
return
url = "https://nu31.space/api/electricty_tracker/alive"
try:
headers = {'Authorization': f'Bearer {token}'}
response = urequests.post(url, headers=headers)
print("Status Code:", response.status_code)
print("Response Content:", response.text)
response.close()
led.value(1)
time.sleep(2)
led.value(0)
except Exception as e:
print("Error during GET request:", e)
def connect_to_wifi():
"""
Tries to connect to Wi-Fi using saved credentials.
Returns True on success, False on failure.
"""
sta_if = network.WLAN(network.STA_IF)
if not sta_if.isconnected():
try:
with open(CONFIG_FILE, 'r') as f:
config = json.load(f)
ssid = config.get('ssid')
password = config.get('password')
if not ssid or not password:
print("No saved credentials found.")
return False
print(f"Connecting to saved network: {ssid}...")
sta_if.active(True)
sta_if.connect(ssid, password)
for _ in range(10):
if sta_if.isconnected():
print("Connection successful!")
print(f"IP Info: {sta_if.ifconfig()}")
return True
time.sleep(1)
print("Connection failed.")
sta_if.active(False)
return False
except OSError:
print("No config file found.")
return False
else:
return True
def start_config_server():
"""
Starts the Access Point and a web server to get Wi-Fi credentials and token.
"""
print("Starting configuration server...")
sta_if = network.WLAN(network.STA_IF)
sta_if.active(True)
scan_results = sta_if.scan()
sta_if.active(False)
unique_ssids = set(net[0].decode('utf-8') for net in scan_results if net[0])
options_html = "".join(f'<option value="{ssid}">\n' for ssid in sorted(unique_ssids))
ap = network.WLAN(network.AP_IF)
ap.active(True)
ap.config(essid=AP_SSID)
print(f"--- Connect to this Wi-Fi ---")
print(f"SSID: {AP_SSID}")
print(f"Then open http://{ap.ifconfig()[0]} in your browser")
print("-------------------------------")
html_page = f"""
<!DOCTYPE html>
<html>
<head>
<title>ESP32 Wi-Fi Config</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="font-family: Arial, sans-serif; text-align: center; padding: 20px;">
<h2>ESP32 Device Configuration</h2>
<form action="/save" method="GET">
<p><strong>Step 1: Wi-Fi Credentials</strong></p>
<p>
<label for="ssid">Wi-Fi Name (SSID):</label><br>
<input type="text" id="ssid" name="ssid" list="wifi-list" required
style="width: 80%; padding: 10px;">
<datalist id="wifi-list">
{options_html}
</datalist>
</p>
<p>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password" required
style="width: 80%; padding: 10px;">
</p>
<p><strong>Step 2: Authorization Token</strong></p>
<p>
<label for="token">Your API Token:</label><br>
<input type="password" id="token" name="token" required
style="width: 80%; padding: 10px;">
</p>
<p>
<input type="submit" value="Save and Connect"
style="padding: 15px 30px; background-color: #007bff;
color: white; border: none; border-radius: 5px; font-size: 16px;">
</p>
</form>
</body>
</html>
"""
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(1)
while True:
try:
conn, addr = s.accept()
print(f"Got connection from {addr}")
request_line = conn.recv(1024).decode('utf-8').split('\n')[0]
print(f"Request: {request_line}")
if request_line.startswith('GET /save?'):
try:
params_str = request_line.split('?')[1].split(' ')[0]
ssid = ''
password = ''
token = ''
for part in params_str.split('&'):
key_value = part.split('=', 1)
if len(key_value) == 2:
key = key_value[0]
raw_value = key_value[1]
if key == 'ssid':
ssid = url_decode(raw_value)
elif key == 'password':
password = url_decode(raw_value)
elif key == 'token':
token = url_decode(raw_value)
print(f"Saving SSID: {ssid}, Password: [HIDDEN], Token: [HIDDEN]")
with open(CONFIG_FILE, 'w') as f:
json.dump({
'ssid': ssid,
'password': password,
'token': token
}, f)
conn.sendall(b'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n'
b'<html><body>'
b'<h1>Credentials saved!</h1>'
b'<p>Rebooting to connect to your Wi-Fi...</p>'
b'</body></html>')
conn.close()
print("Credentials saved. Rebooting...")
time.sleep(2)
machine.reset()
except Exception as e:
print(f"Error parsing save request: {e}")
conn.close()
elif request_line.startswith('GET /'):
conn.sendall(b'HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n')
conn.sendall(html_page.encode('utf-8'))
conn.close()
except Exception as e:
print(f"Web server error: {e}")
if 'conn' in locals():
conn.close()
# --- Main execution ---
if not connect_to_wifi():
start_config_server()
else:
send_data_to_network()
while True:
print("Still connected. Sleeping for 300 seconds (5 minutes)...")
time.sleep(300)
send_data_to_network()
@VovaStelmashchuk
Copy link
Author

IDEA:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment