diff --git a/README.md b/README.md
index b131a2769f49fc03e0d0e6f6fb81750c4c184837..a1109cee926efec4b463f1a439585054b9fbcd45 100644
--- a/README.md
+++ b/README.md
@@ -59,6 +59,8 @@ as the `hausgeist.py` file. This file must look like this:
     PIPI_DELAY=<Delay in seconds as spam protection. This is the number of seconds between two chat announcements>
     PIPI_THRESHOLD_1=<First Threshold. Used to change color and show, it is a bit more urgent>
     PIPI_THRESHOLD_2=<Second Threshold. Used to change color and show, that it is really urgent>
+    PIPIMETER_LOOP=<Number of minutes, when the current pipi count should get sent into the chat, when the stream is life>
+    PIPI_RESET_THRESHOLD=<Number of minutes, the stream had to be offline, when it turns live, to reset the pipi count>
     PIPI_COLOR_0=<Neutral color used for !pause command, and if pipi vote counter is 0>
     PIPI_COLOR_1=<Color used when pipi vote is at least one, and less than PIPI_THRESHOLD_1>
     PIPI_COLOR_2=<Color used when pipi vote is at least PIPI_THRESHOLD_1, and less than PIPI_THRESHOLD_2>
@@ -73,6 +75,9 @@ as the `hausgeist.py` file. This file must look like this:
     VOTE_MINUS=<Negative Chat Emote>
     VOTE_NEUTRAL=<Neutral Chat Emote>
     
+    # Giveaway Bot
+    GIVEAWAY_BOT=<Chat Color that is used to send giveaway messages>
+    
     # Redis Server
     REDIS_HOST=<IP of the Redis-Server>
     REDIS_PORT=<Port of the Redis-Server>
diff --git a/giveaway_cog.py b/giveaway_cog.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c0d09f3fb1af59f557cc1362458d97029c697dd
--- /dev/null
+++ b/giveaway_cog.py
@@ -0,0 +1,74 @@
+import os
+import random
+
+from twitchio.ext import commands
+
+
+@commands.core.cog(name="GiveawayCog")
+class GiveawayGog:
+    def __init__(self, bot):
+        self.bot = bot
+        self.giveaway_enabled = False
+        self.giveaway_entries = {}
+        self.COLOR = os.getenv("GIVEAWAY_COLOR")
+
+    @commands.command(name="giveaway")
+    async def cmd_giveaway(self, ctx):
+        """ take part at the giveaway """
+
+        if self.giveaway_enabled:
+            self.giveaway_entries[ctx.author.name] = 1
+
+    @commands.command(name="giveaway-open")
+    async def cmd_giveaway_open(self, ctx):
+        """ Reset and Open the giveaway """
+
+        if ctx.author.is_mod:
+            self.giveaway_enabled = True
+            self.giveaway_entries = {}
+            await self.bot.send_me(ctx,
+                                   "Das Giveaway wurde gestartet. Schreibe !giveaway in den Chat um daran teilzunehmen.",
+                                   self.COLOR)
+
+    @commands.command(name="giveaway-reopen")
+    async def cmd_giveaway_reopen(self, ctx):
+        """ Reopen the giveaway after closing it (so reset) """
+
+        if ctx.author.is_mod:
+            self.giveaway_enabled = True
+            await self.bot.send_me(ctx,
+                                   "Das Giveaway wurde wieder geöffnet. Schreibe !giveaway in den Chat um daran teilzunehmen.",
+                                   self.COLOR)
+
+    @commands.command(name="giveaway-close")
+    async def cmd_giveaway_close(self, ctx):
+        """ Close the giveaway """
+
+        if ctx.author.is_mod:
+            self.giveaway_enabled = False
+            await self.bot.send_me(ctx, "Das Giveaway wurde geschlossen. Es kann niemand mehr teilnehmen.", self.COLOR)
+
+    @commands.command(name="giveaway-draw")
+    async def cmd_giveaway_draw(self, ctx):
+        """ Draw a giveaway winner """
+
+        if ctx.author.is_mod:
+            if len(self.giveaway_entries) > 0:
+                winner = random.choice(list(self.giveaway_entries))
+                entry_count = len(self.giveaway_entries)
+                del self.giveaway_entries[winner]
+                await self.bot.send_me(ctx,
+                                       f"Es wurde aus {entry_count} Einträgen ausgelost. Und der Gewinner ist... @{winner}",
+                                       self.COLOR)
+            else:
+                await self.bot.send_me(ctx, "Es muss Einträge geben, damit ein Gewinner gezogen werden kann.",
+                                       self.COLOR)
+
+    @commands.command(name="giveaway-reset")
+    async def cmd_giveaway_reset(self, ctx):
+        """ Reset giveaway entrys """
+
+        if ctx.author.is_mod:
+            self.giveaway_enabled = False
+            self.giveaway_entries = {}
+            await self.bot.send_me(ctx, "Das Giveaway wurde geschlossen und alle Einträge entfernt.", self.COLOR)
diff --git a/hausgeist.py b/hausgeist.py
index 42c0cbd3a5e4dbe880d35ec0c6f6475c0f13e05f..a480b4cd8710f8ad6f1d7886d9cfd1af9606e2cf 100644
--- a/hausgeist.py
+++ b/hausgeist.py
@@ -1,30 +1,24 @@
 import asyncio
 import os
