TV Guide (UK)

Hi all.

I searched for a way to add a TV Guide that I can display on wall mounted tablets. There were a couple of posts, but nothing really explained how to get a good TV Guide, so I just did it myself and I am pretty pleased with the result so I thought I would share.

There are two parts… COLLECTION, and DISPLAY.

Collection is using a Rest Sensor in your Configuration.yaml. You will want one for every TV Channel you want to collect data for…

  # EPG Collectors
  - platform: rest
    resource: "https://www.freesat.co.uk/tv-guide/api/0?channel=560"
    scan_interval: 28800
    name: EPG_BBCOne
    value_template: "BBC One"
    json_attributes_path: "$.0"
    json_attributes:
      - event

You can see here that I am collecting BBC One from the Freesat API on channel 560. You can easily find the channel number from the Freesat API here;

freesat.co.uk/tv-guide/api

This will create a new sensor (once restarted) that will look like this;

(The attribute does get truncated in the picture, but you get the gist…).

Now you have the Sensor and the Attribute with all of the TV Guide in for the day, you can add it to your dashboard with a little Markdown Card as follows;

<div style="text-align:center">
  <img src="/local/media/images/BBCOneHD_uk.jpg" alt="Amazon Music"/>
</div>
<b>{{ states('sensor.epg_bbcone') }}</b>

  {% set ns = namespace(counter=0) %} 

  {% for time in states.sensor.epg_bbcone.attributes.event -%}

  {% if ns.counter == 0  %}
   {% if (as_datetime(time.startTime+time.duration)+timedelta(hours=0) > now())  %}
   {% set ns.counter = ns.counter + 1 %}
   <b><h2>{{ (as_datetime(time.startTime)+timedelta(hours=1)).strftime("%H:%M")}}  : {{time.name}}</b></h2>
   {{ time.description}}<br>
   <img src="upload://9GHxzX9iFBeNiOjEsaSAyF1SiOn.jpeg">
   {% endif %}

  {% else %}
   {% if (as_datetime(time.startTime)+timedelta(hours=0) > now())  %}
   <details>  
   <summary>
   {{ (as_datetime(time.startTime)+timedelta(hours=1)).strftime("%H:%M")}}  : {{time.name}}
   </summary>
     <br>{{ time.description}}<br><p>
   <img src="upload://9GHxzX9iFBeNiOjEsaSAyF1SiOn.jpeg">
   </details>
    {% endif %}
  
  {% endif %}

 {% endfor %}.

This will now give you a lovely dashboard view of your favourite channels like so…

Obvs, the way you lay out your card on your dashboard is tots up to you.

Hope this is useful to someone.

7 Likes

This is fantastic. I’ve been hoping for this for ages. Thanks so much!

1 Like

Hi @mbarne36

I’m trying to set the state of the sensor to the current programme name. Here’s my Yaml so far:

# TV Listings
- resource: "https://www.freesat.co.uk/tv-guide/api/0?channel=560"
  scan_interval: 28800
  sensor:
  - name: Freesat BBC One
    value_template: >-
      {% for event in value_json ??? %}
      {% if event.startTime < as_timestamp(now()) and event.startTime + event.duration > as_timestamp(now())%}
      {{ event.name }}
      {% endif %}
      {% endfor %}
    json_attributes_path: "$.0"
    json_attributes:
      - event

Do you know what I should use where I have the ‘???’ to get the collection of events?

Thanks

This should probably be moved to the “Share your projects” category.
It is a textbook example for that category and it should not be buried in questions in the configuration category and then forgotten in a few days.

Didn’t know there was such a place… so thank you!

I tried to do this too, and failed :-(. I am sure there is a solution to it though…

I’ve moved the post to the Share Projects category as suggested

Hello.

I found some time to work this out for you… actually it was pretty easy in the end…

So this now puts the current event into the State for the Sensor.

My next little play is to spin up a new sensor to capture the now-playing image of the current programme so I can put it on the wall mounted tablets running Home Remote. :slight_smile:

  # EPG Collectors
  - platform: rest
    resource: "https://www.freesat.co.uk/tv-guide/api/0?channel=560"
    scan_interval: 28800
    name: EPG_BBCOne
    value_template: >-
      {% set ns = namespace(counter=0) %} 
      {% for time in value_json.0.event %}
      {% if ns.counter == 0  %}
      {% if (as_datetime(time.startTime+time.duration)+timedelta(hours=0) > now())  %}
      {% set ns.counter = ns.counter + 1 %}
      {{ (as_datetime(time.startTime)+timedelta(hours=1)).strftime("%H:%M")}}  : {{time.name}}
      {% endif %}
      {% endif %}
      {% endfor %}
    json_attributes_path: "$.0"
    json_attributes:
      - event

Hi, I’m fully onboard.

With a 28800 scan interval, I went back to the original naming, and the value_template is too slow.
No point storing the images, they change too often.

Thanks though …

The original setup works great.

Excellent work! I’ve played with the markdown card a bit, although it was a learn as you go along exercise and this is what works for me.

<div style="text-align:center">
<img src="https://msaas.img.freeviewplay.net/cache/ms/img/chan/chan/BBCOneHD-Web-Logo-135x76.jpg" alt="Amazon Music"/>
</div>
{% set ns = namespace(counter=0) %} 
{% for time in states.sensor.epg_bbcone.attributes.event -%}
{% if ns.counter == 0  %}
{% if (as_datetime(time.startTime+time.duration)+timedelta(hours=0) > now())  %}
{% set ns.counter = ns.counter + 1 %}
<b><h2>{{ (as_datetime(time.startTime)+timedelta(hours=1)).strftime("%H:%M") }}  : {{time.name}}</b></h2>
{{ time.description }}<br>
<img src="https://msaas.img.freeviewplay.net/cache{{ time.image}}">{% endif %}
{% else %}
{% if (as_datetime(time.startTime)+timedelta(hours=0) > now())  %}
<details>  
<summary>
{{ (as_datetime(time.startTime)+timedelta(hours=1)).strftime("%H:%M")}}  : {{time.name}}
</summary>
<br>{{ time.description}}<br><p>
<img src="upload://9GHxzX9iFBeNiOjEsaSAyF1SiOn.jpeg">
</details>
{% endif %}
{% endif %}
{% endfor %}

Current program image is displayed. Today’s task is to have a look at having just the one card displaying the current channel. I’m not sure if it would be better but it’s fun tinkering!