Free #Alexa Skill for Air Quality in Northern Ireland – #OpenSource


This is a free skill available for Alexa, that you can enable here;

It’s open source, and open to improvements and suggestions by anyone interested in collaborating.

You can ask it questions such as “Alexa, ask air quality northern Ireland what is the level of nitrous oxide in Belfast“, or ask about particulate matter, carbon monoxide, ozone, or sulfur dioxide.

The data itself is courtesty of  the Northern Ireland Department of Environment. via AirQualityNI.

At a high level, this skill runs on the Alexa platform, which hooks into Amazon’s Lambda service, running NodeJS. From there, it connects to an API, which is described here; – Which is hosted on a Windows server, and makes the connection on to the AirQualityNI website, and dynamically converts CSV data to the more readable JSON format.

Here is a run down on the constituent parts

The Alexa interaction model is defined here;

This defines the phrases that can be used with the skill, such as

What is the level of Nitrous oxide in {city}

Where {city} is of type AMAZON.GB_CITY, this is interpreted as the NitrogenOxideIntent, and passed to the Lambda handler at index.js here;

This, then checks the intentName, and if it’s equal to NitrogenOxideIntent, then handleNitrogenOxideIntent is called, which then calls airQuality.NitrogenOxide(..), which is defined here:

The NitrogenOxide() function calls DescribePollutants(), passing a function to filter the data by city, and these three types of Nitrogen-Oxide pollutants; “NO“,”NO₂” and “NOₓ as NO₂“. DescribePollutants() then makes an HTTP request to, which returns yesterday’s mean values of air pollutants in Northen Ireland. – It then formats the response into a spoken string, for example, using NamePollutant() to convert chemical formulae like “NO₂” to “Nitrogen Dioxide”. 

Please, feel free to enable the skill on your alexa device, and give it a good rating, also feel free to contact me if you’d like to build upon this skill or API.






Categories: Uncategorized

Air Quality #API for Northern Ireland



This is a simple API based on the data available from by default, it will return a daily mean of Yesterday’s Automatic Monitoring Data for all pollutants, for all regions in northern ireland.

To specify a specific date, other than yesterday, use a date parameter in the querystring, such as


Sample data:

  "Date": "03/07/2019",
  "Site": "Armagh Lonsdale Road",
  "Pollutant": "NO",
  "Daily_Mean": "26",
  "Status": "P",
  "Unit": "µg/m³"
  "Date": "03/07/2019",
  "Site": "Armagh Lonsdale Road",
  "Pollutant": "NO₂",
  "Daily_Mean": "17",
  "Status": "P",
  "Unit": "µg/m³"


Developed by /

Categories: Uncategorized

#Webcam streamer #app using C#


This is a bit of a resurrection of an old project – How it works, is that there is a iOS App available here “” which reads images that are posted to a URL via a Windows application that is downloadable here; – and there is a Webservice here;

So, bascically, the windows application uploads images contstantly to the service via the webservice, and the mobile application reads the url of where the image should be from the web service, and constantly refreshes the image. If the connection is fast enough, it looks like video – although always a bit jerky.

Is it a great design, no – but to be honest, for me, this was about bringing an old app and website back to life, and I was surprised it still worked, all I did was renew the expired domain name!

You can probably see the age, from the links to Palm and Windows Phone, both of which are obsolete now!



Categories: Uncategorized

#Unsplash #API using C#


Unsplash is a great source of free photos, that you can use in your websites, and it also offers an API that allows you to integrate free image searches into your app. This might be an easy way to add a splash of colour to features that otherwise might just have a placeholder image.

In order to use their API, you need to register as a developer with them, then create an application, and with that you’ll get your access key and secret key. For this application, I’m only using the access key, since I’m only looking at public data.

So, for those who want to cut right to the code, here is the github repo: and here is a demo

The page is written in bootstrap and jquery, with the results rendered using Mustache. The magic happens with a call from the javascript to an ASPX page with this AJAX call;