-import random
 import time
+from abc import ABC
 
 import redis
 from dotenv import load_dotenv
 from twitchio.dataclasses import Context, Message, Channel
 from twitchio.ext import commands
 
+from giveaway_cog import GiveawayGog
+from pipi_cog import PipiCog
+
 load_dotenv()
 IRC_TOKEN = os.getenv("IRC_TOKEN")
+CLIENT_ID = os.getenv("CLIENT_ID")
+CLIENT_SECRET = os.getenv("CLIENT_SECRET")
 NICK = os.getenv("NICK")
 CHANNEL = os.getenv("CHANNEL")
 PREFIX = os.getenv("PREFIX")
 
-# pipibot related
-PIPI_DELAY = int(os.getenv("PIPI_DELAY"))
-PIPI_THRESHOLD_1 = int(os.getenv("PIPI_THRESHOLD_1"))
-PIPI_THRESHOLD_2 = int(os.getenv("PIPI_THRESHOLD_2"))
-PIPI_COLOR_0 = os.getenv("PIPI_COLOR_0")
-PIPI_COLOR_1 = os.getenv("PIPI_COLOR_1")
-PIPI_COLOR_2 = os.getenv("PIPI_COLOR_2")
-PIPI_COLOR_3 = os.getenv("PIPI_COLOR_3")
-pipi_task = None
-pipi_votes = {}
-
 # vote bot related
 VOTE_DELAY_END = int(os.getenv("VOTE_DELAY_END"))
 VOTE_DELAY_INTERIM = int(os.getenv("VOTE_DELAY_INTERIM"))
@@ -38,16 +32,47 @@ vote_interim_task = None
 vote_task_new = None
 votes = {}
 
-# giveaway bot related
-giveaway_enabled = False
-giveaway_entries = {}
 
-bot = commands.Bot(
-    irc_token=IRC_TOKEN,
-    prefix=PREFIX,
-    nick=NICK,
-    initial_channels=[CHANNEL]
-)
+class HaugeBot(commands.Bot, ABC):
+    def __init__(self):
+        self.IRC_TOKEN = os.getenv("IRC_TOKEN")
+        self.CLIENT_ID = os.getenv("CLIENT_ID")
+        self.CLIENT_SECRET = os.getenv("CLIENT_SECRET")
+        self.NICK = os.getenv("NICK")
+        self.CHANNEL = os.getenv("CHANNEL")
+        self.PREFIX = os.getenv("PREFIX")
+        super().__init__(irc_token=IRC_TOKEN, prefix=PREFIX, nick=NICK, initial_channels=[CHANNEL], client_id=CLIENT_ID,
+                         client_secret=CLIENT_SECRET)
+        self.pipi_cog = PipiCog(self)
+        self.giveaway_cog = GiveawayGog(self)
+        self.add_cog(self.pipi_cog)
+        self.add_cog(self.giveaway_cog)
+
+    @staticmethod
+    async def send_me(ctx, content, color):
+        """ Change Text color to color and send content as message """
+
+        if type(ctx) is Context or type(ctx) is Channel:
+            await ctx.color(color)
+            await ctx.send_me(content)
+        elif type(ctx) is Message:
+            await ctx.channel.color(color)
+            await ctx.channel.send_me(content)
+
+    async def event_ready(self):
+        print('Logged in')
+        await self.pipi_cog.start_pipimeter_loop()
+
+    @staticmethod
+    def get_percentage(part, total):
+        """ Calculate percentage """
+        if total != 0:
+            return round(part / total * 100, 1)
+
+        return 0
+
+
+bot = HaugeBot()
 
 # redis-server related
 R_HOST = os.getenv("REDIS_HOST")
@@ -70,9 +95,6 @@ except Exception as ex:
 
 if useRedis and r:
     # update constants in Redis-DB
