Saturday 24 February 2018

Coding for day or night events

This post was promoted by a post on the  GarysShed blog after a discussion on triggering events based on whether it's day or night time.

To be fair, the whole post is an excuse to include following video from the BBC's 'Walk on the Wildside' series

I needed to modify the behaviour of the illumination LEDs in one of my Raspberry Pi-based  birdboxes based on whether it is light or dark.  This box has IR (Infra-Red) as well as visible light LEDs, I wanted the IR to operate all the time, and the standard LEDs to come on (and IR LED go off) only in the event of a daytime  motion 'event', which could be triggered by any of:  Entrance hole IR beam being broken, PIR insider the box triggered or motion detected on camera.

An IR-cut filter over the camera can then be switched on or off depending based on this too - IR LED off when visible LEDs are on.  (An IR-cut filter turns an IR-sensitive camera into a daylight-only sensitive camera).

The idea was that I didn't want visible LEDs coming on during the night, mainly to disturb any occupants, I also didn't want this happening as it looks a bit odd from the outside:

Possible solutions:
1) Analyse camera image for brightness
2) Use a light-dependent resistor (LDR) to sense ambient light and modify LED behaviour based on this.
3) Implement a software-method to predict day vs night based on longitude and latitude

1) Analyse camera image for brightness.  Borrowed code from here and here and here
convert test.png -colorspace hsb -resize 1x1 txt:- | sed -n 2p | sed 's/.*(//; s/).*//'

If run in the terminal, will output something like: 81.857%,38.706%,17.7462% where these figures are the HSB (hue, saturation, brightness) values from a 1x1 pixel converted version of the original image (test.png in this example)

2) Use LDR to monitor light.  There's loads of examples out there how to do this, a randomly selected recent one here

At one time I did a merge of method 1 & 2 to which I've uploaded to a github repository Ambient-Light-Monitoring, the script is called  This reads actual light level via an  LDR, and also takes image with a Raspberry Pi Camera and measures image brightness.  All these variables are then written to a file for playing with which could be applied with in a variety of contexts..

3) Software method
I've tried two approaches, both rely on feeding the application the current location via longitude and latitude.

3.1) SunWait.  A stand-alone program, an example use is described in a blog post here.  Essentially you run a crontab job every ?minute that writes to a file to indicate the current light/dark state.  You can then read that file into your application and base the outcome on whether its day (..light) or night (...dark).  I could not get it to work..

3.2) Python module: pyephem, website here
This is a python module, so is used within a python script.  You need to install python-dev first or the install of this module will fail. The module can then be installed with the pip python module installer
sudo apt-get install python-dev
sudo apt-get install python-pip  #if pip not available, e.g. on Raspbian Lite
sudo pip install ephem
Note, the sudo bit is important otherwise if you attempt to run a python script from rc.local  containing this module (to run it at boot) the root user wont be able to find the module since without 'sudo...' it will install ephem under the user 'pi'

This approach worked for me.  Longitude and Latitude can be generated on various websites, eg here, pyephem also uses height above sea level which I think I got off google earth.  This would be aprticularly relevant if you're using it at the top of a mountain....
Refer to the example script in the above mentioned githib repository

3.3) ?Pikrellcam motion capture application
I use the awesome motion capture application PiKrellCam in my birdboxes.  In its .config file is the facility to define location by longitude and latitude.  I spotted a recent forum post querying if it was possible to switch an IR-cut filter on or off by using the day/night status within Pikrellcam to trigger a command to the GPOI pin(s) controlling the IR cut.  See my IR-cut post on how to wire such a thing up.