# Author: Pascual Alarcon Cortijo
# Date: August 2023
import max7219
import machine
import time
import network
import socket
import json
'''
We configure the WiFi connection.
Arguments:
- ssid
- password
'''
def connect_to_wifi(ssid, password):
print('Connecting to WiFi...')
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect(ssid, password)
while not wlan.isconnected():
print('Waiting for connection...')
time.sleep(1)
print(wlan.isconnected(), '--> Connected!')
print(wlan.ifconfig())
'''
We get the data from the 'server' through
a HTTP request using socket library.
Arguments:
- None
'''
def get_net_data():
request = b'GET /bin/api.pl?lat=51.78&lon=19.45&product=civillight&output=json HTTP/1.1\r\nHost: www.7timer.info\r\nUser-Agent: MicroPython\r\nAccept: application/json\r\n\r\n'
BUFFER_SIZE = 512 # I need more buffer size
addr = socket.getaddrinfo('www.7timer.info',80)[0][-1]
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(addr)
s.send(request)
full_recv_data = b''
while True:
chunk = s.recv(BUFFER_SIZE)
if chunk == b'0\r\n\r\n':
break
else:
full_recv_data += chunk
s.close()
full_recv_data = full_recv_data.decode('utf-8')
end_of_headers = full_recv_data.find('\r\n\r\n') + 5 # The five is necessary
if end_of_headers != -1:
data = full_recv_data[end_of_headers + 4:]
else:
data = full_recv_data
# print('This is the data:', data)
data = json.loads(data)
data = data['dataseries']
print('Data succesfully obtained!')
return data
'''
We configure the leds in order to get them working.
Arguments:
- None
'''
def configure_leds():
pin = [8, 9, 10, 11, 12, 13, 14, 15]
led = []
for i in range(8):
led.append(None)
led[i] = machine.Pin(pin[i], machine.Pin.OUT)
return led
'''
We get the temperature of a specific day.
Arguments:
- day: The day we want info from.
- weather_info: Data obtained from get_net_data().
'''
def get_forecast_for_day(weather_info, day):
weather_date = str((weather_info[day])['date'])
weather_temp = (weather_info[day])['temp2m']
weather_sky = (weather_info[day])['weather']
year = weather_date[:4]
month = weather_date[4:6]
day = weather_date[6:8]
weather_date = day+'-'+month+'-'+year
return weather_sky, weather_date, weather_temp['max'], weather_temp['min']
def get_sky_status(sky_weather):
sky_status = {
'clear': ['Sunny', 0], # Yellow -
'pcloudy': ['Partially cloudy', 1], # Orange -
'mcloudy': ['Medium cloudy', 1], # Orange -
'cloudy': ['Cloudy', 2], # Dark orange -
'humid': ['Humid', 3], # Purple -
'lightrain': ['Light rain', 4], # Light blue -
'oshower': ['Heavy shower', 5], # Blue -
'ishower': ['Light shower', 5], # Blue -
'lightsnow': ['Light snow', 7], # White -
'rain': ['Rain', 6], # Dark blue
'snow': ['Snow', 7], # White -
'rainsnow': ['Rain now!', 6], # Dark blue
}
return (sky_status[sky_weather])[0], (sky_status[sky_weather])[1]
'''
We light the specific led.
Arguments:
- led: The list of leds
- light: The specific led we want to light.
'''
def light_led(led, light):
led[light].toggle()
time.sleep(2)
led[light].toggle()
'''
We configure the displays (max7219).
Arguments:
- sck: clock for SPI protocol.
- mosi: Master output slave input.
- cs: Chip select.
- width: Of the display.
- length: Of the display.
'''
def configure_display(sck, mosi, cs, width, length):
spi = machine.SPI(0, baudrate=10000000, sck=machine.Pin(sck), mosi=machine.Pin(mosi))
display = max7219.Max7219(width, length, spi, machine.Pin(cs), False)
display.marquee('OK')
return display
'''
Function for scrolling info through the display.
Arguments:
- display: The actual display in which we want to scroll info.
- text: Info we want to display.
'''
def display_scroll_text(display, text):
display.marquee(text)
'''
Function for showing info through the display.
Arguments:
- display: The actual display in which we want to show info.
- text: Info we want to display.
'''
def display_show_text(display, text, pos1=0, pos2=0):
display.text(text, pos1, pos2)
display.show()
time.sleep(1)
'''
Function for selecting the days.
Arguments:
- day: The actual day.
'''
def button_weather(day):
while True:
if yAxis.read_u16()==0:
if day>=6:
day = 6
break
else:
day += 1
break
if yAxis.read_u16()==65535:
if day<=0:
day = 0
break
else:
day -= 1
break
if button.value()==0:
break
return day
'''
Main program
'''
# We configure both displays, the joystick and the leds.
display1 = configure_display(18, 19, 17, 32, 8)
display2 = configure_display(2, 3, 5, 32, 8)
xAxis = machine.ADC(machine.Pin(27))
yAxis = machine.ADC(machine.Pin(26))
button = machine.Pin(16, machine.Pin.IN, machine.Pin.PULL_UP)
leds = configure_leds()
# We connect to WiFi.
connect_to_wifi('Wokwi-GUEST', '')
# We get the data.
forecast_data = get_net_data()
### While loop that will manage our program.
# Actual day is equal to zero.
i = 0 # Select between 0 and 6.
while True:
day = button_weather(i) # We check if we want to see previous, next or actual day.
i = day # We upload i variable to save the day we are on.
#Getting and displaying temperature info.
weather, date, max_temp, min_temp = get_forecast_for_day(forecast_data, day)
word, light = get_sky_status(weather)
# Displaying the information
# Date:
display_scroll_text(display2, 'Date:'+date)
# Maximum temperature:
display_scroll_text(display1, 'Maximum temperature:')
display_show_text(display1, str(max_temp)+' C')
# Minimum temperature:
display_scroll_text(display1, 'Minimum temperature:')
display_show_text(display1, str(min_temp)+' C')
display_scroll_text(display1, '')
# Sky status:
display_scroll_text(display2, word)
light_led(leds, light)