pb pbaumgarten.com
Courses Python Reference Networking
Login
Course
Python Reference
Topic
MicroPython
Python Reference

Networking

Connect to wifi

  • Requires WIFI.py file (bottom of page)
from WIFI import WIFI

networks = (("SCWiFi","wifi1234"),) # Wifi network and password
wifi = WIFI(networks)
ip = wifi.connect()                # Connect to the wifi network
wifi.ntptime()                     # Fetch current time

Get current date/time

  • Requires an active Internet connection over wifi (as per above)
import time
from WIFI import WIFI

# Connect to Wifi and fetch the current time
networks = (("SCWiFi","wifi1234"),) # Wifi network and password
wifi = WIFI(networks)
ip = wifi.connect()                # Connect to the wifi network
wifi.ntptime()                     # Fetch current time

# Get the current time as a tuple variable
# Format: (Year, Month, Day, Hour, Minute, Second, Weekday, Day_of_Year)
now = time.localtime()

# We can pick out specific pieces of time using their index! (Count from 0)
# Index [3] is the Hour (in 24-hour format: 0 to 23)
# Index [4] is the Minute (0 to 59)
# Index [5] is the Second (0 to 59)
current_hour = now[3]  
current_minute = now[4] 
print("The time is", current_hour, ":", current_minute)

Example using a NeoPixel as an alarm clock

import time
import machine
import neopixel
from WIFI import WIFI

# Connect to Wifi and fetch the current time
networks = (("SCWiFi","wifi1234"),) # Wifi network and password
wifi = WIFI(networks)
ip = wifi.connect()                # Connect to the wifi network
wifi.ntptime()                     # Fetch current time

# Setup the NeoPixel 
led = neopixel.NeoPixel(machine.Pin(48), 1)

while True:
    # Read the clock
    now = time.localtime()
    hour = now[3]
    minute = now[4]

    # Check if it's 14:30 (2:30 PM in 24-hour time)
    if hour == 14 and minute == 30:
        print("Time's up! Flashing the light!")

        # Flash Blue
        led[0] = (0, 0, 255)
        led.write()
        time.sleep(0.5) # Wait half a second

        # Turn Off
        led[0] = (0, 0, 0)
        led.write()
        time.sleep(0.5)        
    else:
        # If it's not the right time, print a status and sleep
        print("Waiting... Current time ->", hour, ":", minute)        
        # Wait 10 seconds before checking the clock again
        time.sleep(10) 

Asking for Information (eg, Dad joke)

import requests # Use 'urequests' if running on ESP32
import json
from WIFI import WIFI

# Connect to Wifi and fetch the current time
networks = (("SCWiFi","wifi1234"),) # Wifi network and password
wifi = WIFI(networks)
ip = wifi.connect()                # Connect to the wifi network
wifi.ntptime()                     # Fetch current time

# Fetch data from a web URL
response = requests.get("https://icanhazdadjoke.com/", headers={"Accept": "application/json"})

# Check if it worked (200 means OK!)
print(response.status_code) 

# Show me the joke
data = ujson.loads(response.text)
print(data["joke"])

Asking for Information (eg, Weather)

import requests # Use 'urequests' if running on ESP32
import json
from WIFI import WIFI

# Connect to Wifi and fetch the current time
networks = (("SCWiFi","wifi1234")) # Wifi network and password
wifi = WIFI(networks)
ip = wifi.connect()                # Connect to the wifi network
wifi.ntptime()                     # Fetch current time

# Documentation is at
# https://data.gov.hk/en-data/dataset/hk-hko-rss-current-weather-report
url = "https://data.weather.gov.hk/weatherAPI/opendata/weather.php?dataType=rhrread&lang=en"
response = requests.get(url, headers={"Accept": "application/json"})


if response.status_code == 200:
    # Extract the info we want from the data returned.
    # To solve this requires studying the documentation from 
    # the API provider (in this case HKO)
    data = json.loads(response.text)
    rainfall = data['rainfall']['data'][6]['max'] # Sha Tin district
    temperature = data['temperature']['data'][6]['value'] # Sha Tin district
    humidity = data['humidity']['data'][0]['value'] # HK region


    print("Rainfall the past hour: ",rainfall,"mm")
    print("Current temperature: ",temperature,"°C")
    print("Humidity: ",humidity,"%")

Send a message via ntfy

import requests # use urequests for micropython

requests.post("https://ntfy.sh/your-channel-id", data="This is your message")

WIFI.py

