From a45a14febc69165d452d1d6b81e115d301bcdeec Mon Sep 17 00:00:00 2001 From: Tobias Peper Date: Sat, 6 Jul 2024 00:23:33 +0200 Subject: [PATCH] =?UTF-8?q?=C3=84nderungen=20eingepflegt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../metertoinflux/MeterReadException.java | 23 +++++ .../info/peper/metertoinflux/MeterReader.java | 7 ++ .../metertoinflux/Shelly3EmCloudReader.java | 86 +++++++++++++++++++ .../ShellyPlus1PmLocalReader.java | 48 +++++++++++ .../metertoinflux/TestMeterReaderMain.java | 15 ++++ 5 files changed, 179 insertions(+) create mode 100644 src/main/java/info/peper/metertoinflux/MeterReadException.java create mode 100644 src/main/java/info/peper/metertoinflux/MeterReader.java create mode 100644 src/main/java/info/peper/metertoinflux/Shelly3EmCloudReader.java create mode 100644 src/main/java/info/peper/metertoinflux/ShellyPlus1PmLocalReader.java create mode 100644 src/main/java/info/peper/metertoinflux/TestMeterReaderMain.java diff --git a/src/main/java/info/peper/metertoinflux/MeterReadException.java b/src/main/java/info/peper/metertoinflux/MeterReadException.java new file mode 100644 index 0000000..adf2d8d --- /dev/null +++ b/src/main/java/info/peper/metertoinflux/MeterReadException.java @@ -0,0 +1,23 @@ +package info.peper.metertoinflux; + +public class MeterReadException extends Exception { + + private static final long serialVersionUID = -1413981604296334092L; + + public MeterReadException() { + super(); + } + + public MeterReadException(String message, Throwable cause) { + super(message, cause); + } + + public MeterReadException(String message) { + super(message); + } + + public MeterReadException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/info/peper/metertoinflux/MeterReader.java b/src/main/java/info/peper/metertoinflux/MeterReader.java new file mode 100644 index 0000000..a612eac --- /dev/null +++ b/src/main/java/info/peper/metertoinflux/MeterReader.java @@ -0,0 +1,7 @@ +package info.peper.metertoinflux; + +import java.util.Properties; + +public interface MeterReader { + double getCurrentValue() throws MeterReadException; +} diff --git a/src/main/java/info/peper/metertoinflux/Shelly3EmCloudReader.java b/src/main/java/info/peper/metertoinflux/Shelly3EmCloudReader.java new file mode 100644 index 0000000..8d22580 --- /dev/null +++ b/src/main/java/info/peper/metertoinflux/Shelly3EmCloudReader.java @@ -0,0 +1,86 @@ +package info.peper.metertoinflux; + +import java.io.IOException; +import java.io.Reader; +import java.util.Properties; + +import com.google.gson.Gson; +import com.google.gson.stream.JsonReader; + +import okhttp3.FormBody; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.RequestBody; +import okhttp3.Response; + +public class Shelly3EmCloudReader implements MeterReader { + + private final String authKey; + private final String id; + private final String cloudServerHostname; + private final OkHttpClient httpClient; + + public Shelly3EmCloudReader(final Properties config) { + this.authKey = config.getProperty("authKey"); + this.id = config.getProperty("id"); + this.cloudServerHostname = config.getProperty("cloudServerHostname"); + this.httpClient = new OkHttpClient(); + } + + @Override + public double getCurrentValue() throws MeterReadException { + try { + final RequestBody requestBody = new FormBody.Builder() + .add("auth_key", this.authKey) + .add("id", this.id) + .build(); + final Request request = new Request.Builder().url("https://" + this.cloudServerHostname + "/device/status") + .post(requestBody) + .build(); + final Response response = httpClient.newCall(request).execute(); + if (response.isSuccessful()) { + double sum = 0.0; + final Reader bodyReader = response.body().charStream(); + final Gson gson = new Gson(); + final JsonReader jsonReader = gson.newJsonReader(bodyReader); + jsonReader.beginObject(); + int level = 0; + int phase = 0; + while (jsonReader.hasNext()) { + final String name = jsonReader.nextName(); + if ("data".equals(name) && level == 0) { + jsonReader.beginObject(); + level++; + } else if ("device_status".equals(name) && level == 1) { + jsonReader.beginObject(); + level++; + } else if ("emeters".equals(name) && level == 2) { + jsonReader.beginArray(); + jsonReader.beginObject(); + phase = 1; + level++; + } else if ("power".equals(name) && level == 3) { + sum += jsonReader.nextDouble(); + while (jsonReader.hasNext()) { + jsonReader.nextName(); + jsonReader.skipValue(); + } + jsonReader.endObject(); + if (jsonReader.hasNext()) { + phase++; + jsonReader.beginObject(); + } + } else { + jsonReader.skipValue(); + } + } + if (phase > 0) { + return sum; + } + } + } catch (IOException e) { + throw new MeterReadException("Could not get value from meter.", e); + } + throw new MeterReadException("Could not get value from meter."); + } +} diff --git a/src/main/java/info/peper/metertoinflux/ShellyPlus1PmLocalReader.java b/src/main/java/info/peper/metertoinflux/ShellyPlus1PmLocalReader.java new file mode 100644 index 0000000..90ad8f0 --- /dev/null +++ b/src/main/java/info/peper/metertoinflux/ShellyPlus1PmLocalReader.java @@ -0,0 +1,48 @@ +package info.peper.metertoinflux; + +import java.io.IOException; +import java.io.Reader; +import java.util.Properties; + +import com.google.gson.Gson; +import com.google.gson.stream.JsonReader; + +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +public class ShellyPlus1PmLocalReader implements MeterReader { + + private final String hostname; + private final OkHttpClient httpClient; + + public ShellyPlus1PmLocalReader(final Properties config) { + this.hostname = config.getProperty("hostname"); + this.httpClient = new OkHttpClient(); + } + + @Override + public double getCurrentValue() throws MeterReadException { + try { + final Request request = new Request.Builder().url("http://" + hostname + "/rpc/Switch.GetStatus?id=0").build(); + final Response response = httpClient.newCall(request).execute(); + if (response.isSuccessful()) { + final Reader bodyReader = response.body().charStream(); + final Gson gson = new Gson(); + final JsonReader jsonReader = gson.newJsonReader(bodyReader); + jsonReader.beginObject(); + while (jsonReader.hasNext()) { + final String name = jsonReader.nextName(); + if ("apower".equals(name)) { + return jsonReader.nextDouble(); + } else { + jsonReader.skipValue(); + } + } + } + } catch (IOException e) { + throw new MeterReadException("Could not get value from meter.", e); + } + throw new MeterReadException("Could not get value from meter."); + } +} diff --git a/src/main/java/info/peper/metertoinflux/TestMeterReaderMain.java b/src/main/java/info/peper/metertoinflux/TestMeterReaderMain.java new file mode 100644 index 0000000..b11a57c --- /dev/null +++ b/src/main/java/info/peper/metertoinflux/TestMeterReaderMain.java @@ -0,0 +1,15 @@ +package info.peper.metertoinflux; + +import java.util.Properties; + +public class TestMeterReaderMain { + + public static void main(String[] args) throws Exception { + final Properties propsLocal = new Properties(); + propsLocal.setProperty("hostname", "photovoltaik"); + final MeterReader readerLocal = new ShellyPlus1PmLocalReader(propsLocal); + System.out.println(readerLocal.getCurrentValue()); + + } + +}