Best 3.5mm to USB Type C adapters for microphone input

After switching to a reconditioned Galaxy S21 Ultra which has no 3.5mm headphone jack, the prospect of moving to Bluetooth earbuds didn’t phase me; they’re cheap enough & the quality is pretty good.

However, I wanted to use my Boya BY-M1 lav mic (with 3.5mm jack) to record videos for YouTube, and therefore needed a 3.5mm to USB Type-C adapter. After rooting around on Amazon I found a couple with decent reviews; one at £8, the other £18.

They might be fine for listening, but both were a absolute disaster for recording audio! The cheaper one had a poor frequency range, so it sounded like I was talking through a cushion. The other had a good frequency range (similar to the internal mic), but a high amount of electrical noise.

Since then, I’ve tested a couple more adapters and have put together a series of video reviews to show you which ones to avoid, and which ones I’d recommend you buy.

Displaying a Replicon Time-Off Calendar in SharePoint (or wherever!)

Our team just started using Replicon to record our time off, but wanted to have a nice calendar widget on our SharePoint page (or wherever) rather than having to log into Replicon each time.

At first I tried their API, but struggled with permissions and getting any time-off data out of it.

However, I did find a more straight forward way.. through the iCalendar feed! I’m posting my solution here for anyone else who might want to do this with the minimum of effort (but it does need some effort! ;).

First off, you need to proxy the iCal data feed through something due to web (CORS) security.. so I’m doing that with a very simple Azure Logic App that grabs the feed & responds with the data.

Proxying the iCalendar Feed

This can then be consumed by our calendar JavaScript code, which takes the iCalendar data, reformats it to JSON, then tidies it to feed into a free JavaScript calendar called FullCalendar.

The full source for this is in a CodePen, which makes it easy for you to try this out yourself.

(you’ll need to edit the URL in the code to point at your iCalendar data proxy).

Once you’re happy with the code (in CodePen) you’ll need to host it on a webserver, then you can use the Embed component in SharePoint to get it onto your site page. To do this, I actually used another quick Azure Logic App, since it means I don’t need to have an actual web server.

I pasted all the code from the CodePen into a Response blog & boom, we have an easily-embedded calendar containing our team’s holidays!

Hosting the code in a Logic App

Hopefully this will help anyone else trying to do something similar, so you don’t have to start from scratch.

Arduino IR Code Translator – Unsupported Device Control with a Fire TV Remote

[Update: As featured on Hackaday! :) ]

The Fire TV remote has a neat feature which lets you control other equipment like the TV or a soundbar. The list of manufacturers & devices it’ll control is massive.. but not all encompassing!

I bought an Edifier R1855DB (very similar to the R1850DB), and wanted to control it using the Fire TV remote.. which saves juggling 2 remotes (and the Edifier one is pretty cheap & feels like it could break at any moment!).

I soon found out that this particular Edifier model isn’t in the list of supported devices in the Fire TV equipment control feature which is really frustrating. There’s no route to get added to the Amazon list, nor does it have a ‘learn’ mode.

When I contacted Edifier they said “Our remotes use custom IR codes that can not be inputted into a universal remote”. And “information about the IR code is not open to the public”. Pretty ridiculous.

This is where I got curious about what IR codes the Edifier remote is sending out.. so I took a cheap Arduino Nano microcontroller and an IR receiver & wired them up on a breadboard. There’s an IR library with a bunch of examples, so I used the ‘IR dump’ code, uploaded it to the board & could instantly see the codes from the remote.

Capturing IR Codes

Apparently the Edifier R1855DB uses the NEC protocol, which is really common, and you can see the sequences it sends easily enough. I noted down the IR codes for each of the buttons I was interested in, and can now look at transmitting them!

You can get an IR transmitter for the Arduino .. at first I tried an IR LED from an old TV remote, but it needed a transistor to make it work properly, which I didn’t have. So I ended up buying a KY-005 IR module from eBay for £2.50.

KY-005 IR Module attached to the Arduino Nano

Hooking this up to the Arduino was simple, and I tested it was working using more example code from the IR Remote library. Finding the right format to play back the NEC codes I captured was a bit trial-and-error.. I eventually found the raw codes worked best. I actually used a Raspberry Pi with another IR receiver to validate the codes being sent were identical to the original remote.

What I can then do is have an IR receiver AND transmitter hooked up to the same Arduino and have it act as a translator between one manufacturers codes to another.

We can power the Arduino using the USB socket on the TV. This only powers up when the TV is on, which is quite handy.. and if it turns on, we can write some code to send the speaker power on IR command when the Arduino boots.

