diff --git a/libraries/database/broadcasts.py b/libraries/database/broadcasts.py
index 03f47cab52ec3b3023a3dc14429f41519c0f3a69..8c02f160b55ec69ce9f13f0962237aef9d1fc0c3 100644
--- a/libraries/database/broadcasts.py
+++ b/libraries/database/broadcasts.py
@@ -189,15 +189,15 @@ class Schedule(DB.Model, AuraDatabaseModel):
     is_repetition = Column(Boolean())
 
     playlist_id = Column(Integer) #, ForeignKey("playlist.playlist_id"))
-    timeslot_fallback_id = Column(Integer)
+    schedule_fallback_id = Column(Integer)
     show_fallback_id = Column(Integer)
     station_fallback_id = Column(Integer)
 
     playlist = relationship("Playlist",
                             primaryjoin="and_(Schedule.schedule_start==Playlist.schedule_start, Schedule.playlist_id==Playlist.playlist_id, Schedule.show_name==Playlist.show_name)",
                             back_populates="schedule")
-    timeslot_fallback = relationship("Playlist",
-                            primaryjoin="and_(Schedule.schedule_start==Playlist.schedule_start, Schedule.timeslot_fallback_id==Playlist.playlist_id, Schedule.show_name==Playlist.show_name)",
+    schedule_fallback = relationship("Playlist",
+                            primaryjoin="and_(Schedule.schedule_start==Playlist.schedule_start, Schedule.schedule_fallback_id==Playlist.playlist_id, Schedule.show_name==Playlist.show_name)",
                             back_populates="schedule")
     show_fallback = relationship("Playlist",
                             primaryjoin="and_(Schedule.schedule_start==Playlist.schedule_start, Schedule.show_fallback_id==Playlist.playlist_id, Schedule.show_name==Playlist.show_name)",
@@ -289,12 +289,20 @@ class Playlist(DB.Model, AuraDatabaseModel):
         Raises:
             Exception:              In case there a inconsistent database state, such es multiple playlists for given date/time.
         """
-        playlists = DB.session.query(Playlist).filter(Playlist.schedule_start == datetime and Playlist.playlist_id == playlist_id).all()
-        if playlists and len(playlists) > 1:
-            raise Exception("Inconsistent Database State: Multiple playlists for given schedule '%s' and playlist id#%d available!" % (str(datetime), playlist_id))
-        if not playlists:
-            return None
-        return playlists[0]
+        playlist = None
+        playlists = DB.session.query(Playlist).filter(Playlist.schedule_start == datetime).all()
+        # FIXME There are unknown issues with the native SQL query by ID
+        # playlists = DB.session.query(Playlist).filter(Playlist.schedule_start == datetime and Playlist.playlist_id == playlist_id).all()
+        
+        for p in playlists:
+            if p.playlist_id == playlist_id:
+                playlist = p
+        # if playlists and len(playlists) > 1:
+        #     raise Exception("Inconsistent Database State: Multiple playlists for given schedule '%s' and playlist id#%d available!" % (str(datetime), playlist_id))
+        # if not playlists:
+        #     return None
+        # return playlists[0]
+        return playlist
 
 
     @staticmethod
diff --git a/modules/scheduling/calendar.py b/modules/scheduling/calendar.py
index 98712e1b92032f142a1d2cd0e6155fcb28b7dcbb..f7153b99b602a1be7fe7cfece1fccaddff2a49ff 100644
--- a/modules/scheduling/calendar.py
+++ b/modules/scheduling/calendar.py
@@ -52,7 +52,8 @@ class AuraCalendarService(threading.Thread):
     _stop_event = None
     logger = None
     fetched_schedule_data = None
-    url = dict()
+    # FIXME is it needed?
+    #url = dict() 
     data = dict()
     calendar_fetcher = None
 
@@ -75,8 +76,9 @@ class AuraCalendarService(threading.Thread):
 
         self._stop_event = threading.Event()
 
-        self.__set_url__("calendar")
-        self.__set_url__("importer")
+        # FIXME is it needed?
+        # self.__set_url__("api_calendar_url")
+        # self.__set_url__("api_playlist_url")
 
         self.calendar_fetcher = CalendarFetcher(config)
 
@@ -141,26 +143,28 @@ class AuraCalendarService(threading.Thread):
             self.logger.debug("Schedule data: " + str(fetched_schedule_data))
             
             ret_schedule = []
-            #            for schedule in self.fetched_schedule_data:
-            #                if "start" not in schedule:
-            #                    self.logger.warning("No start of schedule given. skipping the schedule: "+str(schedule))
-            #                    continue
-            #                if "end" not in schedule:
-            #                    self.logger.warning("No end of schedule given. skipping the schedule: "+str(schedule))
-            #                    continue
 
             for schedule in fetched_schedule_data:
+
+                # Check schedule for validity
+                if "start" not in schedule:
+                    self.logger.warning("No 'start' of schedule given. Skipping the schedule: %s " % str(schedule))
+                    continue
+                if "end" not in schedule:
+                    self.logger.warning("No 'end' of schedule given. Skipping the schedule: %s " % str(schedule))
+                    continue
+
                 # Store the schedule
                 schedule_db = self.store_schedule(schedule)
 
                 # Store playlists to play
-                self.logger.warning("--- Storing playlist only ---")
                 self.store_playlist(schedule_db, schedule_db.playlist_id, schedule["playlist"])
-
-                #FIXME Store fallbacks in DB logic
-                # self.store_schedule_playlist(schedule_db, schedule, "schedule_fallback", 1)
-                # self.store_schedule_playlist(schedule_db, schedule, "show_fallback", 2)
-                # self.store_schedule_playlist(schedule_db, schedule, "station_fallback", 3)
+                if schedule_db.schedule_fallback_id:
+                    self.store_playlist(schedule_db, schedule_db.schedule_fallback_id, schedule["schedule_fallback"], 1)
+                if schedule_db.show_fallback_id:
+                    self.store_playlist(schedule_db, schedule_db.show_fallback_id, schedule["show_fallback"], 2)
+                if schedule_db.station_fallback_id:
+                    self.store_playlist(schedule_db, schedule_db.station_fallback_id, schedule["station_fallback"], 3)
 
                 ret_schedule.append(schedule_db)
 
@@ -215,9 +219,9 @@ class AuraCalendarService(threading.Thread):
         schedule_db.topic = schedule["show_topics"]
         schedule_db.musicfocus = schedule["show_musicfocus"]
 
-        if schedule["playlist_id"] is None:
-            # FIXME Manually assigned playlist ID.
-            schedule["playlist_id"] = 1
+        # if schedule["playlist_id"] is None:
+        #     # FIXME Manually assigned playlist ID.
+        #     schedule["playlist_id"] = 1
 
         schedule_db.playlist_id = schedule["playlist_id"]
         schedule_db.schedule_fallback_id = schedule["schedule_fallback_id"]
@@ -228,7 +232,8 @@ class AuraCalendarService(threading.Thread):
 
         return schedule_db
 
-    # ------------------------------------------------------------------------------------------ #
+
+
     def store_playlist(self, schedule_db, playlist_id, fetched_playlist, fallbackplaylist_type=0):
         """
         Stores the Playlist to the database.
@@ -245,15 +250,20 @@ class AuraCalendarService(threading.Thread):
         playlist_db.schedule_start = schedule_db.schedule_start
         playlist_db.show_name = schedule_db.show_name
         playlist_db.fallback_type = fallbackplaylist_type
-        playlist_db.entry_count = len(fetched_playlist["entries"])
+        if "entries" in fetched_playlist:
+            playlist_db.entry_count = len(fetched_playlist["entries"])
+        else:
+            playlist_db.entry_count = 0
 
         playlist_db.store(havetoadd, commit=True)
 
-        self.store_playlist_entries(playlist_db, fetched_playlist)
+        if playlist_db.entry_count > 0:
+            self.store_playlist_entries(playlist_db, fetched_playlist)
 
         return playlist_db
 
 
+
     def store_playlist_entries(self, playlist_db, fetched_playlist):
         """
         Stores the playlist entries to the database.
@@ -285,6 +295,8 @@ class AuraCalendarService(threading.Thread):
             entry_num = entry_num + 1
             time_marker += duration
 
+
+
     def store_playlist_entry_metadata(self, playlistentry_db, metadata):
         """
         Stores the meta-data for a PlaylistEntry.
@@ -297,8 +309,8 @@ class AuraCalendarService(threading.Thread):
 
         playlistentrymetadata_db.artificial_entry_id = playlistentry_db.artificial_id
         if "artist" not in metadata:
-            self.logger.warning("Artist not found in metadata for track '%s'. Setting to 'N/a'" % playlistentry_db.filename)
-            playlistentrymetadata_db.artist = "N/a"
+            self.logger.warning("Artist not found in metadata for track '%s'. Setting to 'n/a'" % playlistentry_db.filename)
+            playlistentrymetadata_db.artist = "n/a"
         else:
             playlistentrymetadata_db.artist = metadata["artist"]
         playlistentrymetadata_db.title = metadata["title"]
@@ -307,6 +319,7 @@ class AuraCalendarService(threading.Thread):
 
         playlistentrymetadata_db.store(havetoadd, commit=True)
 
+
     # ------------------------------------------------------------------------------------------ #
 
     # FIXME Needed?
@@ -380,15 +393,17 @@ class AuraCalendarService(threading.Thread):
         return audio_file.info.length
 
     # ------------------------------------------------------------------------------------------ #
-    def __set_url__(self, type):
-        url = self.config.get(type+"url")
-        pos = url.find("?")
+    # FIXME is it needed?
 
-        if pos > 0:
-            self.url[type] = url[0:pos]
-            self.data[type] = url[pos:]
-        else:
-            self.url[type] = url
+    # def __set_url__(self, type):
+    #     #url = self.config.get(type+"url")
+    #     pos = url.find("?")
+
+    #     if pos > 0:
+    #         self.url[type] = url[0:pos]
+    #         self.data[type] = url[pos:]
+    #     else:
+    #         self.url[type] = url
 
     # ------------------------------------------------------------------------------------------ #
     def stop(self):
diff --git a/modules/scheduling/calender_fetcher.py b/modules/scheduling/calender_fetcher.py
index 238cbfc9c976dae9fc50b4fd3e88001a2b9eeaee..7bd3e3c7d533cc3f4aeca19248706386f05556c6 100644
--- a/modules/scheduling/calender_fetcher.py
+++ b/modules/scheduling/calender_fetcher.py
@@ -8,63 +8,86 @@ from datetime import datetime, timedelta
 #from modules.models.schedule import Schedule
 from modules.base.simpleutil import SimpleUtil
 
+
 class CalendarFetcher:
+    """
+    Fetches the schedules, playlists and playlist entries as JSON
+    via the API endpoints.
+    """
     url = dict()
     url_parameter = dict()
     config = None
     logging = None
     has_already_fetched = False
     fetched_schedule_data = None
+
     # FIXME another crutch because of the missing TANK
     used_random_playlist_ids = list()
 
+
     def __init__(self, config):
+        """
+        Constructor
+
+        Args:
+            config (AuraConfig):    Holds the engine configuration
+        """
         self.config = config
         self.logger = logging.getLogger("AuraEngine")
-        self.__set_url__("calendar")
-        self.__set_url__("importer")
-        self.__set_url__("api_show_")
+        self.__set_url__("api_calendar_url")
+        self.__set_url__("api_playlist_url")
+        self.__set_url__("api_show_url")
+
+
+    #
+    #   PUBLIC METHODS
+    #
+
 
     def fetch(self):
-        # fetch upcoming schedules from STEERING
+        """
+        Retrieve all required data from the API.
+        """
+
+        # Fetch upcoming schedules from STEERING
         try:
             self.logger.debug("Fetching schedules from STEERING")
             self.fetched_schedule_data = self.__fetch_schedule_data__()
         except urllib.error.HTTPError as e:
-            self.logger.critical("Cannot fetch from " + self.url["calendar"] + "! Reason: " + str(e))
+            self.logger.critical("Cannot fetch from " + self.url["api_calendar_url"] + "! Reason: " + str(e))
             self.fetched_schedule_data = None
             return None
         except (urllib.error.URLError, IOError, ValueError) as e:
-            self.logger.critical("Cannot connect to " + self.url["calendar"] + "! Reason: " + str(e))
+            self.logger.critical("Cannot connect to " + self.url["api_calendar_url"] + "! Reason: " + str(e))
             self.fetched_schedule_data = None
             return None
 
-        # fetch playlist and fallbacks to the schedules from TANK
+        # Fetch playlist and fallbacks to the schedules from TANK
         try:
             self.logger.debug("Fetching playlists from TANK")
             self.__fetch_schedule_playlists__()
         except urllib.error.HTTPError as e:
-            self.logger.critical("Cannot fetch from " + self.url["importer"] + "! Reason: " + str(e))
+            self.logger.critical("Cannot fetch from " + self.url["api_playlist_url"] + "! Reason: " + str(e))
             self.fetched_schedule_data = None
             return None
         except (urllib.error.URLError, IOError, ValueError) as e:
-            self.logger.critical("Cannot connect to " + self.url["importer"] + "! Reason: " + str(e))
+            self.logger.critical("Cannot connect to " + self.url["api_playlist_url"] + "! Reason: " + str(e))
             self.fetched_schedule_data = None
             return None
 
         return_data = []
-        # gather returndata
+        # Gather returndata
         try:
             for schedule in self.fetched_schedule_data:
-                # skip schedule if no start or end is given
+                # Skip schedule if no start or end is given
                 if "start" not in schedule:
-                    self.logger.warning("No start of schedule given. skipping schedule: " + str(schedule))
+                    self.logger.warning("No start of schedule given. Skipping schedule: " + str(schedule))
                     schedule = None
                 if "end" not in schedule:
-                    self.logger.warning("No end of schedule given. skipping schedule: " + str(schedule))
+                    self.logger.warning("No end of schedule given. Skipping schedule: " + str(schedule))
                     schedule = None
                 if "playlist" not in schedule:
-                    self.logger.warning("No playlist for schedule given. skipping schedule: " + str(schedule))
+                    self.logger.warning("No playlist for schedule given. Skipping schedule: " + str(schedule))
                     schedule = None
 
                 if schedule:
@@ -76,9 +99,19 @@ class CalendarFetcher:
 
         return return_data
 
-    # ------------------------------------------------------------------------------------------ #
+
+
+    #
+    #   PRIVATE METHODS
+    #
+
+
+    # FIXME Refactor for more transparent API requests.
     def __set_url__(self, type):
-        url = self.config.get(type+"url")
+        """
+        Initializes URLs and parameters for API calls.
+        """
+        url = self.config.get(type)
         pos = url.find("?")
 
         if pos > 0:
@@ -87,30 +120,28 @@ class CalendarFetcher:
         else:
             self.url[type] = url
 
-    # ------------------------------------------------------------------------------------------ #
+
+
     def __fetch_schedule_data__(self):
-        servicetype = "calendar"
+        """
+        Fetches schedule data from Steering.
+
+        Returns:
+            ([Schedule]):   An array of schedules
+        """
+        servicetype = "api_calendar_url"
         schedule = None
 
         # fetch data from steering
-        html_response = self.__fetch_data__(servicetype)
+        url = self.__build_url__(servicetype)
+        html_response = self.__fetch_data__(servicetype, url)
 
-        # FIXME move hardcoded test-data to separate testing logic.
         # use testdata if response fails or is empty
         if not html_response or html_response == b"[]":
             self.logger.critical("Got no response from Steering!")
-            #html_response = '[{"schedule_id":1,"start":"' + (datetime.now() + timedelta(hours=0)).strftime('%Y-%m-%d %H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%d %H:00:00') + '","show_id":9,"show_name":"FROzine","show_hosts":"Sandra Hochholzer, Martina Schweiger","is_repetition":false,"playlist_id":2,"schedule_fallback_id":12,"show_fallback_id":92,"station_fallback_id":1,"rtr_category":"string","comment":"Kommentar","languages":"Sprachen","type":"Typ","category":"Kategorie","topic":"Topic","musicfocus":"Fokus"},{"schedule_id":2,"schedule_start":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%d %H:00:00') + '","schedule_end":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%d %H:00:00') + '","show_id":10,"show_name":"FROMat","show_hosts":"Sandra Hochholzer, Martina Schweiger","is_repetition":false,"playlist_id":4,"schedule_fallback_id":22,"show_fallback_id":102,"station_fallback_id":1,"rtr_category":"string","comment":"Kommentar","languages":"Sprachen","type":"Typ","category":"Kategorie","topic":"Topic","musicfocus":"Fokus"},{"schedule_id":3,"schedule_start":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%d %H:00:00') + '","schedule_end":"' + (datetime.now() + timedelta(hours=3)).strftime('%Y-%m-%d %H:00:00') + '","show_id":11,"show_name":"Radio für Senioren","show_hosts":"Sandra Hochholzer, Martina Schweiger","is_repetition":false,"playlist_id":6,"schedule_fallback_id":32,"show_fallback_id":112,"station_fallback_id":1,"rtr_category":"string","comment":"Kommentar","languages":"Sprachen","type":"Typ","category":"Kategorie","topic":"Topic","musicfocus":"Fokus"}]'
-
-            # use testdata if wanted
-            if self.config.get("use_test_data"):
-                # FIXME move hardcoded test-data to separate testing logic.
-                html_response = '[{"id":1,"schedule_id":1,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=0)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":9,"show_name":"TestData: FROzine","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":2,"schedule_fallback_id":12,"show_fallback_id":92,"station_fallback_id":1,"rtr_category":"string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"},' \
-                                 '{"id":2,"schedule_id":2,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":10,"show_name":"TestData: FROMat","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":4,"schedule_fallback_id":22,"show_fallback_id":102,"station_fallback_id":1,"rtr_category":"TestData: string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"},' \
-                                 '{"id":3,"schedule_id":3,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=3)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":11,"show_name":"TestData: Radio für Senioren","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":6,"schedule_fallback_id":32,"show_fallback_id":112,"station_fallback_id":1,"rtr_category":"TestData: string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"}]'
-                self.logger.critical("Using hardcoded Response!")
-            else:
-                html_response = "{}"
 
+            # FIXME move hardcoded test-data to separate testing logic.
+            html_response = self.get_test_schedules()
 
         # convert to dict
         schedule = simplejson.loads(html_response)
@@ -123,59 +154,89 @@ class CalendarFetcher:
         #self.fetched_schedule_data = self.remove_unnecessary_data(schedule)
         return self.remove_unnecessary_data(schedule)
 
-    # ------------------------------------------------------------------------------------------ #
+
+
     def __fetch_schedule_playlists__(self):
+        """
+        Fetches all playlists including fallback playlists for every schedule.
+        This method used the class member `fetched_schedule_data`` to iterate
+        over and extend schedule data.
+        """
         # store fetched entries => do not have to fetch playlist_id more than once
         fetched_entries=[]
 
         try:
-            self.logger.warning("only fetching normal playlists. no fallbacks")
             for schedule in self.fetched_schedule_data:
 
-                # Enhance schedule with details of show (e.g. slug)
+                # Extend schedule with details of show (e.g. slug)
                 schedule = self.__fetch_show_details__(schedule)
-                # retrieve playlist and the fallbacks for every schedule
-                # if a playlist (like station_fallback) is already fetched, it is not fetched again but reused
-                schedule["playlist"]          = self.__fetch_schedule_playlist__(schedule, "playlist_id",          fetched_entries)
-                #schedule["schedule_fallback"] = self.__fetch_schedule_playlist__(schedule, "schedule_fallback_id", fetched_entries)
-                #schedule["show_fallback"]     = self.__fetch_schedule_playlist__(schedule, "show_fallback_id",     fetched_entries)
-                #schedule["station_fallback"]  = self.__fetch_schedule_playlist__(schedule, "station_fallback_id",  fetched_entries)
 
-                #self.logger.info(str(schedule))
+                # Retrieve playlist and the fallback playlists for every schedule.
+                # If a playlist (like station_fallback) is already fetched, it is not fetched again but reused
+                schedule["playlist"]          = self.__fetch_schedule_playlist__(schedule, "playlist_id",          fetched_entries)
+                schedule["schedule_fallback"] = self.__fetch_schedule_playlist__(schedule, "schedule_fallback_id", fetched_entries)
+                schedule["show_fallback"]     = self.__fetch_schedule_playlist__(schedule, "show_fallback_id",     fetched_entries)
+                schedule["station_fallback"]  = self.__fetch_schedule_playlist__(schedule, "station_fallback_id",  fetched_entries)
 
         except Exception as e:
             self.logger.error("Error: "+str(e))
 
-    # ------------------------------------------------------------------------------------------ #
+
+
     def __fetch_show_details__(self, schedule):
-        servicetype = "api_show_"
+        """
+        Fetches details of a show from Steering.
 
-        json_response = self.__fetch_data__(servicetype, "${ID}", str(schedule["show_id"]))
+        Args:
+            schedule (Schedule):    A schedule holding a valid `show_id`
+
+        Returns:
+            (Schedule):             The given schedule with additional show fields set.
+        """
+        servicetype = "api_show_url"
+
+        url = self.__build_url__(servicetype, "${ID}", str(schedule["show_id"]))
+        json_response = self.__fetch_data__(servicetype, url)
         show_details = simplejson.loads(json_response)
 
-        # Augment "schedules" with details of "show"
+        # Extend "schedules" with details of "show"
         schedule["show_slug"] = show_details["slug"]
-        ### ... add more properties here, if needed ... ###
+        ### ...
+        ### ... Add more properties here, if needed 
+        ### ...
 
         return schedule
 
-    # ------------------------------------------------------------------------------------------ #
-    def __fetch_schedule_playlist__(self, schedule, id_name, fetched_schedule_entries):
-        servicetype = "importer"
+
+
+    def __fetch_schedule_playlist__(self, schedule, id_name, fetched_playlists):
+        """
+        Fetches the playlist for a given schedule.
+
+        Args:
+            schedule (Schedule):    The schedule to fetch playlists for
+            id_name (String):       The type of playlist to fetch (e.g. normal vs. fallback)
+            fetched_playlists ([]): Previously fetched playlists to avoid re-fetching
+
+        Returns:
+            ([Schedule]):   Array of playlists
+        """
+        servicetype = "api_playlist_url"
 
         # fetch playlists from TANK
         if not "show_slug" in schedule:
             raise ValueError("Missing 'show_slug' for schedule", schedule)
 
         slug = str(schedule["show_slug"])
-        json_response = self.__fetch_data__(servicetype, "${SLUG}", slug)
+        url = self.__build_url__(servicetype, "${SLUG}", slug)
+        json_response = self.__fetch_data__(servicetype, url)
 
         # if a playlist is already fetched, do not fetch it again
-        for entry in fetched_schedule_entries:
-            # FIXME schedule["playlist_id"] is always None, review if entry["id"] is valid
-            if entry["id"] == schedule[id_name]:
-                self.logger.debug("playlist #" + str(schedule[id_name]) + " already fetched")
-                return entry
+        for playlist in fetched_playlists:
+            # FIXME schedule["playlist_id"] is always None, review if playlist["id"] is valid
+            if playlist["id"] == schedule[id_name]:
+                self.logger.debug("Playlist #" + str(schedule[id_name]) + " already fetched")
+                return playlist
 
         if self.config.get("use_test_data"):
             # FIXME move hardcoded test-data to separate testing logic.
@@ -183,30 +244,76 @@ class CalendarFetcher:
             json_response = self.create_test_data(id_name, schedule)
 
         # convert to list
-        schedule_entries = simplejson.loads(json_response)
-        if "results" in schedule_entries:
-            schedule_entries = schedule_entries["results"][0]
-
-            for entry in schedule_entries["entries"]:
-                if entry["uri"].startswith("file"):
-                    entry["filename"] = self.convert_to_filename(entry["uri"])
+        playlists = simplejson.loads(json_response)
+        pl = None
+
+        if "results" in playlists:
+            # FIXME Currently we use hardcoded playlist and fallback assignments due to issues in Dashboard/Steering/Tank
+            self.logger.warn("FIXME Currently we use hardcoded playlist and fallback assignments due to issues in Dashboard/Steering/Tank")
+            i = 0
+            for playlist in playlists["results"]:
+                
+                pl = playlist
+                # FIXME Always use the first playlist, since the schedule.playlist_id is currently not set via Dashboard:
+                if i == 0 and id_name == "playlist_id":
+                    schedule["playlist_id"] = playlist["id"]
+                    break
+                # FIXME Currently it's not possible to set & query the fallback for a timeslot/show/station; therefore hardcode it:
+                elif i == 1 and id_name == "schedule_fallback_id":
+                    schedule["schedule_fallback_id"] = playlist["id"]
+                    break
+                elif i == 2 and id_name == "show_fallback_id":
+                    schedule["show_fallback_id"] = playlist["id"]
+                    break
+                elif i == 3 and id_name == "station_fallback_id":
+                    schedule["station_fallback_id"] = playlist["id"]
+                    break   
+                else:
+                    pl = None             
+                i += 1
+
+            if pl:
+                # Note: playlists without entries are allowed -> will trigger fallbacks
+                if "entries" in pl:
+                    for entry in pl["entries"]:
+                        if entry["uri"].startswith("file"):
+                            entry["filename"] = self.convert_to_filename(entry["uri"])
+
+                fetched_playlists.append(pl)
+
+
+        return pl
 
-            fetched_schedule_entries.append(schedule_entries)
 
-        return schedule_entries
 
     def convert_to_filename(self, uri):
-        # convert to normal filename
+        """
+        Converts a file-system URI to an actual, absolute path to the file.
+
+        Args:
+            uri (String):   The URI of the file
+
+        Returns:
+            path (String):  Absolute file path
+        """
         e = self.config.get("audiofolder") + "/" + uri[7:] + ".flac"
         if not os.path.isfile(e):
             self.logger.warning("File %s does not exist!" % e)
         return e
 
-    # ------------------------------------------------------------------------------------------ #
-    def __fetch_data__(self, type, placeholder=None, value=None):
-        # Init html_response
+
+
+    def __fetch_data__(self, type, url):
+        """
+        Fetches JSON data for the given URL.
+
+        Args:
+            url (String):       The API endpoint to call
+        
+        Returns:
+            (Byte[]):           An UTF-8 encoded byte object holding the response
+        """
         html_response = b''
-        url = self.__build_url__(type, placeholder, value)
 
         # Send request to the API and read the data
         try:
@@ -239,7 +346,7 @@ class CalendarFetcher:
         url = self.url[type]
         if placeholder:
             url = url.replace(placeholder, value)
-            # print("built URL: "+url)
+            # self.logger.info("built URL: "+url)
         return url
 
 
@@ -304,7 +411,28 @@ class CalendarFetcher:
         return items
 
 
-    # ------------------------------------------------------------------------------------------ #
+
+
+    #
+    #   TESTING
+    #
+
+
+    def get_test_schedules(self):
+        html_response = "{}"
+
+        # use testdata if wanted
+        if self.config.get("use_test_data"):
+            
+            html_response = '[{"id":1,"schedule_id":1,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=0)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":9,"show_name":"TestData: FROzine","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":2,"schedule_fallback_id":12,"show_fallback_id":92,"station_fallback_id":1,"rtr_category":"string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"},' \
+                                '{"id":2,"schedule_id":2,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=1)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":10,"show_name":"TestData: FROMat","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":4,"schedule_fallback_id":22,"show_fallback_id":102,"station_fallback_id":1,"rtr_category":"TestData: string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"},' \
+                                '{"id":3,"schedule_id":3,"automation-id":1,"className":"TestData","memo":"TestData","show_fundingcategory":"TestData","start":"' + (datetime.now() + timedelta(hours=2)).strftime('%Y-%m-%dT%H:00:00') + '","end":"' + (datetime.now() + timedelta(hours=3)).strftime('%Y-%m-%dT%H:00:00') + '","show_id":11,"show_name":"TestData: Radio für Senioren","show_hosts":"TestData: Sandra Hochholzer, Martina Schweiger","title":"TestData:title","is_repetition":false,"playlist_id":6,"schedule_fallback_id":32,"show_fallback_id":112,"station_fallback_id":1,"rtr_category":"TestData: string","comment":"TestData: Kommentar","show_languages":"TestData: Sprachen","show_type":"TestData: Typ","show_categories":"TestData: Kategorie","show_topics":"TestData: Topic","show_musicfocus":"TestData: Fokus"}]'
+            self.logger.critical("Using hardcoded Response!")
+
+        return html_response
+            
+        
+
     def create_test_data(self, id_name, schedule):
         import random
         rand_id = random.randint(1, 10000)