Astro binding - Enhancement for tomorrow's sunrise and sunset

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 :wink:

  • 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 :slight_smile:

4 Likes

Worked first time after I added astral python install , now to think of some nice visualization