clock_radio_20160909_smallWe had a really old alarm clock in our bedroom.  Really old.  The LED number segments, which were a nice dim red in color, had been dying at the rate of 1 segment a year and it was getting hard to read the time.  My wife finally had enough of my “I’ll get a new one real soon” excuse and bought a new big, bright, blue LED clock to replace the old clock.  It was blue … and *really* bright … even in its dim-mode 🙁  It had to go!

My converted 1942 Crosley Radio was collecting dust on my workbench.  I had finally received a Raspberry Pi Zero and Zero4U USB hub to play with but was already lusting after the new R-Pi Zero with camera port.  I recently upgraded the audio-output on my Mac from an old USB HiFiMan Express DAC to  a Schiit Modi DAC.   Hmmmmm, seemed like I had the ingredients to make a BIG clock “radio” with alarm(s) and great stereo audio?

I had neglected my old media-center radio which had an original Raspberry Pi as its “heart”.  The R-Pi connected via HDMI to a display board driving a 9.7 inch, 1024 x 768, iPad LCD screen (non-touch).  Audio output was via the audio-jack to a small stereo amp.  The video was great but sound was mediocre.

radio_back_20160901
Dusty, old media-center radio with old R-Pi removed. Just waiting for the Zero!

My first step was to see if I could get decent sound out of the Zero via my HiFiMan Express HM-101 USB DAC.  After much Googling and research, I had an approach.  One of the best resources for configuring USB audio under Jessie OS is at Adafruit.  If you don’t want or need to use a USB DAC, just ignore this part 😉  You can use the “normal” audio-out jack on the R-Pi 1, 2 or 3 and omxplayer app.  As I was using a Zero, I needed another way to get audio out. Plus, I was after “good” audio, not just adequate.  I use the ALSA compatible mpg123 and mpg321 apps for audio playback.  These provide different options including various types of random playlist support.

I now had a working system with audio and video.  I added an Edimax WiFi dongle and  a Logitech wireless keyboard/trackpad via a UUGear Zero4U USB Hub.  The hub sits on top of the Zero with no soldering required.

hifiman_dac_201609
Zero connected via Zero4U USB hub to WiFi, keyboard & HiFiMan DAC

 

OK, I might have lost sight of the original goal — which was a bedroom clock.  I started thinking about displaying the time and complete weather forecast, while playing music.  I ran the idea by my wife who again informed me that “we” wanted a not-too-bright, readable-across-the-room, simple clock.  I did get her to agree that displaying (just) the outside temperature might be useful!

How best to show a clock and display temperature?  I needed to use an external resource of some kind to obtain the local outside temperature.  I was tempted to use another R-Pi with some kind of sensor HAT but I wanted something simple and quick.  I had investigated Weather Underground APIs for weather info in the past and still had an active developer account.  Providing I kept API calls to under 500 per day, it would be free. The Weather Underground APIs return data as JSON so I needed a way to GET and extract the temperature data.  I thought about a Python app but I’ve been doing some web development lately and decided to use a web “app” — i.e. use a browser to display a web page with associated JavaScript functions calling the JQuery JavaScript library.  The web page with associated scripts and CSS could be local to the R-Pi or remotely located and downloaded from a server.

I needed a browser that could be run in kiosk mode so there were no distracting elements.  I chose kweb.  The latest version I found was 1.7.4.  There’s a PDF doc that does a great job describing kweb and all its options by Günter Kreidl – here.  Providing you have the Jessie OS and a GUI installed, i.e. not a minimal Jessie image, you can install kweb:

cd ~
mkdir kweb
cd kweb
wget http://steinerdatenbank.de/software/kweb-1.7.4.tar.gz
tar -xzf kweb-1.7.4.tar.gz
cd kweb-1.7.4/
./debinstall

I like to have a variety of fonts, including the Microsoft core set:

Install the font installer 😉 and then run the installer when prompted.  You can then list all fonts installed:

cd ~
sudo apt-get install ttf-mscorefonts-installer
fc-list

To hide the distracting cursor while in browser kiosk mode, you can use “unclutter”:

sudo apt-get install unclutter

For a clean clock display, you need to create a kweb configuration file that loads the clock web page and hides all UI elements, including the cursor – while leaving the keyboard active.  I suggest creating a file, “mykiosk” in your pi home directory that contains:
pi@PiZero:~ $ cat mykiosk

#!/bin/sh
xset -dpms
xset s noblank
xset s off
matchbox-window-manager &
unclutter &
kweb -KHUAJ+-zbhrqfpoklgtjneduwxyavcsmi#?!., file:///home/pi/clock/index.html

