2
This commit is contained in:
@@ -0,0 +1,73 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!-- You may freely edit this file. See commented blocks below for -->
|
||||||
|
<!-- some examples of how to customize the build. -->
|
||||||
|
<!-- (If you delete it and reopen the project it will be recreated.) -->
|
||||||
|
<!-- By default, only the Clean and Build commands use this build script. -->
|
||||||
|
<!-- Commands such as Run, Debug, and Test only use this build script if -->
|
||||||
|
<!-- the Compile on Save feature is turned off for the project. -->
|
||||||
|
<!-- You can turn off the Compile on Save (or Deploy on Save) setting -->
|
||||||
|
<!-- in the project's Project Properties dialog box.-->
|
||||||
|
<project name="kebaAgent" default="default" basedir=".">
|
||||||
|
<description>Builds, tests, and runs the project kebaAgent.</description>
|
||||||
|
<import file="nbproject/build-impl.xml"/>
|
||||||
|
<!--
|
||||||
|
|
||||||
|
There exist several targets which are by default empty and which can be
|
||||||
|
used for execution of your tasks. These targets are usually executed
|
||||||
|
before and after some main targets. They are:
|
||||||
|
|
||||||
|
-pre-init: called before initialization of project properties
|
||||||
|
-post-init: called after initialization of project properties
|
||||||
|
-pre-compile: called before javac compilation
|
||||||
|
-post-compile: called after javac compilation
|
||||||
|
-pre-compile-single: called before javac compilation of single file
|
||||||
|
-post-compile-single: called after javac compilation of single file
|
||||||
|
-pre-compile-test: called before javac compilation of JUnit tests
|
||||||
|
-post-compile-test: called after javac compilation of JUnit tests
|
||||||
|
-pre-compile-test-single: called before javac compilation of single JUnit test
|
||||||
|
-post-compile-test-single: called after javac compilation of single JUunit test
|
||||||
|
-pre-jar: called before JAR building
|
||||||
|
-post-jar: called after JAR building
|
||||||
|
-post-clean: called after cleaning build products
|
||||||
|
|
||||||
|
(Targets beginning with '-' are not intended to be called on their own.)
|
||||||
|
|
||||||
|
Example of inserting an obfuscator after compilation could look like this:
|
||||||
|
|
||||||
|
<target name="-post-compile">
|
||||||
|
<obfuscate>
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</obfuscate>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
For list of available properties check the imported
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
|
||||||
|
Another way to customize the build is by overriding existing main targets.
|
||||||
|
The targets of interest are:
|
||||||
|
|
||||||
|
-init-macrodef-javac: defines macro for javac compilation
|
||||||
|
-init-macrodef-junit: defines macro for junit execution
|
||||||
|
-init-macrodef-debug: defines macro for class debugging
|
||||||
|
-init-macrodef-java: defines macro for class execution
|
||||||
|
-do-jar: JAR building
|
||||||
|
run: execution of project
|
||||||
|
-javadoc-build: Javadoc generation
|
||||||
|
test-report: JUnit report generation
|
||||||
|
|
||||||
|
An example of overriding the target for project execution could look like this:
|
||||||
|
|
||||||
|
<target name="run" depends="kebaAgent-impl.jar">
|
||||||
|
<exec dir="bin" executable="launcher.exe">
|
||||||
|
<arg file="${dist.jar}"/>
|
||||||
|
</exec>
|
||||||
|
</target>
|
||||||
|
|
||||||
|
Notice that the overridden target depends on the jar target and not only on
|
||||||
|
the compile target as the regular run target does. Again, for a list of available
|
||||||
|
properties which you can use, check the target you are overriding in the
|
||||||
|
nbproject/build-impl.xml file.
|
||||||
|
|
||||||
|
-->
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# Einstellungen UniCon KemaAgent
|
||||||
|
|
||||||
|
aliases: links, rechts
|
||||||
|
|
||||||
|
links.port: 502
|
||||||
|
#links.ip: 192.168.0.28
|
||||||
|
links.ip: localhost
|
||||||
|
|
||||||
|
|
||||||
|
rechts.port: 503
|
||||||
|
#rechts.ip: 192.168.0.29
|
||||||
|
rechts.ip: localhost
|
||||||
|
|
||||||
|
webserver.port: 50000
|
||||||
|
webserver.defaultUri: /keba
|
||||||
|
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
X-COMMENT: Main-Class will be added automatically by build
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,8 @@
|
|||||||
|
build.xml.data.CRC32=11b719f8
|
||||||
|
build.xml.script.CRC32=606a34af
|
||||||
|
build.xml.stylesheet.CRC32=f85dc8f2@1.119.0.48
|
||||||
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||||
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||||
|
nbproject/build-impl.xml.data.CRC32=11b719f8
|
||||||
|
nbproject/build-impl.xml.script.CRC32=b9fa6210
|
||||||
|
nbproject/build-impl.xml.stylesheet.CRC32=12e0a6c2@1.119.0.48
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
annotation.processing.enabled=true
|
||||||
|
annotation.processing.enabled.in.editor=false
|
||||||
|
annotation.processing.processors.list=
|
||||||
|
annotation.processing.run.all.processors=true
|
||||||
|
annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output
|
||||||
|
application.title=kebaAgent
|
||||||
|
application.vendor=holz
|
||||||
|
build.classes.dir=${build.dir}/classes
|
||||||
|
build.classes.excludes=**/*.java,**/*.form
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
build.dir=build
|
||||||
|
build.generated.dir=${build.dir}/generated
|
||||||
|
build.generated.sources.dir=${build.dir}/generated-sources
|
||||||
|
# Only compile against the classpath explicitly listed here:
|
||||||
|
build.sysclasspath=ignore
|
||||||
|
build.test.classes.dir=${build.dir}/test/classes
|
||||||
|
build.test.results.dir=${build.dir}/test/results
|
||||||
|
# Uncomment to specify the preferred debugger connection transport:
|
||||||
|
#debug.transport=dt_socket
|
||||||
|
debug.classpath=\
|
||||||
|
${run.classpath}
|
||||||
|
debug.modulepath=\
|
||||||
|
${run.modulepath}
|
||||||
|
debug.test.classpath=\
|
||||||
|
${run.test.classpath}
|
||||||
|
debug.test.modulepath=\
|
||||||
|
${run.test.modulepath}
|
||||||
|
# Files in build.classes.dir which should be excluded from distribution jar
|
||||||
|
dist.archive.excludes=
|
||||||
|
# This directory is removed when the project is cleaned:
|
||||||
|
dist.dir=dist
|
||||||
|
dist.jar=${dist.dir}/kebaAgent.jar
|
||||||
|
dist.javadoc.dir=${dist.dir}/javadoc
|
||||||
|
dist.jlink.dir=${dist.dir}/jlink
|
||||||
|
dist.jlink.output=${dist.jlink.dir}/kebaAgent
|
||||||
|
endorsed.classpath=
|
||||||
|
excludes=
|
||||||
|
file.reference.jlibmodbus-1.2.9.4.jar=lib\\jlibmodbus-1.2.9.4.jar
|
||||||
|
file.reference.json.jar=lib\\json.jar
|
||||||
|
includes=**
|
||||||
|
jar.compress=false
|
||||||
|
javac.classpath=\
|
||||||
|
${file.reference.jlibmodbus-1.2.9.4.jar}:\
|
||||||
|
${file.reference.json.jar}
|
||||||
|
# Space-separated list of extra javac options
|
||||||
|
javac.compilerargs=
|
||||||
|
javac.deprecation=false
|
||||||
|
javac.external.vm=true
|
||||||
|
javac.modulepath=
|
||||||
|
javac.processormodulepath=
|
||||||
|
javac.processorpath=\
|
||||||
|
${javac.classpath}
|
||||||
|
javac.source=25
|
||||||
|
javac.target=25
|
||||||
|
javac.test.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}
|
||||||
|
javac.test.modulepath=\
|
||||||
|
${javac.modulepath}
|
||||||
|
javac.test.processorpath=\
|
||||||
|
${javac.test.classpath}
|
||||||
|
javadoc.additionalparam=
|
||||||
|
javadoc.author=false
|
||||||
|
javadoc.encoding=${source.encoding}
|
||||||
|
javadoc.html5=false
|
||||||
|
javadoc.noindex=false
|
||||||
|
javadoc.nonavbar=false
|
||||||
|
javadoc.notree=false
|
||||||
|
javadoc.private=false
|
||||||
|
javadoc.splitindex=true
|
||||||
|
javadoc.use=true
|
||||||
|
javadoc.version=false
|
||||||
|
javadoc.windowtitle=
|
||||||
|
# The jlink additional root modules to resolve
|
||||||
|
jlink.additionalmodules=
|
||||||
|
# The jlink additional command line parameters
|
||||||
|
jlink.additionalparam=
|
||||||
|
jlink.launcher=true
|
||||||
|
jlink.launcher.name=kebaAgent
|
||||||
|
main.class=kebaagent.KebaAgent
|
||||||
|
manifest.file=manifest.mf
|
||||||
|
meta.inf.dir=${src.dir}/META-INF
|
||||||
|
mkdist.disabled=false
|
||||||
|
platform.active=default_platform
|
||||||
|
run.classpath=\
|
||||||
|
${javac.classpath}:\
|
||||||
|
${build.classes.dir}
|
||||||
|
# Space-separated list of JVM arguments used when running the project.
|
||||||
|
# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value.
|
||||||
|
# To set system properties for unit tests define test-sys-prop.name=value:
|
||||||
|
run.jvmargs=
|
||||||
|
run.modulepath=\
|
||||||
|
${javac.modulepath}
|
||||||
|
run.test.classpath=\
|
||||||
|
${javac.test.classpath}:\
|
||||||
|
${build.test.classes.dir}
|
||||||
|
run.test.modulepath=\
|
||||||
|
${javac.test.modulepath}
|
||||||
|
source.encoding=UTF-8
|
||||||
|
src.dir=src
|
||||||
|
test.src.dir=test
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://www.netbeans.org/ns/project/1">
|
||||||
|
<type>org.netbeans.modules.java.j2seproject</type>
|
||||||
|
<configuration>
|
||||||
|
<data xmlns="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
|
<name>kebaAgent</name>
|
||||||
|
<source-roots>
|
||||||
|
<root id="src.dir"/>
|
||||||
|
</source-roots>
|
||||||
|
<test-roots>
|
||||||
|
<root id="test.src.dir"/>
|
||||||
|
</test-roots>
|
||||||
|
</data>
|
||||||
|
</configuration>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
*/
|
||||||
|
package kebaagent;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Headers;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author holz
|
||||||
|
*/
|
||||||
|
class JsonHandler implements HttpHandler
|
||||||
|
{
|
||||||
|
private final KebaAgent agent;
|
||||||
|
|
||||||
|
JsonHandler(KebaAgent agent)
|
||||||
|
{
|
||||||
|
this.agent = agent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(HttpExchange httpExchange) throws IOException
|
||||||
|
{
|
||||||
|
// nur GET
|
||||||
|
if (!"GET".equals(httpExchange.getRequestMethod()))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parameter ermitteln: path ist Teil hinter Domain: "/t/allowed?..."
|
||||||
|
String uri = httpExchange.getRequestURI().toString();
|
||||||
|
Map<String, String> params = getParams(uri);
|
||||||
|
|
||||||
|
String callData = agent.getDataAsJson(params);
|
||||||
|
// response
|
||||||
|
OutputStream outputStream = httpExchange.getResponseBody();
|
||||||
|
// StringBuilder sb = new StringBuilder();
|
||||||
|
// sb
|
||||||
|
// .append("<html>")
|
||||||
|
// .append("<body>")
|
||||||
|
// .append("<h1>")
|
||||||
|
// .append("Hello ")
|
||||||
|
// .append(callData)
|
||||||
|
// .append("</h1>")
|
||||||
|
// .append("</body>")
|
||||||
|
// .append("</html>");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// String htmlResponse = sb.toString();
|
||||||
|
String htmlResponse = callData;
|
||||||
|
|
||||||
|
// jaho: Header erweitern
|
||||||
|
Headers responseHeaders = httpExchange.getResponseHeaders();
|
||||||
|
responseHeaders.set("Content-Type", "application/json");
|
||||||
|
|
||||||
|
// this line is a must (jaho: header senden)
|
||||||
|
httpExchange.sendResponseHeaders(200, htmlResponse.length());
|
||||||
|
|
||||||
|
outputStream.write(htmlResponse.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, String> getParams(String uri)
|
||||||
|
{
|
||||||
|
// split bei ?
|
||||||
|
List<String> l = new ArrayList<>(List.of(uri.split("\\?")));
|
||||||
|
final Map<String, String> paramsMap = new HashMap();
|
||||||
|
|
||||||
|
l.removeFirst();
|
||||||
|
l.forEach(xparam ->
|
||||||
|
{
|
||||||
|
// key/value extrahieren
|
||||||
|
String[] split = xparam.split("=");
|
||||||
|
String k = split[0];
|
||||||
|
String v = split.length > 1 ? split[1] : "";
|
||||||
|
paramsMap.put(k, v);
|
||||||
|
});
|
||||||
|
|
||||||
|
System.out.println("");
|
||||||
|
return paramsMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
/*
|
||||||
|
Webservice bereitstellen und auf http:GET-Anfrage Werte von KEBA-Wallbox per MODBUS holen
|
||||||
|
*/
|
||||||
|
package kebaagent;
|
||||||
|
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Properties;
|
||||||
|
import static kebaagent.KebaModbus.connect;
|
||||||
|
import static kebaagent.KebaModbus.readInt32BigEndian;
|
||||||
|
import static kebaagent.KebaModbus.sleep;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author holz
|
||||||
|
*/
|
||||||
|
public class KebaAgent
|
||||||
|
{
|
||||||
|
public static final int WEBSERVER_PORT = 50000;
|
||||||
|
|
||||||
|
|
||||||
|
private Properties prop = new Properties();
|
||||||
|
|
||||||
|
|
||||||
|
public KebaAgent(String[] args)
|
||||||
|
{
|
||||||
|
String propertiesFilename = "kemaagent.properties";
|
||||||
|
|
||||||
|
if (args.length > 0)
|
||||||
|
{
|
||||||
|
List<String> lArgs = List.of(args);
|
||||||
|
if (!lArgs.getLast().startsWith("-"))
|
||||||
|
{
|
||||||
|
propertiesFilename = lArgs.getLast();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.printf("benutzer Einstellungen aus %s\n", propertiesFilename);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
prop.load(new FileReader(propertiesFilename));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param alias
|
||||||
|
* @param name
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Optional<String> getPropValue(String alias, String name)
|
||||||
|
{
|
||||||
|
return Optional.of(prop.getProperty(alias + "." + name));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int getPort()
|
||||||
|
{
|
||||||
|
int defPort = WEBSERVER_PORT;
|
||||||
|
String key = "webserver.port";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
defPort = Integer.parseInt(prop.getProperty(key, ""));
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e)
|
||||||
|
{
|
||||||
|
System.err.printf("Schlüssel %s konnte nicht aus properties eingelesen werden. Es wird Standard %d benutzt.\n", key, defPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
return defPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liste von Instanzen über Namen
|
||||||
|
*/
|
||||||
|
private final Map<String, KebaModbus> kebaModbusMap = new HashMap<>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
|
||||||
|
KebaAgent agent = new KebaAgent(args);
|
||||||
|
agent.init();
|
||||||
|
|
||||||
|
|
||||||
|
Webserver webserver = new Webserver(agent.getPort());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
webserver.start(agent);
|
||||||
|
}
|
||||||
|
catch (IOException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
System.out.println("webserver gestartet");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* alle wichtigen modbus-Daten beschaffen
|
||||||
|
* @param params
|
||||||
|
* @return JSON-Daten
|
||||||
|
*/
|
||||||
|
String getDataAsJson(Map<String, String> params)
|
||||||
|
{
|
||||||
|
final int slaveId = 255;
|
||||||
|
|
||||||
|
JSONObject joRoot = new JSONObject();
|
||||||
|
JSONArray jaStations = new JSONArray();
|
||||||
|
|
||||||
|
getAliases()
|
||||||
|
.forEach(name ->
|
||||||
|
{
|
||||||
|
|
||||||
|
KebaModbus kebaModbus = kebaModbusMap.get(name);
|
||||||
|
|
||||||
|
JSONObject joPart = new JSONObject();
|
||||||
|
|
||||||
|
int val;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (kebaModbus.initFailed)
|
||||||
|
{
|
||||||
|
joPart.put("error", "initError");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
joPart.put("alias", name);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
String
|
||||||
|
jName = "chargingState";
|
||||||
|
int register = 1000;
|
||||||
|
val = kebaModbus.read(jName, register, slaveId);
|
||||||
|
// val = readInt32BigEndian(kebaModbus.getModbusMaster(), slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d: %d (0x%04x)\n", register, val, val);
|
||||||
|
joPart.put(jName, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
jName = "s/n";
|
||||||
|
register = 1014;
|
||||||
|
val = kebaModbus.read(jName, register, slaveId);
|
||||||
|
System.out.printf("Wert für reg %d: %d (0x%04x)\n", register, val, val);
|
||||||
|
joPart.put(jName, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
jName = "power";
|
||||||
|
register = 1020;
|
||||||
|
val = kebaModbus.read(jName, register, slaveId);
|
||||||
|
// val = readInt32BigEndian(kebaModbus.getModbusMaster(), slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (active Power): %1.1f kW (0x%04x)\n", register, val/1e6, val);
|
||||||
|
joPart.put(jName, val/1e6);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
jName = "RFID";
|
||||||
|
register = 1500;
|
||||||
|
val = kebaModbus.read(jName, register, slaveId);
|
||||||
|
// val = readInt32BigEndian(kebaModbus.getModbusMaster(), slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (RFID-Card): %d (0x%04x)\n", register, val, val);
|
||||||
|
joPart.put(jName, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
jName = "chargedEnergy";
|
||||||
|
// angeblich Wh, aber in Wirklichkeit Wh/10
|
||||||
|
register = 1502;
|
||||||
|
val = kebaModbus.read(jName, register, slaveId);
|
||||||
|
// val = readInt32BigEndian(kebaModbus.getModbusMaster(), slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (charged energy [kWh]): %1.1f (0x%04x)\n", register, val/10000f, val);
|
||||||
|
joPart.put(jName, val/10000f);
|
||||||
|
|
||||||
|
jaStations.put(joPart);
|
||||||
|
}
|
||||||
|
catch (ModbusProtocolException | ModbusNumberException | ModbusIOException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
// joPart.put("Error", "exception: %s".formatted(ex.getMessage());
|
||||||
|
// return "{ error: 'exception: %s'}".formatted(ex.getMessage());
|
||||||
|
}
|
||||||
|
catch (JSONException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
joRoot.put("stations", jaStations);
|
||||||
|
return joRoot.toString();
|
||||||
|
}
|
||||||
|
catch (JSONException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
return "{ error: '%s'".formatted(ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void init()
|
||||||
|
{
|
||||||
|
getAliases().forEach(alias ->
|
||||||
|
{
|
||||||
|
getPropValue(alias, "ip").ifPresent(sIP ->
|
||||||
|
{
|
||||||
|
KebaModbus km = new KebaModbus(sIP, getModbusPort(alias));
|
||||||
|
km.initFailed = true;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
km.init();
|
||||||
|
km.initFailed = false;
|
||||||
|
kebaModbusMap.put(alias, km);
|
||||||
|
}
|
||||||
|
catch (UnknownHostException | ModbusIOException | NumberFormatException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaAgent.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// KebaModbus km = new KebaModbus("localhost", 502);
|
||||||
|
// kebaModbusMap.put("links", km);
|
||||||
|
// km.initFailed = true;
|
||||||
|
// km.init();
|
||||||
|
// km.initFailed = false;
|
||||||
|
//
|
||||||
|
// km = new KebaModbus("localhost", 503);
|
||||||
|
// kebaModbusMap.put("rechts", km);
|
||||||
|
// km.initFailed = true;
|
||||||
|
// km.init();
|
||||||
|
// km.initFailed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @return Liste von aliases aus den properties
|
||||||
|
*/
|
||||||
|
private List<String> getAliases()
|
||||||
|
{
|
||||||
|
String a = prop.getProperty("aliases", "");
|
||||||
|
return List.of(a.split(",")).stream().map(s -> s.trim()).toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Port aus konfig oder 502
|
||||||
|
* @param alias
|
||||||
|
* @return
|
||||||
|
* @throws NumberFormatException
|
||||||
|
*/
|
||||||
|
private int getModbusPort(String alias) throws NumberFormatException
|
||||||
|
{
|
||||||
|
Optional<String> oPort = getPropValue(alias, "port");
|
||||||
|
if (oPort.isPresent())
|
||||||
|
{
|
||||||
|
return Integer.parseInt(oPort.get());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return 502;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,341 @@
|
|||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kebaagent;
|
||||||
|
|
||||||
|
import com.intelligt.modbus.jlibmodbus.Modbus;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.msg.request.ReadHoldingRegistersRequest;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.msg.response.ReadHoldingRegistersResponse;
|
||||||
|
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
//import oracle.jrockit.jfr.tools.ConCatRepository;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abfrage KEBA-Wallbox
|
||||||
|
* @author jaho
|
||||||
|
*/
|
||||||
|
public class KebaModbus
|
||||||
|
{
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
private String ip;
|
||||||
|
public boolean initFailed;
|
||||||
|
private ModbusMaster modbusMaster;
|
||||||
|
|
||||||
|
private final Map<String, Integer> valueMap = new HashMap();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void init() throws UnknownHostException, ModbusIOException
|
||||||
|
{
|
||||||
|
TcpParameters tcpParameters = new TcpParameters();
|
||||||
|
// TcpParameters tcpParametersSlave = new TcpParameters();
|
||||||
|
|
||||||
|
//tcp parameters have already set by default as in example
|
||||||
|
// tcpParameters.setHost(InetAddress.getLocalHost());
|
||||||
|
tcpParameters.setHost(InetAddress.getByName(ip));
|
||||||
|
tcpParameters.setKeepAlive(true);
|
||||||
|
tcpParameters.setPort(port);
|
||||||
|
// tcpParametersSlave.setPort(Modbus.TCP_PORT);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// if you would like to set connection parameters separately,
|
||||||
|
// you should use another method: createModbusMasterTCP(String host, int port, boolean keepAlive);
|
||||||
|
m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
|
||||||
|
Modbus.setAutoIncrementTransactionId(true);
|
||||||
|
// jaho
|
||||||
|
m.setResponseTimeout(60000);
|
||||||
|
*/
|
||||||
|
System.err.printf("try to connect to %s:%d ...", ip, port);
|
||||||
|
// ! diese Methode kommt immer sofort zurück. Man muss Ergebnis prüfen!
|
||||||
|
modbusMaster = connect(tcpParameters, timeout_ms);
|
||||||
|
if (modbusMaster.isConnected())
|
||||||
|
System.err.printf("done\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modbusMaster.connect();
|
||||||
|
if (!modbusMaster.isConnected())
|
||||||
|
{
|
||||||
|
System.err.printf("FAILED\n");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModbusMaster getModbusMaster()
|
||||||
|
{
|
||||||
|
return modbusMaster;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getValueMap()
|
||||||
|
{
|
||||||
|
return valueMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public KebaModbus(String ip, int port)
|
||||||
|
{
|
||||||
|
this.ip = ip;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static int timeout_ms = 10000;
|
||||||
|
|
||||||
|
|
||||||
|
public static ModbusMaster connect(TcpParameters tcpParameters, int responeTimeout_ms)
|
||||||
|
{
|
||||||
|
// if you would like to set connection parameters separately,
|
||||||
|
// you should use another method: createModbusMasterTCP(String host, int port, boolean keepAlive);
|
||||||
|
ModbusMaster m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
|
||||||
|
Modbus.setAutoIncrementTransactionId(true);
|
||||||
|
if (responeTimeout_ms > 0)
|
||||||
|
m.setResponseTimeout(responeTimeout_ms);
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args the command line arguments: IP Startadr len [port]
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
if (args.length < 3)
|
||||||
|
{
|
||||||
|
usage();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int slaveId = 255; //1;
|
||||||
|
|
||||||
|
int offset = 1022; // Register-offset
|
||||||
|
int quantity = 5; // Anz. Bytes
|
||||||
|
String ipa = "192.168.0.199";
|
||||||
|
int port = Modbus.TCP_PORT; // default 502
|
||||||
|
|
||||||
|
// Parameterauswertung
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ipa = args[0];
|
||||||
|
offset = Integer.parseInt(args[1]);
|
||||||
|
quantity = Integer.parseInt(args[2]);
|
||||||
|
if(args.length > 3)
|
||||||
|
port = Integer.parseInt(args[3]);
|
||||||
|
|
||||||
|
|
||||||
|
TcpParameters tcpParameters = new TcpParameters();
|
||||||
|
// TcpParameters tcpParametersSlave = new TcpParameters();
|
||||||
|
|
||||||
|
//tcp parameters have already set by default as in example
|
||||||
|
// tcpParameters.setHost(InetAddress.getLocalHost());
|
||||||
|
tcpParameters.setHost(InetAddress.getByName(ipa));
|
||||||
|
tcpParameters.setKeepAlive(true);
|
||||||
|
tcpParameters.setPort(port);
|
||||||
|
// tcpParametersSlave.setPort(Modbus.TCP_PORT);
|
||||||
|
|
||||||
|
|
||||||
|
ModbusMaster modbusMaster;
|
||||||
|
/*
|
||||||
|
// if you would like to set connection parameters separately,
|
||||||
|
// you should use another method: createModbusMasterTCP(String host, int port, boolean keepAlive);
|
||||||
|
m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
|
||||||
|
Modbus.setAutoIncrementTransactionId(true);
|
||||||
|
// jaho
|
||||||
|
m.setResponseTimeout(60000);
|
||||||
|
*/
|
||||||
|
System.err.printf("try to connect to %s:%d ...", ipa, port);
|
||||||
|
// ! diese Methode kommt immer sofort zurück. Man muss Ergebnis prüfen!
|
||||||
|
modbusMaster = connect(tcpParameters, timeout_ms);
|
||||||
|
if (modbusMaster.isConnected())
|
||||||
|
System.err.printf("done\n");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modbusMaster.connect();
|
||||||
|
if (!modbusMaster.isConnected())
|
||||||
|
{
|
||||||
|
System.err.printf("FAILED\n");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// since 1.2.8
|
||||||
|
if (!modbusMaster.isConnected())
|
||||||
|
{
|
||||||
|
System.err.printf("retry connect to %s:%d ...\n", ipa, port);
|
||||||
|
modbusMaster.connect();
|
||||||
|
}
|
||||||
|
|
||||||
|
System.err.printf("connected to %s:%d, reading Holding Registers %d +%d\n", ipa, port, offset, quantity);
|
||||||
|
// Abfrage Holding-Regs
|
||||||
|
// at next string we receive x holdingRegisters from a slave with id of 1 at offset of 0.
|
||||||
|
int[] registerValues = modbusMaster.readHoldingRegisters(slaveId, offset, quantity);
|
||||||
|
|
||||||
|
// Ausgabe Adr (dezimal), Wort (dez), h-Byte (dez), L-Byte (dez), Wort(hex), h-Byte(hex), L-Byte(hex)
|
||||||
|
for (int value : registerValues)
|
||||||
|
{
|
||||||
|
System.out.printf("%04d:%05d:%03d:%03d:%04X:%02X:%02X\n", offset++, value, (value & 0xff00) / 256, value & 0xff, value, (value & 0xff00) / 256, value & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Dieser Teil schein nicht zu gehen
|
||||||
|
/*
|
||||||
|
// also since 1.2.8.4 you can create your own request and process it with the master
|
||||||
|
offset = 0;
|
||||||
|
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest();
|
||||||
|
request.setServerAddress(1);
|
||||||
|
request.setStartAddress(offset);
|
||||||
|
request.setTransactionId(0);
|
||||||
|
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) m.processRequest(request);
|
||||||
|
// you can get either int[] containing register values or byte[] containing raw bytes.
|
||||||
|
System.out.println("-----------------------");
|
||||||
|
for (int value : response.getRegisters())
|
||||||
|
{
|
||||||
|
System.out.println("Address: " + offset++ + ", Value: " + value);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
sleep(600);
|
||||||
|
int register = 1000;
|
||||||
|
int val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d: %d (0x%04x)\n", register, val, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
register = 1004;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d: %d (0x%04x)\n", register, val, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
register = 1014;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (S/N): %d (0x%04x)\n", register, val, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
register = 1008;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (current 1 [A]): %1.1f (0x%04x)\n", register, val/1000f, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
register = 1020;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (active Power): %1.1f kW (0x%04x)\n", register, val/1e6, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
register = 1500;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (RFID-Card): %d (0x%04x)\n", register, val, val);
|
||||||
|
|
||||||
|
sleep(600);
|
||||||
|
// angeblich Wh, aber in Wirklichkeit Wh/10
|
||||||
|
register = 1502;
|
||||||
|
val = readInt32BigEndian(modbusMaster, slaveId, register);
|
||||||
|
System.out.printf("Wert für reg %d (charged energy [kWh]): %1.1f (0x%04x)\n", register, val/10000f, val);
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
} catch (ModbusProtocolException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ModbusNumberException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (ModbusIOException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
catch (NumberFormatException e)
|
||||||
|
{
|
||||||
|
System.err.println("Parameter ist keine Zahl: " + e.getMessage());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
modbusMaster.disconnect();
|
||||||
|
} catch (ModbusIOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e)
|
||||||
|
{
|
||||||
|
throw e;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(0);
|
||||||
|
} // main
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static void usage()
|
||||||
|
{
|
||||||
|
System.err.println("Reading MODBUS-Register from IPAdr\n\nusage:\nSwgModbus <IPAdr> <AdrOffset> <count> [port]\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4 Bytes lesen. Das geht hier nur mit dem Abruf von 2 16-Bit-Registern
|
||||||
|
* @param slaveId
|
||||||
|
* @param register Startregister
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
static int readInt32BigEndian(ModbusMaster modbusMaster, int slaveId, int register) throws ModbusProtocolException, ModbusNumberException, ModbusIOException
|
||||||
|
{
|
||||||
|
int[] registerValues = modbusMaster.readHoldingRegisters(slaveId, register, 2);
|
||||||
|
return registerValues[0] << 16 | registerValues[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void sleep(int dur_ms)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(dur_ms);
|
||||||
|
}
|
||||||
|
catch (InterruptedException ex)
|
||||||
|
{
|
||||||
|
System.getLogger(KebaModbus.class.getName()).log(System.Logger.Level.ERROR, (String) null, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lesen und in Map speichern
|
||||||
|
* @param status
|
||||||
|
* @param register
|
||||||
|
* @param slaveId
|
||||||
|
* @throws ModbusProtocolException
|
||||||
|
* @throws ModbusNumberException
|
||||||
|
* @throws ModbusIOException
|
||||||
|
*/
|
||||||
|
int read(String name, int register, int slaveId) throws ModbusProtocolException, ModbusNumberException, ModbusIOException
|
||||||
|
{
|
||||||
|
var val = readInt32BigEndian(getModbusMaster(), slaveId, register);
|
||||||
|
valueMap.put(name, val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,229 @@
|
|||||||
|
/*
|
||||||
|
*/
|
||||||
|
package kebaagent;
|
||||||
|
|
||||||
|
import com.sun.net.httpserver.Headers;
|
||||||
|
import com.sun.net.httpserver.HttpExchange;
|
||||||
|
import com.sun.net.httpserver.HttpHandler;
|
||||||
|
import com.sun.net.httpserver.HttpHandlers;
|
||||||
|
import com.sun.net.httpserver.HttpServer;
|
||||||
|
import com.sun.net.httpserver.Request;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author holz
|
||||||
|
*/
|
||||||
|
public class Webserver
|
||||||
|
{
|
||||||
|
|
||||||
|
private final int port;
|
||||||
|
|
||||||
|
private KebaAgent agent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call start()
|
||||||
|
* @see #start()
|
||||||
|
* @param port
|
||||||
|
*/
|
||||||
|
public Webserver(int port)
|
||||||
|
{
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Webserver
|
||||||
|
* @param agent
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void start(KebaAgent agent) throws IOException
|
||||||
|
{
|
||||||
|
this.agent = agent;
|
||||||
|
|
||||||
|
// Create an HttpServer instance on port
|
||||||
|
HttpServer server = HttpServer.create(new InetSocketAddress(port), 0);
|
||||||
|
|
||||||
|
String defaultUri = "/keba";
|
||||||
|
Optional<String> pv = agent.getPropValue("webserver", "defaultUri");
|
||||||
|
if (pv.isPresent())
|
||||||
|
defaultUri = pv.get();
|
||||||
|
|
||||||
|
// Define a context that serves files from the current directory
|
||||||
|
// server.createContext("/", new com.sun.net.httpserver.HttpHandler()
|
||||||
|
// {
|
||||||
|
// @Override
|
||||||
|
// public void handle(com.sun.net.httpserver.HttpExchange exchange) throws IOException
|
||||||
|
// {
|
||||||
|
// // Handle requests here (simple file serving)
|
||||||
|
// System.out.println("recvd: " + exchange);
|
||||||
|
//// TODO: müsste jetzt die Response generieren. Wie genau, noch nicht nachvollzogen
|
||||||
|
//// ein komplexeres Bsp unter https://dzone.com/articles/simple-http-server-in-java
|
||||||
|
//// Daraus stammt die Klasse MyHttpHandler unten
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
// andere Variante für Handler am Bsp url http://localhost:8000/t/allowed oder http://localhost:8000/t<irgendwas anderes>
|
||||||
|
// Headers headers = new Headers();
|
||||||
|
// headers.set("Allow", "GET");
|
||||||
|
// headers.set("Content-Type", "text/plain");
|
||||||
|
//
|
||||||
|
// HttpHandler allowedResponse = HttpHandlers.of(200, headers, getBody()); // Statuscode, Headers, body
|
||||||
|
|
||||||
|
// Trivialhandler für einfache Antwort
|
||||||
|
HttpHandler deniedResponse = HttpHandlers.of(401, Headers.of("Deny", "GET"), "Denied");
|
||||||
|
|
||||||
|
JsonHandler allowedResponse = new JsonHandler(agent);
|
||||||
|
|
||||||
|
|
||||||
|
// welche URL ist erlaubt?
|
||||||
|
final String fDefUri = defaultUri;
|
||||||
|
Predicate<Request> findAllowedPath = r ->
|
||||||
|
// r.getRequestURI().getPath().equals("/t/allowed");
|
||||||
|
r.getRequestURI().getPath().equals(fDefUri);
|
||||||
|
|
||||||
|
HttpHandler handler = HttpHandlers.handleOrElse(findAllowedPath, allowedResponse, deniedResponse);
|
||||||
|
// context ist weiter oben angebunden (ab /t)
|
||||||
|
// server.createContext("/t", handler);
|
||||||
|
server.createContext(defaultUri, handler);
|
||||||
|
|
||||||
|
// ggf. 2. Handler für / bauen (Infoseite)
|
||||||
|
|
||||||
|
|
||||||
|
// mit MyHttpHandler, ziemlich buggy und unvollständig von https://dzone.com/articles/simple-http-server-in-java
|
||||||
|
// MyHttpHandler myHandler = new MyHttpHandler(agent);
|
||||||
|
// server.createContext("/m", myHandler);
|
||||||
|
|
||||||
|
|
||||||
|
// Start the server
|
||||||
|
server.start();
|
||||||
|
System.out.printf("Server started on port %d\n", port);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// private String getBody()
|
||||||
|
// {
|
||||||
|
// return "{ 'info': 'hello'}";
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static class MyHttpHandler implements HttpHandler
|
||||||
|
{
|
||||||
|
|
||||||
|
private KebaAgent agent;
|
||||||
|
|
||||||
|
private MyHttpHandler(KebaAgent a)
|
||||||
|
{
|
||||||
|
agent = a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zu implementierende Methode
|
||||||
|
* @param httpExchange
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void handle(HttpExchange httpExchange) throws IOException
|
||||||
|
{
|
||||||
|
String requestParamValue = null;
|
||||||
|
System.out.println("MyHttpHandler.handle() httpExchange " + httpExchange);
|
||||||
|
String requestMethod = httpExchange.getRequestMethod();
|
||||||
|
System.out.println("MyHttpHandler.handle().getRequestMethod(): " + requestMethod);
|
||||||
|
if ("GET".equals(httpExchange.getRequestMethod()))
|
||||||
|
{
|
||||||
|
requestParamValue = handleGetRequest(httpExchange);
|
||||||
|
System.out.println("MyHttpHandler.handle() GET: requestParamValue = " + requestParamValue);
|
||||||
|
}
|
||||||
|
// TODO: nicht im Bsp.
|
||||||
|
// else if("POST".equals(httpExchange))
|
||||||
|
// {
|
||||||
|
// requestParamValue = handlePostRequest(httpExchange);
|
||||||
|
// }
|
||||||
|
handleResponse(httpExchange, requestParamValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hier hat der Autor Schwachsinn produziert
|
||||||
|
* @param httpExchange
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String handleGetRequest(HttpExchange httpExchange)
|
||||||
|
{
|
||||||
|
String path = httpExchange.getRequestURI().toString();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// return path.split("\\?")[1]
|
||||||
|
return path.split("/")[1]
|
||||||
|
// .split("=")[1];
|
||||||
|
;
|
||||||
|
} catch (Exception e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
return e.getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void handleResponse(HttpExchange httpExchange, String requestParamValue) throws IOException
|
||||||
|
{
|
||||||
|
System.out.println("MyHttpHandler.handleResponse ");
|
||||||
|
OutputStream outputStream = httpExchange.getResponseBody();
|
||||||
|
StringBuilder htmlBuilder = new StringBuilder();
|
||||||
|
htmlBuilder
|
||||||
|
.append("<html>")
|
||||||
|
.append("<body>")
|
||||||
|
.append("<h1>")
|
||||||
|
.append("Hello ")
|
||||||
|
.append(requestParamValue)
|
||||||
|
.append("</h1>")
|
||||||
|
.append("</body>")
|
||||||
|
.append("</html>");
|
||||||
|
// encode HTML content
|
||||||
|
// apache commons text + lang
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Schwachsinn: Anwendung auf den ganzen HTML-Code
|
||||||
|
// String htmlResponse = StringEscapeUtils.escapeHtml4(htmlBuilder.toString());
|
||||||
|
// So OK
|
||||||
|
String htmlResponse = htmlBuilder.toString();
|
||||||
|
|
||||||
|
// jaho: Header erweitern
|
||||||
|
Headers responseHeaders = httpExchange.getResponseHeaders();
|
||||||
|
responseHeaders.set("Content-Type", "text/plain");
|
||||||
|
|
||||||
|
|
||||||
|
// this line is a must (jaho: header senden)
|
||||||
|
httpExchange.sendResponseHeaders(200, htmlResponse.length());
|
||||||
|
|
||||||
|
|
||||||
|
outputStream.write(htmlResponse.getBytes());
|
||||||
|
outputStream.flush();
|
||||||
|
outputStream.close();
|
||||||
|
|
||||||
|
} catch (Throwable e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} // MyHttpHandler
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user