-    r.set('pipiDelay', PIPI_DELAY)
-    r.set('pipiT1', PIPI_THRESHOLD_1)
-    r.set('pipiT2', PIPI_THRESHOLD_2)
     r.set('voteMin', VOTE_MIN_VOTES)
     r.set('voteDelayEnd', VOTE_DELAY_END)
     r.set('voteDelayInter', VOTE_DELAY_INTERIM)
@@ -85,51 +107,6 @@ if useRedis and r:
     p.execute()  # transaction end
 
 
-def get_percentage(part, total):
-    """ Calculate percentage """
-    if total != 0:
-        return round(part / total * 100, 1)
-
-    return 0
-
-
-async def notify_pipi(ctx, use_timer=True, message=None):
-    """ Write a message in chat, if there hasn't been a notification since PIPI_DELAY seconds. """
-
-    global pipi_task
-
-    if use_timer and pipi_task and not pipi_task.done():
-        return
-
-    if pipi_task:
-        pipi_task.cancel()
-
-    pipi_task = asyncio.create_task(pipi_block_notification())
-    vote_ctr = 0
-    chatters = await bot.get_chatters(CHANNEL)
-
-    if message is not None:
-        await send_me(ctx, message, PIPI_COLOR_0)
-    else:
-        for vote in pipi_votes.values():
-            if vote == 1:
-                vote_ctr += 1
-
-        percentage = get_percentage(vote_ctr, chatters.count)
-
-        if vote_ctr == 0:
-            await send_me(ctx, f'Kein Druck (mehr) auf der Blase. Es kann fröhlich weiter gestreamt werden!',
-                          PIPI_COLOR_0)
-        elif vote_ctr == 1:
-            await send_me(ctx, f'{vote_ctr} ({percentage}%) Mensch müsste mal', PIPI_COLOR_1)
-        elif vote_ctr < PIPI_THRESHOLD_1:
-            await send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal', PIPI_COLOR_1)
-        elif vote_ctr < PIPI_THRESHOLD_2:
-            await send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal haugeAgree', PIPI_COLOR_2)
-        else:
-            await send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal haugeAgree haugeAgree', PIPI_COLOR_3)
-
-
 async def notify_vote_result(message, final_result=False):
     votes_list = get_votes()
 
@@ -139,67 +116,7 @@ async def notify_vote_result(message, final_result=False):
     output += f'Endergebnis' if final_result else f'Zwischenergebnis'
     output += f' mit insgesamt {len(votes)} abgegebenen Stimmen'
 
-    await send_me(message, output, VOTE_COLOR)
-
-
-async def send_me(ctx, content, color):
-    """ Change Text color to color and send content as message """
-
-    if type(ctx) is Context or type(ctx) is Channel:
-        await ctx.color(color)
-        await ctx.send_me(content)
-    elif type(ctx) is Message:
-        await ctx.channel.color(color)
-        await ctx.channel.send_me(content)
-
-
-@bot.event
-async def event_ready():
-    print('Logged in')
-
-
-@bot.command(name="pipi", aliases=["Pipi"])
-async def cmd_pipi(ctx):
-    """ User mentioned there is a need to go to toilet. """
-
-    pipi_votes[ctx.author.name] = 1
-    await notify_pipi(ctx)
-
-
-@bot.command(name="warpipi", aliases=["Warpipi", "zuspät", "Zuspät"])
-async def cmd_warpipi(ctx):
-    """ User already went to toilet. """
-
-    if ctx.author.name in pipi_votes:
-        pipi_votes[ctx.author.name] = 0
-        await notify_pipi(ctx)
-
-
-@bot.command(name="pause", aliases=["Pause"])
-async def cmd_pause(ctx):
-    """ We will do a break now! """
-
-    global pipi_votes
-
-    if ctx.author.is_mod:
-        pipi_votes = {}
-        await send_me(ctx, "Jetzt geht noch mal jeder aufs Klo, und dann streamen wir weiter!", PIPI_COLOR_0)
-
-
-@bot.command(name="reset", aliases=["Reset"])
-async def cmd_pause(ctx):
-    """ Reset pipi votes """
-
-    global pipi_votes
-
-    if ctx.author.is_mod:
-        pipi_votes = {}
-
-
-@bot.command(name="pipimeter", aliases=["Pipimeter"])
-async def cmd_pipimeter(ctx):
-    if ctx.author.is_mod:
-        await notify_pipi(ctx, use_timer=False)
+    await bot.send_me(message, output, VOTE_COLOR)
 
 
 @bot.command(name="hauge-commands", aliases=["Hauge-commands", "haugebot-commands", "Haugebot-commands"])
