diff --git a/README.md b/README.md
index 5027fd4060c2693e0d83c847f7742c52d2e6d4fa..c41c12d69fb4adb84d77b8d79deb31be072a247f 100644
--- a/README.md
+++ b/README.md
@@ -30,13 +30,13 @@ Settings
 The addon has three settings:
 
 * the MQTT broker's IP address (defaults to 127.0.0.1)
-* the MQTT broker's port. This defaults to 1883, which is standard.
+* the MQTT broker's port. This defaults to 1883, which is the MQTT standard port for unencrypted connections.
 * the topic prefix which to use in all published and subscribed topics. Defaults to "kodi/".
 
 
 Topics
 ------
-The addon publishes on the following topics:
+The addon publishes on the following topics (prefixed with the configured topic prefix):
 
 * connected: 2 if the addon is currently connected to the broker, 0 otherwise. This topic is set to 0 with a MQTT will.
 * status/playbackstate: a JSON-encoded object with the fields
@@ -52,10 +52,24 @@ The addon publishes on the following topics:
   - "val": the title of the current playback item
   - "kodi_details": an object with further details about the current playback items. This is effectivly the result
     of a JSON-RPC call Player.GetItem with the properties "title", "streamdetails" and "file"
-    
-  
+
+The addon listens to the following topics (prefixed with the configured topic prefix):
+
+* command/notify: Either a simple string, or a JSON encoded object with the fields "message" and "title". Shows 
+  a popup notification in Kodi
+* command/play: Either a simple string which is a filename or URL, or a JSON encoded object which  correspondents
+  to the Player.Open() JSON_RPC call
+* command/playbackstate: A simple string or numeric with the values:
+  - "0" or "stop" to stop playback
+  - "1" or "resume" to resume playback (when paused)
+  - "2" or "pause" to stop playback (when playing)
+  - "next" to play the next track
+  - "previous" to play the previous track
+
+
 See also
 --------
+- JSON-RPC API v6 in Kodi: http://kodi.wiki/view/JSON-RPC_API/v6
 - Project overview: https://github.com/mqtt-smarthome
   
   
diff --git a/service.mqtt/addon.xml b/service.mqtt/addon.xml
index 67d735fd0bc2541329b3e99ef3dcdd4a7fa43e72..6526d4fe9632ee03486d81814683cb90ac2080eb 100644
--- a/service.mqtt/addon.xml
+++ b/service.mqtt/addon.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<addon id="service.mqtt" name="MQTT Adapter" version="0.2" provider-name="owagner">
+<addon id="service.mqtt" name="MQTT Adapter" version="0.3" provider-name="owagner">
   <requires>
     <import addon="xbmc.python" version="2.19.0"/>
   </requires>
diff --git a/service.mqtt/changelog.txt b/service.mqtt/changelog.txt
index efd664b8af5896178a14a79ff1237fd29052a96f..ace370521fb27aa01a673a9982e57b7cbcb35811 100644
--- a/service.mqtt/changelog.txt
+++ b/service.mqtt/changelog.txt
@@ -1,3 +1,9 @@
+V0.3 - 2015-03-22 - owagner
+  - fixed division by zero when switching TV channels
+  - now supports command/notify to send notifications
+  - now supports command/play to start playback of files or items
+  - now supports command/playbackstate to control the playback state
+  
 V0.2 - 2015-03-22 - owagner
   - refactored as a Kodi addon
   
\ No newline at end of file
diff --git a/service.mqtt/service.py b/service.mqtt/service.py
index 5cf524e9ec42eec9c864db19df74d897eb1f4a6e..e128edbaaa54636060d36d18a1700cd8ca1a7ab9 100644
--- a/service.mqtt/service.py
+++ b/service.mqtt/service.py
@@ -17,6 +17,11 @@ def sendrpc(method,params):
     xbmc.log("MQTT: JSON-RPC call "+method+" returned "+res)
     return json.loads(res)
 
+#
+# Publishes a MQTT message. The topic is built from the configured
+# topic prefix and the suffix. The message itself is JSON encoded,
+# with the "val" field set, and possibly more fields merged in.
+#
 def publish(suffix,val,more):
     global topic,mqc
     robj={}
