Hi there,
I am using the Astro binding to show some astro information like moon phases, sunrise and sunset and so on. It bothered me that I only get the sunrise time for the same day (running the binding shortly after midnight gets only the sunrise for the upcoming day). To be able to get the sunrise and sunset time for the next day I have created a python script with great support of @vzorglub (Vincent) who showed me how to leverage the astral
python library to calculate these times for any location and any date.
As I am running OpenHAB in a docker container, I chose to run the python script outside the container on my NAS and pushing the data into my container leveraging the OpenHAB REST-API via curl. If you are able to run a python script within your OpenHAB environment (probably on a raspberry pi) then it looks a little different. I will show you below the python scripts for both of these options to either run the script outside or inside of your OpenHAB instance.
You will need to install some pre-requisites before you can start, which is Python
and pip
and the python astral
library:
-
Installing
Python
depends on your platform hence you have to find out on your own -
To install
pip
I followed this documentation: https://pip.pypa.io/en/stable/installing/ -
Installing
astral
library:# sudo pip install astral
If you intend to calculate other astro events from the astral
library than sunrise and sunset you may want to use this documentation link to find out the appropriate values that the astral
library delivers.
Once you have installed the pre-requisites you may use one of the two versions of the script to calculate the desired values which is in my case the sunrise and sunset time for tomorrow:
1) Python Script for running script outside of OpenHAB instance:
#!/usr/bin/python
import datetime
import astral
import requests
import json
my = astral.Location(info=("YOUR_CITY", "YOUR_COUNTRY", YOUR_LATITUDE, YOUR_LONGITUDE, "YOUR_TIMEZONE", YOUR_METERS_ABOVE_SEA_LEVEL))
my.solar_depression = 'civil'
# the variable 'tomorrow' below defines the time delta from today for which the sunrise and sunset times are calculated
# In my case I have a time delta of 1 day = datetime.timedelta(1) to calculate tomorrows sunrise and sunset times
tomorrow = datetime.date.today() + datetime.timedelta(1)
sun = my.sun(date=tomorrow, local=True)
sunrise_time_tomorrow = str(sun['sunrise'].isoformat())[11:16]
sunset_time_tomorrow = str(sun['sunset'].isoformat())[11:16]
openhab_headers = { 'Content-Type': "text/plain", 'Accept': "application/json" }
sunrise_tomorrow_response = requests.put('http://YOUR_OPENHAB_IP:YOUR_OPENHAB_PORT/rest/items/TomorrowSunrise/state', headers=openhab_headers, data=sunrise_time_tomorrow.encode())
sunset_tomorrow_response = requests.put('http://YOUR_OPENHAB_IP:YOUR_OPENHAB_PORT/rest/items/TomorrowSunset/state', headers=openhab_headers, data=sunset_time_tomorrow.encode())
… where TomorrowSunrise
is your String item
in OpenHAB for tomorrow’s sunrise time and TomorrowSunset
is your String item
in OpenHAB for tomorrow’s sunset time.
String TomorrowSunrise "Sunrise tomorrow [%s]" (gAstro)
String TomorrowSunset "Sunset tomorrow [%s]" (gAstro)
2) Python scripts for running script inside of OpenHAB instance:
a) Python script for sunrise: sunrise_tomorrow.py:
#!/usr/bin/python
import datetime
import astral
my = astral.Location(info=("YOUR_CITY", "YOUR_COUNTRY", YOUR_LATITUDE, YOUR_LONGITUDE, "YOUR_TIMEZONE", YOUR_METERS_ABOVE_SEA_LEVEL))
my.solar_depression = 'civil'
# the variable 'tomorrow' below defines the time delta from today for which the sunrise time is calculated
# In my case I have a time delta of 1 day = datetime.timedelta(1) to calculate tomorrows sunrise time
tomorrow = datetime.date.today() + datetime.timedelta(1)
sun = my.sun(date=tomorrow, local=True)
print(str(sun['sunrise'].isoformat())[11:16])
b) Python script for sunset: sunset_tomorrow.py:
#!/usr/bin/python
import datetime
import astral
my = astral.Location(info=("YOUR_CITY", "YOUR_COUNTRY", YOUR_LATITUDE, YOUR_LONGITUDE, "YOUR_TIMEZONE", YOUR_METERS_ABOVE_SEA_LEVEL))
my.solar_depression = 'civil'
# the variable 'tomorrow' below defines the time delta from today for which the sunset time is calculated
# In my case I have a time delta of 1 day = datetime.timedelta(1) to calculate tomorrows sunset time
tomorrow = datetime.date.today() + datetime.timedelta(1)
sun = my.sun(date=tomorrow, local=True)
print(str(sun['sunset'].isoformat())[11:16])
run for testing on the command line:
# python sunrise_tomorrow.py
# python sunset_tomorrow.py
In your OpenHAB instance configure the following two rules:
rule "get tomorrow's sunrise"
when
Time cron "0 5 0 ? * * *" // Everyday at 5 past midnight
then
val timeString = executeCommandLine("python /path/to/script/sunrise_tomorrow.py", 5000)
logInfo("Tomorrow's sunrise: ", timeString)
TomorrowSunrise.postUpdate(DateTimeType.valueOf(timeString))
end
rule "get tomorrow's sunset"
when
Time cron "0 5 0 ? * * *" // Everyday at 5 past midnight
then
val timeString = executeCommandLine("python /path/to/script/sunset_tomorrow.py", 5000)
logInfo("Tomorrow's sunset: ", timeString)
TomorrowSunset.postUpdate(DateTimeType.valueOf(timeString))
end
… where TomorrowSunrise
is your String item
in OpenHAB for tomorrow’s sunrise time and TomorrowSunset
is your String item
in OpenHAB for tomorrow’s sunset time.
String TomorrowSunrise "Sunrise tomorrow [%s]" (gAstro)
String TomorrowSunset "Sunset tomorrow [%s]" (gAstro)
The explanation how to set the calculation to tomorrow (or any other day) is given within the scripts:
# the variable 'tomorrow' below defines the time delta from today for which the sunset time is calculated
# In my case I have a time delta of 1 day = datetime.timedelta(1) to calculate tomorrows sunset time
tomorrow = datetime.date.today() + datetime.timedelta(1)
sun = my.sun(date=tomorrow, local=True)
For further details on the time calculation which is done by the python library datetime
please refer to its documentation found at this link: https://docs.python.org/2/library/datetime.html
I kindly appreciate your feedback if this tutorial is helpful or has any mistakes