Here’s a quick wiring diagram, showing how everything is connected together;

Wiring Diagram

I didn’t have a cable long enough, so I took an old USB cable, cut it up, and soldered it into the IR transmitter so that I could place it near the Edifier IR receiver.. that was the most fiddly bit of this project.

Once I had that set up, I picked a supported device from the Fire TV equipment list – the Amazon Basics Soundbar – and dumped the IR codes for it from the Fire TV remote.

I then wrote some code to listen for the Amazon Basics Soundbar commands & emit a corresponding Edifier IR code. This worked an absolute treat after a bit of debugging. I even added a sequence detector so you can press Mute x2 then Vol Up to send the speaker power signal in case it somehow gets out of sync. Adapting the code to work with whatever equipment you have should be straightforward..

Altering the Arduino code for your equipment

You can build your own version of this for about £8, and it’s incredibly easy to put together, only requiring some basic electronics and coding skills.

Hope this has been useful.. let me know how you get on if you decide to build one of these yourself.

The GitHub repo for this project has a lot more detail & all the source code you need;

There’s a video of this project on YouTube if you want to see a bit more of the build process and see it working.

DIY IoT Motion Sensor for Remotely Monitoring Elderly Relatives

We have an elderly relative who, in the coming years, we expect have to keep a closer eye on. It’s not like we don’t have almost daily contact with them already, but having an early heads up of any mobility issues would be beneficial & give a degree of peace of mind.

Having a wifi-enabled camera installed is one option, but would be pretty intrusive, and I don’t want to have to watch it to figure out if there are any problems.

What I realised I needed was a Passive Infrared (PIR) movement sensor which could ping a service in the Cloud & alert me for anything out of the ordinary.

There are such solutions sold by a bunch of companies, but cost upwards of £100 and tend to have a subscription charge.

I started to think I’d roll my own solution using a development board and PIR sensor, but I remembered I actually have an old battery-powered PIR which activates a mains adapter (the idea is you’d maybe have a lamp in the socket for home security).

The adapter I have is from a company called Timeguard, but it’s about 15 years old and is obsolete.. they don’t have any current products of this type, but you can find similar ones on Amazon easily enough.

What I like about this, is that I can concentrate on the IoT piece, and let the adapter + sensor do their thing without worrying about the electronics.

All I needed to do next was take a small ESP8266 board I had lying around and code it up to connect to the local wifi & call a URL.. which in my case will be an Azure Logic App. Logic Apps are great.. you can get them up and running very easily, at minimal cost, and without writing any code!

At first, the code for the ESP8266 just used the examples from the Arduino IDE. In very little time I had it connected to Wi-Fi and ready to make a HTTP call to wherever I wanted. However, I soon discovered the examples only worked with non-HTTPS sites (Logic Apps are HTTPS-only).

After a bunch of Googling, I found this library from gojimmypi on GitHub, which allows you to make HTTPS calls.

After switching to that & rewriting portions of the code, the board called the Logic App URL without issues and I received a 202 response (Accepted), and I could see the call in History;

Now we’re cooking! The motion sensor will activate the power adapter, which boots up the ESP8266 board, connects to wifi & calls Azure. The adapter will stay powered for 15s to 15min.. so having it set to 15 minutes means we’re not repeatedly powering the board & calling Azure (and incurring a load of cost).

The Logic App can do whatever we want to record the event.. update a table, or write a small text file with a timestamp.

Now we have that, we can have a secondary Logic App running on a schedule to monitor the events & alert us by email (or whatever) if it falls outside what we typically expect. For example, at 9am check that there’s been motion detected in the last 3 hours. If there hasn’t, send me an email so I can give the relative a quick call to check they’re ok.

With Azure, it’s always good to keep an eye on costs. In this case, lets look at the worst case scenario where we have a very active elderly relative who trips the motion sensor every 15 minutes from 7am to 11pm.. so that’s 16hrs x 4 = 64 possible calls a day.

Logic Apps cost you per Action block, and cost a bit more for Standard + Premium actions. In our case we have 1 trigger block and 1 standard block to write to a Storage Account (table or file).

The Azure cost calculator can then be used to figure out the monthly cost..

That’s a maximum of 21 pence (GBP) a month if it triggers every 15 min (which it won’t).. not bad!

We’ll also have the ‘event monitor’ Logic App, but that won’t run as often.. maybe every 4 hours starting at 9am, finishing at 9pm.. so that’s 4 times a day, with a few more action blocks in it to figure out what to do.. so maybe 10-15 blocks, 5 of which might be ‘Standard’…

