A widget to stream latest Tele M1 News (Swiss local TV station) to Chromecast (Audio or Video)

As I like to listen the local news in the evening I’ve created a widget to cast the latest local news show to my audio cast device in my bedroom (it works surprisingly well to just listen to a TV news show):

image

Widget Code
uid: tele_m1_aktuell
tags:
  - multimedia
props:
  parameters: []
  parameterGroups: []
timestamp: Jul 9, 2023, 10:37:13 PM
component: oh-list-card
config:
  accordionList: true
  colorTheme: blue
  mediaList: false
  noBorder: false
  noShadow: false
  outline: true
slots:
  default:
    - component: oh-list-item
      config:
        accordionItem: true
        accordionItemOpened: false
        after: =`Aktuell - ${@'Tele_M1_Aktuell'}`
        media: https://ch.az-cdn.ch/static/2.27.2/telem1/device-icons/48x48.png
        mediaItem: tru
        title: Tele M1
      slots:
        accordion:
          - component: f7-col
            slots:
              default:
                - component: f7-row
                  slots:
                    default:
                      - component: f7-col
                        slots:
                          default:
                            - component: f7-segmented
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      action: command
                                      actionCommand: https://klive.kaltura.com/env/cluster-1-d.live.nvp1/live/hls/p/1719221/e/1_ljzy3evp/tl/main/st/0/t/aG1N1BfzMxQdZwBcLmPaLw/index-s32.m3u8
                                      actionItem: chromecast_tv_stream
                                      iconF7: radiowaves_right
                                      text: Live TV
                                  - component: oh-button
                                    config:
                                      action: command
                                      actionCommand: =`https://cdnapisec.kaltura.com/p/1719221/sp/171922100/playManifest/entryId/${@'tele_m1_aktuell_video_id'}/protocol/https/format/applehttp/flavorIds/1_xg1cypuc,1_od67xqgg,1_wsuylbb5,1_f5ktwp0d/a.m3u8?playSessionId=10012dac-3505-6027-844a-90357325306c:76e7250c-ce3c-902a-6451-9770d7dc2578&referrer=aHR0cHM6Ly93d3cudGVsZW0xLmNoL2FrdHVlbGwvc29ubnRhZy0xNDk3Mjc5ODQ=&clientTag=html5:v1.3.0`
                                      actionItem: chromecast_tv_stream
                                      iconF7: tv
                                      text: TV
                                  - component: oh-button
                                    config:
                                      action: toggle
                                      actionCommand: =`http://cdnapisec.kaltura.com/p/1719221/sp/171922100/playManifest/entryId/${@'tele_m1_aktuell_video_id'}/protocol/http/format/applehttp/flavorIds/1_xg1cypuc,1_od67xqgg,1_wsuylbb5,1_f5ktwp0d/a.m3u8?playSessionId=10012dac-3505-6027-844a-90357325306c:76e7250c-ce3c-902a-6451-9770d7dc2578&referrer=aHR0cHM6Ly93d3cudGVsZW0xLmNoL2FrdHVlbGwvc29ubnRhZy0xNDk3Mjc5ODQ=&clientTag=html5:v1.3.0`
                                      actionCommandAlt: = ''
                                      actionItem: Google_Home_Schlafzimmer__Play_URI
                                      active: =@'Google_Home_Schlafzimmer__Media_Control' === 'PLAY'
                                      iconF7: bed_double
                                      text: Schlafzimmer
                - component: f7-row
                  config:
                    visible: =@'Google_Home_Schlafzimmer__Play_URI' === `http://cdnapisec.kaltura.com/p/1719221/sp/171922100/playManifest/entryId/${@'tele_m1_aktuell_video_id'}/protocol/http/format/applehttp/flavorIds/1_xg1cypuc,1_od67xqgg,1_wsuylbb5,1_f5ktwp0d/a.m3u8?playSessionId=10012dac-3505-6027-844a-90357325306c:76e7250c-ce3c-902a-6451-9770d7dc2578&referrer=aHR0cHM6Ly93d3cudGVsZW0xLmNoL2FrdHVlbGwvc29ubnRhZy0xNDk3Mjc5ODQ=&clientTag=html5:v1.3.0`
                  slots:
                    default:
                      - component: widget:simple_player
                        config:
                          control_item: Google_Home_Schlafzimmer__Media_Control
                          volume_item: Google_Home_Schlafzimmer__Volume

The data I load directly from the web packge via http binding:

UID: http:url:b9394d12a5
label: 📺 Tele M1 Aktuell - (HTML)
thingTypeUID: http:url
configuration:
  authMode: BASIC
  ignoreSSLErrors: true
  baseURL: https://www.telem1.ch/aktuell
  delay: 0
  stateMethod: GET
  refresh: 600
  commandMethod: GET
  contentType: text/html
  timeout: 3000
  bufferSize: 2048
channels:
  - id: telem1_aktuell_html
    channelTypeUID: http:string
    label: Tele M1 Aktuell - HTML
    description: ""
    configuration:
      mode: READONLY

With the help of a RegEx transformation the JSON with the media resources is extracted into a channel of the thing:

The following JavaScrip rule identifies the latest show and provides the info required for the ui widget:

configuration: {}
triggers:
  - id: "3"
    configuration:
      itemName: _Tele_M1_Aktuell__HTML_Tele_M1_Aktuell__HTML
    type: core.ItemStateUpdateTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      type: application/javascript;version=ECMAScript-2021
      script: >-
        {
          const json = items.getItem("_Tele_M1_Aktuell__HTML_Tele_M1_Aktuell__HTML").state;
          
          if (json !== 'NULL') {
            const videoAssets = actions.Transformation.transform("JSONPATH", '$..[?(@.video)].assetId', json);
            const assetId = JSON.parse(videoAssets).sort().reverse()[0];

            console.trace(`Tele M1 📺 - latest video: ${assetId}`);

            const filter = `$..[?(@.assetId === \"${assetId}\" && @.video)]`;
            const title = actions.Transformation.transform("JSONPATH", `${filter}.title`, json);
            const videoKey = actions.Transformation.transform("JSONPATH", `${filter}.video.id`, json);
            const kalturaKey = actions.Transformation.transform("JSONPATH", "$..[\""+ videoKey +"\"].kaltura.id", json);
            const kalturaId = actions.Transformation.transform("JSONPATH", "$..[\""+ kalturaKey +"\"].kalturaId", json);

            console.trace(`Tele M1 📺\nVideo Key: ${videoKey}\nKaltura Key: ${kalturaKey}\nKaltura Id: ${kalturaId}`);
            console.trace(`Tele M1 📺 - Aktuell vom ${title} - ${kalturaId}`);

            items.getItem("Tele_M1_Aktuell").sendCommand(title);
            items.getItem("tele_m1_aktuell_video_id").sendCommand(kalturaId);
          } else {
            console.warn(`Tele M1 - Keine gültigen JSON-Daten erhalten: [${json}]`)
          }
        }
    type: script.ScriptAction

If you post this to the Marketplace users can install and configure the widget without copy/paste/edit.