Custom Tile - Current UK Weather Forecast (Video) via YouTube API

I’ll start by saying I’m way out of my depth here as I can’t code, but I’m wondering if someone can confirm whether what I’m looking for is achievable with a custom tile?

I recently found that it’s easy to add a url pointing to a YouTube video. For instance if I add a url tile that points to https://www.youtube.com/embed/ycwCbIZe-Es?autoplay=1&modestbranding=1 clicking it will autoplay the UK Met Office Friday Morning forecast video from YouTube and I can open that in modal on my dashboard which is great…instant weather forecast video on my tablets running SharpTools and Fully. The problem is that it’s temporary, in that every forecast has a different embed code (Friday mornings weather is of no interest on Saturday!)

This got me to wondering if there was a way to use a custom tile to fetch the latest forecast. I’ve registered a Google Cloud Platform account and had a play with their API explorer and can see that it’s possible to use the ‘search list’ function. I can enter:

  • YouTube channelID - UC40Tw2tFuMzK305mi7nj8rg
  • q (search query) - morning_forecast|afternoon_forecast
  • maxResults - 1

The results from that will contain the last upload on the Met Office YouTube Channel that is either their morning or afternoon forecast (they release two a day) and in those details will be the videoId needed to enter in the embed url for the tile. The output also gives me the code in various formats (cURL, http, java, javascript and python)

So is it possible to get a custom tile or app to periodically perform that search and replace the videoId within the url so that clicking the tile will always autoplay the latest video? I realise there are other ways (url intent to the Met Office app, or the YouTube page etc) but they’re a bit clunky and I like the idea of a an up to date, single click, video weather forecast.

Any pointers appreciated

Yes, if you have a source to query and it returns the expected YouTube video ID, then you could in theory dynamically construct the embed within a tile. We don’t currently support the ability to open a URL in a modal directly from a Custom Tile, but it could either be embedded in the tile or you could open it in a new window.

Here’s a proof of concept for you:

And a Custom Tile import link for you if you just want to try it out:

:arrow_double_down: Import YouTube Search Custom Tile :arrow_double_down:

You can certainly adjust it to your needs as you see fit, but it has the basics. There are settings for:

  • YouTube API Key
  • YouTube Channel ID
  • query

Then when the tile loads, it runs the query and embeds the first result as a video. Then every 12 hours it refreshes itself (specified around line 74).

1 Like

Amazing! I’ve just tried the tile and that works. I’ve a few (too many, I’m afraid!) queries:

1 - As this video needs to be viewable at a reasonable size (but not take over my dashboard completely), I’m guessing the best way for me to use this would be to make this custom tile large on its own individual dashboard page with a back button. I would then have another tile on my main dashboard link to that dashboard page via it’s SharpTools url (I could use some other weather tile or super tile with my outside temperature on)

2 - When I tried it, the video it has picked is not the latest. For the channel I used, it brought up the Thursday Morning Forecast when the latest is the Friday Afternoon Forecast. I ran the same settings in the YouTube API Explorer panel and that also got the same incorrect result. So I had a look in the API Explorer and I added the below setting:

Executing it again then returned the correct latest forecast (currently Friday Afternoon). Is it possible for me to enter that ‘order’ somewhere within the code so that I get the correct video returned? See edit - sorted!

3 - Finally (I think), can I enter my API Key, YouTube Channel ID, query etc in the code if I wanted to?

Thanks

Edit: I’ve sorted out ‘2’ above. After messing around unsuccessfully, I finally realised that I needed to enter 'date' not date for the order (missing the quotes returned no result and a blank tile)

1 Like

Yeah, that’s a reasonable way to do it.

Sounds like you got it sorted. Nice work!

Without the quotes, it’s trying to reference a variable called ‘date’ whereas when you add the quotes its referring to the literal string ‘date’.

order: date, //referencing a variable called 'date' which doesn't exist
order: 'date', //the actual string 'date'

Sure, I originally had everything hard coded, but figured I would use the Tile Settings to make it more shareable. But if it’s for your own use, you could just delete the various tile settings (from the Custom Tile developer UI), then hard code your settings around line 19-21.

1 Like

Perfect - thanks Josh. I’m sure this custom tile will be of interest to others for weather or perhaps the latest news summary. I’ve messed around with various tiles for weather over the last year or so. I’ve found there’s either not enough detail on them or they’re too fussy/illegible on a tablet. The ability to grab the most up to date video forecast from a specific YouTube channel automatically and view it on demand with a single click is fantastic.

@josh - a quick query regarding the updates as the Google Cloud Console is mind bogglingly complicated with regard to cost and after going through multiple pages I can’t work out if I’ll end up with an unexpected bill/charge!