@@ -297,9 +214,9 @@ def get_votes():
         elif x == 'minus':
             minus += 1
 
-    return [[plus, get_percentage(plus, len(votes))],
-            [neutral, get_percentage(neutral, len(votes))],
-            [minus, get_percentage(minus, len(votes))]]
+    return [[plus, bot.get_percentage(plus, len(votes))],
+            [neutral, bot.get_percentage(neutral, len(votes))],
+            [minus, bot.get_percentage(minus, len(votes))]]
 
 
 async def vote_end_voting(channel):
@@ -347,83 +264,4 @@ async def vote_block_votes():
     await asyncio.sleep(VOTE_DELAY_INTERIM)
 
 
-async def pipi_block_notification():
-    """ Just do nothing but sleep for PIPI_DELAY seconds """
-
-    await asyncio.sleep(PIPI_DELAY)
-@bot.command(name="giveaway")
-async def cmd_giveaway(ctx):
-    """ take part at the giveaway """
-
-    global giveaway_entries
-    global giveaway_enabled
-
-    if giveaway_enabled:
-        giveaway_entries[ctx.author.name] = 1
-
-
-@bot.command(name="giveaway-open")
-async def cmd_giveawayopen(ctx):
-    """ Reset and Open the giveaway """
-
-    global giveaway_entries
-    global giveaway_enabled
-
-    if ctx.author.is_mod:
-        giveaway_enabled = True
-        giveaway_entries = {}
-        await send_me(ctx, "Das Giveaway wurde gestartet. Schreibe !giveaway in den Chat um daran teilzunehmen.", VOTE_COLOR)
-
-@bot.command(name="giveaway-reopen")
-async def cmd_giveawayopen(ctx):
-    """ Reopen the giveaway after closing it (so reset) """
-
-    global giveaway_enabled
-
-    if ctx.author.is_mod:
-        giveaway_enabled = True
-        await send_me(ctx, "Das Giveaway wurde wieder geöffnet. Schreibe !giveaway in den Chat um daran teilzunehmen.", VOTE_COLOR)
-
-
-@bot.command(name="giveaway-close")
-async def cmd_giveawayopen(ctx):
-    """ Close the giveaway """
-
-    global giveaway_entries
-    global giveaway_enabled
-
-    if ctx.author.is_mod:
-        giveaway_enabled = False
-        await send_me(ctx, "Das Giveaway wurde geschlossen. Es kann niemand mehr teilnehmen.", VOTE_COLOR)
-
-
-@bot.command(name="giveaway-draw")
-async def cmd_giveawaydraw(ctx):
-    """ Draw a giveaway winner """
-
-    global giveaway_entries
-
-    if ctx.author.is_mod:
-        if len(giveaway_entries) > 0:
-            winner = random.choice(list(giveaway_entries))
-            entry_count = len(giveaway_entries)
-            del giveaway_entries[winner]
-            await send_me(ctx, f"Es wurde aus {entry_count} Einträgen ausgelost. Und der Gewinner ist... @{winner}", VOTE_COLOR)
-        else:
-            await send_me(ctx, "Es muss Einträge geben, damit ein Gewinner gezogen werden kann.", VOTE_COLOR)
-
-
-@bot.command(name="giveaway-reset")
-async def cmd_giveawayreset(ctx):
-    """ Reset giveaway entrys """
-
-    global giveaway_entries
-    global giveaway_enabled
-
-    if ctx.author.is_mod:
-        giveaway_enabled = False
-        giveaway_entries = {}
-        await send_me(ctx, "Das Giveaway wurde geschlossen und alle Einträge entfernt.", VOTE_COLOR)
-
-
 bot.run()
