pull/812/head
Simon Prickett 2023-08-12 13:33:03 +01:00
rodzic 14eabf360f
commit 658025a99b
1 zmienionych plików z 34 dodań i 28 usunięć

Wyświetl plik

@ -1,9 +1,9 @@
'''
carbon_intensity.py
This example is for the Pico W with GFX Pack.
Displays near realtime information about the different types of electricity
generation for a given UK postcode area. Uses the backlight and a bar graph
to show the current mix of generation sources, and updates itself periodically
Displays near realtime information about the different types of electricity
generation for a given UK postcode area. Uses the backlight and a bar graph
to show the current mix of generation sources, and updates itself periodically
or when button E is pressed.
Find out more about the Carbon Intensity API here:
https://carbon-intensity.github.io/api-definitions/#carbon-intensity-api-v2-0-0
@ -13,7 +13,6 @@ from gfx_pack import GfxPack, SWITCH_E
from network_manager import NetworkManager
import WIFI_CONFIG
import json
import time
import uasyncio
import urequests
@ -24,17 +23,19 @@ display = gp.display
# Replace S9 below with the first part of your postcode e.g. OX1, NG7, LS12
CARBON_INTENSITY_URL = "https://api.carbonintensity.org.uk/regional/postcode/S9"
# Time in seconds between automatic updates...
CARBON_INTENSITY_UPDATE_FREQUENCY = 60
CARBON_INTENSITY_UPDATE_FREQUENCY = 60
DISPLAY_WIDTH, DISPLAY_HEIGHT = display.get_bounds()
sys_status = "STATUS"
# Utility function to clear the screen.
def clear_screen():
display.set_pen(0)
display.clear()
display.set_pen(15)
# Utility function to clear a rectangular area of the screen.
# Used to update the progress bar.
def clear_rect(start_x, start_y, end_x, end_y, height):
@ -42,11 +43,13 @@ def clear_rect(start_x, start_y, end_x, end_y, height):
display.line(start_x, start_y, end_x, end_y, height)
display.set_pen(15)
display.update()
# Utility function to set the backlight to a given rgbw colour.
def set_backlight(r, g, b, w):
gp.set_backlight(r, g, b, w)
# Utility function to display text centred on the screen.
def display_centered(text_to_display, y_pos, scale):
width = display.measure_text(text_to_display, scale)
@ -54,33 +57,34 @@ def display_centered(text_to_display, y_pos, scale):
display.text(text_to_display, x_pos, y_pos, DISPLAY_WIDTH, scale)
return x_pos
# Read values from the API and update the display.
def refresh_intensity_display():
BAR_MIN_X = 50
BAR_MAX_X = 120
BAR_HEIGHT = 4
clear_screen()
set_backlight(0, 0, 0, 80)
display_centered("UPDATING...", 25, 2)
display.update()
response_doc = urequests.get(CARBON_INTENSITY_URL).json()
# Get the region name
region_name = response_doc["data"][0]["shortname"]
# Get the intensity index (very low, low, moderate, high, very high)
intensity_index = response_doc["data"][0]["data"][0]["intensity"]["index"]
# Pick out values from the generation mix data...
# We want solar, wind, gas, nuclear, then other is 100% minus the total of those.
solar_pct = 0
wind_pct = 0
nuclear_pct = 0
gas_pct = 0
for g in response_doc["data"][0]["data"][0]["generationmix"]:
if g["fuel"] == "solar":
solar_pct = g["perc"]
@ -90,10 +94,10 @@ def refresh_intensity_display():
gas_pct = g["perc"]
elif g["fuel"] == "nuclear":
nuclear_pct = g["perc"]
# Forms of generation that are not solar, wind, gas, nuclear...
others_pct = 100 - solar_pct - wind_pct - nuclear_pct - gas_pct
# Figure out the bar lengths.
one_percent_length = (BAR_MAX_X - BAR_MIN_X) / 100
solar_width = round(one_percent_length * solar_pct)
@ -101,7 +105,7 @@ def refresh_intensity_display():
nuclear_width = round(one_percent_length * nuclear_pct)
gas_width = round(one_percent_length * gas_pct)
others_width = round(one_percent_length * others_pct)
# Sort so that the longest bar is first.
sorted_generators = sorted([
(solar_width, "SOLAR"),
@ -109,8 +113,8 @@ def refresh_intensity_display():
(nuclear_width, "NUCLEAR"),
(gas_width, "GAS"),
(others_width, "OTHERS")
], reverse = True)
], reverse=True)
clear_screen()
# Set backlight according to carbon intensity...
@ -132,10 +136,11 @@ def refresh_intensity_display():
display.text(g[1], 5, v_pos, DISPLAY_WIDTH, 1)
display.line(BAR_MIN_X, v_pos + 3, BAR_MIN_X + g[0], v_pos + 3, BAR_HEIGHT)
v_pos += 10
display.text("E: Update", 80, 50, DISPLAY_WIDTH, 1)
display.text("E: Update", 80, 50, DISPLAY_WIDTH, 1)
display.update()
# Utility function used when connecting to wifi.
def display_status():
global sys_status
@ -145,6 +150,7 @@ def display_status():
display.text(sys_status, 0, 0, DISPLAY_WIDTH, 1)
display.update()
# Utility function used when connecting to wifi.
def status_handler(mode, status, ip):
global sys_status
@ -159,12 +165,13 @@ def status_handler(mode, status, ip):
else:
print('Wifi connection failed!')
try:
# Attempt to connect to the wifi.
network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler)
uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK))
# Update the display, then count down to the next update drawing a
# Update the display, then count down to the next update drawing a
# countdown bar periodically. Update immediately if button E pressed.
refresh_intensity_display()
@ -175,25 +182,25 @@ try:
while True:
time.sleep(0.01)
if gp.switch_pressed(SWITCH_E):
# Update immediately.
refresh_intensity_display()
last_updated = time.ticks_ms()
bar_width = DISPLAY_WIDTH
ticks_now = time.ticks_ms()
if time.ticks_diff(ticks_now, ticks_before) > BAR_UPDATE_FREQUENCY:
bar_width = bar_width - (DISPLAY_WIDTH // CARBON_INTENSITY_UPDATE_FREQUENCY)
ticks_before = time.ticks_ms()
if time.ticks_diff(ticks_now, last_updated) > CARBON_INTENSITY_UPDATE_FREQUENCY * 1000:
# It is time for a scheduled update.
refresh_intensity_display()
last_updated = time.ticks_ms()
bar_width = DISPLAY_WIDTH
# Update the countdown to next update bar at the bottom
# of the screen.
clear_rect(0, 61, DISPLAY_WIDTH, 61, 2)
@ -202,5 +209,4 @@ try:
except Exception as e:
# Failed to connect to wifi - check credentials in WIFI_CONFIG.py
print(f'Wifi connection failed! {e}')
print(f'Wifi connection failed! {e}')