Thanks for replying. I tried your two nodes above, as standalone nodes (not connected to anything else), and it doesn't work. It reloads the page okay, but the image is still the old one.
Here's my flow. In the function node, you'll see I have set msg.payload.coverart explicitly (rather than fetching it from global context).
[{"id":"445633.a4b079cc","type":"ui_template","z":"fe3cc4b6.fad208","group":"74f88df7.9c3154","name":"","order":2,"width":0,"height":0,"format":"<!-- Be aware that element styling may work on one Dashboard page but not another. So look at the\n other UI templates on the page where it works, and ensure CSS is copied over to this one.\n Right now, there's no CSS and it works... -->\n\n<style>\n .art {grid-area: art;}\n .player {grid-area: player;}\n .title {grid-area: title;}\n .artist {grid-area: artist;}\n .album {grid-area: album;}\n\n .player-container {\n display:grid;\n grid-template-areas:\n 'art title title title title'\n 'art artist artist artist artist'\n 'art album album album album'\n 'art player player player player';\n grid-gap:2px;\n }\n \n .player-container > div {\n background-color:#444;\n }\n\n</style>\n\n<div class=\"player-container\">\n <div class=\"art\"><img style=\"height:95px; width:95px;\" src=\"{{msg.payload.coverart}}\"/></div>\n <div class=\"player\">{{msg.payload.name}}</div>\n <div class=\"title\">{{msg.payload.title}}</div>\n <div class=\"artist\">{{msg.payload.artist}}</div>\n <div class=\"album\">{{msg.payload.album}}</div>\n \n \n</div>\n\n\n\n<div style=\"\">vol: {{msg.payload.mixer_volume}}</div>\n<div>play: {{msg.payload.mode}}</div>\n<div>{{msg.payload.playerid}}</div>\n<div></div>\n\n<!-- <div ng-if=\"msg.hasscenes == false\" class=\"noscene\">No scenes created yet. Please save your first scene.</div> -->\n<div class=\"button-container\">\n <md-button style=\"\" ng-click=\"send({action: 'prev'})\" >Prev</md-button>\n <md-button style=\"\" ng-click=\"send({action: 'playpause'})\" >Play / Pause</md-button>\n <md-button style=\"\" ng-click=\"send({action: 'next'})\" >Next</md-button>\n</div>\n","storeOutMessages":false,"fwdInMessages":false,"templateScope":"local","x":720,"y":1640,"wires":[[]]},{"id":"ffeb857e.f118a8","type":"function","z":"fe3cc4b6.fad208","name":"Get Player","func":"// get player object\nmsg.payload = global.get(\"home.squeeze.players.\" + msg.playerid)\nmsg.payload.coverart = \"http://192.168.0.13:9000/music/current/cover.jpg?player=00:04:20:17:df:db\"\nreturn msg;\n","outputs":1,"noerr":0,"x":530,"y":1640,"wires":[["445633.a4b079cc","321d6802.0dcb08"]]},{"id":"2450319.88dc2ce","type":"change","z":"fe3cc4b6.fad208","name":"","rules":[{"t":"set","p":"playerid","pt":"msg","to":"Living_Room_Duet","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":1640,"wires":[["ffeb857e.f118a8"]]},{"id":"d26bb0af.5941f","type":"inject","z":"fe3cc4b6.fad208","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":1640,"wires":[["2450319.88dc2ce"]]},{"id":"74f88df7.9c3154","type":"ui_group","z":"","name":"Audio Visual","tab":"8cd9325b.caa1a","order":3,"disp":true,"width":"6","collapse":false},{"id":"8cd9325b.caa1a","type":"ui_tab","z":"","name":"Living Room","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
I guess it may be possible to test this by switching over an image on a webserver by copying a file over another file. You'd need to remove the first line of the function node, and some of the UI template placeholders but I think this would be possible to test. Thanks!