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
+____