diff --git a/Pipfile b/Pipfile
index 29084d528646b28c8b8f3b4c71029fea380182d6..4d2b47851232f73fda0307dbcfeac52002cd3490 100644
--- a/Pipfile
+++ b/Pipfile
@@ -20,6 +20,7 @@ flask-socketio= "==4.3.1"
 apscheduler = "==3.6.3"
 
 # services
+icalendar = "==4.0.7"
 python-jenkins = "==1.5.0"
 
 [dev-packages]
diff --git a/src/logic/service/services/IcsService.py b/src/logic/service/services/IcsService.py
new file mode 100644
index 0000000000000000000000000000000000000000..70f42a43e56cb0119e255f81fa853d1a59414bd5
--- /dev/null
+++ b/src/logic/service/services/IcsService.py
@@ -0,0 +1,67 @@
+from dataclasses import dataclass
+from datetime import datetime
+
+from icalendar import Calendar
+from typing import Dict
+
+from TheCodeLabs_BaseUtils.MultiCacheKeyService import MultiCacheKeyService
+
+
+@dataclass
+class CalendarEvent:
+    summary: str = ''
+    uid: str = ''
+    description: str = ''
+    location: str = ''
+    start: datetime = ''
+    end: datetime = ''
+
+
+class IcsService(MultiCacheKeyService):
+    """
+    Fetches information from a given ics calendar file.
+    """
+
+    EXAMPLE_SETTINGS = {
+        "path": "path/to/my/calendar.ics"
+    }
+
+    def _fetch_data(self, settings: Dict) -> Dict:
+        events = []
+
+        with open(settings['path'], 'rb') as f:
+            calendar = Calendar.from_ical(f.read())
+            for component in calendar.walk():
+                event = CalendarEvent('event')
+
+                if component.get('SUMMARY') is None:
+                    continue
+
+                event.summary = component.get('SUMMARY')
+                event.uid = component.get('UID')
+
+                if component.get('DESCRIPTION') is None:
+                    continue
+
+                event.description = component.get('DESCRIPTION')
+
+                event.location = component.get('LOCATION')
+
+                if hasattr(component.get('dtstart'), 'dt'):
+                    event.start = component.get('dtstart').dt
+
+                if hasattr(component.get('dtend'), 'dt'):
+                    event.end = component.get('dtend').dt
+
+                event.url = component.get('URL')
+                events.append(event)
+        return {'events': events}
+
+
+if __name__ == '__main__':
+    s = IcsService()
+
+    events = s.get_data('0815', 5, {'path': 'C:/Users/RobertG/Desktop/abfallkalender_2020_richard-wagner-str.ics'})['events']
+    for x in events:
+        # if 'Papier' in x.summary:
+        print(x.summary)
diff --git a/src/logic/tile/tiles/GarbageContainerScheduleTile.html b/src/logic/tile/tiles/GarbageContainerScheduleTile.html
new file mode 100644
index 0000000000000000000000000000000000000000..bf77d2fabc53be34df27326b304bb8130ea43764
--- /dev/null
+++ b/src/logic/tile/tiles/GarbageContainerScheduleTile.html
@@ -0,0 +1,68 @@
+<style>
+    .garbageContainerScheduleTile {
+        background-color: #2F2F2F;
+        font-size: 3.5vmin;
+        border-radius: 1vh;
+        font-weight: bold;
+        flex-direction: row;
+    }
+
+    .garbageContainerScheduleTile .icon {
+        font-size: 10vmin;
+    }
+
+    .garbageContainerScheduleTile .content {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+        width: 85%;
+        height: 85%;
+    }
+
+    .garbageContainerScheduleTile .entries {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        justify-content: space-between;
+        flex: 1;
+    }
+
+    .garbageContainerScheduleTile .temperatures {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+    }
+
+    .garbageContainerScheduleTile .temperature-entry {
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        padding-left: 3vmin;
+        justify-content: space-between;
+    }
+
+    .garbageContainerScheduleTile .label {
+        font-size: 2vmin;
+    }
+
+    .garbageContainerScheduleTile .wind {
+        display: flex;
+        flex-direction: row;
+        align-items: center;
+        justify-content: space-between;
+        font-size: 2vmin;
+        padding-top: 1vmin;
+    }
+
+    .garbageContainerScheduleTile .windSpeed {
+        padding-left: 1vmin;
+    }
+</style>
+
+<div class="garbageContainerScheduleTile">
+    <div class="content">
+        {{ nextEventDate }}
+    </div>
+</div>
diff --git a/src/logic/tile/tiles/GarbageContainerScheduleTile.py b/src/logic/tile/tiles/GarbageContainerScheduleTile.py
new file mode 100644
index 0000000000000000000000000000000000000000..5e11a70bda60333609335224c5fa0daa1eef5c04
--- /dev/null
+++ b/src/logic/tile/tiles/GarbageContainerScheduleTile.py
@@ -0,0 +1,55 @@
+import os
+from datetime import datetime
+from typing import Dict, List
+
+from flask import Blueprint
+
+from logic.service.ServiceManager import ServiceManager
+from logic.service.services.IcsService import CalendarEvent
+from logic.tile.Tile import Tile
+
+
+class GarbageContainerScheduleTile(Tile):
+    DATE_FORMAT = '%d.%m. (%a)'
+
+    EXAMPLE_SETTINGS = {
+        "path": "path/to/my/calendar.ics",
+        "garbageType": "Papier" or "Gelbe Säcke" or "Bioabfall" or "Restabfall"
+    }
+
+    def __init__(self, uniqueName: str, settings: Dict, intervalInSeconds: int):
+        super().__init__(uniqueName, settings, intervalInSeconds)
+
+    def fetch(self, pageName: str) -> Dict:
+        icsService = ServiceManager.get_instance().get_service_by_type_name('IcsService')
+
+        cacheKey = f'{pageName}_{self._uniqueName}'
+        events = icsService.get_data(cacheKey, self._intervalInSeconds, self._settings)['events']
+
+        eventsForGarbageType = [x for x in events if self._settings['garbageType'] in x.summary]
+        nextEvent = self.__find_next_date(eventsForGarbageType)
+
+        nextEventDate = '--.--.'
+        if nextEvent:
+            nextEventDate = datetime.strftime(nextEvent.start, self.DATE_FORMAT)
+
+        # TODO: set locale for weekday
+        # TODO: set icon for garbageType
+
+        return {
+            'nextEventDate': nextEventDate
+        }
+
+    def __find_next_date(self, events: List[CalendarEvent]) -> CalendarEvent or None:
+        now = datetime.now().date()
+        for event in events:
+            if event.start < now:
+                continue
+            return event
+        return None
+
+    def render(self, data: Dict) -> str:
+        return Tile.render_template(os.path.dirname(__file__), __class__.__name__, nextEventDate=data['nextEventDate'])
+
+    def construct_blueprint(self, pageName: str, *args, **kwargs):
+        return Blueprint(f'{pageName}_{__class__.__name__}_{self.get_uniqueName()}', __name__)