@@ -28,6 +33,10 @@ def publish(suffix,val,more):
     xbmc.log("MQTT: Publishing @"+fulltopic+": "+jsonstr)
     mqc.publish(fulltopic,jsonstr,qos=0,retain=True)
 
+#
+# Set and publishes the playback state. Publishes more info if
+# the state is "playing"
+#
 def setplaystate(state,detail):
     global activeplayerid
     if state==1:
@@ -41,7 +50,10 @@ def setplaystate(state,detail):
 
 def convtime(ts):
     return("%02d:%02d:%02d" % (ts/3600,(ts/60)%60,ts%60))
-    
+
+#
+# Publishes playback progress
+#
 def publishprogress():
     global player
     if not player.isPlaying():
@@ -50,15 +62,16 @@ def publishprogress():
     tt=player.getTotalTime()
     if pt<0:
         pt=0
-    progress=(pt*100)/tt
+    if tt>0:
+        progress=(pt*100)/tt
+    else:
+        progress=0
     state={"kodi_time":convtime(pt),"kodi_totaltime":convtime(tt)}
     publish("progress",round(progress,1),state)
 
-def reportprogress():
-    global monitor
-    while not monitor.waitForAbort(30):
-        publishprogress()
-
+#
+# Publish more details about the currently playing item
+#
 def publishdetails():
     global player,activeplayerid
     if not player.isPlaying():
@@ -67,6 +80,9 @@ def publishdetails():
     publish("title",res["result"]["item"]["title"],{"kodi_details":res["result"]["item"]})
     publishprogress()
 
+#
+# Notification subclasses
+#
 class MQTTMonitor(xbmc.Monitor):
     def onSettingsChanged(self):
         global mqc
@@ -102,6 +118,54 @@ class MQTTPlayer(xbmc.Player):
     def onPlayBackSpeedChanged(speed):
         setplaystate(1,"speed")
         
+    def onQueueNextItem():
+        xbmc.log("MQTT onqn");
+
+#
+# Handles commands
+#
+def processnotify(data):
+    try:
+        params=json.loads(data)
+    except ValueError:
+        parts=data.split(None,2)
+        params={"title":parts[0],"message":parts[1]}
+    sendrpc("GUI.ShowNotification",params)
+
+def processplay(data):
+    try:
+        params=json.loads(data)
+        sendrpc("Player.Open",params)
+    except ValueError:
+        player.play(data)
+
+def processplaybackstate(data):
+    if data=="0" or data=="stop":
+        player.stop()
+    elif data=="1" or data=="resume":
+        if not player.isPlaying():
+            player.pause()
+    elif data=="2" or data=="pause":
+        if player.isPlaying():
+            player.pause()
+    elif data=="next":
+        player.playnext()
+    elif data=="previous":
+        player.playprevious()        
+
+def processcommand(topic,data):
+    if topic=="notify":
+        processnotify(data)
+    elif topic=="play":
+        processplay(data)
+    elif topic=="playbackstate":
+        processplaybackstate(data)
+    else:
+        xbmc.log("MQTT: Unknown command "+topic)
+
+#
+# Handles incoming MQTT messages
+#
 def msghandler(mqc,userdata,msg):
     try:
         global topic
@@ -122,6 +186,10 @@ def disconnecthandler(mqc,userdata,rc):
     time.sleep(5)
     mqc.reconnect()
 
+#
+# Starts connection to the MQTT broker, sets the will
+# and subscribes to the command topic
+#
 def startmqtt():
     global topic,mqc
     mqc=mqtt.Client()
@@ -137,14 +205,16 @@ def startmqtt():
     mqc.publish(topic+"connected",2,qos=1,retain=True)
     mqc.loop_start()
 
+#
+# Addon initialization and shutdown
+#
 if (__name__ == "__main__"):
     global monitor,player
     xbmc.log('MQTT: MQTT Adapter Version %s started' % __version__)
     monitor=MQTTMonitor()
     player=MQTTPlayer()
-    progressthread=threading.Thread(target=reportprogress)
-    progressthread.start()
     startmqtt()
-    monitor.waitForAbort()
+    while not monitor.waitForAbort(30):
+        publishprogress()
     mqc.loop_stop(True)
     
\ No newline at end of file