Tome's Land of IT

IT Notes from the Powertoe – Tome Tanasovski

Category Archives: XBMC

HTTP POST with PowerShell to JSON RPC -or- How to Control XBMC via PowerShell

As you may already know, I enjoy making PowerShell do things (see Chumby post).  Recently my wife and I decided it was time to upgrade our ancient LCD panel to a 50″ LED panel.  What started as a simple research project into TV technology has made me once again an expert on audio receivers, speakers, game systems, and most importantly for this post media PC OSes.  Allow me to get to the point: Last night I installed Boxee and said, “How can I control this with PowerShell?”

Fortunately, I found a nice API that lets you do this via HTTP.  Very simple to use, and similar to the method I use to control my Chumby.  I quickly mocked up a few functions and BAM I was in control.  The only problem is that the first subject in the documentation for this API is, “THIS API IS DEPRECATED”.  I eventually found that the new version of XBMC (what Boxee is built off of) has documented the latest API: JSON RPC

What is JSON RPC?

JSON is JavaScript Object Notation, but it has really grown into a method of transfering objects between languages.  It’s very similar to xml in concept, but it’s streamlined to be quick and dirty.  JSON RPC is a method to send commands (methods) via JSON objects to remote computers.  An example of what a JSON command to XBMC looks like is this:

{"jsonrpc": "2.0", "method": "AudioPlayer.Stop", "id": 1}

This tells the JSON RPC server to invoke the AudioPlayer.Stop method.  The id is a number that will be returned by the server for all responses to this invocation.  It’s really a way to keep track of messages if you are sending multiple commands to a JSON RPC server.

So, let’s see the PowerShell code:

$url = "http://localhost:8080/jsonrpc"
$command = '{"jsonrpc": "2.0", "method": "JSONRPC.Version", "id": 1}'

$bytes = [System.Text.Encoding]::ASCII.GetBytes($command)
$web = [System.Net.WebRequest]::Create($url)
$web.Method = "POST"
$web.ContentLength = $bytes.Length
$web.ContentType = "application/x-www-form-urlencoded"
$stream = $web.GetRequestStream()
$stream.Write($bytes,0,$bytes.Length)
$stream.close()

$reader = New-Object System.IO.Streamreader -ArgumentList $web.GetResponse().GetResponseStream()
$reader.ReadToEnd()
$reader.Close()

This above script returns the following message on the latest build of XBMC:

{
   "id" : 1,
   "jsonrpc" : "2.0",
   "result" : {
      "version" : 2
   }
}

Notes:

If you are trying this out on your XBMC:

  1. You must have at least the version 10 Dharma release of XBMC
  2. You must also be sure to enable the web server in your settings
  3. The above code does not use a password for the web site, but you could easily modify it to do so
  4. Boxee users cannot use this code yet – We must wait for a new release and merge of XBMC with Boxee before this will be possible

What’s Next?

Obviously this will be a codeplex project shortly.  While I don’t have that much time to work on it I’d like to at least start getting the overall design of the cmdlets down.  I’d like to see something similar to the chumby cmdlets:

$xbmc = Get-XBMC 192.168.1.111
$xbmc |Set-XBMCVolume 50

Special thanks to Adam for providing me with the C# code to steal mercilessly from.

%d bloggers like this: