Getting closer....
/**
* Album Art Tile
*
* Copyright 2021 Simon Burke
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
* for the specific language governing permissions and limitations under the License.
*
* Change History:
*
* Date Who What
* ---- --- ----
* 2021-10-02 Simon Burke Original Creation
*
*/
metadata {
definition (name: "Album Art Tile", namespace: "simnet", author: "Simon Burke") {
capability "Refresh"
attribute "artist" , "string"
attribute "album" , "string"
attribute "albumMBId" , "string"
attribute "coverArtURL" , "string"
attribute "coverArtTile" , "string"
command "setCurrentAlbum" , [[name:"partist", type: "STRING", description: "Enter the Artist" ], [name:"palbum", type: "STRING", description: "Enter the Album" ] ]
command "correctAlbumMBId", [[name:"partist", type: "STRING", description: "Enter the Artist" ], [name:"palbum", type: "STRING", description: "Enter the Album" ], [name:"pmbId", type: "STRING", description: "Enter the Music Brainz ID" ] ]
command "removeAlbum" , [[name:"partist", type: "STRING", description: "Enter the Artist" ], [name:"palbum", type: "STRING", description: "Enter the Album" ] ]
command "removeArtist" , [[name:"partist", type: "STRING", description: "Enter the Artist" ] ]
command "clearAlbumList"
}
preferences {
input(name: "country", type: "string", title:"Preferred country for searches (2 characters)", displayDuringSetup: true, defaultValue: "US")
input(name: "DebugLogging", type: "bool", title:"Enable Debug Logging", displayDuringSetup: true, defaultValue: false)
input(name: "WarnLogging", type: "bool", title:"Enable Warning Logging", displayDuringSetup: true, defaultValue: true)
input(name: "ErrorLogging", type: "bool", title:"Enable Error Logging", displayDuringSetup: true, defaultValue: true)
input(name: "InfoLogging", type: "bool", title:"Enable Description Text (Info) Logging", displayDuringSetup: true, defaultValue: false)
}
}
def removeAlbum(String partist, String palbum) {
if(state.albumList?.get((partist)) != null) {
debugLog("removeAlbum: ${partist} found, removing ${palbum}")
state.albumList.get((partist)).remove((palbum))
if(state.albumList.get((partist)).isEmpty()) { state.albumList.remove((partist)) }
}
else { debugLog("removeAlbum: Unable to find ${partist}") }
}
def removeArtist(String partist) {
if(state.albumList?.get((partist)) != null) {
debugLog("removeArtist: ${partist} found")
state.albumList.remove((partist))
}
else { debugLog("removeArtist: Unable to find ${partist}") }
}
void clearAlbumList() {
state.albumList = [:]
}
void installed() {
debugLog("installed: device installed")
state.albumList = [:];
}
void updated() { debugLog("updated: device updated") }
void refresh() { debugLog("refresh: device refreshed") }
void setCurrentAlbum(String partist, String palbum) {
String[] mbIdList = new String[3];
String mbId = null;
String coverArtURL = null;
String urlEncoding = 'UTF-8';
String bodyJson = '';
def getParams = [:];
def headers = [:];
String uri = '';
if(!findAlbum(partist, palbum)) {
String uriNoCountry = "https://musicbrainz.org/ws/2/release/?query=artistname:%22${URLEncoder.encode(partist,urlEncoding)}%22%20AND%20release:%22${URLEncoder.encode(palbum,urlEncoding)}%22%20AND%20primarytype:%22Album%22%20AND%20status:%22official%22";
uri = "${uriNoCountry}%20AND%20country:%22${country}%22";
debugLog("setCurrentAlbum: Testing - ${uri}")
headers.put("accept", "application/json")
getParams = [
uri: uri,
headers: headers,
contentType: "application/json",
requestContentType: "application/json",
body : bodyJson
]
try {
httpGet(getParams)
{ resp ->
debugLog("setCurrentAlbum: resp = ${resp.data}")
if(resp.data.releases[0]?.id?.value != null) { mbIdList[0] = "${resp.data.releases[0]?.id?.value}" }
if(resp.data.releases[1]?.id?.value != null) { mbIdList[1] = "${resp.data.releases[1]?.id?.value}" }
if(resp.data.releases[2]?.id?.value != null) { mbIdList[2] = "${resp.data.releases[2]?.id?.value}" }
debugLog("setCurrentAlbum: mbIds = ${mbIdList[0]}, ${mbIdList[1]}, ${mbIdList[2]}")
}
}
catch(Exception e)
{
errorLog("setCurrentAlbum: Error looking up MusicBrainz Id - ${e}")
}
if(mbIdList[0] == null) {
getParams.uri = uriNoCountry;
httpGet(getParams)
{ resp ->
debugLog("setCurrentAlbum: resp = ${resp.data}")
if(resp.data.releases[0]?.id?.value != null) { mbIdList[0] = "${resp.data.releases[0]?.id?.value}" }
if(resp.data.releases[1]?.id?.value != null) { mbIdList[1] = "${resp.data.releases[1]?.id?.value}" }
if(resp.data.releases[2]?.id?.value != null) { mbIdList[2] = "${resp.data.releases[2]?.id?.value}" }
debugLog("setCurrentAlbum: mbIds = ${mbIdList[0]}, ${mbIdList[1]}, ${mbIdList[2]}")
}
}
boolean imageFound = false;
for(int i = 0; i < 3 && coverArtURL == null && mbIdList[i] != null; i++) {
mbId = mbIdList[i];
uri = "https://ia600900.us.archive.org/14/items/mbid-${mbId}/index.json"
getParams.uri = uri
try {
httpGet(getParams) { resp ->
//log.debug("setCurrentAlbum: resp = ${resp.data.images}")
//log.debug("setCurrentAlbum: resp = ${resp.data.images?.get(0)}")
coverArtURL = "${resp.data.images?.get(0)?.thumbnails?.small}";
debugLog("setCurrentAlbum: Cover Art URL = ${coverArtURL}")
}
}
catch(Exception e)
{
errorLog("setCurrentAlbum: Error looking up Cover Art Archive - ${e}")
}
}
if(coverArtURL != null) {
debugLog("setCurrentAlbum: updating album list for Artist: ${partist}, Album: ${palbum}, MB Id: ${mbId}, Cover Art URL: ${coverArtURL}");
updateAlbumList(partist, palbum, mbId, coverArtURL)
}
}
setCoverArtTile(partist, palbum)
}
boolean findAlbum(String partist, String palbum) {
boolean result = false;
def albumDetail = [:];
if(state.albumList != null) {
albumDetail = state.albumList.get(partist)?.get(palbum);
}
if (albumDetail != null) { result = true }
return result
}
def getArtistAlbums(String partist) {
def artistAlbums;
if(state.albumList != null) {
artistAlbums = state.albumList.get(partist);
}
if(artistAlbums == null){ artistAlbums = [:] }
debugLog("getArtistAlbums: Artist = ${partist}, albums = ${artistAlbums}")
return artistAlbums
}
void updateAlbumList(String partist, String palbum, String pmbId, String pcoverArtURL) {
def artistAlbums = [:];
debugLog("updateAlbumList: method called")
if(!findAlbum(partist, palbum)) {
debugLog("updateAlbumList: Album not found, about to add ${partist}, Album: ${palbum}, MB Id: ${pmbId}, Cover Art URL: ${pcoverArtURL}");
if (state.albumList == null) { state.albumList = [:] }
artistAlbums = getArtistAlbums(partist)
if(artistAlbums.isEmpty()) { artistAlbums.putAll([(palbum): [(pmbId): (pcoverArtURL)]]) }
else { artistAlbums.putAll([(palbum): [(pmbId): (pcoverArtURL)]]) }
state.albumList.putAll([(partist): artistAlbums])
}
}
void setAlbum(String palbum) {
debugLog("setAlbum: album provided = ${palbum}")
device.sendEvent(name: "album", value: palbum);
}
void setArtist(String partist) {
debugLog("setArtist: artist provided = ${partist}")
device.sendEvent(name: "artist", value: partist);
}
void setAlbumMBId(String pmbId) {
debugLog("setAlbumMBId: Album MB Id provided = ${pmbId}")
device.sendEvent(name: "albumMBId", value: pmbId);
}
void setCoverArtURL(pcoverArtURL) {
debugLog("setCoverArtURL: Cover Art URL provided = ${pcoverArtURL}")
device.sendEvent(name: "coverArtURL", value: pcoverArtURL);
}
void setCoverArtTile(String partist, String palbum) {
debugLog("setCoverArtTile: Artist provided = ${partist}, Album provided = ${palbum}")
String coverArtURL = '';
if(findAlbum(partist, palbum)) {
setArtist(partist);
setAlbum(palbum);
setAlbumMBId(coverArtURL = state.albumList.get(partist).get(palbum).entrySet().iterator().next().getKey());
coverArtURL = state.albumList.get(partist).get(palbum).entrySet().iterator().next().getValue();
device.sendEvent(name: "coverArtTile", value: "<img src=\"${coverArtURL}\" />")
setCoverArtURL(coverArtURL);
}
}
void correctAlbumMBId(String partist, String palbum, String pmbId) {
debugLog("correctAlbumMBId: Artist provided = ${partist}, Album provided = ${palbum}, MB Id = ${pmbId}")
debugLog("correctAlbumMBId: Yet to be implemented")
}
//Utility methods
void debugLog(debugMessage) {
if (DebugLogging == true) {log.debug(debugMessage)}
}
void errorLog(errorMessage) {
if (ErrorLogging == true) { log.error(errorMessage)}
}
void infoLog(infoMessage) {
if(InfoLogging == true) {log.info(infoMessage)}
}
void warnLog(warnMessage) {
if(WarnLogging == true) {log.warn(warnMessage)}
}