Create a directory with the web page and associated script and CSS files:

cd ~
mkdir clock
cd clock

The directory should contain 3 files as listed below. I have made a zip file containing these 3 files plus the “mykiosk” config file that you can download from here.  NOTE: you need to get your own API key from Weather Underground and determine your location string.  See below.

html file “index.html”:

<!DOCTYPE html>
<html>
<head>
<title>Time and Temp</title>
<link href="style.css" rel="stylesheet" type="text/css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="script.js"></script>
</head>
<body onload="getTime(); getTemp()">
<div id="time_txt" class="timediv"></div>
<div id="temp_txt" class="tempdiv"></div>
</body>
</html>


CSS file “style.css”:

/*
style.css
for use with HTML clock
Andy Felong
08 Sep 2016
*/

body, div {
	font-family: Verdana, Geneva, sans-serif; 
	font-size: 320px;  /* adjust to preference and display size */
	background-color: #000000;
	color: #881200;  /* dim scarlet */
}

.timediv {
	font-size: 100%; 
	max-width: 1024px; /* use the width of the display */
	text-align: center;
}

.tempdiv {
	font-size: 60%;
	max-width: 1024px; 
	text-align: center; 
}


JavaScript file “script.js”

/*
script.js
for use with HTML clock
Andy Felong
09 Sep 2016
*/


// can't use "const" in IE -- so use "var"
var CLOCK_CHECK_SECS = 20 * 1000; // 20 seconds
var TEMP_CHECK_MINS = 10 * 60000; // 10 minutes
var WU_URL = "http://api.wunderground.com/api/XXXX_UW_API_KEY_XXXX/geolookup/conditions/q/XXX_STATE_XXX/XXX_YOUR_CITY_XXX.json";
var TEMP_UNITS = "temp_f"; // WU temperature units: Fahrenheit ("temp_f") or Celcius ("temp_c")


function getTime() {
    var today = new Date();
    var hrs = today.getHours();
    if (hrs > 12) { // use 12-hour clock, not 24
        hrs -= 12;
    } else if (hrs === 0) {
        hrs = 12;
    }
    var mins = today.getMinutes();
    if (mins < 10) {
        mins = "0" + mins; // will convert num to string but that's OK
    }
    document.getElementById('time_txt').innerHTML = hrs + ":" + mins; // update time div
    var t = setTimeout(getTime, CLOCK_CHECK_SECS);
}


// getTemp() - uses JQuery library to GET and parse JSON - included by index.html
// <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

function getTemp() {
    jQuery(document).ready(function($) {
        $.ajax({
            url: WU_URL, // Weather Underground URL with key and location
            dataType: "jsonp", // cross-domain JSON request
            success: function(parsed_json) {
                var location = parsed_json['location']['city']; // could use city string if desired
                var temp_f = parsed_json['current_observation'][TEMP_UNITS]; // temperature of city passed in URL
                temp_f = Math.round(temp_f); // round temp to nearest degree
                var theTemp = temp_f + "&deg;";
                document.getElementById('temp_txt').innerHTML = theTemp; // update temperature div
            }
        });
    });
    var tmp = setTimeout(getTemp, TEMP_CHECK_MINS);
}

 

You need to include your specific Weather Underground API key as well as location for temperature disaply in the JavaScript file, “script.js” for the URL — variable “WU_URL”. In the U.S., the location is usually “2-letter state” + “/” + city — with underline substituted for a space.

Example:

var WU_URL = "http://api.wunderground.com/api/0123456789abcdef/geolookup/conditions/q/CA/Los_Angeles.json";

You should also set the browser width to your display width in the CSS file, “style.css”. Look for “max-width” and set this to your screen width. Change the font size inside the “body” section of CSS. Look for:

font-size: 320px; /* adjust to preference and display size */
and
max-width: 1024px; /* use the width of the display */

If you have installed kweb, setup the mykiosk configuration file, created the clock directory with the html, CSS and script files, you should be able to launch your clock with temperature via:

cd ~
xinit ./mykiosk

You can quit the display by hitting ALT-Q on your keyboard or by killing the process via ssh login.

Added window tint film
The LCD screen backlight was a bit bright in a dark room. I used Tap Plastics Window Tint Film to reduce “glare”. There was a slight color-shift but, for a clock-radio, this was not a concern.
clock_radio_20160909_small
Finished clock-radio. Easy to see across the room and not too bright!