I’ve create a small rule to get artist information from lastFM to be displayed in a player widget:
The code to fetch the meta information about the artist (you need a lastFM API key for this to work):
.dsl
import org.openhab.core.model.script.ScriptServiceUtil
import java.net.URLEncoder
val Object _lockArtistMetadataLookup = new Object()
var LoadArtistMetadata = [ String itemPrefix |
val artistItem = ScriptServiceUtil.getItemRegistry?.getItem(itemPrefix + "_MediaArtist")
val summaryItem = ScriptServiceUtil.getItemRegistry?.getItem(itemPrefix + "_ArtistSummary")
var artist = artistItem.state.toString()
// The player is buffering, no artis information available yet.
if ((artist == "ZPSTR_CONNECTING")
|| (artist == "ZPSTR_BUFFERING")) {
return
}
if (artist.trim().isEmpty()) {
return
}
synchronized (_lockArtistMetadataLookup) {
val String url = "http://ws.audioscrobbler.com/2.0/"
val String commandAlbum = "?method=artist.getinfo"
val String artistEncoded = URLEncoder::encode(artist, 'UTF-8')
val String request = url + commandAlbum
+ "&api_key=<your api key>"
+ "&artist=" + artistEncoded
+ "&format=json"
val String json = sendHttpGetRequest(request)
var String artistInfo = transform("JSONPATH", "$..bio.summary", json)
if (artistInfo !== null && artistInfo !== "NULL" && !artistInfo.isEmpty()) {
artistInfo = artistInfo.replaceAll("Read more on Last.fm", "")
if (artistInfo.trim().startsWith("<a href=")) {
summaryItem.postUpdate("Keine Information zum Künstler gefunden.")
return
}
} else {
summaryItem.postUpdate("Keine Information zum Künstler gefunden.")
return
}
if (artistInfo.length > 650) {
artistInfo = artistInfo.substring(0, 650) + " ..."
}
summaryItem.postUpdate(artistInfo.split("<a href").get(0))
}
]
rule "Lade informationen zum Künstler"
when
Item SonosSYMFONISKBuro_MediaArtist changed or
Item SonosSYMFONISKKuche_MediaArtist changed or
Item SonosPortFernsehzimmer_MediaArtist changed or
Item SonosSYMFONISKTechnikraum_MediaArtist changed or
Item SonosSYMFONISKKeller_MediaArtist changed or
Item SonosSYMFONISKBad_MediaArtist changed or
Item SonosSYMFONISKGastezimmer_MediaArtist changed or
Item SonosSYMFONISKSchlafzimmer_MediaArtist changed
then
LoadArtistMetadata.apply(triggeringItemName.split("_").get(0))
end
The widget code:
.yml
uid: player_v2
tags: []
props:
parameters:
- description: Title for the widget
label: Static Title
name: title
required: false
type: TEXT
- description: Player prefix
label: Player prefix
name: prefix
required: true
type: TEXT
parameterGroups: []
timestamp: Apr 13, 2021, 5:15:08 PM
component: f7-card
config:
title: =props.title
style:
min-width: 270px
slots:
default:
- component: f7-row
config:
class: margin display-flex align-items-center
slots:
default:
- component: f7-col
config:
width: 100
xsmall: 100
small: 100
medium: 50
large: 50
xlarge: 50
slots:
default:
- component: f7-row
config:
class: '=(items[props.prefix+"CurrentAlbumCoverArt"].state === "NULL")?"display-none" : "- margin-vertical - justify-content-center"'
slots:
default:
- component: oh-swiper
config:
noBorder: true
noShadow: true
pagination: true
style:
- width: 100%
slots:
default:
- component: oh-image
config:
item: =props.prefix+"_CurrentAlbumCoverArt"
style:
- width: 100%
- component: oh-link
config:
style:
padding: 10px
textColor: black
text: =items[props.prefix+"_ArtistSummary"].state
- component: f7-col
config:
width: 100
xsmall: 100
small: 100
medium: 50
large: 50
xlarge: 50
slots:
default:
- component: f7-row
config:
class: = "display-flex justify-content-center"
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_MediaArtist"].state || "-"
style:
white-space: nowrap
overflow: hidden
font-size: normal
font-weight: bold
font-style: italic
- component: f7-row
config:
class: = "display-flex justify-content-center"
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_MediaTitle"].state || "-"
style:
white-space: nowrap
overflow: hidden
font-size: normal
font-weight: bold
- component: f7-row
config:
class: = "display-flex justify-content-center"
slots:
default:
- component: Label
config:
text: =items[props.prefix+"_CurrentAlbum"].state || "-"
style:
white-space: nowrap
overflow: hidden
font-size: normal
font-style: italic
- component: f7-row
config:
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
- margin-top
slots:
default:
- component: f7-icon
config:
f7: '=(props.prefix+"_Shuffle") ? "shuffle" : ""'
size: 20
color: '=(items[props.prefix+"_Shuffle"].state === "ON") ? "green" : ""'
style:
position: relative
left: +7%
slots:
default:
- component: oh-button
config:
action: command
actionItem: = props.prefix+"_Shuffle"
actionCommand: '=(items[props.prefix+"_Shuffle"].state !== "ON") ? "ON" : "OFF"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: oh-player-item
config:
style:
width: 150px
item: =props.prefix+"_MediaControl"
class:
- display-flex
- margin-
- align-content-stretch
- align-items-center
- justify-content-space-around
- component: f7-icon
config:
f7: '=(props.prefix+"_Repeat") ? (items[props.prefix+"_Repeat"].state === "Off") ? "repeat" : (items[props.prefix+"_Repeat"].state === "Track") ? "repeat_1" : "repeat" : ""'
size: 20
color: '=(items[props.prefix+"_Repeat"].state === "Queue") ? "green" : (items[props.prefix+"_RepeatMode"].state === "track") ? "green" : ""'
style:
position: relative
left: -8%
slots:
default:
- component: oh-button
config:
action: command
actionItem: = props.prefix+"_Repeat"
actionCommand: '=(items[props.prefix+"_Repeat"].state === "Off") ? "Track" : (items[props.prefix+"_Repeat"].state === "Track") ? "Queue": "Off"'
style:
position: absolute
width: 100%
height: 100%
top: 0px
- component: f7-row
config:
class:
- justify-content-space-around
- display-flex
- align-items-center
- align-content-stretch
- margin-top
slots:
default:
- component: f7-card
config:
noShadow: true
class: margin display-flex align-items-center
style:
height: 20px
fontSize: 20px
width: 100%
slots:
default:
- component: f7-icon
config:
f7: speaker_3
class: margin-horizontal margin
size: 25
- component: oh-slider
config:
label: true
style:
width: 75%
--f7-range-knob-color: rgba(122,122,122,0.8)
--f7-range-bar-size: 12px
--f7-range-bar-border-radius: 6px
--f7-range-knob-size: 16px
--f7-range-bar-bg-color: rgba(122,122,122,0.2)
--f7-range-bar-active-bg-color: linear-gradient(to right, rgba(255,255,255,0), rgba(255,255,255,0.6))
--f7-range-knob-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3)
item: =props.prefix+"_Volume"
As I’m using a lot of snippets from the forum I hope this will be useful to someone .