Sunset – Sunrise monitor on a raspberrypi

Imagine that for some reason it is imperative that you know at any given time when the Sun will rise or set next. (Maybe you are a vampire.)

For whatever reasons – who am I to judge – you need that, you can easily achieve it with a raspberry pi, a 2×16 character LCD screen and python!

And as is almost always the case with every python mini project, we are going to utilize a powerful library to achieve our puny goals. In this case Ephem.

Ephem is a quote: Python package for performing high-precision astronomy computations.

I will not be covering how to interface the LCD module with the raspberrypi or how to use the Adafruit library as those topics have been exhausted already.

Let’s start by importing the libraries we are going to need (the number of which will inevitably increase):

import ephem
from datetime import datetime
import Adafruit_CharLCD as LCD

Some pin definitions required by the LCD library which I don’t know why but I didn’t pass them directly to the function:

lcd_rs = 25
lcd_en = 24
lcd_d4 = 23
lcd_d5 = 17
lcd_d6 = 27
lcd_d7 = 22
lcd_backlight = 4
lcd_columns = 16
lcd_rows = 2
lcd = LCD.Adafruit_CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7,lcd_columns, lcd_rows, lcd_backlight)

In order to cram as much information as possible in such a small screen, a nice way to delimit our data is by using custom characters. The hd44780 controller is nice like that.

Using online tools that let you draw the pixels and acquire the byte sequence (such as this one) and some Bob Ross videos, we can create the characters we need.

I made one that is supposedly a Sun on the horizon (yes I know.) and another one for the temperature:

lcd.create_char(0, [0,0,14,27,17,31,31,31])
lcd.create_char(1, [0,4,10,10,10,17,31,14])

Which translate to those two characters (yes it does definitely not look like a Sun we’ve been over that):

And now we can proceed in computing the time difference from now to the next sunset / sunrise.

First, we create a Sun and an observer:

sun = ephem.Sun()
obs = ephem.Observer() = '-49.55'
obs.long= '69.83' = datetime.utcnow()

And now by taking advantage of the wonder that is modern day computing, we can get what wanted in just two lines of code:

delta = min(obs.next_setting(sun).datetime(),obs.next_rising(sun).datetime()) - datetime.utcnow()
riseset = str(delta.seconds//3600) + ":" + str(delta.seconds%3600//60).zfill(2)

This works by calling two functions from the ephem library that return the next sunset and sunrise, finding out which one is closer to the present using min, and subtracting the present daytime in order to get a timedelta object (the time difference).

Then, with a series of mods and divs that should be self-explanatory to get the hours and minutes from the seconds in a pretty way, we have our value!

I also happen to have a dirty bash script that scrapes the current outside temperature from a website for my city, so I’ll throw that in as well (more imports):

temp = subprocess.check_output("./").rstrip()

And finally send everything to the LCD:

lcd.message('\x00 ' + riseset + '\n' + '\x01 ' + temp)

‘\x00’ is the sunset character because in the function create_char we specified the first memory position for it to be stored, and ‘\x01’ the little thermometer.

Now throw everything after the coordinates assignment in a loop with a time delay and Bob’s your uncle:

Thanks for reading!