I created a free tier account ages ago for a Life360 tile that James did (now no longer needs google maps api) and the free credit expired. So I can see that there is a daily quota and that each search has a quota cost of 100. I’m trying to fathom out:

1 - If I put that custom tile on 3 separate dashboards, does each individual instance of the custom tile update individually (using 3 x 100 quota)

2 - Is that update (set at 12 hours in your example) happening in the background once a custom tile is on a dashboard or does the dashboard with the tile present need to be active in a browser. I’m expecting it’s the former as I can see an API call on the Google Cloud Console graph corresponding to the 2 hour interval I’ve set.

It’s difficult to set the update interval correctly as there are two forecasts a day. I’ve looked at the publish time for both over the previous two weeks and can see the new forecasts are published within a one hour time window twice a day, but as there looks to be no way of specifying a time (just an interval), I need to keep the interval quite short.

Yes, since the API calls are being made directly from the tile, each instance updates individually and consumes quota.

It’s only when the tile is actively running. So if your browser or the page showing that tile is closed, then it won’t run.

You could use a schedule, but the tile would need to be updated to account for that logic.

There’s two primary timing functions with JavaScript:

  • setInterval() - recurring
  • setTimeout() - one time

There’s lots of documentation about these online, so I won’t rehash each, but for a schedule the idea is that you calculate the difference between the current time and your expected ‘trigger’ time and use that as the ‘delay’ value in your setTimeout() call.

let today = new Date();
let target = new Date("2022-06-05 08:00"); //tomorrow at 8:00 am 

let delay = target - today; //dates are in millis be default, so the difference is our delay

setTimeout(updateVideo, delay);

The difference here is you have to know what your target date / time is and you have to call setTimeout() each time it refreshes, so it schedules the next refresh. Usually this is done by making a small wrapper method that refreshes and reschedules.

Simplified working example code (tap to expand)

This is just an example and it simplifies certain date/time concepts (rounded hours and doesn’t account for DST), but I wanted to at least demonstrate the concept:

let morningHour = 8; //the raw numeric hour for 8 AM
let eveningHour = 17; //the raw numeric hour for 5 PM

function scheduleRefresh(){
    let now = new Date(); //the current time
    let currentHour = now.getHours(); //the current numeric hour
    let delay; //the delay for our setTimeout which we'll set this later

  	console.log('The current hour is', currentHour, 'and the timestamp is', now);
    //if it's before the morning target, then the morning should be next
    if(currentHour < morningHour){
      console.log('Before morning schedule. Scheduling refresh for morning.')
      delay = (morningHour - currentHour) * 60 * 60 * 1000;
    }
    //if it's after the morning, but before the evening, the evening should be next 
  	else if(currentHour >= morningHour && currentHour < eveningHour){
      console.log('After morning, but before evening. Scheduling refresh for evening.')
      delay = (eveningHour - currentHour) * 60 * 60 * 1000;
    }
    //if it's past the morning target and the evening target, let's schedule for tomorrow morning (maybe we reloaded after the evening refresh)
    else if(currentHour > morningHour && currentHour > eveningHour){ 
      console.log('Past morning and evening schedule, rescheduling for the morning');
      delay = (currentHour - morningHour) * 60 * 60 * 1000; //flip the subtraction, so we get hours until tomorrow (approximate, doesn't work for DST shifts)
    }

    //for logging purposes, we'll convert back to hours
    let delayInHours = delay / (60 * 60 * 1000);
    console.log('Delay (ms) =', delay, ', Delay (hrs) =', delayInHours)

    //Commented out for the demo, but would be uncommented in a real implementation
    //
    //Reschedule ourselves
    //setInterval(refreshAndReschedule, delay);
}

// We would actually want to call a function like this that schedules the refresh AND runs the actual refresh
//
// function refreshAndReschedule(){
//   scheduleRefresh(); //schedule the next one
//   updateVideo(); //and call the refresh / updateVideo method
// }

scheduleRefresh();

If you ran that in your browser console, you would see something like:

The current hour is 20 and the timestamp is Sat Jun 04 2022 20:51:31 GMT-0500 (Central Daylight Time)
Past morning and evening schedule, rescheduling for the morning
Delay (ms) = 43200000 , Delay (hrs) = 12

Thanks @josh that’s provided all the information I need (beautifully explained as always :grinning:).

If I were to have the custom tile on my main always displayed dashboards (I have a main ‘home’ dashboard specific to the room in which the tablet is mounted) then I’ll need to either have a short interval or implement the schedule code which you’ve described above, to ensure the video is up to date. However, I think I’m likely to add a hyperlink that loads a much larger version on its own dashboard page. So in that scenario, an update by interval or scheduled update becomes less important, as an update takes place when I load the custom tile by clicking the hyperlink tile. The video loaded will therefore always be the latest one and that will keep the API calls to a minimum. :+1:

1 Like