# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries # # SPDX-License-Identifier: MIT import os import time import ipaddress import wifi import socketpool import busio import board import microcontroller import displayio import terminalio from adafruit_display_text import label import adafruit_displayio_ssd1306 import adafruit_imageload from digitalio import DigitalInOut, Direction from adafruit_httpserver import Server, Request, Response, POST from adafruit_onewire.bus import OneWireBus from adafruit_ds18x20 import DS18X20 # onboard LED setup led = DigitalInOut(board.LED) led.direction = Direction.OUTPUT led.value = False # pin used for party parrot animation parrot_pin = DigitalInOut(board.GP10) parrot_pin.direction = Direction.OUTPUT parrot_pin.value = False # one-wire bus for DS18B20 ow_bus = OneWireBus(board.GP6) # scan for temp sensor ds18 = DS18X20(ow_bus, ow_bus.scan()[0]) # function to convert celcius to fahrenheit def c_to_f(temp): temp_f = (temp * 9/5) + 32 return temp_f # i2c display setup displayio.release_displays() oled_reset = board.GP9 # STEMMA I2C on picowbell i2c = busio.I2C(board.GP5, board.GP4) display_bus = displayio.I2CDisplay(i2c, device_address=0x3D, reset=oled_reset) WIDTH = 128 HEIGHT = 64 offset_y = 5 display = adafruit_displayio_ssd1306.SSD1306(display_bus, width=WIDTH, height=HEIGHT) # default display group splash = displayio.Group() display.show(splash) # connect to network print() print("Connecting to WiFi") connect_text = "Connecting..." connect_text_area = label.Label( terminalio.FONT, text=connect_text, color=0xFFFFFF, x=0, y=offset_y ) splash.append(connect_text_area) # set static IP address ipv4 = ipaddress.IPv4Address("192.168.1.42") netmask = ipaddress.IPv4Address("255.255.255.0") gateway = ipaddress.IPv4Address("192.168.1.1") wifi.radio.set_ipv4_address(ipv4=ipv4,netmask=netmask,gateway=gateway) # connect to your SSID wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD')) print("Connected to WiFi") pool = socketpool.SocketPool(wifi.radio) server = Server(pool, "/static", debug=True) # variables for HTML # comment/uncomment desired temp unit # temp_test = str(ds18.temperature) # unit = "C" temp_test = c_to_f(ds18.temperature) unit = "F" # font for HTML font_family = "monospace" # the HTML script # setup as an f string # this way, can insert string variables from code.py directly # of note, use {{ and }} if something from html *actually* needs to be in brackets # i.e. CSS style formatting def webpage(): html = f""" Pico W HTTP Server

Pico W HTTP Server


This is a Pico W running an HTTP server with CircuitPython.


The current ambient temperature near the Pico W is {temp_test:.2f}°{unit}


Control the LED on the Pico W with these buttons:


Party?

""" return html # route default static IP @server.route("/") def base(request: Request): # pylint: disable=unused-argument # serve the HTML f string # with content type text/html return Response(request, f"{webpage()}", content_type='text/html') # if a button is pressed on the site @server.route("/", POST) def buttonpress(request: Request): # get the raw text raw_text = request.raw_request.decode("utf8") print(raw_text) # if the led on button was pressed if "ON" in raw_text: # turn on the onboard LED led.value = True # if the led off button was pressed if "OFF" in raw_text: # turn the onboard LED off led.value = False # if the party button was pressed if "party" in raw_text: # toggle the parrot_pin value parrot_pin.value = not parrot_pin.value # reload site return Response(request, f"{webpage()}", content_type='text/html') print("starting server..") # startup the server try: server.start(str(wifi.radio.ipv4_address)) print("Listening on http://%s:80" % wifi.radio.ipv4_address) # if the server fails to begin, restart the pico w except OSError: time.sleep(5) print("restarting..") microcontroller.reset() ping_address = ipaddress.ip_address("8.8.4.4") # text objects for screen # connected to SSID text connect_text_area.text = "Connected to:" ssid_text = f"{os.getenv('CIRCUITPY_WIFI_SSID')}" ssid_text_area = label.Label( terminalio.FONT, text=ssid_text, color=0xFFFFFF, x=0, y=offset_y+15 ) splash.append(ssid_text_area) # display ip address ip_text = f"IP: {wifi.radio.ipv4_address}" ip_text_area = label.Label( terminalio.FONT, text=ip_text, color=0xFFFFFF, x=0, y=offset_y+30 ) splash.append(ip_text_area) # display temp reading temp_text = f"Temperature: {temp_test:.2f} F" temp_text_area = label.Label( terminalio.FONT, text=temp_text, color=0xFFFFFF, x=0, y=offset_y+45 ) splash.append(temp_text_area) # party parrot display group parrot_group = displayio.Group() # load in party parrot bitmap parrot_bit, parrot_pal = adafruit_imageload.load("/partyParrots64.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette) parrot_grid = displayio.TileGrid(parrot_bit, pixel_shader=parrot_pal, width=1, height=1, tile_height=64, tile_width=64, default_tile=1, x=32, y=0) parrot_group.append(parrot_grid) clock = time.monotonic() # time.monotonic() holder for server ping parrot = False # parrot state party = 0 # time.monotonic() holder for party parrot p = 0 # index for tilegrid while True: try: # every 30 seconds, ping server & update temp reading if (clock + 30) < time.monotonic(): if wifi.radio.ping(ping_address) is None: connect_text_area.text = "Disconnected!" ssid_text_area.text = None print("lost connection") else: connect_text_area.text = "Connected to:" ssid_text_area.text = f"{os.getenv('CIRCUITPY_WIFI_SSID')}" print("connected") clock = time.monotonic() # comment/uncomment for desired units # temp_test = ds18.temperature temp_test = c_to_f(ds18.temperature) temp_text_area.text = f"Temperature: {temp_test:.2f} F" #if parrot is True: if parrot_pin.value is True: # switch to party parrot display group display.show(parrot_group) if (party + 0.1) < time.monotonic(): # the party parrot animation cycles parrot_grid[0] = p # p is the tilegrid index location p = (p + 1) % 10 party = time.monotonic() # if it isn't a party else: # show default display with info display.show(splash) # poll the server for incoming/outgoing requests server.poll() # pylint: disable=broad-except except Exception as e: print(e) continue