import machine
import network
import utime
import ntptime
import ubinascii

class WIFI:
    def __init__(self, networks):
        self._networks = networks

    def scan(self, max_attempts=5):
        # Scan and prioritize visible networks
        all_networks = []
        print("[WIFI.scan] Scanning all SSID within range")
        for i in range(max_attempts):
            scan = self._wifi.scan()
            if scan:
                all_networks.extend(scan)
            utime.sleep(0.2)
        print(f"[WIFI.scan] Found {len(all_networks)} networks")
        return all_networks

    def connect(self):
        print("[WIFI.connect] Activating")
        self._wifi = network.WLAN(network.STA_IF)
        while not self._wifi.active():
            self._wifi.active(True)
            utime.sleep(0.1)
        # scan() returns (ssid, bssid, channel, RSSI, security, hidden)
        all_networks = self.scan()
        available = {ssid.decode('utf-8'): RSSI for ssid, bssid, channel, RSSI, security, hidden in all_networks}
        for ssid, password in self._networks:
            if ssid in available:
                print(f"[WIFI.connect] Found {ssid} (signal: {available[ssid]} dBm)")
                self._wifi.connect(ssid, password)
                for _ in range(10):  # 5-second timeout
                    if self._wifi.isconnected():
                        print(f"[WIFI.connect] Connected to {ssid}")
                        self._ip = self._wifi.ifconfig()[0]
                        self._ssid = ssid
                        self._password = password
                        return self._wifi.ifconfig()[0]
                    utime.sleep(0.5)
                print(f"[WIFI.connect] Failed to connect to {ssid}")
                self._wifi.disconnect()
        print("[WIFI.connect] No available networks - using offline mode")
        return False

    def reconnect(self):
        print("[WIFI.reconnect]")
        while not self._wifi.active():
            self._wifi.active(True)
            utime.sleep(0.1)
        if hasattr(self, '_ssid') and hasattr(self, '_password'):
            self._wifi.connect(self._ssid, self._password)
            for _ in range(10):  # 5-second timeout
                if self._wifi.isconnected():
                    print(f"[WIFI.reconnect] Connected to {self._ssid}")
                    self._ip = self._wifi.ifconfig()[0]
                    return self._wifi.ifconfig()[0]
                utime.sleep(0.5)
            print(f"[WIFI.reconnect] Failed to connect to {self._ssid}")
        # Fallback, perhaps we have changed location and need to switch networks
        print("[WIFI.reconnect] Handballing to connect()")
        return self.connect()

    def ntptime(self, timezone_offset=8, max_attempts=5):
        """Sync time via NTP and update RTC with timezone adjustment"""
        # Check WiFi connection state
        if not self._wifi.isconnected():
            print("[WIFI.ntptime] WiFi not connected")
            return False
        ip = self._wifi.ifconfig()[0]
        if ip == '0.0.0.0':
            print("[WIFI.ntptime] No valid IP address")
            return False
        # Try NTP sync
        for attempt in range(1, max_attempts+1):
            try:
                print(f"[WIFI.ntptime] attempt {attempt}/{max_attempts} to {ntptime.host}")
                ntptime.settime()
                break
            except Exception as e:
                print(f"[WIFI.ntptime] attempt {attempt}/{max_attempts} failed: {e}")
                if attempt == max_attempts:
                    return False
            utime.sleep(1)
        # Apply timezone and update RTC
        epoch = utime.time() + (timezone_offset * 3600)
        year, month, day, hour, min, sec, weekday, _ = utime.localtime(epoch)
        machine.RTC().datetime((
            year, month, day,
            (weekday + 1) % 7,  # RTC weekday (Sunday=0)
            hour, min, sec, 0
        ))
        print(f"[WIFI.ntptime] Time: {year:04}-{month:02}-{day:02} {hour:02}:{min:02}:{sec:02} UTC+{timezone_offset}")
        return True

    def _mac_to_str(self, mac_bytes):
        return ":".join("{:02X}".format(b) for b in mac_bytes)

    def status(self):
        print("[WIFI.status]")
        print("WiFi active:", self._wifi.active())  # Should be True
        print("WiFi channel:", self._wifi.config("channel"))  # Should show a number (1-14)
        print("ifconfig:", self._wifi.ifconfig())
        mac_bytes = self._wifi.config('mac')
        mac_address = ubinascii.hexlify(mac_bytes, ':').decode()
        print(f"MAC Address: {mac_address}")
        print(f"IP address: ",self._wifi.ifconfig()[0])