require 'rubygems'
require 'sonos'
def send_transport_message(name, player, part = '1')
@transport_client ||= Savon.client endpoint: "http://#{player.ip}:#{Sonos::PORT}#{TRANSPORT_ENDPOINT}", namespace: Sonos::NAMESPACE, log: Sonos.logging_enabled
action = "#{TRANSPORT_XMLNS}##{name}"
message = %Q{0#{part}}
@transport_client.call(name, soap_action: action, message: message)
end
# Get information about the currently playing track.
# @return [Hash] information about the current track.
def get_now_playing(player)
return nil if player == nil
response = send_transport_message('GetPositionInfo', player)
body = response.body[:get_position_info_response]
doc = Nokogiri::XML(body[:track_meta_data])
# No music
return nil if doc.children.length == 0
art_path = doc.xpath('//upnp:albumArtURI').inner_text
# TODO: No idea why this is necessary. Maybe its a Nokogiri thing
art_path.sub!('/getaa?s=1=x-sonos-http', '/getaa?s=1&u=x-sonos-http')
{
title: doc.xpath('//dc:title').inner_text,
artist: doc.xpath('//dc:creator').inner_text,
album: doc.xpath('//upnp:album').inner_text,
info: doc.xpath('//r:streamContent').inner_text,
queue_position: body[:track],
track_duration: body[:track_duration],
current_position: body[:rel_time],
uri: body[:track_uri],
album_art: "http://#{player.ip}:#{Sonos::PORT}#{art_path}"
}
end
TRANSPORT_ENDPOINT = '/MediaRenderer/AVTransport/Control'
TRANSPORT_XMLNS = 'urn:schemas-upnp-org:service:AVTransport:1'
system = Sonos::System.new
player = nil
system.speakers.each do |speaker|
if speaker.is_playing?
player = speaker
break
end
end
SCHEDULER.every '10s' do
metadata = get_now_playing(player)
if metadata and player
send_event("albumart", { image: metadata[:album_art] })
send_event("nowplaying", { text: metadata[:artist] + ' - ' + metadata[:title], moreinfo: player.name })
elsif player
send_event("albumart", { image: 'assets/sonoslogo.png' })
send_event("nowplaying", { text: "Nothing playing in " + player.name })
else
send_event("albumart", { image: 'assets/sonoslogo.png' })
send_event("nowplaying", { text: "Unable to connect to any player" })
end
end