Index: flowtimer/Phase.py
===================================================================
--- flowtimer/Phase.py	(revision 401678c89093d7ef3f4689b554c2f5ba5eba3a14)
+++ flowtimer/Phase.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -1,14 +1,13 @@
+import json
+
+
 class Phase:
 
     """
-
     This class is a representation of a single phase inside a timer
-
     """
 
     def __init__(self, title, duration):
-
         """
-
         creates the variables associated with that class
 
@@ -18,5 +17,4 @@
         :type duration: int
         :param duration: Duration in seconds
-
         """
 
@@ -26,14 +24,14 @@
         self.time_left = self.duration
 
+    def to_json(self):
+        return json.dumps({"title": self.title, "duration": self.duration})
+        # return json.dumps(self.__dict__)
 
     def __str__(self):
-
         """
-
         Human readable representation of all attributes
 
         :return: human readable representation of all attributes
         :rtype: String
-
         """
 
Index: flowtimer/RecurringPhaseSequence.py
===================================================================
--- flowtimer/RecurringPhaseSequence.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
+++ flowtimer/RecurringPhaseSequence.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -0,0 +1,15 @@
+import json
+
+
+class RecurringPhaseSequence:
+
+    def __init__(self, phase_list, repetitions):
+        self.phase_list = phase_list
+        self.repetitions = repetitions
+
+    def to_json(self):
+        return json.dumps(self.__dict__, default=lambda each: each.to_json())
+
+    def unrolled(self):
+        return [[deepcopy(seq) for seq in [each for each in se1f.repetitions * se1f.phase_list]]]
+        # return self.repetitions * self.phase_list
Index: flowtimer/Schedule.py
===================================================================
--- flowtimer/Schedule.py	(revision 401678c89093d7ef3f4689b554c2f5ba5eba3a14)
+++ flowtimer/Schedule.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -1,10 +1,15 @@
+import json
+
+
 class Schedule:
 
     def __init__(self, phase_list):
-        self.progressbar = None
         self.currentValue = 0
         self.phase_list = phase_list
         self.current_phase = phase_list[0]
         self.state = "initial"
+
+    def to_json(self):
+        json.dumps(self.__dict__)
 
     def start(self):
Index: flowtimer/configs/default.json
===================================================================
--- flowtimer/configs/default.json	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
+++ flowtimer/configs/default.json	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -0,0 +1,21 @@
+{
+  "phase_list": [
+    {
+      "title": "Huddle",
+      "duration": 10
+    },
+    {
+      "title": "Tasking",
+      "duration": 5
+    },
+    {
+      "title": "Work",
+      "duration": 45
+    },
+    {
+      "title": "Break",
+      "duration": 15
+    }
+  ],
+  "repetitions": 2
+}
Index: flowtimer/main.py
===================================================================
--- flowtimer/main.py	(revision 401678c89093d7ef3f4689b554c2f5ba5eba3a14)
+++ flowtimer/main.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -17,7 +17,7 @@
 
 class TimerApp(tk.Frame):
-    
+
     def __init__(self, parent):
-        
+
         super().__init__(parent)
         self.parent = parent
@@ -25,5 +25,6 @@
         self.currentValue = 0
         self.default_config = pd.read_csv("default_config.csv", sep=',', header=0,
-                         names=('Titel', 'Values'), index_col=False, keep_default_na=False)
+                                          names=('Titel', 'Values'), index_col=False,
+                                          keep_default_na=False)
         self.photo = ImageTk.PhotoImage(file='flowtimer_startbg_new.png')
         self.show_config = pd.read_csv("default_config.csv", usecols=[0, 1])
@@ -36,5 +37,7 @@
         s = ttk.Style()
         s.theme_use('clam')
-        s.configure("orange.Horizontal.TProgressbar", troughcolor='ivory3', bordercolor='black', background='CadetBlue1', lightcolor='white', darkcolor='black')
+        s.configure("orange.Horizontal.TProgressbar", troughcolor='ivory3',
+                    bordercolor='black', background='CadetBlue1',
+                    lightcolor='white', darkcolor='black')
 
         self.headline_frame = tk.Frame(self.parent, bg='white')
