def run(self):
        #open the file
        self.running = True
        self.stopped = False

        try:
            #open astro pi data file
            apr = AstroPiDataReader(self.filename)
            self.apr = apr
            #are there any rows?
            if apr.rowcount > 0:
                
                #create connection to minecraft
                mc = Minecraft.create()

                mc.postToChat("Playback {} Started".format(self.filename))

                #find the position of where to put the ISS tower display
                pos = mc.player.getTilePos()
                pos.z -= 10
                pos.y = mc.getHeight(pos.x, pos.z)

                try:
                    #create the iss tower display
                    isstowerdisplay = ISSTowerMinecraftDisplay(mc, pos)

                    #loop until its stopped
                    found_row = True
                    while self.stopped == False and found_row == True:
                        #get the time started
                        real_time_start = time()
                        last_row_time = apr.get_time()
                        
                        #update the ISS dispay with the data
                        isstowerdisplay.update(
                            apr.get_time(),
                            apr.get_cpu_temperature(),
                            apr.get_temperature(),
                            apr.get_humidity(),
                            apr.get_pressure(),
                            apr.get_orientation(),
                            apr.get_joystick())
                        
                        #move onto the next row
                        found_row = apr.next()

                        #wait until the next row time
                        if found_row:
                            #wait until the time in the real world is greater than the time between the rows
                            while (time() - real_time_start) < ((apr.get_time() - last_row_time) / self.speed) :
                                sleep(0.001)
                finally:
                    isstowerdisplay.clear()
                    mc.postToChat("Playback {} finished".format(self.filename))
                    
            else:
                print("Error - {} contained no data".format(self.filename))

        #catch failed to open file error
        except IOError:
            print("Failed to open file '{}'.".format(self.filename))
            print(sys.exc_info()[1])

        #catch any other error
        except:
            print(sys.exc_info()[0])
            print(sys.exc_info()[1])
                        
        finally:
            self.running = False
            self.stopped = True
    #open the cpu temperature object
    cpu_temp = CPUTemp()
    cpu_temp.open()

    #find the position of where to put the ISS tower display
    pos = mc.player.getTilePos()
    pos.z -= 10
    pos.y = mc.getHeight(pos.x, pos.z)

    #create the iss tower display
    isstowerdisplay = ISSTowerMinecraftDisplay(mc, pos)
    
    try:
        while True:
            #keep updating the display based on new data
            isstowerdisplay.update(
                time(),
                cpu_temp.get_temperature(),
                ap.get_temperature(),
                ap.get_humidity(),
                ap.get_pressure(),
                ap.get_orientation(),
                get_joystick())
            sleep(0.5)
    finally:
        #clear the display and stop everything
        isstowerdisplay.clear()
        cpu_temp.close()
        ap.stop()