Posts: 33
Threads: 7
Joined: Oct 2020
New guy here still struggling with time issues.
I'm trying to write a python3 program for my Raspberry PI 3 model B+ that will turn on a LED light every quarter of an hour for a minute and the brightness of the LED will be brighter between dawn and dusk (daylight hours).
With help from this forum, I have this program that tells me sunrise and sunset times in my time zone, but, I can't figure out how to compare current time to sunrise and sunset.
Running during the day should result in LED = 255.
Checking for quarter hour seems to work.
Please look over my code and tell me what I'm assuming or doing wrong.
""" Turn on LED every quarter hour where LED brightness is brighter between sunrise and sunset
"""
import requests
from datetime import datetime,timedelta
from zoneinfo import ZoneInfo
from array import *
latitude = 28.262222
longitude = -96.747165
target_timezone = "America/Chicago"
timezone_offset = ZoneInfo(target_timezone).utcoffset(datetime.now())
quarter_hour = array ('d',[00,15,30,45])
day_brightnes = 255
night_brightnes = 125
url = "https://api.sunrise-sunset.org/json"
params = {
"lat": latitude,
"lng": longitude,
"formatted": 0,
"date": "today",
}
input_format = "%Y-%m-%dT%H:%M:%S+00:00"
output_format = "%H:%M:%S"
resp_json = requests.get(url, params=params).json()
sunrise_date_time = resp_json["results"]["sunrise"]
sunset_date_time = resp_json["results"]["sunset"]
LED = night_brightnes
if (sunrise_date_time < str(datetime.now()) < sunset_date_time):
LED = day_brightnes
print(f"LED brightness is {LED}")
print(f"Current time is {datetime.now()} local")
date_time = datetime.now()
time = date_time.time()
min = int(time.minute)
print(f"Current minute is {min} local")
if min in quarter_hour:
print(f"It is a quarter hour {min} local") Output: >>> %Run check_quarter_hour.py
LED brightness is 125
Current time is 2022-02-08 10:13:54.216009 local
Current minute is 13 local
>>>
Posts: 1,145
Threads: 114
Joined: Sep 2019
Could you not check the hour in the time. If the hour is between 6 and 17 (17 is 5:00 PM) led brightness is 255 else night brightness?
Posts: 33
Threads: 7
Joined: Oct 2020
My desire it to be more accurate than just between 7:00 to 18:00 because sunset around here in the summer is after 21:00 hours DST but only 17:00 hours non DST in the winter.
It is a computer and can be very accurate (providing it is programmed correct).
Posts: 1,145
Threads: 114
Joined: Sep 2019
Feb-08-2022, 06:45 PM
(This post was last modified: Feb-08-2022, 06:45 PM by menator01.
Edit Reason: Updated code / Added comments
)
Maybe this example will help. Using tkinter, getting sunrise and sunset from sunrise-sunset.org. I hard coded sunset to test. Using the sunset from the site should have the same effect. From sunrise to sunset the background is yellow. From sunset to sunrise the background is navy. The clock will change color every 15 minutes for one minute then change back to default.
import tkinter as tk
import json, requests
from datetime import datetime, timedelta
from time import strftime
class Window:
def __init__(self, parent):
# Get location - lat and long
location = json.loads(requests.get('http://ipinfo.io/json').text)['loc']
lat, lon = location.split(',')
# Get sunrise/sunset and format
sunurl = 'https://api.sunrise-sunset.org/json'
params = {'lat': lat, 'lon': lon, 'formatted': 0, 'date': 'today'}
input_format = '%Y-%m-%dT%H:%M:%S+00:00'
output_format = '%H:%M:%S'
sunpage = requests.get(sunurl, params).json()
self.sunrise = sunpage['results']['sunrise']
self.sunrise = datetime.strptime(self.sunrise, input_format)
self.sunrise = self.sunrise + timedelta()
self.sunrise = self.sunrise.strftime(output_format)
self.sunset = sunpage['results']['sunset']
self.sunset = datetime.strptime(self.sunset, input_format)
self.sunset = self.sunset + timedelta()
self.sunset = self.sunset.strftime(output_format)
# Helps with grid layout stretching
parent.columnconfigure(0, weight=1)
parent.columnconfigure(1, weight=1)
# Create text label to display header
time_label = tk.Label(parent, text='Current Local Time: ')
time_label['relief'] = 'ridge'
time_label.grid(column=0, row=0, sticky='new')
# Create text label for displaying clock
self.time_label = tk.Label(parent)
self.time_label['relief'] = 'ridge'
self.time_label.grid(column=1, row=0, sticky='new')
# Create label that will span two columns for displaying a color background
self.color_label = tk.Label(parent, width=5)
self.color_label['relief'] = 'ridge'
self.color_label.grid(column=0, columnspan=2, row=1, sticky='news')
# Call the update function
self.update()
# Define the update function
def update(self):
# Updates the clock display every one second
self.time_label['text'] = strftime('%H:%M:%S')
self.time_label.after(1000, self.update)
# Create a list of the minutes we want to check. This case every 15 minutes
quarters = ['00', '15', '30', '45']
# Loop through the list and checking it against the current time minute
# If the current minute is in the minutes list change background and foreground colors
# of the clock. Colors change back to default after one minute
for quarter in quarters:
if quarter in self.time_label['text'][3:5]:
self.time_label['fg'] = 'lime'
self.time_label['bg'] = 'darkgreen'
else:
self.time_label['fg'] = 'black'
self.time_label['bg'] = 'gray96'
# Check the current time label against the sunrise and sunset time from
# sunrise-sunset.org If the time is between sunrise and sunset, the background color is yellow.
# If the time is between sunset and sunrise, the background color is navy.
if self.time_label['text'] >= self.sunrise and self.time_label['text'] <= self.sunset:
self.color_label['bg'] = 'yellow'
else:
self.color_label['bg'] = 'navy'
def main():
root = tk.Tk()
root['padx'] = 10
root['pady'] = 6
Window(root)
root.mainloop()
if __name__ == '__main__':
main()
Posts: 1,145
Threads: 114
Joined: Sep 2019
Feb-08-2022, 07:10 PM
(This post was last modified: Feb-08-2022, 07:39 PM by menator01.)
While testing the code, when the minutes reached 00, the colors did not change. Adding 01 to the quarters list colors changed as minutes changed to 01.
Update: to get the 00 to work, I converted the quarters list and the self.time_label[3:5] to int
Posts: 33
Threads: 7
Joined: Oct 2020
Thanks a bunch menator01.
With your suggestion, I was able to get my code to work.
I'm betting there are more slick and eloquent ways to do this, but, this is such a small program and the only one I plan on running on the RPi.
I'll run another test tonight after sunset to double check but I'm pretty confident it will work.
""" Turn on LED every quarter hour where LED brightness is brighter between sunrise and sunset
"""
import requests
from datetime import datetime,timedelta
from zoneinfo import ZoneInfo
from array import *
latitude = 28.262222
longitude = -96.747165
target_timezone = "America/Chicago"
timezone_offset = ZoneInfo(target_timezone).utcoffset(datetime.now())
quarter_hour = array ('d',[00,15,30,45])
day_brightnes = 255
night_brightnes = 125
url = "https://api.sunrise-sunset.org/json"
params = {
"lat": latitude,
"lng": longitude,
"formatted": 0,
"date": "today",
}
input_format = "%Y-%m-%dT%H:%M:%S+00:00"
output_format = "%H:%M:%S"
resp_json = requests.get(url, params=params).json()
sunrise_date_time = resp_json["results"]["sunrise"]
sunset_date_time = resp_json["results"]["sunset"]
sunrise = datetime.strptime(sunrise_date_time, input_format)
local_sunrise = sunrise + timezone_offset
sunrise = local_sunrise.strftime(output_format)
sunset = datetime.strptime(sunset_date_time, input_format)
local_sunset = sunset + timezone_offset
sunset = local_sunset.strftime(output_format)
local_datetime = datetime.now()
local_time = local_datetime.strftime(output_format)
print(sunrise, " ", local_time, " ", sunset)
LED = night_brightnes
if (sunrise < local_time < sunset):
LED = day_brightnes
print(f"LED brightness is {LED}")
print(f"Current time is {datetime.now()} local")
date_time = datetime.now()
time = date_time.time()
min = int(time.minute)
print(f"Current minute is {min} local")
if min in quarter_hour:
print(f"It is a quarter hour {min} local") Output: >>> %Run check_quarter_hour.py
07:08:37 13:15:05 18:13:40
LED brightness is 255
Current time is 2022-02-08 13:15:05.893387 local
Current minute is 15 local
It is a quarter hour 15 local
>>>
Posts: 1,145
Threads: 114
Joined: Sep 2019
Glad I could help. Posting changed code I have in case it may help someone else.
import tkinter as tk
import json, requests
from datetime import datetime, timedelta
from time import strftime
class Window:
def __init__(self, parent):
# Get location - lat and long
location = json.loads(requests.get('http://ipinfo.io/json').text)['loc']
lat, lon = location.split(',')
# Get sunrise/sunset and format
sunurl = 'https://api.sunrise-sunset.org/json'
params = {'lat': lat, 'lon': lon, 'formatted': 0, 'date': 'today'}
input_format = '%Y-%m-%dT%H:%M:%S+00:00'
output_format = '%H:%M:%S'
sunpage = requests.get(sunurl, params).json()
self.sunrise = sunpage['results']['sunrise']
self.sunrise = datetime.strptime(self.sunrise, input_format)
self.sunrise = self.sunrise + timedelta()
self.sunrise = self.sunrise.strftime(output_format)
self.sunset = sunpage['results']['sunset']
self.sunset = datetime.strptime(self.sunset, input_format)
self.sunset = self.sunset + timedelta()
self.sunset = self.sunset.strftime(output_format)
# Helps with grid layout stretching
parent.columnconfigure(0, weight=1)
parent.columnconfigure(1, weight=1)
# Create text label to display header
time_label = tk.Label(parent, text='Current Local Time: ')
time_label['relief'] = 'ridge'
time_label.grid(column=0, row=0, sticky='new')
# Create text label for displaying clock
self.time_label = tk.Label(parent)
self.time_label['relief'] = 'ridge'
self.time_label.grid(column=1, row=0, sticky='new')
# Create label that will span two columns for displaying a color background
self.color_label = tk.Label(parent, width=5)
self.color_label['relief'] = 'ridge'
self.color_label.grid(column=0, columnspan=2, row=1, sticky='news')
# Call the update function
self.update()
# Define the update function
def update(self):
# Updates the clock display every one second
self.time_label['text'] = strftime('%H:%M:%S')
self.time_label.after(1000, self.update)
# Create a list of the minutes we want to check. This case every 15 minutes
quarters = [00, 15, 30, 45]
# Loop through the list and checking it against the current time minute
# If the current minute is in the minutes list change background and foreground colors
# of the clock. Colors change back to default after one minute
minute = int(self.time_label['text'][3:5])
if minute in quarters:
self.time_label['fg'] = 'lime'
self.time_label['bg'] = 'darkgreen'
else:
self.time_label['fg'] = 'black'
self.time_label['bg'] = 'gray96'
# Check the current time label against the sunrise and sunset time from
# sunrise-sunset.org If the time is between sunrise and sunset, the background color is yellow.
# If the time is between sunset and sunrise, the background color is navy.
if self.time_label['text'] >= self.sunrise and self.time_label['text'] <= self.sunset:
self.color_label['bg'] = 'yellow'
else:
self.color_label['bg'] = 'navy'
def main():
root = tk.Tk()
root['padx'] = 10
root['pady'] = 6
Window(root)
root.mainloop()
if __name__ == '__main__':
main()
Posts: 582
Threads: 1
Joined: Aug 2019
Hi @ menator01 , great code, thank you. I immediately used parts of it, I hope you don't mind  .
But to my surprise the sunrise and sunset times were not correct. I found the reason why: you use parameter "lon" for the longitude, but it should be "lng".
params = {'lat': lat, 'lon': lon, 'formatted': 0, 'date': 'today'}
# should be:
params = {'lat': lat, 'lng': lon, 'formatted': 0, 'date': 'today'}
Posts: 1,145
Threads: 114
Joined: Sep 2019
(Feb-09-2022, 11:41 AM)ibreeden Wrote: Hi @menator01 , great code, thank you. I immediately used parts of it, I hope you don't mind .
But to my surprise the sunrise and sunset times were not correct. I found the reason why: you use parameter "lon" for the longitude, but it should be "lng".
params = {'lat': lat, 'lon': lon, 'formatted': 0, 'date': 'today'}
# should be:
params = {'lat': lat, 'lng': lon, 'formatted': 0, 'date': 'today'}
Although I can't seem to find it now but, somewhere in their docs. lon is what they are using for the param. That's why I used it. lng will not return the right results.
Posts: 6,800
Threads: 20
Joined: Feb 2020
Their API says it is lng.
https://sunrise-sunset.org/api
Quote:API documentation
Ours is a very simple REST api, you only have to do a GET request to https://api.sunrise-sunset.org/json.
Parameters
lat (float): Latitude in decimal degrees. Required.
lng (float): Longitude in decimal degrees. Required.
date (string): Date in YYYY-MM-DD format. Also accepts other date formats and even relative date formats. If not present, date defaults to current date. Optional.
callback (string): Callback function name for JSONP response. Optional.
formatted (integer): 0 or 1 (1 is default). Time values in response will be expressed following ISO 8601 and day_length will be expressed in seconds. Optional.
|