Skip to content

Commit 36cc5f4

Browse files
authored
Merge pull request #2427 from adafruit/star_fragment
adding code for star fragment lamp
2 parents 74cd746 + f814923 commit 36cc5f4

File tree

1 file changed

+218
-0
lines changed

1 file changed

+218
-0
lines changed

Star_Fragment_Lamp/code.py

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
# SPDX-FileCopyrightText: 2023 Liz Clark for Adafruit Industries
2+
# SPDX-License-Identifier: MIT
3+
4+
import os
5+
import ssl
6+
import time
7+
import board
8+
import wifi
9+
import socketpool
10+
import adafruit_requests
11+
import neopixel
12+
import simpleio
13+
from adafruit_ticks import ticks_ms, ticks_add, ticks_diff
14+
from adafruit_io.adafruit_io import IO_HTTP
15+
16+
# latitude
17+
lat = 42.36
18+
# longitude
19+
long = -71.06
20+
21+
# API request to open-meteo
22+
weather_url = "https://api.open-meteo.com/v1/forecast?"
23+
# pass latitude and longitude
24+
# will return sunrise and sunset times
25+
weather_url += "latitude=%d&longitude=%d&timezone=auto&daily=sunrise,sunset" % (lat, long)
26+
27+
# connect to SSID
28+
wifi.radio.connect(os.getenv('CIRCUITPY_WIFI_SSID'), os.getenv('CIRCUITPY_WIFI_PASSWORD'))
29+
30+
pool = socketpool.SocketPool(wifi.radio)
31+
requests = adafruit_requests.Session(pool, ssl.create_default_context())
32+
33+
pool = socketpool.SocketPool(wifi.radio)
34+
35+
# adafruit IO info
36+
aio_username = os.getenv('aio_username')
37+
aio_key = os.getenv('aio_key')
38+
location = "America/New York"
39+
40+
# io HTTP for getting the time from the internet
41+
io = IO_HTTP(aio_username, aio_key, requests)
42+
43+
# function for making http requests with try/except
44+
def get_request(num_tries, ping):
45+
tries = num_tries
46+
for i in range(tries):
47+
try:
48+
n = ping
49+
# print(now)
50+
except RuntimeError as e:
51+
print(e)
52+
time.sleep(2)
53+
if i < tries - 1: # i is zero indexed
54+
continue
55+
raise
56+
break
57+
return n
58+
59+
# get the time on start-up
60+
now = get_request(5, io.receive_time())
61+
print(now)
62+
today = now.tm_mday
63+
64+
# function to make a request to open-meteo
65+
def sun_clock():
66+
# make the API request
67+
response = get_request(5, requests.get(weather_url))
68+
# packs the response into a JSON
69+
response_as_json = response.json()
70+
# gets sunrise
71+
_rise = response_as_json['daily']['sunrise'][0]
72+
# gets sunset
73+
_set = response_as_json['daily']['sunset'][0]
74+
return _rise, _set
75+
76+
# initial API call
77+
sunrise, sunset = sun_clock()
78+
79+
# the sunrise/sunset time is returned as a JSON aka a string
80+
# this function chops up the string to get the hours and minutes as integers
81+
def divide_time(z):
82+
string_time = z.split("-")
83+
clock_time = string_time[2].split("T")
84+
int_time = clock_time[1].split(":")
85+
return int(int_time[0]), int(int_time[1])
86+
87+
rise_hour, rise_minute= divide_time(sunrise)
88+
set_hour, set_minute = divide_time(sunset)
89+
90+
# function that tracks how many hours/minutes until sunrise or sunset
91+
def sun_countdown(sun_hour, sun_minute):
92+
hours_until = sun_hour - now.tm_hour
93+
minutes_until = sun_minute - now.tm_min
94+
return hours_until, minutes_until
95+
96+
hours_until_sunset, mins_until_sunset = sun_countdown(set_hour, set_minute)
97+
hours_until_sunrise, mins_until_sunrise = sun_countdown(rise_hour, set_minute)
98+
99+
# red and yellow color percentage for neopixels
100+
percent_red = 0
101+
percent_yellow = 0
102+
103+
# neopixel setup
104+
NUMPIXELS = 30 # number of neopixels
105+
BRIGHTNESS = 0.05 # A number between 0.0 and 1.0, where 0.0 is off, and 1.0 is max.
106+
PIN = board.A3 # This is the default pin on the NeoPixel Driver BFF.
107+
108+
pixels = neopixel.NeoPixel(PIN, NUMPIXELS, brightness=BRIGHTNESS, auto_write=False)
109+
110+
# check to see if the star fragment should be lit up on start-up
111+
if hours_until_sunset < 0:
112+
star_glow = True
113+
else:
114+
star_glow = False
115+
116+
# ticks time tracker
117+
clock = ticks_ms()
118+
119+
# tracker for initial start-up state
120+
first_run = True
121+
122+
# 15 minutes in milliseconds
123+
time_check = 900000
124+
# state to tell if it's after midnight yet before sunrise
125+
looking_for_sunrise = False
126+
127+
while True:
128+
# if it's daytime
129+
if not star_glow:
130+
# every 15 minutes...
131+
if first_run or ticks_diff(ticks_ms(), clock) > time_check:
132+
first_run = False
133+
# get the time from IO
134+
now = get_request(5, io.receive_time())
135+
print(now)
136+
print("pinging Open-Meteo")
137+
sunrise, sunset = sun_clock()
138+
hours_until_sunset, mins_until_sunset = sun_countdown(set_hour, set_minute)
139+
print("%d hour(s) until sunset" % hours_until_sunset)
140+
print("%d minutes(s) until sunset" % mins_until_sunset)
141+
print(sunset)
142+
print()
143+
# less than an hour until sunset...
144+
if hours_until_sunset == 0:
145+
# check every minute
146+
time_check = 60000
147+
# map color to ramp up in brightness over the course of the final hour
148+
percent_red = simpleio.map_range(mins_until_sunset, 59, 0, 0, 255)
149+
percent_yellow = simpleio.map_range(mins_until_sunset, 59, 0, 0, 125)
150+
# if the sun has set..
151+
if mins_until_sunset < 1:
152+
percent_red = 255
153+
percent_yellow = 125
154+
time_check = 900000
155+
star_glow = True
156+
print("star is glowing")
157+
# otherwise just keep checking every 15 minutes
158+
else:
159+
time_check = 900000
160+
percent_red = 0
161+
percent_yellow = 0
162+
# reset clock
163+
clock = ticks_add(clock, time_check)
164+
# if it's nighttime...
165+
else:
166+
if first_run or ticks_diff(ticks_ms(), clock) > time_check:
167+
now = get_request(5, io.receive_time())
168+
# check to see if it's past midnight by seeing if the date has changed
169+
# includes some logic if you are starting up the project in the very early morning hours
170+
if today != now.tm_mday or (first_run and now.tm_hour < rise_hour):
171+
today = now.tm_mday
172+
looking_for_sunrise = True
173+
# begin tracking the incoming sunrise
174+
if looking_for_sunrise:
175+
print("pinging Open-Meteo")
176+
sunrise, sunset = sun_clock()
177+
hours_until_sunrise, mins_until_sunrise = sun_countdown(rise_hour, rise_minute)
178+
print("%d hour(s) until sunrise" % hours_until_sunrise)
179+
print("%d minutes(s) until sunrise" % mins_until_sunrise)
180+
print(sunrise)
181+
print(now)
182+
print()
183+
# less than an hour until sunset...
184+
if hours_until_sunrise == 0:
185+
# check every minute
186+
time_check = 60000
187+
# map color to decrease brightness over the course of the final hour
188+
percent_red = simpleio.map_range(mins_until_sunrise, 59, 0, 255, 0)
189+
percent_yellow = simpleio.map_range(mins_until_sunrise, 59, 0, 125, 0)
190+
# if the sun has risen..
191+
if mins_until_sunrise < 1:
192+
percent_red = 0
193+
percent_yellow = 0
194+
time_check = 900000
195+
star_glow = False
196+
looking_for_sunrise = False
197+
print("star is off")
198+
# otherwise just keep checking every 15 minutes
199+
# and keep neopixels on
200+
else:
201+
time_check = 900000
202+
percent_red = 255
203+
percent_yellow = 125
204+
# otherwise just keep checking every 15 minutes
205+
# and keep neopixels on
206+
else:
207+
print("not looking for sunrise")
208+
print(now)
209+
print()
210+
time_check = 900000
211+
percent_red = 255
212+
percent_yellow = 125
213+
first_run = False
214+
# reset clock
215+
clock = ticks_add(clock, time_check)
216+
# turn neopixels on using RGB values
217+
pixels.fill((percent_red, percent_yellow, 0))
218+
pixels.show()

0 commit comments

Comments
 (0)