diff --git a/config.py b/config.py
index f6b6532b24385ab7508ae8eca15045e45c4a27f2..c171108e35085b262ee42588587b72ea7f4a81ff 100644
--- a/config.py
+++ b/config.py
@@ -14,7 +14,8 @@ default_hw_config = {
     "flask_host": "0.0.0.0",
     "flask_port": 5000,
     "show_fps": False,
-    "fps_max": 60
+    "fps_max": 60,
+    "main_update_frequency": 500
 }
 
 hw_config = default_hw_config.copy()
diff --git a/main.py b/main.py
index 818c2ff432058872e21d3fd781107b137f2f0379..016f8772df199c3ce6f025834bb29062f51702c6 100644
--- a/main.py
+++ b/main.py
@@ -14,7 +14,7 @@ import screenwidgets
 from config import PROP_AVAILABLE_WIDGETS, PROP_AVAILABLE_PATTERNS, PROP_WINDOW_SCALE, PROP_WINDOW_FULLSCREEN, \
     PROP_SCREEN_WIDTH, PROP_SCREEN_HEIGHT, PROP_HIDE_MOUSE, PROP_LEDS_DRIVER, PROP_LEDS_LENGTH, PROP_LEDS_LOCATION, \
     PROP_FLASK_DEBUG, PROP_FLASK_HOST, PROP_FLASK_PORT, hw_config
-from utils.jsonencoding import get_cfg_from_request, decode_dict
+from utils.jsonencoding import get_cfg_from_request, decode_dict, encode_dict
 from utils.net import json_response, verify_json_request
 
 app = Flask(__name__)
@@ -57,20 +57,20 @@ def load_sequences():
     global widget_sequence, pattern_sequence
     with open("sequence_default.json") as f:
         seq = json.load(f)
-        widget_sequence = seq.get("widgets", [])
-        pattern_sequence = seq.get("patterns", [])
+        widget_sequence = seq.get("widget", [])
+        pattern_sequence = seq.get("pattern", [])
 
     if os.path.exists("sequence_config.json"):
         with open("sequence_config.json") as f:
             seq = json.load(f)
-            widget_sequence = seq.get("widgets", widget_sequence)
-            pattern_sequence = seq.get("patterns", pattern_sequence)
+            widget_sequence = seq.get("widget", widget_sequence)
+            pattern_sequence = seq.get("pattern", pattern_sequence)
 
 def save_sequences():
     with open("sequence_config.json", "w") as f:
         json.dump({
-            "widgets": widget_sequence,
-            "patterns": pattern_sequence
+            "widget": widget_sequence,
+            "pattern": pattern_sequence
         }, f, indent=4)
 
 mainthread_queue = queue.Queue()
@@ -209,7 +209,7 @@ def load_pattern(pattern_name: str, leds: ILedString, config_override: dict=None
 # Loop Functions #
 ##################
 
-def run_screen(start_widget: str):
+def run_screen(start_widget: dict):
     # Initialise Pygame and create a window
     pygame.init()
 
@@ -227,9 +227,10 @@ def run_screen(start_widget: str):
     clock = pygame.time.Clock()
 
     # Init widgets
-    widget_to_load = start_widget
+    widget_to_load = start_widget.get("type")
+    config_override = start_widget.get("config", {})
 
-    current_widget = load_widget(widget_to_load)
+    current_widget = load_widget(widget_to_load, config_override)
 
     # Main loop
     running = True
@@ -283,7 +284,7 @@ def run_screen(start_widget: str):
     # Quit Pygame
     pygame.quit()
 
-def run_leds(start_pattern: str):
+def run_leds(start_pattern: dict):
     # Load LEDs
     if PROP_LEDS_DRIVER == "dummy":
         from absled.dummy import DummyLedString
@@ -294,9 +295,10 @@ def run_leds(start_pattern: str):
     else:
         raise ValueError("Invalid LED driver")
 
-    pattern_name = start_pattern
+    pattern_name = start_pattern.get("type")
+    config_override = start_pattern.get("config", {})
 
-    current_pattern = load_pattern(pattern_name, leds)
+    current_pattern = load_pattern(pattern_name, leds, config_override)
     pattern_timer = module_config.get(pattern_name, {}).get("tick_rate", -1)
     current_pattern.tick()
 
@@ -331,8 +333,19 @@ if __name__ == "__main__":
     load_module_config()
     load_sequences()
 
-    initial_widget = widget_sequence[0].get("type") if len(widget_sequence) > 0 else PROP_AVAILABLE_WIDGETS[0]
-    initial_pattern = pattern_sequence[0].get("type") if len(pattern_sequence) > 0 else PROP_AVAILABLE_PATTERNS[0]
+    if len(widget_sequence) == 0:
+        raise ValueError("No widgets in sequence")
+    if len(pattern_sequence) == 0:
+        raise ValueError("No patterns in sequence")
+
+    initial_widget = widget_sequence[0]
+    initial_pattern = pattern_sequence[0]
+
+    current_widget_index = 0
+    current_pattern_index = 0
+
+    current_widget_delta = 0
+    current_pattern_delta = 0
 
     # Fork off pygame
     pygame_thread = threading.Thread(
@@ -358,6 +371,7 @@ if __name__ == "__main__":
     # Wait for the threads to finish
     try:
         while True:
+            # Process message queue
             try:
                 message = mainthread_queue.get_nowait()
                 parts = message.split(":")
@@ -384,8 +398,38 @@ if __name__ == "__main__":
                         }, f, indent=4)
             except queue.Empty:
                 pass
+            # Check if time delta has passed
+            # For Widgets
+            curr_widget = widget_sequence[current_widget_index]
+            if curr_widget.get("duration", -1) != -1:
+                # Check if the widget has existed for too long
+                if curr_widget.get("duration") * 1000 <= current_widget_delta:
+                    # Set the widget to the next widget
+                    current_widget_index += 1
+                    if current_widget_index >= len(widget_sequence):
+                        current_widget_index = 0
+                    display_queue.put("SET_WIDGET:" +
+                                      widget_sequence[current_widget_index].get("type") + ":" +
+                                      encode_dict(widget_sequence[current_widget_index].get("config", {}))
+                                      )
+                    current_widget_delta = 0
+            # For patterns
+            curr_pattern = pattern_sequence[current_pattern_index]
+            if curr_pattern.get("duration", -1) != -1:
+                # Check if the pattern has existed for too long
+                if curr_pattern.get("duration") * 1000 <= current_pattern_delta:
+                    # Set the pattern to the next pattern
+                    current_pattern_index += 1
+                    if current_pattern_index >= len(pattern_sequence):
+                        current_pattern_index = 0
+                    led_queue.put("SET_PATTERN:" +
+                                  pattern_sequence[current_pattern_index].get("type") + ":" +
+                                  encode_dict(pattern_sequence[current_pattern_index].get("config", {}))
+                                  )
+                    current_pattern_delta = 0
             # Keep main thread alive
-            time.sleep(1)
+            current_widget_delta += hw_config["main_update_frequency"]
+            time.sleep(hw_config["main_update_frequency"] / 1000)
     except KeyboardInterrupt:
         exit()
     exit()