@@ -45,14 +48,20 @@
         self.button_frame.pack(side='bottom', fill='both', expand=False)
 
-        self.label_headline = tk.Label(self.headline_frame, text=("Hochintensive Intervallarbeit"), bg='white', fg='grey', font="serif 20")
+        self.label_headline = tk.Label(self.headline_frame,
+                                       text=("Hochintensive Intervallarbeit"),
+                                       bg='white', fg='grey', font="serif 20")
         self.label_headline.pack(side='left', fill='both', expand=True)
 
-        self.label_config = tk.LabelFrame(self.headline_frame, text="config: ", bg='white', font="serif 12")
-        self.label_config.pack(side='right', fill='both', expand=False, ipadx=20, padx=20, pady=10)
-        
-        self.config_button = tk.Button(self.headline_frame, text="change config", font="courier 14", width=20, command=self.change_config)
+        self.label_config = tk.LabelFrame(self.headline_frame, text="config: ",
+                                          bg='white', font="serif 12")
+        self.label_config.pack(side='right', fill='both', expand=False,
+                               ipadx=20, padx=20, pady=10)
+
+        self.config_button = tk.Button(self.headline_frame, text="change config",
+                                       font="courier 14", width=20, command=self.change_config)
         self.config_button.pack(side='right', padx=10, pady=10, expand=False)
 
-        self.label_config_text = tk.Label(self.label_config, text=self.show_config, bg='white', font="serif 10", justify='right')
+        self.label_config_text = tk.Label(self.label_config, text=self.show_config,
+                                          bg='white', font="serif 10", justify='right')
         self.label_config_text.pack()
 
@@ -62,21 +71,27 @@
         self.label_sequence = tk.Label(self.center_frame)
         self.label_sequence.pack(side='top', fill='both', expand=True)
-        
-        self.progressbar = ttk.Progressbar(self.center_frame, style="orange.Horizontal.TProgressbar", orient="horizontal",length=600, mode="determinate")
+
+        self.progressbar = ttk.Progressbar(self.center_frame,
+                                           style="orange.Horizontal.TProgressbar",
+                                           orient="horizontal", length=600, mode="determinate")
         self.progressbar.pack(side='top')
 
         self.label_duration = tk.Label(self.center_frame)
         self.label_duration.pack(side='top', fill='both', expand=True)
-        
-        self.start_timer_button = tk.Button(self.button_frame, text="START", font="courier 14", width=20, command=self.start)
+
+        self.start_timer_button = tk.Button(self.button_frame, text="START",
+                                            font="courier 14", width=20, command=self.start)
         self.start_timer_button.pack(side='left', fill='both', ipady=20, expand=True)
 
-        self.freeze_button = tk.Button(self.button_frame, text="PLAY/PAUSE", font="courier 14", width=20, command=self.toggle_tick)
+        self.freeze_button = tk.Button(self.button_frame, text="PLAY/PAUSE",
+                                       font="courier 14", width=20, command=self.toggle_tick)
         self.freeze_button.pack(side='left', fill='both', ipady=20, expand=True)
 
-        self.skip_button = tk.Button(self.button_frame, text=("SKIP"), font="courier 14", width=20, command=self.skip)
+        self.skip_button = tk.Button(self.button_frame, text=("SKIP"),
+                                     font="courier 14", width=20, command=self.skip)
         self.skip_button.pack(side='left', fill='both', ipady=20, expand=True)
 
-        self.quit_button = tk.Button(self.button_frame, text="QUIT", font="courier 14", width=20, command=self.quit_app)
+        self.quit_button = tk.Button(self.button_frame, text="QUIT",
+                                     font="courier 14", width=20, command=self.quit_app)
         self.quit_button.pack(side='left', fill='both', ipady=20, expand=True)
 
@@ -95,13 +110,15 @@
 
         if repeat_of_phases == 3:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3)]
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3)]
 
         if repeat_of_phases == 4:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
-                          copy(phase_2), copy(phase_3)]
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3)]
 
         if repeat_of_phases == 5:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
-                          copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3)]
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3)]
 
         self.repeats = repeat_of_phases
@@ -110,5 +127,5 @@
 
     def tick(self):
-        
+
         if self.schedule.is_paused():
             return
@@ -121,5 +138,7 @@
             self.label_sequence.config(text=("\n" + str(self.schedule.current_phase.title) + "..."))
             self.label_duration.config(self.start_color(root))
-            self.label_duration.config(text=("noch " + str(math.ceil(self.schedule.current_phase.time_left)) + " Min\n"))
+            self.label_duration.config(text=("noch " +
+                                             str(math.ceil(self.schedule.current_phase.time_left)) +
+                                             " Min\n"))
             self.schedule.start()
             self.schedule.tick(1)
@@ -132,8 +151,10 @@
                 self.label_sequence.config(bg=self.random_color(self.label_sequence))
                 self.label_duration.config(self.random_color(root))
-                self.label_duration.config(text=("noch " + str(math.ceil(self.schedule.current_phase.time_left)) + " Min\n"), bg=self.random_color(self.label_duration))
+                self.label_duration.config(text=("noch " +
+                                                 str(math.ceil(self.schedule.current_phase.time_left))
+                                                 + " Min\n"), bg=self.random_color(self.label_duration))
                 if self.schedule.tick(1/60):
                     self.round_counter()
-                    
+
             else:
                 self.label_sequence.configure(self.time_out_color(root))
@@ -147,5 +168,5 @@
                 self.freeze_button['state'] = 'disabled'
                 self.freeze_button.config(fg="ivory3")
-    
+
     def start(self):
         self.schedule.start()
@@ -154,5 +175,5 @@
         self.start_timer_button.config(fg="ivory3")
         self.config_button.pack_forget()
-        
+
     def skip(self):
         self.schedule.skip()
@@ -160,5 +181,5 @@
         if self.schedule.state == "running":
             self.round_counter()
-    
+
     def toggle_tick(self):
         if self.schedule.is_paused():
@@ -177,5 +198,5 @@
     def quit_app(self):
         self.parent.destroy()
-    
+
     def random_color(self, widget):
         if self.schedule.current_phase.title == "B-Phase":
@@ -194,5 +215,4 @@
             self.label_duration.configure(fg="blue")
 
-
     def start_color(self, widget):
         self.label_sequence.configure(fg="white", font="times 72")
@@ -200,8 +220,8 @@
         self.center_frame.configure(bg="blue")
         widget.configure(bg="blue")
-    
+
     def time_out_color(self, widget):
         widget.configure(bg="red")
-        
+
     def progress(self, currentValue):
         self.progressbar["value"] = self.currentValue
@@ -214,16 +234,21 @@
         if self.count < 3:
             self.currentValue = 0
-            self.progress(self.currentValue +1)
+            self.progress(self.currentValue + 1)
             self.progressbar.update()
             self.label_config.config(text="Runde: ")
-            self.label_config_text.config(text=("1", "/", self.repeats), fg='blue',font="Times 48")
+            self.label_config_text.config(text=("1", "/", self.repeats),
+                                          fg='blue', font="Times 48")
         if self.count >= 3 and self.count < 5:
-            self.label_config_text.config(text=("2", "/", self.repeats), fg='blue',font="Times 48")
+            self.label_config_text.config(text=("2", "/", self.repeats),
+                                          fg='blue', font="Times 48")
         if self.count >= 5 and self.count < 7:
-            self.label_config_text.config(text=("3", "/", self.repeats), fg='blue',font="Times 48")
+            self.label_config_text.config(text=("3", "/", self.repeats),
+                                          fg='blue', font="Times 48")
         if self.count >= 7 and self.count < 9:
