This commit is contained in:
Ollo
2022-01-21 21:28:50 +01:00
54 changed files with 10931 additions and 1390 deletions

View File

@@ -1,8 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes>
<attribute name="module" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/luaj-jme-3.0.1.jar" sourcepath="libs/luaj-3.0.1/src"/>
<classpathentry kind="lib" path="libs/luaj-jse-3.0.1.jar"/>
<classpathentry kind="lib" path="libs/org.eclipse.paho.client.mqttv3-1.2.5.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@@ -6,7 +6,7 @@ The simualation should be started with the following arguments at this position:
# Use it without Eclipse
Compiling:
`javac -d bin/ -cp libs/luaj-jme-3.0.1.jar:libs/luaj-jse-3.0.1.jar $(find src -name '*.java')`
`javac -d bin/ -cp libs/luaj-jme-3.0.1.jar:libs/luaj-jse-3.0.1.jar:libs/org.eclipse.paho.client.mqttv3-1.2.5.jar $(find src -name '*.java')`
Running:
`java -cp libs/luaj-jme-3.0.1.jar:libs/luaj-jse-3.0.1.jar:bin de.c3ma.ollo.WS2812Simulation ../init.lua ws28128ClockLayout.txt config.lua`
`java -cp libs/luaj-jme-3.0.1.jar:libs/luaj-jse-3.0.1.jar:libs/org.eclipse.paho.client.mqttv3-1.2.5.jar:bin de.c3ma.ollo.WS2812Simulation ../init.lua ws28128ClockLayout.txt config.lua`

View File

@@ -1,15 +1,22 @@
green=0
green2=128
red=128
blue=0
green2=200
red=200
blue=200
color=string.char(0, 0, 128)
color1=string.char(128, 0, 0)
color2=string.char(tonumber(green2*0.8), 0, 0)
color3=string.char(tonumber(green2*0.4), 0, 0)
color4=string.char(tonumber(green2*0.2), 0, 0)
color=string.char(0, 0, blue)
color1=string.char(red, 0, 0)
color2=string.char(tonumber(red*0.9), 0, 0)
color3=string.char(tonumber(red*0.8), 0, 0)
color4=string.char(tonumber(red*0.7), 0, 0)
colorBg=string.char(0,0,0) -- black is the default background color
sntpserverhostname="ptbtime1.ptb.de"
timezoneoffset=1
dim="on"
mqttServer="192.168.1.1"
mqttPrefix="test"
if (file.open("simulation.config.lua")) then
dofile("simulation.config.lua")
else
print("Default configuration, used")
end

View File

@@ -1,7 +1,13 @@
# Dependencies
## Lua
The following file is expected here:
`luaj-3.0.1.zip`
It can be downloaded here:
https://sourceforge.net/projects/luaj/files/latest/download
## MQTT
It can be downloaded here:
https://search.maven.org/classic/#search%7Cgav%7C1%7Cg%3A%22org.eclipse.paho%22%20AND%20a%3A%22org.eclipse.paho.client.mqttv3%22

View File