As you can see, the monthly costs are minimal, and helps illustrate how useful Azure can be for something like this!

It took a few hours to put this all together & I’m pretty happy with the solution. We can put the battery-powered PIR sensor in somewhere like the kitchen, or hallway and be safe in the knowledge we’d get an alert if there wasn’t the level of activity we’d typically expect to see.

If you’re interested in the ESP8266 source, here it is;

char ssid[] = "YOUR_WIFI_SSID";
char pass[] = "YOUR_WIFI_PASSWORD";
char logicAppURL[] = "https://YOUR_LOGIC_APP_URL";
// Needed to go here & install board support for ESP8266.
// This gave access to the WiFiClientSecureBearSSL client library (which is needed for HTTPS).
// See install instructions on that GitHub page.
// Also installed h/w support for the TTGO OLED board I have.
#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecureBearSSL.h>
#include <Arduino.h>
#include <U8g2lib.h> // make sure to add U8g2 library and restart Arduino IDE
#include <SPI.h>
#include <Wire.h>
#define OLED_SDA 2
#define OLED_SCL 14
#define OLED_RST 4
ESP8266WiFiMulti WiFiMulti;
void setup()
oledPrint("Start…", false);
oledPrint("Wifi connect ..", false);
Serial.print("Connecting to ");
WiFiMulti.addAP(ssid, pass);
String progress = ".";
while ( != WL_CONNECTED) {
oledPrint(progress, false);
progress = progress + ".";
oledPrint("Wifi connected", false);
Serial.println("Calling HTTP");
void loop()
void httpGET(String url) {
std::unique_ptr<BearSSL::WiFiClientSecure>client(new BearSSL::WiFiClientSecure);
HTTPClient https;
Serial.print("[HTTPS] begin…\n");
oledPrint("[HTTPS] begin", false);
if (https.begin(*client, url)) { // HTTPS
Serial.print("[HTTPS] GET…\n");
oledPrint("[HTTPS] GET…", false);
// start connection and send HTTP header
int httpCode = https.GET();
// httpCode will be negative on error
if (httpCode > 0) {
// HTTP header has been send and Server response header has been handled
Serial.printf("[HTTPS] GET… code: %d\n", httpCode);
oledPrint("[HTTPS] GET " + String(httpCode), false);
// file found at server
if (httpCode == HTTP_CODE_OK || httpCode == HTTP_CODE_MOVED_PERMANENTLY) {
String payload = https.getString();
} else {
Serial.printf("[HTTPS] GET… failed, error: %s\n", https.errorToString(httpCode).c_str());
oledPrint("[HTTPS] GET " + String(https.errorToString(httpCode)), false);
} else {
Serial.printf("[HTTPS] Unable to connect\n");
oledPrint("[HTTPS] GET Err", false);
void oledInit() {
Serial.println("OLED Start..");
void oledPrint(String message, bool frame) {
char charBuf[15];
message.toCharArray(charBuf, 25);
u8g2.drawStr(10, 25, charBuf);
if (frame) u8g2.drawRFrame(0,0,128,32,4); //

Fujifilm X-E3 Accessories, Tips, and Sample Videos

One of the pieces of tech I bought this year was a mirrorless APS-C digital camera which replaces an ageing Nikon D5000. I wanted something super-compact, but with interchangeable lenses & the ability to record 4K video.

Since were so many options, I started researching cameras & ended up creating a spreadsheet to record all the things I was interested in :)

Long story short, I chose the Fujifilm X-E3 due to the price-vs-features, and 8 months later I’m still happy with my choice; it produces some brilliant images, and is very portable for taking with me & the family.

Video is pretty decent from the camera, as long as you choose the right resolution & FPS. I’ve uploaded samples from the camera into a YouTube playlist for anyone who is interested it how the different modes look.

There are a few things that could be improved; adding 60 fps for 4K video, longer recording times (it’s limited to 10min at 4K, 15 min for 1080p, which is low these days), a dedicated ‘Record’ button (rather than having to dip into the Drive Mode menu to switch from Photo to Video), and a larger flippy screen on the back. Let’s see what the X-E4 brings in 2021!

Camera Bag

Next, if you’re looking for a really compact bag, I really like the Think Tank Mirrorless Mover 10, which is the smallest I could find that fit the camera + the 18-55mm lens. It’s also pretty cheap at about £20-30 (watch out for deals!).

Extra Batteries

There are plenty of cheap 3rd party batteries available; the ones I chose are from Baxxtar and I’ve had no issues with them at all.. performance is just as good as the one that came with the camera.

Companion App

If you get any newer Fujifilm camera, there’s a companion app available which allows you to connect your phone to the camera & do automatic synchronisation of the photos. It does this after you turn the camera off, and sets up an ad-hoc Wifi access point to do the transfer (Bluetooth is too slow). It’s pretty handy, since your photos all end up on your phone, which can then sync with Google Photos when you’re back at home, making the whole process quite seamless.

However, if you use this, one thing you’ll want to do is enable full-resolution files, since by default it downsizes everything to keep the transfer fast. Here’s how to do that;

Synchronise Videos to Your Phone

The Fujifilm app won’t transfer videos, so you’ll need to use some other apps to sync them automatically to your phone using a USB OTG adaptor & SD card reader. One of the apps is called FolderSync, and the other is Automate. Here’s how I use them to automate the process;

That’s it, I hope these tips have helped anyone with an X-E3, or anyone doing their research on what camera to buy.

The Modern Yahoo Pipes Alternative … Azure Logic Apps!

Back in 2015, Yahoo! shut down a service I used to love called Yahoo Pipes. It allowed you to combine and filter XML-based RSS feeds to create a new RSS feed containing the data you wanted.

At the time, I looked for a decent alternative and didn’t find anything.. until recently, when I realised that Logic Apps (which I’d been creating for over a year at work) were actually comparable to a next-gen version of Yahoo Pipes, with A LOT more functionality.

Since Logic Apps / Power Automate (used to be called Flow) is a lot more feature-rich, it does mean it’s a little harder to do what you want with the data, but once you’ve developed a few, you’ll see how much more flexible they are, especially when the world has moved to JSON-based APIs, with XML-based RSS taking a backseat.

While Pipes would just output RSS, Logic Apps can output the result into pretty much anything you want.. JSON, email, other APIs, Twitter, spreadsheets (Office 365 and Google Sheets).. the list goes on and on!

You can get started with Logic Apps for free.. and they’re very low cost to run beyond the Azure trial period. You’re talking pennies to run them monthly, depending on run-frequency & complexity. The pricing calculator can help you if you’re worried about cost. If you created 10 Logic Apps, each containing 10 basic actions and 10 standard actions, and ran them all once a day for 30 days it’d cost you 34p a month;

Actions in Logic Apps are the blocks you see in a flow;

It starts with a ‘Trigger’.. so in this case I’ve chosen a Recurrence (schedule), but you could set one up to trigger on a HTTP call from an RSS reader app, something happening on Twitter, or pretty much anything.. here’s a few of the triggers to choose from…

Just some of the Trigger actions available!

Non-Microsoft products are well represented, so don’t go thinking you’re limited to Sharepoint or Office 365, that’s not the case.

You then design the flow how you want it to behave, e.g. get data from X and Y, merge it together, filter it, query an API, persist some data in a sheet, then send back a piece of JSON.

Choose from Built-In, Standard or Enterprise actions.. you can even build your own custom connectors for systems that aren’t currently listed.

List of the Built-In actions (April 2020)

As you’ll see in the video I put together, to replace Yahoo Pipes, you need to be able to merge, filter, manipulate, and sort JSON. You can do a lot of this with the  built-in actions, but you can use Inline Code to achieve anything else.

Inline Code runs NodeJS and has access to standard built-in Javascript objects.

The one thing that’s Logic Apps aren’t great for compared to Yahoo Pipes is sharing what you’ve created.. it was really easy to adapt what someone else made to suit your needs. Logic Apps don’t work like that at all, and you’ll need to roll your own, which takes some trial-and-error & patience.

Basic filtering (etc) is quite straightforward …

… but Inline Code might take you longer to figure out, so to get you started, here are some Inline Code snippets you might find useful;

Simple Text Filter

const filtered = workflowContext.actions.Current_JSON.outputs.filter(item => item.display_name=='My search string');
return filtered;

Multi-Filter Example Including Regex

var titles = workflowContext.actions.Filter_array_on_year.outputs.body;
var newTitles = [];
const regex = /(.*)(2019|2020|2021).*/i; // Regex for year filtering
titles.forEach(function(item) {
// Additional filter for titles containing 1080p only
if (item.title.indexOf('1080p') > 1) {
// Extract the title and year only
var titleMatch = regex.exec(item.title);
if (titleMatch!=null && titleMatch.length>0) {
var tidyTitle = titleMatch[1]+titleMatch[2];
var pubDay = item.pubdate.substr(5, 2); // Get the day number
tidyTitle = pubDay + " – " + tidyTitle;
// Simple dedupe
if (!newTitles.includes(tidyTitle)) newTitles.push(tidyTitle);
} else {
return newTitles;

view raw


hosted with ❤ by GitHub

Generate HTML for an Email

var titles = workflowContext.actions.Execute_JavaScript_Code.outputs.body;
var html = '';
titles.forEach(function(fulltitle) {
var title = fulltitle.substr(5); // Strip off the first 5 characters.. '12 – Headline' becomes 'Headline'
html += fulltitle +
' | <a href=";+title+'">Somesite</a>' +
' | <a href=";+title+'">Another</a>' +
html += '<br><br>Footer of email goes here';
return html;

view raw


hosted with ❤ by GitHub

This hasn’t been a step-by-step guide, but has hopefully shown you enough to spark your interest.. get yourself a free trial of Azure, and give it a go!


How to list Azure Resources that don’t have Alerts enabled

Alerts are great for letting you know when Logic Apps or Function Apps fail to run for any reason.. the problem is, while you can list out which resources have Alerts, you can’t get a list of resources which don’t have Alerts!

So how do you find out which resources you need to add Alerts to? Well, the CLI has the tools you need, but it’s a bit more complicated than it should be!

First you need a list of resources which have alerts.. you can do that with a command like this;

az resource list --output tsv --resource-type "Microsoft.Insights/metricAlerts" --query [].id

You can run that as part of this command, which is supposed to take the Alert ID list, pipe it into az resource show, and output the value in properties.scopes[0], which is the ID of the resource the alert is set up to monitor.

az resource show --ids $(az resource list --output tsv --resource-type "Microsoft.Insights/metricAlerts" --query [].id) --query properties.scopes[0] --output tsv

However, this fails miserably when the Alert name has a space in it; there ends up being a space in the Alert ID, which makes our command throw an error. UPDATE – Microsoft are figuring out if they can fig it in this bug report I raised.

What I ended up having to do is break up the commands inside a Bash script & use a loop.

alerts=$(az resource list –output tsv –resource-type "Microsoft.Insights/metricAlerts" –query [].id)
alerts=${alerts// /SPACEFIX}
for alert in $alerts
az resource show –ids "${alert//SPACEFIX/ }" –query properties.scopes[0] –output tsv

view raw

hosted with ❤ by GitHub

This will assign all the Alert IDs to a variable, then replaces spaces with ‘SPACEFIX’. We then loop over the Alert IDs, querying the Alert to find what resource they’re monitoring. ‘SPACEFIX’ is replaced within the loop. It’s somewhat of a hack to get round this silly issue!

There might be a better way to handle this, but I didn’t find it in a hurry.

Now we’ve got a list of resources that have alerting enabled, we need to list out all the resources we want to check.. for this example I’m just interested in Logic Apps, and this script will list them out, one resource per line;

logicapps=$(az resource list –output tsv –resource-type "Microsoft.Logic/workflows" –query [].id)
for logicapp in $logicapps
echo "$logicapp"

Now we can redirect the output of the 2 scripts into temporary files, and use the ‘comm’ command to show us the lines that exist in one file that don’t in the other.. here’s how it looks;

echo Finding what Alerts exist already …
./ > listAlertIds.tmp
echo Finding what Logic Apps exist …
./ > listLogicApps.tmp
echo Logic Apps without an Alert are …
comm -23 <(sort -u ./listLogicApps.tmp) <(sort -u ./listAlertIds.tmp)

This gets us what we want.. a list of Logic Apps that don’t have Alerts set up for them. You can pipe the results through grep to check certain Resource Groups, or whatever you need.

Hope this helps save you some time, and gives you a few ideas for useful scripts.

I’ve published some videos on YouTube showing various Azure tips, which you might want to check out!


Sync Photos from a Camera SD Card to your Phone

As I get used to owning a Fujifilm X-E3 compact mirrorless APS-C camera, one thing I’ve just figured out is how I can transfer photos and videos off it to my Android phone.

The Fuji app is supposed to do a lot of this automatically, but I’ve found it unreliable (often not connecting to the camera), doesn’t sync video, and needs to use its own WiFi hotspot for the transfer.

What I’ve figured out is I can use a USB on-the-go (OTG) adaptor, USB SD card reader, and a couple of apps to do everything I need. Here’s how you can set up the same workflow:

Get a USB OTG adaptor and USB SD Card Reader. Make sure your phone can read the SD card when it’s attached.

You’ll need to use a file-browsing app to look for the attached USB device; phone manufacturers usually pre-install one for you.

If you can see the files on your SD card, you can move onto the next step!

Next download FolderSync. This will allow you to sync the files from your SD card to your phones’ internal memory. Set up a ‘folder pair’ to sync the files where you want them (even to the Cloud).

Now you’ve got the files syncing from your SD card to your phone, you may need to perfect things depending on the camera you have. Fujifilm cameras  save videos as .MOV files which don’t show up in Google Photos or the gallery app (not on Samsung phones anyway).

To fix this, I’ve used an app called Automate to rename the copied files to .MOV.mp4. That (weirdly) sorts it out!

If you haven’t seen Automate before, it’s a bit like Tasker, but you build the automation (flow) using blocks.

The MOV renamer process I built looks like this;

This can be added to my homescreen as a shortcut which runs the flow when I tap it.

I’ve published the final version of the flow to the Automate community so that you can download and adapt it however you see fit.

To help show you exactly how this works I’ve created a short video. I go into more detail on the flow I used, and you can see the whole thing in action.

How to Remove Adverts from your new Samsung Smart TV

When I bought the Samsung Q9FN flagship TV the last thing I expected was for there to be adverts built into the menu bar, and for movie trailers to start playing when I powered on the TV each time!

For the adverts in the menu bar, take a look in Settings & check the Policy Agreements. Be sure to un-tick any of the options that agree to advertising or tracking. Once you’ve made those changes, the ads should disappear.

The film trailers are coming from built-in apps like TV Plus & Rakuten. It’s not that easy to figure out how to get rid of them; you certainly can’t uninstall the apps.. Samsung don’t let you do that. They’re like the apps that are pre-installed on smartphones.. most of those you can’t remove either.

There’s apparently a maintenance menu that allows you to disable TV Plus, but the jury is out on whether accessing this service menu voids your warranty. There’s an easier way, which I demonstrate in this video, which definitely doesn’t affect your warranty.

Autopilot for Cosmos db – The Cost of Convenience

In the October 2019 update of Azure, Microsoft added ‘Autopilot’ that automatically controls the throughput of a Cosmos d/b. This is handy for unpredictable workloads.. like irregular imports, when you’ll hit the 400 RU maximum and have a Data Factory Pipeline cut out part way.

This can’t be retroactively set on existing Cosmos db containers.. only new ones.

We compared the cost to a d/b with a manual setting of 400 RUs and ran them for a couple of days with no usage.

This it how it looked in Cost Analysis:

Daily Cost
Yearly Cost
400 RUs $0.75 $273
600 RUs $1.15 $419
Autopilot 4000 RU max $1.13 $412

As you can see, the standing charge is more expensive for Autopilot… $138/yr more expensive than 400 RUs. But equivalent to running at 600 RUs.

If you have a 400 RU container with predictable high-throughput bursts you can run a script to temporarily increase the RUs, then set them back when you’re done.. that’ll save you money, especially if you have a lot of similarly configured containers.

How to Automate PageSpeed Insights for Multiple URLs on a Schedule using Logic Apps or Flow

For the website I’m responsible for, I was interested in capturing the data from the Google PageSpeed Insights tool, and having the data recorded somewhere on a schedule. There’s a blog post on that talked about doing this with a Google Sheet, but it wasn’t quite what I was after; I wanted the data to be collected more regularly.

Instead of using Google Sheets (and a fair amount of code), I decided to use an Azure Logic App (you can use this or Microsoft Flow), which is part of Microsoft’s Cloud platform.

The Logic App is run on a Recurrence trigger which I set to every 6 hours. By collecting the results automatically over time, you’ll see how the changes you’re making to your site affect your PageSpeed scores.


The first step simply defines the URLs you want to check, then it’ll loop over each one & call the PageSpeed API. Go get an API key, and make sure PageSpeed API is enabled.

Results from the API call are parsed out and pushed into a new row in an Excel Online sheet.

If you’re interested in setting this up yourself, I recorded a short video which shows how it works in more detail.

There are a few foibles in Logic Apps which caught me out, first, getting the list of URLs into an Array didn’t work as expected. I had to switch to Code View to correct the escaping of the return character to read;

@split(variables('urlList'), '\n')

The JSON payload from the PageSpeed API is pretty large, so I’ve listed the path to the elements you’ll be interested in below. I’m using split (on space) purely to get at the numerical value, which is more useful in the spreadsheet;

First Contentful Paint

@{split(body('HTTP')?['lighthouseResult']?['audits']?['first-contentful-paint']?['displayValue'], ' ')[0]}

First Meaningful Paint

@{split(body('HTTP')?['lighthouseResult']?['audits']?['first-meaningful-paint']?['displayValue'], ' ')[0]}

Speed Index

@{split(body('HTTP')?['lighthouseResult']?['audits']?['speed-index']?['displayValue'], ' ')[0]}

Time To Interactive

@{split(body('HTTP')['lighthouseResult']['audits']['interactive']['displayValue'], ' ')[0]}

Time to First Byte

@{split(body('HTTP')?['lighthouseResult']?['audits']?['time-to-first-byte']?['displayValue'], ' ')[3]}

Overall, this was quite easy to put together and shows the power of Azure Logic Apps. Being able to do this without any code or (your own) servers, and getting things live in a couple of hours is a fantastic tool to have at your disposal.

Make your own £5 ambient TV backlight

After clearing out some junk, which included an old halogen desk lamp, I was thinking about putting in an LED light behind the PC monitor.

Then I remembered I’d bought a ring of 24 RGB LEDs from Aliexpress last year & hadn’t used it in a project.

I also had a spare Arduino Nano, and all the things I’d need to allow me to hook up a dial (potentiometer) for the light level, and button to cycle through different colour modes.

Here’s a quick video of it in action..


LED Ring – £2
Arduino Nano – £1.75
Breadboard & bits – £1.25

Wiring it up

It’s an easy one to wire up.. I took a few basic examples and mashed them together to get what I wanted from the design.

I’m not an electronics expert, and approached this like I approach software development; write it in manageable/testable chunks, which I can implement and test individually, then bolt it all together.


The code for the project is pretty simple.. I think the most complicated bit is handling the button, which needed debounce functionality.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#define PIN 6 // pin on the Arduino is connected to the LED ring
#define NUMPIXELS 24 // Number of pixels on the LED ring
#define POT_PIN 0 // Potentiometer pin
#define BUTTON_PIN 2 // Button pin
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int showType = 0;
bool oldState = HIGH;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // Declare pushbutton as input
pixels.begin(); // This initializes the NeoPixel library.
void loop() {
// Read the potentiometer value and translate to how many pixels we want to illuminate
int value = analogRead(POT_PIN);
value = map(value, 0, 1023, 0, 25);
// Switch colours if the button is pressed
bool newState = digitalRead(BUTTON_PIN);
if (newState == LOW && oldState == HIGH) {
delay(20); // Short delay to debounce button.
// Check if button is still low after debounce.
newState = digitalRead(BUTTON_PIN);
if (newState == LOW) {
// Cycle through different colour schemes
if (showType > 8) showType=0;
oldState = newState; // Set the last button state to the old state.
uint32_t color = pixels.Color(255,255,255); // default to white when first booted
if (showType==1) color = pixels.Color(0,0,255); // blue
if (showType==2) color = pixels.Color(0,255,0); // green
if (showType==3) color = pixels.Color(255,0,0); // red
if (showType==4) color = pixels.Color(0,127,255);
if (showType==5) color = pixels.Color(255,127,0);
if (showType==6) color = pixels.Color(255,0,127);
if (showType==7) color = pixels.Color(0,255,255);
if (showType==8) color = pixels.Color(127,127,255);
// Illuminate X pixels depending on how far the potentiometer is turned
for(int i=0;i<NUMPIXELS;i++){
if (i<value) {
pixels.setPixelColor(i, color);
} else {
pixels.setPixelColor(i, pixels.Color(0,0,0)); // Don't show anything
}; // This sends the updated pixel configuration to the hardware.

And here are a few pictures of it in place behind the PC monitor..

Samsung Q9FN Tips, Tricks, Secrets & Problems

The 2018 flagship TV from Samsung is the Q9FN (Amazon link: This is a FALD (Full Array Local Dimming) display with 480 LEDs lighting the display, rather than being edge-lit like a lot of the models. This generally means it’s much more capable of providing good contrast ratios. Overall I think it’s a good TV … most of the time….


However, the reality is different from the headlines and reviews in the major publications. What a lot of people have found is that the Contract Enhancement & Local Dimming features can cause light fluctuation problems, which are especially apparent in dark scenes with subtitles.

Light Fluctuations

You can see for yourself in this clip from Narcos Mexico S01E05 at about 45 minutes. This is being viewed via the built-in Netflix player in HDR, with Contrast Enhancement turned on, since without it enabled, dark scenes are waaay too dark to see anything!

It shows how subtitles affect the light levels in other areas of the screen.. like right at the top, nowhere near the subtitles.

Backlight Flicker

This shows how I’m seeing a flicker certain scenes. It’s like the TV can’t quite decide on the light level it’s supposed to display, and clicks into place. I’ve run this at standard speed, then slowed it right down to illustrate the flicker. You’ll need to look closely at the background & look for the light fluctuation.

FALD Confusion!

There are also instances when FALD gets in the way of drawing a background with a solid colour. This video shows a short excerpt from the film Searching (2018).. at about 52 min 30 sec. The FALD back light system has real trouble working out what to do with the dark blue satnav background which should be a solid/uniform colour.. but the bright white roads cause it a lot of problems. This could be a disadvantage of FALD over edge-lit or OLED. At least that’s the way it seems. I’m not entirely sure whether you could even solve this in software.

The blue lights/dots on the left are a reflection of the Xmas tree lights.. so nothing to do with the TV ;)

Tips & Tricks

Okay, enough with the problems, and onto the tips!

Secret Buttons!

At first glance the TV has no physical buttons to control it.. so if you’ve misplaced the remote, it looks like there’s nothing you can do. However, take a look under frame near the logo and there’s a neat directional control + OK button.

Steam Link for Free!

Instead of buying a Steam Link device, there’s actually a free app that lets you stream games from your Gaming PC to your TV. Install the app & plug your controller into the TV and you’re pretty much good to go!

Removing Adverts(!!) from the Menus

Yes, adverts.. in the menus.. on a brand new TV that you paid a lot of money for!

This video shows how I’ve been able to get rid of the movie trailers which annoyingly play so easily. They’re coming from apps like TV Plus & Rakuten. It’s not that easy to figure out how to get rid of them.. you certainly can’t uninstall the apps.. Samsung don’t let you do that :(

I found ads in the menu too.. if you go back into the policy agreements and make sure you’ve not ticked any of the options to agree to them, the ads should go away.

Here’s a link to the Q9FN on Amazon;

Installing SABnzbd on a Raspberry Pi running OSMC

For quite some time I’ve been running SABnzbd on a PC, downloading files, and then transferring them over the local network to a USB drive attached to a Raspberry Pi which is running OSMC. There’s a Linux version of SABnzbd which means I can cut out the PC and have the Pi handle the downloads. It’ll mean I can queue up the downloads from a web interface running on whatever device I have to hand, like an iPad.

First Try

The initial installation of SABnzbd was quite easy;

sudo apt-get install python-openssl unrar par2

sudo apt-get install sabnzbdplus

Edit the settings so that the web client starts up on port 8085..

sudo nano /etc/default/sabnzbdplus


sudo service sabnzbdplus restart

This then allowed me to connect to SABnzbd and transfer over all my settings that I was using on my PC.

Delayed Start

What I found was that SABnzbd started before the USB drive was properly mounted by OSMC, so I disabled the main service from starting up, and added a script to wait for the USB drive to get mounted at a particular path.

There was a good forum post here that pointed me in the right direction.

Disable the default service…

sudo update-rc.d sabnzbdplus disable

Write a quick shell script to wait for the directory/USB drive to be mounted…

nano /home/osmc/


# Wait for this folder to be mounted...

while [ ! -d "$DIR" ]; do
sleep 120

/etc/init.d/sabnzbdplus start

chmod a+x /home/osmc/startsabnzb

Add the script to system startup…

sudo nano /etc/rc.local



The version of SABnzbd that installed above was very dated. That repo doesn’t get updated very often. Here’s how I updated it to the latest version.

sudo su root

echo "deb xenial main" | tee -a /etc/apt/sources.list
echo "deb xenial main" | tee -a /etc/apt/sources.list

apt-key adv --keyserver hkp:// --recv-keys 0x98703123E0F52B2BE16D586EF13930B14BB9F05F

sudo apt-get update

Upgrading sabyenc

This solved the issue where SABnzbd was complaining that sabyenc wasn’t the right version. It uses the 2nd repo (sab-addons) we added in the steps above.

sudo apt-get install python-sabyenc

Final thoughts

SABnzbd runs quite well on the Pi. It is a lot slower than it was on a PC.. it only manages about 3 MB/s on the download on a wired connection (compared to 6 MB/s on a Wifi connection on a laptop), and unpacking is slow.

However, the files are unpacked onto the device which I was manually copying the files to anyway, so that saves time.

%d bloggers like this: