Merged
This commit is contained in:
@@ -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>
|
||||
|
@@ -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`
|
||||
|
@@ -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
|
||||
|
@@ -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
|
BIN
simulation/libs/org.eclipse.paho.client.mqttv3-1.2.5.jar
Normal file
BIN
simulation/libs/org.eclipse.paho.client.mqttv3-1.2.5.jar
Normal file
Binary file not shown.
@@ -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 {
|
||||
|
@@ -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());
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
90
simulation/src/de/c3ma/ollo/mockup/ESP8266Gpio.java
Normal file
90
simulation/src/de/c3ma/ollo/mockup/ESP8266Gpio.java
Normal 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)");
|
||||
}
|
||||
}
|
||||
}
|
208
simulation/src/de/c3ma/ollo/mockup/ESP8266Mqtt.java
Normal file
208
simulation/src/de/c3ma/ollo/mockup/ESP8266Mqtt.java
Normal 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");
|
||||
}
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user