@@ -18,7 +18,7 @@ public class LuaThreadTmr extends Thread {
private LuaValue code;
private final int delay;
private int delay;
private final int timerNumber;
@@ -28,7 +28,7 @@ public class LuaThreadTmr extends Thread {
this.delay = delay;
this.timerNumber = timerNumber;
}
@Override
public void run() {
try {

View File

@@ -14,6 +14,8 @@ import de.c3ma.ollo.mockup.DoFileFunction;
import de.c3ma.ollo.mockup.ESP8266Adc;
import de.c3ma.ollo.mockup.ESP8266File;
import de.c3ma.ollo.mockup.ESP8266GPIO;
import de.c3ma.ollo.mockup.ESP8266Gpio;
import de.c3ma.ollo.mockup.ESP8266Mqtt;
import de.c3ma.ollo.mockup.ESP8266Net;
import de.c3ma.ollo.mockup.ESP8266Node;
import de.c3ma.ollo.mockup.ESP8266Time;
@@ -38,6 +40,8 @@ public class WS2812Simulation implements LuaSimulation {
private ESP8266Node espNode = new ESP8266Node(this);
private DoFileFunction doFile = new DoFileFunction(globals);
private ESP8266Ws2812 ws2812 = new ESP8266Ws2812();
private ESP8266Gpio gpio = new ESP8266Gpio();
private ESP8266Mqtt mqtt = new ESP8266Mqtt();
private ESP8266Adc adc = new ESP8266Adc();
private String scriptName;
@@ -49,6 +53,8 @@ public class WS2812Simulation implements LuaSimulation {
globals.load(espNode);
globals.load(new ESP8266GPIO());
globals.load(adc);
globals.load(gpio);
globals.load(mqtt);
globals.load(new ESP8266Wifi());
globals.load(new ESP8266Net());
globals.load(new ESP8266Time());

View File

@@ -26,15 +26,19 @@ public class DoFileFunction extends OneArgFunction {
public LuaValue call(LuaValue luaFilename) {
String filename = luaFilename.checkjstring();
//System.out.println("[Nodemcu] dofile " + filename);
File f = new File(workingDir.getAbsolutePath() + File.separator + filename);
if (f.exists()) {
LuaValue chunk = this.globals.loadfile(f.getAbsolutePath());
return chunk.call();
} else {
return LuaValue.valueOf(false);
try {
if (f.exists()) {
LuaValue chunk = this.globals.loadfile(f.getAbsolutePath());
chunk.call();
return LuaValue.valueOf(true);
} else {
return LuaValue.valueOf(false);
}
} catch (Exception e) {
System.err.println("Cannot load " + f.getName());
e.printStackTrace();
return LuaValue.valueOf(false);
}
}

View File

@@ -0,0 +1,90 @@
package de.c3ma.ollo.mockup;
import java.util.HashMap;
import javax.swing.SwingUtilities;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
/**
* created at 18.03.2021 - 21:09:03<br />
* creator: ollo<br />
* project: Esp8266 GPIO Emulation<br />
* $Id: $<br />
* @author ollo<br />
*/
public class ESP8266Gpio extends TwoArgFunction {
private static final String DIRECTION_INPUT = "input";
private HashMap<Integer, Integer> mInputs = new HashMap<Integer, Integer>();
@Override
public LuaValue call(LuaValue modname, LuaValue env) {
env.checkglobals();
final LuaTable gpio = new LuaTable();
gpio.set("mode", new Mode(this));
gpio.set("read", new Read(this));
gpio.set("INPUT", DIRECTION_INPUT);
env.set("gpio", gpio);
env.get("package").get("loaded").set("gpio", gpio);
return gpio;
}
private class Mode extends VarArgFunction {
private ESP8266Gpio gpio;
public Mode(ESP8266Gpio a) {
this.gpio = a;
}
public Varargs invoke(Varargs varargs) {
if (varargs.narg() == 2) {
final int pin = varargs.arg(1).toint();
final LuaString lsDirection = varargs.arg(2).checkstring();
String direction = lsDirection.toString();
if (direction.equals(DIRECTION_INPUT)) {
gpio.mInputs.put(pin, -1);
}
System.out.println("[GPIO] PIN" + pin +" as " + direction);
return LuaValue.valueOf(true);
} else {
return LuaValue.NIL;
}
}
}
private class Read extends OneArgFunction {
private ESP8266Gpio gpio;
public Read(ESP8266Gpio a) {
this.gpio = a;
}
@Override
public LuaValue call(LuaValue arg) {
int pin = arg.toint();
if (mInputs.containsKey(pin)) {
return LuaValue.valueOf(mInputs.get(pin));
} else {
System.out.println("[GPIO] pin" + pin + " not defined (gpio.mode missing)");
return LuaValue.NIL;
}
}
}
public void setPin(int pin, int newValue) {
if (mInputs.containsKey(pin)) {
mInputs.put(pin, newValue);
} else {
System.out.println("[GPIO] PIN" + pin +" not defined (missing gpio.mode)");
}
}
}

View File

@@ -0,0 +1,208 @@
package de.c3ma.ollo.mockup;
import java.util.UUID;
import org.eclipse.paho.client.mqttv3.IMqttClient;
import org.eclipse.paho.client.mqttv3.IMqttMessageListener;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;
import org.eclipse.paho.client.mqttv3.MqttSecurityException;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
/**
*
* @author ollo
*
*/
public class ESP8266Mqtt extends TwoArgFunction implements IMqttMessageListener {
private static final String ON_PREFIX = "on_";
private static final String MESSAGE = "message";
private IMqttClient mMqttClient = null;
final LuaTable onMqtt = new LuaTable();
@Override
public LuaValue call(LuaValue modname, LuaValue env) {
env.checkglobals();
final LuaTable mqtt = new LuaTable();
mqtt.set("Client", new LuaMqttClient());
env.set("mqtt", mqtt);
env.get("package").get("loaded").set("tmr", mqtt);
System.out.println("[MQTT] Modlue loaded");
return mqtt;
}
private class LuaMqttClient extends VarArgFunction {
public LuaValue invoke(Varargs varargs) {
final LuaTable dynMqtt = new LuaTable();
if (varargs.narg() == 2) {
final String client = varargs.arg(1).toString().toString();
final int timeout = varargs.arg(2).toint();
dynMqtt.set("on", new OnMqtt(client, timeout));
dynMqtt.set("publish", new PublishMqtt());
dynMqtt.set("subscribe", new SubscribeMqtt());
dynMqtt.set("connect", new ConnectMqtt());
System.out.println("[MQTT] New client: " + client + "(" + timeout+ "s)");
}
return dynMqtt;
}
}
private class OnMqtt extends VarArgFunction {
private String client=null;
private int timeout = 0;
private OnMqtt(String client, int timeout) {
this.client = client;
this.timeout = timeout;
}
public LuaValue invoke(Varargs varargs) {
if (varargs.narg() == 3) {
final LuaTable table = varargs.arg(1).checktable();
final String callback = varargs.arg(2).toString().toString();
final LuaValue code = varargs.arg(3);
System.out.println("[MQTT] On " + this.client + " " + callback);
onMqtt.set(ON_PREFIX + callback, code);
} else {
for(int i=0; i <= varargs.narg(); i++) {
System.err.println("[MQTT] On ["+(i) + "] (" + varargs.arg(i).typename() + ") " + varargs.arg(i).toString() );
}
return LuaValue.NIL;
}
return onMqtt;
}
}
private class PublishMqtt extends VarArgFunction {
public LuaValue invoke(Varargs varargs) {
final LuaTable onMqtt = new LuaTable();
if (varargs.narg() == 5) {
final String topic = varargs.arg(2).toString().toString();
final String message = varargs.arg(3).toString().toString();
final String qos = varargs.arg(4).toString().toString();
final String retain = varargs.arg(4).toString().toString();
if ( !mMqttClient.isConnected()) {
return LuaValue.NIL;
}
MqttMessage msg = new MqttMessage(message.getBytes());
if (qos.equals("0")) {
msg.setQos(0);
}
msg.setRetained(!retain.contentEquals("0"));
try {
mMqttClient.publish(topic,msg);
System.out.println("[MQTT] publish " + topic);
} catch (MqttPersistenceException e) {
System.err.println("[MQTT] publish " + topic + " failed : " + e.getMessage());
} catch (MqttException e) {
System.err.println("[MQTT] publish " + topic + " failed : " + e.getMessage());
}
} else {
for(int i=0; i <= varargs.narg(); i++) {
System.err.println("[MQTT] publish ["+(i) + "] (" + varargs.arg(i).typename() + ") " + varargs.arg(i).toString() );
}
return LuaValue.NIL;
}
return onMqtt;
}
}
private class SubscribeMqtt extends VarArgFunction {
public LuaValue invoke(Varargs varargs) {
final LuaTable onMqtt = new LuaTable();
final int numberArg = varargs.narg();
if (numberArg == 3) {
final String topic = varargs.arg(2).toString().toString();
final int qos = varargs.arg(3).tonumber().toint();
try {
if (mMqttClient != null) {
mMqttClient.subscribe(topic, ESP8266Mqtt.this);
System.out.println("[MQTT] subscribe " + topic + " (QoS " + qos + ")");
} else {
throw new Exception("Client not instantiated");
}
} catch (MqttSecurityException e) {
System.err.println("[MQTT] subscribe " + topic + " (QoS " + qos + ") failed: " + e.getMessage());
e.printStackTrace();
} catch (MqttException e) {
System.err.println("[MQTT] subscribe " + topic + " (QoS " + qos + ") failed: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
System.err.println("[MQTT] subscribe " + topic + " (QoS " + qos + ") failed: " + e.getMessage());
}
} else {
for(int i=0; i <= numberArg; i++) {
System.err.println("[MQTT] subscribe ["+(i) + "/" + numberArg + "] (" + varargs.arg(i).typename() + ") " + varargs.arg(i).toString() );
}
return LuaValue.NIL;
}
return onMqtt;
}
}
private class ConnectMqtt extends VarArgFunction {
public LuaValue invoke(Varargs varargs) {
final LuaTable onMqtt = new LuaTable();
if ((varargs.narg() == 6) && (mMqttClient == null)) {
final LuaTable table = varargs.arg(1).checktable();
final String targetIP = varargs.arg(2).toString().toString();
final int portnumber = varargs.arg(3).toint();
final boolean secureTLS = varargs.arg(4).toboolean();
final LuaValue codeOnConnected = varargs.arg(5);
final LuaValue codeOnFailed = varargs.arg(6);
String publisherId = "LuaSim" + UUID.randomUUID().toString();
try {
mMqttClient = new MqttClient("tcp://" + targetIP + ":" + portnumber,publisherId);
MqttConnectOptions options = new MqttConnectOptions();
options.setAutomaticReconnect(false);
options.setCleanSession(true);
options.setConnectionTimeout(10);
mMqttClient.connect(options);
System.out.println("[MQTT] connected to " + targetIP + ":" + portnumber);
codeOnConnected.call();
} catch (MqttException e) {
System.err.println("[MQTT] connect failed : " + e.getMessage());
codeOnFailed.call();
}
} else if (mMqttClient != null) {
System.err.println("[MQTT] client already exists : " + mMqttClient);
return LuaValue.NIL;
} else {
for(int i=0; i <= varargs.narg(); i++) {
System.err.println("[MQTT] connect ["+(i) + "] (" + varargs.arg(i).typename() + ") " + varargs.arg(i).toString() );
}
return LuaValue.NIL;
}
return onMqtt;
}
}
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
LuaValue messageCallback = onMqtt.get(ON_PREFIX + MESSAGE);
if (messageCallback != null) {
LuaValue call2 = messageCallback.call(LuaValue.NIL,
LuaValue.valueOf(topic),
LuaValue.valueOf(message.getPayload()));
//FIXME call the LUA code
} else {
System.err.println("[MQTT] message "+ topic + " : " + message + " without callback");
}
}
}

View File

@@ -34,6 +34,7 @@ public class ESP8266Node extends TwoArgFunction {
final LuaTable node = new LuaTable();
node.set("compile", new CompileFunction());
node.set("restart", new RestartFunction());
node.set("heap", new HeapFunction());
env.set("node", node);
env.get("package").get("loaded").set("node", node);
return node;
@@ -73,6 +74,18 @@ public class ESP8266Node extends TwoArgFunction {
}
private class HeapFunction extends ZeroArgFunction {
@Override
public LuaValue call() {
System.out.println("[Node] Heap");
return LuaValue.valueOf(Runtime.getRuntime().freeMemory());
}
}
public void setWorkingDirectory(File workingDir) {
this.workingDir = workingDir;
}

View File

@@ -6,6 +6,7 @@ import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import de.c3ma.ollo.LuaThreadTmr;
@@ -18,9 +19,11 @@ import de.c3ma.ollo.LuaThreadTmr;
*/
public class ESP8266Tmr extends TwoArgFunction {
private static final int MAXTHREADS = 7;
private static final int MAXTHREADS = 10;
private static LuaThreadTmr[] allThreads = new LuaThreadTmr[MAXTHREADS];
private static LuaThreadTmr[] dynamicThreads = new LuaThreadTmr[MAXTHREADS];
private static int dynamicThreadCounter=0;
public static int gTimingFactor = 1;
@@ -30,6 +33,10 @@ public class ESP8266Tmr extends TwoArgFunction {
final LuaTable tmr = new LuaTable();
tmr.set("stop", new stop());
tmr.set("alarm", new alarm());
tmr.set("create", new create());
tmr.set("wdclr", new watchDog());
tmr.set("ALARM_AUTO", "ALARM_AUTO");
tmr.set("ALARM_SINGLE", "ALARM_SINGLE");
env.set("tmr", tmr);
env.get("package").get("loaded").set("tmr", tmr);
@@ -37,6 +44,9 @@ public class ESP8266Tmr extends TwoArgFunction {
for (Thread t : allThreads) {
t = null;
}
for (Thread t : dynamicThreads) {
t = null;
}
return tmr;
}
@@ -87,6 +97,79 @@ public class ESP8266Tmr extends TwoArgFunction {
}
}
private class dynRegister extends VarArgFunction {
private final int dynIndex;
public dynRegister(int index) {
this.dynIndex = index;
}
public Varargs invoke(Varargs varargs) {
if (varargs.narg() == 4) {
final String endlessloop = varargs.arg(3).toString().toString();
final int delay = varargs.arg(2).toint();
final LuaValue code = varargs.arg(4);
dynamicThreads[dynIndex] = new LuaThreadTmr(dynIndex, code, (endlessloop.contains("AUTO")), Math.max(delay / gTimingFactor, 1));
System.out.println("[TMR] DynTimer" + dynIndex + " registered");
}
return LuaValue.valueOf(true);
}
}
private class dynStart extends ZeroArgFunction {
private final int dynIndex;
public dynStart(int index) {
this.dynIndex = index;
}
public LuaValue call() {
if (dynamicThreads[dynIndex] != null) {
dynamicThreads[dynIndex].start();
System.out.println("[TMR] DynTimer" + dynIndex + " started");
return LuaValue.valueOf(true);
} else {
return LuaValue.valueOf(false);
}
}
}
private class watchDog extends ZeroArgFunction {
public LuaValue call() {
System.out.println("[TMR] Watchdog fed");
return LuaValue.valueOf(true);
}
}
private class dynStop extends ZeroArgFunction {
private final int dynIndex;
public dynStop(int index) {
this.dynIndex = index;
}
public LuaValue call() {
boolean status = false;
if (dynamicThreads[dynIndex] != null) {
dynamicThreads[dynIndex].stopThread();
dynamicThreads[dynIndex] = null;
System.out.println("[TMR] DynTimer" + dynIndex + " stopped");
status = true;
}
return LuaValue.valueOf(status);
}
}
private class create extends ZeroArgFunction {
public LuaValue call() {
if (dynamicThreadCounter >= MAXTHREADS) {
return LuaValue.error("[TMR] DynTimer" + dynamicThreadCounter + " exeeded maximum");
}
final LuaTable dynTimer = new LuaTable();
dynTimer.set("register", new dynRegister(dynamicThreadCounter));
dynTimer.set("start", new dynStart(dynamicThreadCounter));
dynTimer.set("unregister", new dynStop(dynamicThreadCounter));
dynamicThreadCounter++;
return dynTimer;
}
}
public void stopAllTimer() {
for (int i = 0; i < allThreads.length; i++) {
stopTmr(i);

View File

@@ -1,14 +1,18 @@
package de.c3ma.ollo.mockup;
import java.awt.Color;
import java.io.File;
import java.util.ArrayList;
import javax.swing.SwingUtilities;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaTable;
import org.luaj.vm2.LuaValue;
import org.luaj.vm2.Varargs;
import org.luaj.vm2.lib.OneArgFunction;
import org.luaj.vm2.lib.TwoArgFunction;
import org.luaj.vm2.lib.VarArgFunction;
import org.luaj.vm2.lib.ZeroArgFunction;
import de.c3ma.ollo.LuaSimulation;
@@ -32,6 +36,7 @@ public class ESP8266Ws2812 extends TwoArgFunction {
final LuaTable ws2812 = new LuaTable();
ws2812.set("init", new init());
ws2812.set("write", new write());
ws2812.set("newBuffer", new newBuffer());
env.set("ws2812", ws2812);
env.get("package").get("loaded").set("ws2812", ws2812);
return ws2812;
@@ -54,6 +59,12 @@ public class ESP8266Ws2812 extends TwoArgFunction {
if (arg.isstring()) {
LuaString jstring = arg.checkstring();
final int length = jstring.rawlen();
if (ESP8266Ws2812.layout == null) {
System.err.println("[WS2812] Not initialized (" + length + "bytes to be updated)");
return LuaValue.valueOf(false);
}
if ((length % 3) == 0) {
final byte[] array = jstring.m_bytes;
SwingUtilities.invokeLater(new Runnable() {
@@ -70,13 +81,11 @@ public class ESP8266Ws2812 extends TwoArgFunction {
}
});
}
if (ESP8266Ws2812.layout == null) {
System.out.println("[WS2812] write length:" + length);
} else {
}
return LuaValue.valueOf(true);
} else {
System.out.println("[WS2812] write no string given");
return LuaValue.NIL;
}
return LuaValue.valueOf(true);
}
}
@@ -85,4 +94,175 @@ public class ESP8266Ws2812 extends TwoArgFunction {
ESP8266Ws2812.layout = WS2812Layout.parse(file, nodemcuSimu);
}
}
private class newBuffer extends VarArgFunction {
public Varargs invoke(Varargs varargs) {
if (varargs.narg() == 2) {
final int leds = varargs.arg(1).toint();
final int bytesPerLeds = varargs.arg(2).toint();
final LuaTable rgbBuffer = new LuaTable();
ArrayList<Color> ledList = new ArrayList<Color>();
for(int i=0; i < leds; i++) {
ledList.add(new Color(0,0,0));
}
rgbBuffer.set("fill", new bufferFill(ledList));
rgbBuffer.set("set", new bufferWrite(ledList));
rgbBuffer.set("get", new bufferRead(ledList));
System.out.println("[WS2812] " + leds + "leds (" + bytesPerLeds + "bytes per led)");
return rgbBuffer;
} else {
return LuaValue.NIL;
}
}
}
private class bufferFill extends VarArgFunction {
private ArrayList<Color> ledList = null;
public bufferFill(ArrayList<Color> ledList) {
this.ledList = ledList;
}
public Varargs invoke(Varargs varargs) {
if (varargs.narg() == 4) {
/* first argument is the object itself */
final int red = varargs.arg(2).toint();
final int green = varargs.arg(3).toint();
final int blue = varargs.arg(4).toint();
/* update local buffer */
for(int i=0; i < ledList.size(); i++) {
ledList.set(i, new Color(red, green, blue));
}
/* Update GUI */
if (ESP8266Ws2812.layout != null) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ESP8266Ws2812.layout.fillLEDs(red, green, blue);
}
});
}
System.out.println("[WS2812] buffer fill with " + red + "," + green + "," + blue);
return LuaValue.valueOf(true);
} else if (varargs.isstring(2)) {
final LuaString color = varargs.arg(2).checkstring();
final int length = color.rawlen();
if ((length == 3) && (ESP8266Ws2812.layout != null)) {
final byte[] array = color.m_bytes;
final int r = array[0]+(Byte.MIN_VALUE*-1);
final int b = array[1]+(Byte.MIN_VALUE*-1);
final int g = array[2]+(Byte.MIN_VALUE*-1);
/* update local buffer */
for(int i=0; i < ledList.size(); i++) {
ledList.set(i, new Color(r, g, b));
}
/* Update GUI */
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ESP8266Ws2812.layout.fillLEDs(r, g, b);
}
});
//System.out.println("[WS2812] buffer fill with " + r + "," + g + "," + b);
return LuaValue.valueOf(true);
} else {
System.err.println("[WS2812] buffer not initialized ("+varargs.narg() +"args) , length "+ length + ", raw:" + color.toString());
return LuaValue.NIL;
}
} else {
System.err.println("[WS2812] fill with " + varargs.narg() + " arguments undefined.");
return LuaValue.NIL;
}
}
}
private class bufferWrite extends VarArgFunction {
private ArrayList<Color> ledList = null;
public bufferWrite(ArrayList<Color> ledList) {
this.ledList = ledList;
}
public Varargs invoke(Varargs varargs) {
if (varargs.narg() == 3) {
final int index = varargs.arg(2).toint();
final LuaString color = varargs.arg(3).checkstring();
final int length = color.rawlen();
if (length == 3) {
final byte[] array = color.m_bytes;
final int r = array[0]+(Byte.MIN_VALUE*-1);
final int b = array[1]+(Byte.MIN_VALUE*-1);
final int g = array[2]+(Byte.MIN_VALUE*-1);
// update buffer
ledList.set(index - 1, new Color(r, g, b));
// update GUI
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ESP8266Ws2812.layout.updateLED(index - 1, r, g, b);
}
});
return LuaValue.valueOf(true);
} else {
System.err.println("[WS2812] set with " + varargs.narg() + " arguments at index="+ index + " and "+ length + " charactes not matching");
return LuaValue.NIL;
}
} else if (varargs.narg() == 5) {
final int index = varargs.arg(2).toint();
final int green = varargs.arg(3).toint();
final int red = varargs.arg(4).toint();
final int blue = varargs.arg(5).toint();
// update buffer
ledList.set(index - 1, new Color(red, green, blue));
// update GUI
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ESP8266Ws2812.layout.updateLED(index - 1, red, green, blue);
}
});
return LuaValue.valueOf(true);
} else {
for(int i=0; i <= varargs.narg(); i++) {
System.err.println("[WS2812] write ["+(i) + "] (" + varargs.arg(i).typename() + ") " + varargs.arg(i).toString() );
}
System.err.println("[WS2812] set with " + varargs.narg() + " arguments undefined.");
return LuaValue.NIL;
}
}
}
private class bufferRead extends VarArgFunction {
private ArrayList<Color> ledList = null;
public bufferRead(ArrayList<Color> ledList) {
this.ledList = ledList;
}
@Override
public Varargs invoke(Varargs varargs) {
final int offset = varargs.arg(2).toint();
if (ledList != null) {
// receiver from buffer
Color color = ledList.get(offset - 1);
final char[] array = new char[3];
array[0] = (char) (color.getRed() );
array[1] = (char) (color.getGreen() );
array[2] = (char) (color.getBlue() );
// System.err.println("[WS2812] reading " + offset + ":" + ((int)array[0]) +"," + ((int) array[1]) + "," + ((int) array[2]) + " from " + color);
return LuaString.valueOf(array);
}
System.err.println("[WS2812] reading " + offset + " impossible");
return LuaValue.NIL;
}
}
}

View File

@@ -288,6 +288,10 @@ public class WS2812Layout extends JFrame {
this.setForeground(new Color(red, green, blue));
this.repaint();
}
public Color getColor() {
return this.getForeground();
}
@Override
public String toString() {
@@ -319,5 +323,40 @@ public class WS2812Layout extends JFrame {
}
}
}
public Element getLED(int index) {
if (mElements != null) {
int i = (index / mColumn);
int j = (index % mColumn);
if (i % 2 == 1) {
j = (mColumn-1) - j;
}
if (i < 0 || j < 0) {
System.err.println("LED index" + index + " results in " + i + "x" + j + " coordinate");
return null;
}
if ((i < mElements.length) && (j < mElements[i].length) && (mElements[i][j] != null)) {
return mElements[i][j];
} else {
return null;
}
} else {
return null;
}
}
public void fillLEDs(int r, int g, int b) {
if (mElements != null) {
for(int i=0;(i < mElements.length); i++) {
for (int j=0; (j < mElements[i].length); j++) {
if (mElements[i][j] != null) {
Element curlbl = mElements[i][j];
curlbl.setColor(r, g, b);
}
}
}
}
}
}