diff --git a/simulation/src/de/c3ma/ollo/WS2812Simulation.java b/simulation/src/de/c3ma/ollo/WS2812Simulation.java
index fc585de..9701eb3 100644
--- a/simulation/src/de/c3ma/ollo/WS2812Simulation.java
+++ b/simulation/src/de/c3ma/ollo/WS2812Simulation.java
@@ -4,6 +4,8 @@ import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
 
+import javax.management.RuntimeErrorException;
+
 import org.luaj.vm2.Globals;
 import org.luaj.vm2.LuaValue;
 import org.luaj.vm2.lib.jse.JsePlatform;
@@ -33,11 +35,12 @@ public class WS2812Simulation implements LuaSimulation {
     private ESP8266File espFile = new ESP8266File();
     private ESP8266Node espNode = new ESP8266Node(this);
     private DoFileFunction doFile = new DoFileFunction(globals);
+    private ESP8266Ws2812 ws2812 = new ESP8266Ws2812();
     private String scriptName;
         
     public WS2812Simulation(File sourceFolder) {
         globals.load(new ESP8266Uart());
-        globals.load(new ESP8266Ws2812());
+        globals.load(ws2812);
         globals.load(espTmr);
         globals.load(espFile);
         globals.load(espNode);
@@ -76,11 +79,16 @@ public class WS2812Simulation implements LuaSimulation {
             return;
         }
         
-        if (args.length == 1) {
+        if (args.length >= 1) {
             File f = new File(args[0]);
             if (f.exists()) {
                 WS2812Simulation simu = new WS2812Simulation(f.getParentFile());
                 System.out.println("File : " + f.getAbsolutePath());
+                
+                if (args.length >= 2) {
+                    simu.setWS2812Layout(new File(args[1]));
+                }
+                
                 simu.callScript(f.getName());
             }    
         } else {
@@ -89,6 +97,14 @@ public class WS2812Simulation implements LuaSimulation {
         
     }
 
+    private void setWS2812Layout(File file) {
+        if (file.exists()) {
+            ws2812.setLayout(file);
+        } else {
+            throw new RuntimeException("WS2812 Layout: " + file.getAbsolutePath() + " does not exists");
+        }
+    }
+
     private static void printUsage() {
         System.out.println("Usage:");
         System.out.println("one argument required: file to execute.");
diff --git a/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java b/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java
index 97d015c..f9df097 100644
--- a/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java
+++ b/simulation/src/de/c3ma/ollo/mockup/ESP8266Ws2812.java
@@ -1,11 +1,15 @@
 package de.c3ma.ollo.mockup;
 
+import java.io.File;
+
 import org.luaj.vm2.LuaTable;
 import org.luaj.vm2.LuaValue;
 import org.luaj.vm2.lib.OneArgFunction;
 import org.luaj.vm2.lib.TwoArgFunction;
 import org.luaj.vm2.lib.ZeroArgFunction;
 
+import de.c3ma.ollo.mockup.ui.WS2812Layout;
+
 /**
  * created at 28.12.2017 - 23:34:04
  * creator: ollo
@@ -15,6 +19,8 @@ import org.luaj.vm2.lib.ZeroArgFunction;
  */
 public class ESP8266Ws2812 extends TwoArgFunction {
 
+    private static WS2812Layout layout = null;
+
     @Override
     public LuaValue call(LuaValue modname, LuaValue env) {
         env.checkglobals();
@@ -42,20 +48,29 @@ public class ESP8266Ws2812 extends TwoArgFunction {
         public LuaValue call(LuaValue arg) {
             if (arg.isstring()) {
                 int length = arg.checkstring().rawlen();
-                System.out.println("[WS2812] write length:" + length);
                 if ((length % 3) == 0) {
                     byte[] array = arg.toString().getBytes();
                     for (int i = 0; i < length; i+=3) {
-                        /*System.out.println(
-                                array[i+0] + " " 
-                                + array[i+1] + " "
-                                + array[i+2]
-                                );*/
+                        if (ESP8266Ws2812.layout != null) {
+                            ESP8266Ws2812.layout.updateLED(i/3, array[i+0], array[i+1], array[i+2]);
+                        }
                     }
                 }
+
+                if (ESP8266Ws2812.layout == null) {
+                    System.out.println("[WS2812] write length:" + length);
+                } else {
+                    /*ESP8266Ws2812.layout.update(ESP8266Ws2812.layout.getGraphics());*/
+                    ESP8266Ws2812.layout.repaint();
+                }
             }
             return LuaValue.valueOf(true);
         }
-        
+    }
+
+    public void setLayout(File file) {
+        if (ESP8266Ws2812.layout == null) {
+            ESP8266Ws2812.layout = WS2812Layout.parse(file);
+        }
     }
 }
diff --git a/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java b/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java
new file mode 100644
index 0000000..2d9f0bf
--- /dev/null
+++ b/simulation/src/de/c3ma/ollo/mockup/ui/WS2812Layout.java
@@ -0,0 +1,195 @@
+package de.c3ma.ollo.mockup.ui;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.GridLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+/**
+ * created at 02.01.2018 - 12:57:02
+ * creator: ollo
+ * project: WS2812Emulation
+ * $Id: $
+ * @author ollo
+ */
+public class WS2812Layout extends JFrame {
+    
+    /**
+     * 
+     */
+    private static final long serialVersionUID = -6815557232118826140L;
+    
+    private ArrayList mLines = new ArrayList();
+    private int mColumn = 0;
+    private int mRow = 0;
+    private Element[][] mElements;
+
+    public static WS2812Layout parse(File file) {
+        WS2812Layout layout = null;
+        try {
+            BufferedReader br = new BufferedReader(new FileReader(file));
+            try {
+                String line = br.readLine();
+                if (line != null) {
+                    layout = new WS2812Layout();
+                }
+                
+                while (line != null) {
+                    if (!line.startsWith("#")) {
+                        layout.mLines.add(line);
+                        layout.mRow++;
+                        layout.mColumn = Math.max(layout.mColumn, line.length());
+                    }
+                    /* get the next line */
+                    line = br.readLine();
+                }
+                
+                /* parse each line */
+                layout.parse();
+                layout.createAndDisplayGUI();
+            } finally {
+                if (br != null) {
+                    br.close();
+                }
+            }
+        } catch (IOException ioe) {
+            
+        }
+        return layout;
+    }
+
+    private void createAndDisplayGUI() {
+        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+
+        JPanel contentPane = new JPanel();
+        contentPane.setLayout(new BorderLayout());
+        contentPane.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 2));
+
+        JPanel ledPanel = new JPanel();
+        ledPanel.setLayout(new GridLayout(this.mRow, this.mColumn, 10, 10));
+        for (int i = 0; i < this.mRow; i++)
+        {
+            for (int j = 0; j < this.mColumn; j++)
+            {
+                if (this.mElements[i][j] != null) {
+                    ledPanel.add(this.mElements[i][j]);
+                }
+            }
+        }
+        contentPane.add(ledPanel, BorderLayout.CENTER);
+        JButton button = new JButton("Do something");
+        button.setActionCommand("Do something");
+        button.addActionListener(new ActionListener()
+        {
+            public void actionPerformed(ActionEvent ae)
+            {
+                JButton but = (JButton) ae.getSource();
+                //FIXME some clever logic                           
+            }
+        });
+        contentPane.add(button, BorderLayout.SOUTH);
+        
+        
+        setContentPane(contentPane);
+        pack();
+        setLocationByPlatform(true);
+        setVisible(true);
+    }
+
+    private void parse() {
+        this.mElements = new Element[this.mRow][this.mColumn];
+        int row=0;
+        for (String line : this.mLines) {
+            for (int i = 0; i < line.length(); i++) {
+                char c = line.charAt(i);
+                if ((('A' <= c) && (c <= 'Z')) ||
+                    (('0' <= c) && (c <= '9')) ||
+                    (c == 'Ä') || (c == 'Ö') || (c == 'Ü')) {
+                    this.mElements[row][i] = new Element(c);
+                } else {
+                    this.mElements[row][i] = new Element();
+                }
+                this.mElements[row][i].setColor(0, 0, 0);
+            }
+            row++;
+        }
+    }
+    
+    public class Element extends JLabel {
+        
+        /**
+         * 
+         */
+        private static final long serialVersionUID = -3933903441113933637L;
+        
+        private boolean noText=false;
+
+        /**
+         * Draw a simple rect
+         */
+        public Element() {
+            super();
+            this.noText = true;
+            this.setBackground(Color.BLACK);
+        }
+        
+        /**
+         * Draw a character
+         * @param character to show
+         */
+        public Element(char character) {
+            super(""+character);
+            setFont(new Font("Dialog", Font.BOLD, 24));
+            setHorizontalAlignment(CENTER);
+            this.setBackground(Color.BLACK);
+        }
+        
+        public void setColor(int red, int green, int blue) {
+            this.setForeground(new Color(red, green, blue));
+            this.update(this.getGraphics());
+            //this.repaint();
+            System.out.println( this.toString());
+        }
+        
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            if (noText) {
+                sb.append(" ");
+            } else {
+                sb.append("" + this.getText());
+            }
+            sb.append(Integer.toHexString(this.getForeground().getRed()) + 
+                    " " + Integer.toHexString(this.getForeground().getGreen()) +
+                    " " + Integer.toHexString(this.getForeground().getBlue()));
+            
+            return sb.toString();
+        }
+    }
+
+    public void updateLED(int index, byte red, byte green, byte blue) {
+        if (this.mElements != null) {
+            int i = (index / this.mColumn);
+            int j = (index % this.mColumn);
+            if ((i < this.mElements.length) &&
+                    (j < this.mElements[i].length) &&
+                    (this.mElements[i][j] != null)) {
+                this.mElements[i][j].setColor(red, green, blue);
+            }
+        }
+    }
+    
+}
diff --git a/simulation/ws28128ClockLayout.txt b/simulation/ws28128ClockLayout.txt
new file mode 100644
index 0000000..2fda3e4
--- /dev/null
+++ b/simulation/ws28128ClockLayout.txt
@@ -0,0 +1,17 @@
+# This file describes the layout of the WS2812 LEDs.
+# _ will only draw a rect
+# A-Z or 1-9 will draw the text or number
+# each element will be updated with its color with the known commands of the nodemcu firmware
+#
+# Here the configuration for the wordclock:
+ESKISTLFÜNF
+ZEHNZWANZIG
+DREIVIERTEL
+TGNACHVORJM
+HALBXZWÖLFP
+ZWEINSIEBEN
+KDREIRHFÜNF
+ELFNEUNVIER
+WACHTZEHNRS
+BSECHSFMUHR
+____