How to write a moon phase display dizmo with Ajax and webservices

This tutorial is another variation of how a dizmo can connect to third party systems. This time, we will use jQuery’s Ajax library for web service calls.

As the name of our moonphasedisplay dizmo suggests, it will display moon and sun information at the current location. This requires two public web services:

  1. nominatim.openstreetmap.org to get the latitude and longitude from a given location
  2. api.met.no is an API from the Norwegian weather service to get the astronomical data from a given location

The basics

The basic syntax is straight forward. Start with creating a new directory called ‘moonphasedisplay’ and add the application.js file:

function showFront() {
dizmo.showFront();
}

function showBack() {
    dizmo.showBack();
}

dizmo.onShowBack(function() {
    // You can add your own code here that will be executed when the back side is shown.
});

dizmo.onShowFront(function() {
    // You can add your own code here that will be executed when the front side is shown.
});

document.addEventListener('dizmoready', function() {
    console.log("ready");
    $.ajax({
        method: "GET",
        url: "http://nominatim.openstreetmap.org/search?q=zurich&format=json",
        success: function (response) {
            console.log(response);
        }
    });
});

Next, we create the file index.html and add the jQuery library to the head section:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
            <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.js"></script>
            <script src="application.js"></script>
    </head>
    <body>
        <div id="front">
            <div id="displaydata"></div>
        </div>

        <div id="back">
        </div>
    </body>
</html>

And lastly, we will create our Info.plist file:

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>ApiVersion</key>
        <string>1.2</string>
        <key>BundleDisplayName</key>
        <string>moonphasedisplay</string>
        <key>BundleIdentifier</key>
        <string>com.dizmo.moonfphasedisplay</string>
        <key>BundleName</key>
        <string>moonphasedisplay</string>
        <key>BundleShortVersionString</key>
        <string>0.1</string>
        <key>BundleVersion</key>
        <string>0.1</string>
        <key>ElementsVersion</key>
        <string>1.0</string>
        <key>Height</key>
        <integer>300</integer>
        <key>HiddenDizmo</key>
        <false/>
        <key>MainHTML</key>
        <string>index.html</string>
        <key>Width</key>
        <integer>250</integer>
    </dict>
</plist>

Now, open the moonphasedisplay dizmo and view its output in the console of the web inspector. As you can see, the function call returns geo-information (including the longitude and latitude that we’ll need later) from Zurich in JSON format.

Adding moon and sun information

We will now add the web service call to get moon and sun information, but this time we use the XML data format. The function call itself looks similar, the parsing will be different though.

function getSunMoonData(lat,lon) {
    var _today = new Date();
    var mm=_today.getMonth()+1 // since January returns 0
    var dd=_today.getDate();
    if(dd<10) {
        dd='0'+dd
    }
    if(mm<10) {
        mm='0'+mm
    }
    var today=_today.getFullYear()+"-"+mm+"-"+dd;

    $.ajax({
        method: "GET",
        url: "http://api.met.no/weatherapi/sunrise/1.0/?lat="+lat+";lon="+lon+";date="+today,
        dataType: 'xml',
        success: function (response) {
            xmlParser(response);
        }
    });
});

First, we construct a string containing the current date, as its required by the web service. We then use the latitude and longitude, which are passed in as parameters to construct the web service call. Once called, we get a response back, this time in XML.

The following function will parse the XML, prepare the output and write it to the display area on the content side (<div id="displaydata">) of our moonphasedisplay dizmo.

function xmlParser(response){
    var out="";

    out+="<p>Sunrise: "+$(response).find('sun').attr('rise')+" Sunset: "+$(response).find('sun').attr('set')+"</p>";
    out+="<p>Moonphase: "+$(response).find('moon').attr('phase')+" Moonrise: "+$(response).find('moon').attr('rise')+" Moonset: "+$(response).find('moon').attr('set')+"</p>";

    $('#displaydata').append(out);
}

Now, we add a new function that parses the longitude and latitude information from the openstreetmap response and use the same to call the next web service to get the data from the given location.

function jsonParser(response){
    var lat=response[0].lat;
    var lon=response[0].lon;
    getSunMoonData(lat,lon);
}

Finally, change the call to the openstreetmap web service to the following:

success: function (response) {
    jsonParser(response);
}

Homework

Homework suggestions:

  • Add a graphical representation of the moon phase
  • Improve the display of the date and time information
  • Add an input field for the location to the settings
  • Do you have any improvement suggestions? Let us know in our forum!

Get the source code

You can find the source code on Github

$ git clone https://github.com/dizmo/moonphasedisplay.git

Leave a Reply

Your email address will not be published. Required fields are marked *