Squeeze Control Custom Widget

Hi,

I want to share my first Custom Widget for MainUI…
It’s a fully configurable widget which loads data dynamically to the selected player.

It is intended to work with the existing Squeezebox Binding

Here’s how the widget looks on my Smartphone

You have to pay attention to a few things before usage.

the according player item-names should follow this structure:

  • Prefix-Playername-Suffix

e.g.

...
SqueezeLivingroomTitle
...
SqueezeBedroomArtist
...
SqueezeBathroomGenre
etc.

you have to fill the widget configuration

and provide some information there:

  • your prefix
  • your suffixes
  • a comma separated list of your available players
  • an item for storing player selection e.g. SqueezePlayerSelect or similar (you have to create one and use the item type String)
  • the item which provides your server’s favorite-list

after that you will be able to control all your squeezebox players with one widget :wink:

and here is the yaml code

uid: SqueezeControl
tags:
  - card
props:
  parameters:
    - description: Title for the widget
      label: Static Widget Title
      name: title
      required: false
      type: TEXT
    - description: Prefix for the Items
      label: Item Prefix
      name: prefix
      required: true
      type: TEXT
    - context: item
      description: Item for Playerselection
      label: Player Selector Item
      name: selected
      required: true
      type: TEXT
    - context: item
      description: Item for Serverlist
      label: Serverlist Item
      name: favoriteslist
      required: true
      type: TEXT
    - description: Suffix for CoverArt
      label: CoverArt Suffix
      name: coverart
      required: true
      type: TEXT
    - description: Suffix for Artist
      label: Artist Suffix
      name: artist
      required: true
      type: TEXT
    - description: Suffix for Album
      label: Album Suffix
      name: album
      required: true
      type: TEXT
    - description: Suffix for Title
      label: Title Suffix
      name: title
      required: true
      type: TEXT
    - description: Suffix for Duration
      label: Duration Suffix
      name: duration
      required: true
      type: TEXT
    - description: Suffix for Player Control
      label: Control Suffix
      name: control
      required: true
      type: TEXT
    - description: Suffix for Volume
      label: Volume Suffix
      name: volume
      required: true
      type: TEXT
    - description: Suffix for Shuffle
      label: Shuffle Suffix
      name: shuffle
      required: true
      type: TEXT
    - description: Suffix for Repeat
      label: Repeat Suffix
      name: repeat
      required: true
      type: TEXT
    - description: Suffix for Sleepmode
      label: Sleepmode Suffix
      name: sleepmode
      required: true
      type: TEXT
    - description: Suffix for Power
      label: Power Suffix
      name: power
      required: true
      type: TEXT
    - description: Suffix for Favorites
      label: Favorites Suffix
      name: favorites
      required: true
      type: TEXT
    - description: List of known Players (comma separated)
      label: Available Players
      name: playerlist
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Jun 25, 2021, 12:05:48 AM
component: f7-card
slots:
  default:
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-label-card
                  config:
                    item: =props.selected
                    width: 100%
                    height: auto
                    action: options
                    actionItem: =props.selected
                    actionFeedback: =items[props.selected].state
                    actionOptions: =props.playerlist
    - component: f7-row
      slots:
        default:
          - component: oh-image
            config:
              item: =props.prefix+items[props.selected].state+props.coverart
              style:
                width: 100%
                height: auto
    - component: f7-row
      config:
        class:
          - justify-content-left
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    class:
                      - text-align-right
                      - margin-top
                      - margin-right
                    text: =items[props.prefix+items[props.selected].state+props.artist].state
    - component: f7-row
      config:
        class:
          - justify-content-left
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    class:
                      - text-align-right
                      - margin-right
                    text: =items[props.prefix+items[props.selected].state+props.title].state
    - component: f7-row
      config:
        class:
          - justify-content-left
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    class:
                      - text-align-right
                      - margin-right
                    text: =items[props.prefix+items[props.selected].state+props.album].state
    - component: f7-row
      config:
        class:
          - justify-content-left
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: Label
                  config:
                    pattern: %1$tM:%1$tS
                    class:
                      - text-align-right
                      - margin-right
                    text: =items[props.prefix+items[props.selected].state+props.duration].displayState
    - component: f7-row
      config:
        class:
          - padding-top
          - padding-bottom
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-player-controls
                  config:
                    item: =props.prefix+items[props.selected].state+props.control
    - component: f7-row
      config:
        class:
          - padding-top
          - padding-bottom
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-slider
                  config:
                    label: Volume
                    item: =props.prefix+items[props.selected].state+props.volume
                    min: 0
                    max: 100
                    step: 2
                    unit: "%"
    - component: f7-row
      config:
        height: 30px
        class:
          - padding-top
          - padding-bottom
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-label-card
                  config:
                    fontSize: -6
                    item: =props.prefix+items[props.selected].state+props.shuffle
                    action: options
                    actionItem: =props.prefix+items[props.selected].state+props.shuffle
                    actionFeedback: =items[props.prefix+items[props.selected].state+props.shuffle].state
                    actionOptions: 0=Off,1=Shuffle Songs,2=Shuffle Albums
          - component: f7-col
            slots:
              default:
                - component: oh-label-card
                  config:
                    fontSize: -6
                    item: =props.prefix+items[props.selected].state+props.repeat
                    action: options
                    actionItem: =props.prefix+items[props.selected].state+props.repeat
                    actionFeedback: =items[props.prefix+items[props.selected].state+props.repeat].state
                    actionOptions: 0=Off,1=Repeat Song,2=Repeat Playlist
          - component: f7-col
            slots:
              default:
                - component: oh-label-card
                  config:
                    fontSize: -6
                    label: Sleepmode
                    item: =props.prefix+items[props.selected].state+props.sleepmode
                    action: options
                    actionItem: =props.prefix+items[props.selected].state+props.sleepmode
                    actionFeedback: =items[props.prefix+items[props.selected].state+props.sleepmode].state
                    actionOptions: 0=Off,15=15 Minutes,30=30 Minutes,45=45 Minutes,60=60 Minutes,90=90 Minutes
    - component: f7-row
      config:
        class:
          - padding-top
          - padding-bottom
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-button
                  config:
                    text: POWER
                    iconF7: power
                    fill: true
                    color: red
                    action: command
                    actionCommand: toggle
                    actionFeedback: Power
                    actionItem: =props.prefix+items[props.selected].state+props.power
                    class:
                      - margin-top
    - component: f7-row
      slots:
        default:
          - component: f7-col
            slots:
              default:
                - component: oh-label-card
                  config:
                    item: =props.prefix+items[props.selected].state+props.favorites
                    width: 100%
                    height: auto
                    action: options
                    actionItem: =props.prefix+items[props.selected].state+props.favorites
                    actionFeedback: =items[props.prefix+items[props.selected].state+props.favorites].state
                    actionOptions: =items[props.favoriteslist].state

I hope I provided all information needed - if not feel free to ask…

1 Like

I like the player selector feature. I’ll have to revisit my Chromecast widget and add something like that.

Thanks for posting!

1 Like

you’re welcome :wink:
since my widget is based on yours this should be a nobrainer…

have a nice day