import network
import urequests
import time
import ssd1306
import socket
from machine import Pin, SoftI2C
import neopixel
# 🌐 Disable AP mode
ap = network.WLAN(network.AP_IF)
ap.active(False)
# 🚀 Wi-Fi Credentials
SSID = "your mobile hotspot"
PASSWORD = "mobile hotspot password"
# 🌍 OpenWeatherMap API using Latitude & Longitude
API_KEY = "your api key "# create 🌍 OpenWeatherMap API key
LATITUDE = "your location latitude" # Example: Chennai
LONGITUDE = "your location longitude"
API_URL = f"https://api.openweathermap.org/data/2.5/weather?lat={LATITUDE}&lon={LONGITUDE}&appid={API_KEY}&units=metric"
# 🌈 WS2812 LED Setup (1 LED on GPIO2)
rain_led = neopixel.NeoPixel(Pin(2), 1)
rain_led[0] = (0, 0, 0)
rain_led.write()
# 🖥 OLED (SSD1306) Init on GPIO1=SDA, GPIO3=SCL
i2c = SoftI2C(scl=Pin(3), sda=Pin(1))
oled = ssd1306.SSD1306_I2C(128, 64, i2c)
# 📶 Connect Wi-Fi
def connect_wifi():
wifi = network.WLAN(network.STA_IF)
wifi.active(True)
wifi.connect(SSID, PASSWORD)
print("Connecting to Wi-Fi...", end="")
for _ in range(10):
if wifi.isconnected():
print("\nConnected! IP:", wifi.ifconfig()[0])
return wifi.ifconfig()[0]
print(".", end="")
time.sleep(1)
print("\nWi-Fi connection failed.")
return None
# 🌦️ Fetch Weather Data
def get_weather():
try:
response = urequests.get(API_URL)
data = response.json()
response.close()
temp = data["main"]["temp"]
humidity = data["main"]["humidity"]
wind_speed = data["wind"]["speed"]
pressure = data["main"]["pressure"]
cloud_cover = data["clouds"]["all"]
weather_desc = data["weather"][0]["description"].lower()
# 🌧️ Rain classification
if "heavy" in weather_desc:
rain_level = "Heavy Rain"
led_color = (255, 0, 0) # Bright Red
elif "moderate" in weather_desc:
rain_level = "Moderate Rain"
led_color = (255, 100, 0) # Orange
elif "light" in weather_desc or "drizzle" in weather_desc:
rain_level = "Light Rain"
led_color = (255, 0, 255) # Magenta
else:
rain_level = "No Rain"
led_color = (0, 0, 0) # Off
return temp, humidity, wind_speed, pressure, cloud_cover, weather_desc, rain_level, led_color
except Exception as e:
print("Weather fetch error:", e)
return None, None, None, None, None, "Error", "Error", (0, 0, 0)
# 🖥 OLED Display
def display_weather():
oled.fill(0)
temp, humidity, wind_speed, pressure, cloud_cover, weather_desc, rain_level, led_color = get_weather()
if temp is not None:
oled.text(f"T: {temp}C", 0, 12)
oled.text(f"H: {humidity}%", 0, 22)
oled.text(f"W: {wind_speed}m/s", 0, 32)
oled.text(f"P: {pressure}hPa", 0, 42)
oled.text(f"Clouds: {cloud_cover}%", 0, 52)
if rain_level != "No Rain":
oled.text(rain_level, 5, 0)
else:
oled.text("Clear Sky", 20, 0)
rain_led[0] = led_color
rain_led.write()
else:
oled.text("Weather Error", 10, 30)
oled.show()
# 🌐 Web Dashboard
def web_server(ip):
addr = socket.getaddrinfo("0.0.0.0", 80)[0][-1]
s = socket.socket()
s.bind(addr)
s.listen(5)
print("Web Server Running on:", ip)
while True:
client, _ = s.accept()
temp, humidity, wind_speed, pressure, cloud_cover, weather_desc, rain_level, _ = get_weather()
rain_msg = f"⚠️ {rain_level}" if "Rain" in rain_level else "☀️ No Rain Expected"
html = f"""<!DOCTYPE html>
<html>
<head>
<title>ESP32-S3 Weather</title>
<meta http-equiv="refresh" content="600">
<style>
body {{ font-family: Arial; text-align: center; background: #eef; }}
.container {{ background: white; padding: 20px; margin: 50px auto; width: 300px; border-radius: 10px; box-shadow: 0 0 10px #aaa; }}
.alert {{ font-weight: bold; color: red; }}
</style>
</head>
<body>
<h2>🌦️ ESP32 Weather Dashboard</h2>
<div class="container">
<p><b>Temperature:</b> {temp if temp else 'N/A'}°C</p>
<p><b>Humidity:</b> {humidity if humidity else 'N/A'}%</p>
<p><b>Wind Speed:</b> {wind_speed if wind_speed else 'N/A'} m/s</p>
<p><b>Pressure:</b> {pressure if pressure else 'N/A'} hPa</p>
<p><b>Cloud Cover:</b> {cloud_cover if cloud_cover else 'N/A'}%</p>
<p class="alert">{rain_msg}</p>
<p><b>Description:</b> {weather_desc}</p>
</div>
</body>
</html>"""
client.send("HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n" + html)
client.close()
# 🛑 Turn Off LED on Stop
def turn_off_led():
rain_led[0] = (0, 0, 0)
rain_led.write()
# 🔄 Run System
try:
ip = connect_wifi()
if ip:
display_weather()
web_server(ip)
else:
print("Wi-Fi Not Connected.")
finally:
turn_off_led()