-            self.label_config_text.config(text=("4", "/", self.repeats), fg='blue',font="Times 48")
+            self.label_config_text.config(text=("4", "/", self.repeats),
+                                          fg='blue', font="Times 48")
         if self.count >= 9 and self.count < 11:
-            self.label_config_text.config(text=("5", "/", self.repeats), fg='blue',font="Times 48")
+            self.label_config_text.config(text=("5", "/", self.repeats),
+                                          fg='blue', font="Times 48")
 
     def change_config(self):
@@ -235,5 +260,6 @@
                                                  filetypes=self.config_files)
         self.user_config = pd.read_csv(self.answer, sep=',', header=0,
-                                       names=('Titel', 'Values'), index_col=False, keep_default_na=False)
+                                       names=('Titel', 'Values'),
+                                       index_col=False, keep_default_na=False)
         self.choosed_config = pd.read_csv(self.answer, usecols=[0, 1])
         self.df = self.user_config
@@ -253,13 +279,16 @@
 
         if repeat_of_phases == 3:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3)]
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3)]
 
         if repeat_of_phases == 4:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3),
                           copy(phase_2), copy(phase_3)]
 
         if repeat_of_phases == 5:
-            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
-                          copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3)]
+            phase_list = [phase_1, phase_2, phase_3, copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3), copy(phase_2), copy(phase_3),
+                          copy(phase_2), copy(phase_3)]
 
         self.repeats = repeat_of_phases
@@ -267,7 +296,6 @@
         self.schedule = Schedule(phase_list)
 
+
 root = tk.Tk()
-
-
 root.title("--=> flowtimer <=-- " + "  date: " + date + "  time: " + time)
 root.geometry("1280x860")
Index: tests/testPhase.py
===================================================================
--- tests/testPhase.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
+++ tests/testPhase.py	(revision 84123db241e5003f75dc20ce13a71f3ab41f96ba)
@@ -0,0 +1,63 @@
+import pytest
+from phase import Phase
+
+
+class TestPhase:
+  def test_phase_initialization():
+phase = Phase("Warm-up", 300)
+                assert phase.title == "Warm-up"
+                assert phase.duration == 300
+                assert phase.state == "initial"
+                assert phase.time_left == 300
+
+                        def test_phase_str_representation():
+
+                                phase = Phase("Warm-up", 300)
+                                expected_str = "-->Warm-up\nDuration=300\n"
+                                assert str(phase) == expected_str
+
+                                        def test_phase_start():
+
+                                                phase = Phase("Warm-up", 300)
+                                                phase.start()
+                                                assert phase.state == "running"
+                                                assert phase.running() is True
+
+                                                            def test_phase_pause():
+
+                                                                    phase = Phase("Warm-up", 300)
+                                                                    phase.start()
+                                                                    phase.pause()
+                                                                    assert phase.state == "paused"
+                                                                    assert phase.paused() is True
+
+                                                                                    def test_phase_abort():
+
+                                                                                            phase = Phase("Warm-up", 300)
+                                                                                            phase.abort()
+                                                                                            assert phase.state == "finished"
+                                                                                            assert phase.finished() is True
+
+                                                                                                        def test_phase_tick():
+
+                                                                                                                phase = Phase("Warm-up", 300)
+                                                                                                                phase.start()
+                                                                                                                phase.tick(60)
+                                                                                                                assert phase.time_left == 240
+                                                                                                                assert phase.state == "running"
+
+                                                                                                                                def test_phase_tick_to_completion():
+
+                                                                                                                                        phase = Phase("Warm-up", 300)
+                                                                                                                                        phase.start()
+                                                                                                                                        phase.tick(300)
+                                                                                                                                        assert phase.time_left == 0
+                                                                                                                                        assert phase.finished() is True
+
+                                                                                                                                                        def test_phase_tick_beyond_completion():
+
+                                                                                                                                                                phase = Phase("Warm-up", 300)
+                                                                                                                                                                phase.start()
+                                                                                                                                                                phase.tick(350)
+                                                                                                                                                                assert phase.time_left == 0
+                                                                                                                                                                assert phase.finished() is True