function callAPI(searchTerm) {
    if (searchTerm === "") {
        bootbox.alert("Please enter a search term");
    console.log("searching: " + searchTerm);
    $.getJSON("/search.aspx?searchTerm=" + searchTerm,
        function (data) {
            if (data.results.length === 0) {
                bootbox.alert("Sorry, No Results");
            var tpl = $("#tplItem").html();
            var strHtml = Mustache.render(tpl, data);

Then we just proxy the call to the unsplash /search/photos API call as follows;

var searchTerm = Request.QueryString[“searchTerm”];
if (string.IsNullOrEmpty(searchTerm))
throw new Exception(“searchTerm is required”);
var strUrl = “”;
strUrl += “client_id=c9492064c857d14c8704afd5e85e22df1413d97f54002f62037313049395b3c9”;
strUrl += “&query=” + searchTerm;
query Search terms.
page Page number to retrieve. (Optional; default: 1)
per_page Number of items per page. (Optional; default: 10)
collections Collection ID(‘s) to narrow search. If multiple, comma-separated.
orientation Filter search results by photo orientation. Valid values are landscape, portrait, and squarish.
var wc = new WebClient();
var strJson = wc.DownloadString(strUrl);

Once the json is back, we can render it with the following Mustache template

        <a href="{{urls.full}}" class="list-group-item" target="_blank">
            <img src="{{urls.thumb}}" style="width: 100px; height: 100px; padding-right:10px" >{{alt_description}}
            <span class="badge badge-dark">{{likes}} Likes</span>          


Categories: Uncategorized

#OCR using #Azure Cognitive services


OCR or Optical Character Recognition is the process of extracting text from an Image. Microsoft Azure offers a service within Azure, called “Computer Vision”, which offers a free tier, that you can use to run small batches of OCR on images.

Here’s some sample code to use it in C#. I’ve used the Nuget package Newtonsoft.JSON for Json processing. I’ve also omitted the key, which you can get from Azure

private static string OcrUsingAzure(string url)
const string strUrl = “;;
var wc = new WebClient();
wc.Headers[“Ocp-Apim-Subscription-Key”] = “xxxxxxx”;
var jPost = new { url = url };
var strPost = JsonConvert.SerializeObject(jPost, Formatting.Indented);
var strJson = wc.UploadString(strUrl, “POST”, strPost);
var jObject = JObject.Parse(strJson);
var strOutput = “”;
foreach (var region in jObject[“regions”])
foreach (var line in region[“lines”])
foreach (var word in line[“words”])
strOutput += word[“text”] + ” “;
strOutput += Environment.NewLine;
}return strOutput.Trim();

You pass in a url of an image with some text, and it spits out the text the other side.

If you know in advance the language of the document, i.e. english, you can improve the accuracy by changing the language parameter in the Querystring.


Categories: Uncategorized

Add and List mailboxes set up in #MailEnable


MailEnable is a popular mail server for windows, that allows you manage your own email accounts on your server, but instead of managing it via remote desktop, they also offer an API to adminsister it. If your email needs are quite simple, but repetitive, then this could be a great way to pass on mail administration from developers to admin staff, by creating a web interface for email management.

My particular need for this was for , migrating from Linux (Dovecot) to Windows (MailEnable) – The source code for this article is available on GitHub here;

First, you have to add a reference to MailEnable.Adminstration, which is available here;

C:\Program Files (x86)\Mail Enable\Bin\NETWebAdmin\bin\MailEnable.Administration.dll

(Assuming a default installation path)

The most simple thing is to list all mailboxes in a PostOffice, as follows

private static IEnumerable<string> ListMailboxes(string postOffice)
var oMailbox = new Mailbox
Postoffice = postOffice
if (oMailbox.FindFirstMailbox() != 1)
throw new Exception(“Failed to find mailboxes”);
var mailboxes = new List<string>();
var sMailboxName = oMailbox.MailboxName;
while (oMailbox.FindNextMailbox() == 1);
return mailboxes;

This code needs to be run as an administrator, or it hangs unhelpfully on FindFirstMailbox()

Now, it’s more complex code to actually add an account, which would be as follows;

private static void AddMailbox(string postOffice, string email, string password)
var user = email.Split(‘@’)[0];
var domain = email.Split(‘@’)[1];
var oMailbox = new MailEnable.Administration.Mailbox();
var oLogin = new Administration.Login();
var sMailboxName = user;
var sPassword = password;
const string sRights = “USER”; // USER – User, ADMIN – Administrator;
oLogin.Account = postOffice;
oLogin.LastAttempt = -1;
oLogin.LastSuccessfulLogin = -1;
oLogin.LoginAttempts = -1;
oLogin.Password = “”;
oLogin.Rights = “”;
oLogin.Status = -1;
oLogin.UserName = sMailboxName + “@” + domain;
// If the login does not exist we need to create it
if (oLogin.GetLogin() == 0)
oLogin.Account = postOffice;
oLogin.LastAttempt = 0;
oLogin.LastSuccessfulLogin = 0;
oLogin.LoginAttempts = 0;
oLogin.Password = sPassword;
oLogin.Rights = sRights;
oLogin.Status = 1; // 0 – Disabled, 1 – Enabled
oLogin.UserName = sMailboxName + “@” + domain;
if (oLogin.AddLogin() != 1)
// Error adding the Login
throw new Exception(“Failed to add Login”);
// Now we create the mailbox
oMailbox.Postoffice = postOffice;
oMailbox.MailboxName = sMailboxName;
oMailbox.Size = 0;
oMailbox.Limit = -1; // -1 – Unlimited OR size value (in KB)
oMailbox.Status = 1;
if (oMailbox.AddMailbox() != 1)
// Failed to add mailbox
throw new Exception(“Failed to add mailbox”);
// Now we need to add the Address Map entries for the Account
var oAddressMap = new MailEnable.Administration.AddressMap
Account = postOffice,
DestinationAddress = “[SF:” + postOffice + “/” + sMailboxName + “]”,
SourceAddress = “[SMTP:” + sMailboxName + “@” + domain + “]”,
Scope = “0” // ?
if (oAddressMap.AddAddressMap() != 1)
// Failed to add Address Map for some reason!
throw new Exception(“Failed to add AddressMap”);


For a full reference for this code, refer to the MailEnable .NET reference here;


Categories: Uncategorized

Publish a #Google Doc to the web on your own domain name


Writing a Google Doc is super easy, and you can even publish a Google doc to the web with two clicks, but unfortunately, you end up with a URL like this;……&#8230;.

Which nobody is ever going to remember, but with you can now use your own domain name, so it can be on not “….” – and it doesn’t cost anything, as long as you own the domain name

Here’s a quick example.


Create a Google doc, and write some text in it, as shown above.


Press File then “Publish to the web”


Press Embed.


Copy the URL between the https:// and the embed=true as shown above. Now go to



In the left box, paste the URL from google, and add a “#” to the end of the url. so it should look something like this;

In the right box, enter your domain name, and then press “Setup”


At this point, you need to set up the DNS on your domain. This means that you need to do is log into the website where you bought your domain name, go to the DNS settings, and add a “CNAME” record on “www” to point to “”. You should also add an A record on “@” to point to

When this is done, press the “Click here when this is done” button, and it will check the DNS on your domain.


And Voila! once it’s done, you can navigate to your domain name in your browser, and you will see your google doc, with a pretty url. – and it’s perfectly SEO friendly. This example shows “” as a demo.


Categories: Uncategorized