diff --git a/pipi_cog.py b/pipi_cog.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f6e51dc977c9f4d11c841f77cb04bc28cc237e8
--- /dev/null
+++ b/pipi_cog.py
@@ -0,0 +1,123 @@
+import asyncio
+import os
+
+from twitchio.dataclasses import Message
+from twitchio.ext import commands
+
+
+@commands.core.cog(name="PipiCog")
+class PipiCog:
+    def __init__(self, bot):
+        self.bot = bot
+        self.DELAY = int(os.getenv("PIPI_DELAY"))
+        self.THRESHOLD_1 = int(os.getenv("PIPI_THRESHOLD_1"))
+        self.THRESHOLD_2 = int(os.getenv("PIPI_THRESHOLD_2"))
+        self.PIPIMETER_LOOP = int(os.getenv("PIPIMETER_LOOP"))
+        self.RESET_THRESHOLD = int(os.getenv("PIPI_RESET_THRESHOLD"))
+        self.COLOR_0 = os.getenv("PIPI_COLOR_0")
+        self.COLOR_1 = os.getenv("PIPI_COLOR_1")
+        self.COLOR_2 = os.getenv("PIPI_COLOR_2")
+        self.COLOR_3 = os.getenv("PIPI_COLOR_3")
+        self.pipi_task = None
+        self.pipi_votes = {}
+
+    async def start_pipimeter_loop(self):
+        asyncio.create_task(self.pipimeter_loop())
+
+    async def notify_pipi(self, ctx, use_timer=True, message=None):
+        """ Write a message in chat, if there hasn't been a notification since DELAY seconds. """
+
+        if use_timer and self.pipi_task and not self.pipi_task.done():
+            return
+
+        if self.pipi_task:
+            self.pipi_task.cancel()
+
+        self.pipi_task = asyncio.create_task(self.pipi_block_notification())
+        vote_ctr = 0
+        chatters = await self.bot.get_chatters(self.bot.CHANNEL)
+
+        if message is not None:
+            await self.bot.send_me(ctx, message, self.COLOR_0)
+        else:
+            for vote in self.pipi_votes.values():
+                if vote == 1:
+                    vote_ctr += 1
+
+            percentage = self.get_percentage(vote_ctr, chatters.count)
+
+            if vote_ctr == 0:
+                await self.bot.send_me(ctx,
+                                       f'Kein Druck (mehr) auf der Blase. Es kann fröhlich weiter gestreamt werden!',
+                                       self.COLOR_0)
+            elif vote_ctr == 1:
+                await self.bot.send_me(ctx, f'{vote_ctr} ({percentage}%) Mensch müsste mal', self.COLOR_1)
+            elif percentage < self.THRESHOLD_1:
+                await self.bot.send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal', self.COLOR_1)
+            elif percentage < self.THRESHOLD_2:
+                await self.bot.send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal haugeAgree',
+                                       self.COLOR_2)
+            else:
+                await self.bot.send_me(ctx, f'{vote_ctr} ({percentage}%) Menschen müssten mal haugeAgree haugeAgree',
+                                       self.COLOR_3)
+
+    async def pipi_block_notification(self):
+        """ Just do nothing but sleep for DELAY seconds """
+
+        await asyncio.sleep(self.DELAY)
+
+    async def pipimeter_loop(self):
+        """ Send !pipimeter into the chat every x Minutes. Also check, whether the stream was offline for x Minutes.
+         If this is true, reset the pipi counter, as you can assume, that the stream recently started."""
+
+        offline_since = 0
+
+        while True:
+            await asyncio.sleep(self.PIPIMETER_LOOP * 60)
+
+            if await self.bot.get_stream(self.bot.CHANNEL):
+                if offline_since >= self.RESET_THRESHOLD:
+                    self.pipi_votes = {}
+                offline_since = 0
+
+                channel = self.bot.get_channel(self.bot.CHANNEL)
+                message = Message(channel=channel)
+                await self.notify_pipi(message, use_timer=False)
+            else:
+                offline_since += self.PIPIMETER_LOOP
+
+    @commands.command(name="pipi", aliases=["Pipi"])
+    async def cmd_pipi(self, ctx):
+        """ User mentioned there is a need to go to toilet. """
+
+        self.pipi_votes[ctx.author.name] = 1
+        await self.notify_pipi(ctx)
+
+    @commands.command(name="warpipi", aliases=["Warpipi", "zuspät", "Zuspät"])
+    async def cmd_warpipi(self, ctx):
+        """ User already went to toilet. """
+
+        if ctx.author.name in self.pipi_votes:
+            self.pipi_votes[ctx.author.name] = 0
+            await self.notify_pipi(ctx)
+
+    @commands.command(name="pause", aliases=["Pause"])
+    async def cmd_pause(self, ctx):
+        """ We will do a break now! """
+
+        if ctx.author.is_mod:
+            self.pipi_votes = {}
+            await self.bot.send_me(ctx, "Jetzt geht noch mal jeder aufs Klo, und dann streamen wir weiter!",
+                                   self.COLOR_0)
+
+    @commands.command(name="reset", aliases=["Reset"])
+    async def cmd_reset(self, ctx):
+        """ Reset pipi votes """
+
+        if ctx.author.is_mod:
+            self.pipi_votes = {}
+
+    @commands.command(name="pipimeter", aliases=["Pipimeter"])
+    async def cmd_pipimeter(self, ctx):
+        if ctx.author.is_mod:
+            await self.notify_pipi(ctx, use_timer=False)