Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

new wallbox: Open WB 2 #1464

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions TeslaLogger/ElectricityMeterBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public static ElectricityMeterBase Instance(string type, string host, string par
{
if (type == "openwb")
return new ElectricityMeterOpenWB(host, paramater);
else if (type == "openwb2")
return new ElectricityMeterOpenWB2(host, paramater);
else if (type == "cfos")
return new ElectricityMeterCFos(host, paramater);
else if (type == "go-e")
Expand Down
340 changes: 340 additions & 0 deletions TeslaLogger/ElectricityMeterOpenWB2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,340 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Runtime.Caching;
using Exceptionless;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace TeslaLogger
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Keine allgemeinen Ausnahmetypen abfangen", Justification = "<Pending>")]
class ElectricityMeterOpenWB2 : ElectricityMeterBase
{
string host;
string parameter;
string chargepointid;
string gridmeterid;
internal string api_state;

internal string mockup_version;
internal string mockup_charge_state;
internal string mockup_charge_point;
internal string mockup_grid;
internal string mockup_hierarchy;

Guid guid; // defaults to new Guid();
static WebClient client;

public ElectricityMeterOpenWB2(string host, string parameter)
{
if (client == null)
{
client = new WebClient();
}

this.host = host;
this.parameter = parameter;


/*
Example parameters:
"": grid id will be assumed from hierarchy, first charge point id will be taken from hierarchy
"CP:26": chargepoind id = 26, grid id will be assumed from hierarchy
"G:7|CP:27": Grid meter with id = 7 and chargepoind id = 26
*/

var args = parameter.Split('|');
foreach (var p in args)
{
if (p.StartsWith("CP", StringComparison.InvariantCultureIgnoreCase))
{
string[] parts = p.Split(':');
if (!string.IsNullOrEmpty(parts[1]))
chargepointid = parts[1];
}
if (p.StartsWith("G", StringComparison.InvariantCultureIgnoreCase))
{
string[] parts = p.Split(':');
if (!string.IsNullOrEmpty(parts[1]))
gridmeterid = parts[1];
}
}
}

string GetCurrentData(string topic)
{
try
{
string cacheKey = "owb2_" + topic + guid.ToString();
object o = MemoryCache.Default.Get(cacheKey);

if (o != null)
return (string)o;

string url = host + "/v1/?topic=" + topic;
string lastJSON = client.DownloadString(url);

MemoryCache.Default.Add(cacheKey, lastJSON, DateTime.Now.AddSeconds(10));
return lastJSON;
}
catch (Exception ex)
{
if (ex is WebException wx)
{
if ((wx.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
{
Logfile.Log(wx.Message);
return "";
}

}
if (!WebHelper.FilterNetworkoutage(ex))
ex.ToExceptionless().FirstCarUserID().Submit();

Logfile.Log(ex.ToString());
}

return "";
}

public override double? GetUtilityMeterReading_kWh()
{
string h = null;
string j = null;
try
{
if (string.IsNullOrEmpty(gridmeterid))
{
//get grid meter id via hierarchy:
if (mockup_hierarchy != null)
{
h = mockup_hierarchy;
}
else
{
h = GetCurrentData("openWB/counter/get/hierarchy");
}

JArray jsonArray = JArray.Parse(h);
JToken firstCounter = jsonArray
.FirstOrDefault(item => (string)item["type"] == "counter");

if (string.IsNullOrEmpty(firstCounter["id"].ToString()))
return null;

gridmeterid = firstCounter["id"].ToString();
}

if (mockup_grid != null)
{
j = mockup_grid;
}
else
{
j = GetCurrentData("openWB/counter/" + gridmeterid + "/get/imported");
}

dynamic jsonResult = JsonConvert.DeserializeObject(j);
if (jsonResult == null)
return null;

if (!Tools.IsPropertyExist(jsonResult, "status"))
return null;

Dictionary<string, object> r1 = jsonResult.ToObject<Dictionary<string, object>>();

r1.TryGetValue("status", out object status);
if (status.ToString() != "success")
return null;

if (r1.ContainsKey("message"))
{
double.TryParse(r1["message"].ToString(), out double value);
return value;
}
else
{
return double.NaN;
}


}
catch (Exception ex)
{
ex.ToExceptionless().FirstCarUserID().Submit();
Logfile.ExceptionWriter(ex, j);
}

return null;
}

public override double? GetVehicleMeterReading_kWh()
{
string h = null;
string j = null;
try
{
if (string.IsNullOrEmpty(chargepointid))
{
//no charge point id provided, get first charge point id via hierarchy:
if (mockup_hierarchy != null)
{
h = mockup_hierarchy;
}
else
{
h = GetCurrentData("openWB/counter/get/hierarchy");
}

JArray jsonArray = JArray.Parse(h);
JObject firstItem = (JObject)jsonArray[0];
JArray childrenArray = (JArray)firstItem["children"];
JToken cpEntry = childrenArray
.Where(child => (string)child["type"] == "counter" && child["children"] != null)
.SelectMany(child => child["children"])
.Where(grandchild => (string)grandchild["type"] == "cp")
.FirstOrDefault();

if (cpEntry == null)
{
return null;
}

chargepointid = cpEntry["id"].ToString();
}

if (mockup_charge_point != null)
{
j = mockup_charge_point;
}
else
{
j = GetCurrentData("openWB/chargepoint/" + chargepointid + "/get/imported");
}

dynamic jsonResult = JsonConvert.DeserializeObject(j);
if (jsonResult == null)
return null;

if (!Tools.IsPropertyExist(jsonResult, "status"))
return null;

Dictionary<string, object> r1 = jsonResult.ToObject<Dictionary<string, object>>();

r1.TryGetValue("status", out object status);
if (status.ToString() != "success")
return null;

if (r1.ContainsKey("message"))
{
double.TryParse(r1["message"].ToString(), out double value);
return value;
}
else
{
return double.NaN;
}

}
catch (Exception ex)
{
ex.ToExceptionless().FirstCarUserID().Submit();
Logfile.ExceptionWriter(ex, j);
}

return null;
}

public override bool? IsCharging()
{
string j = null;
try
{
if (mockup_charge_state != null)
{
j = mockup_charge_state;
}
else
{
j = GetCurrentData("openWB/chargepoint/" + chargepointid + "/get/charge_state");
}

dynamic jsonResult = JsonConvert.DeserializeObject(j);
if (jsonResult == null)
return null;

if (!Tools.IsPropertyExist(jsonResult, "status"))
return null;

Dictionary<string, object> r1 = jsonResult.ToObject<Dictionary<string, object>>();

r1.TryGetValue("status", out object status);
if (status.ToString() != "success")
return null;

r1.TryGetValue("message", out object version);
if (version.ToString() == "true")
{
return true;
}
else
{
return false;
}

}
catch (Exception ex)
{
ex.ToExceptionless().FirstCarUserID().Submit();
Logfile.ExceptionWriter(ex, j);
}

return null;
}

public override string GetVersion()
{
string j = null;
try
{
if (mockup_version != null)
{
j = mockup_version;
}
else
{
j = GetCurrentData("openWB/system/version");
}

dynamic jsonResult = JsonConvert.DeserializeObject(j);
if (jsonResult == null)
return null;

if (!Tools.IsPropertyExist(jsonResult, "status"))
return null;

Dictionary<string, object> r1 = jsonResult.ToObject<Dictionary<string, object>>();

r1.TryGetValue("status", out object status);
if (status.ToString() != "success")
return null;

r1.TryGetValue("message", out object version);
return version.ToString();
}
catch (Exception ex)
{
if (!WebHelper.FilterNetworkoutage(ex))
ex.ToExceptionless().FirstCarUserID().Submit();

Logfile.ExceptionWriter(ex, j);
}

return "";
}

}

}
1 change: 1 addition & 0 deletions TeslaLogger/TeslaLogger.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@
<Compile Include="CaptchaSolver.cs" />
<Compile Include="CaptchaSolverKey.cs" />
<Compile Include="Car.cs" />
<Compile Include="ElectricityMeterOpenWB2.cs" />
<Compile Include="ElectricityMeterSmartEVSE3.cs" />
<Compile Include="ElectricityMeterWARP.cs" />
<Compile Include="MQTTAutoDiscovery.cs" />
Expand Down
1 change: 1 addition & 0 deletions TeslaLogger/www/admin/wallbox.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ function btn_save_click()
<option value="cfos">cFos</option>
<option value="go-e">Go e-Charger</option>
<option value="openwb">Open WB</option>
<option value="openwb2">Open WB 2</option>
<option value="shelly3em">Shelly 3EM</option>
<option value="shellyem">Shelly EM</option>
<option value="smartevse3">SmartEVSE 3</option>
Expand Down
24 changes: 24 additions & 0 deletions UnitTestsTeslalogger/UnitTestWallbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,30 @@ public void OpenWBMeterConstructor()
Console.WriteLine(ret);
}

[TestMethod]
public void OpenWB2()
{
var v = new ElectricityMeterOpenWB2("", "");

v.mockup_version = System.IO.File.ReadAllText(@"..\..\testdata\openwb2_version.txt");
v.mockup_charge_state = System.IO.File.ReadAllText(@"..\..\testdata\openwb2_charge_state.txt");
v.mockup_charge_point = System.IO.File.ReadAllText(@"..\..\testdata\openwb2_cp.txt");
v.mockup_grid = System.IO.File.ReadAllText(@"..\..\testdata\openwb2_grid.txt");
v.mockup_hierarchy = System.IO.File.ReadAllText(@"..\..\testdata\openwb2_hierarchy.txt");

double? kwh = v.GetVehicleMeterReading_kWh();
var charging = v.IsCharging();
var utility_meter_kwh = v.GetUtilityMeterReading_kWh();
var version = v.GetVersion();
string ret = v.ToString();
Console.WriteLine(ret);
Assert.AreEqual(441759, kwh);
Assert.AreEqual(false, charging);
Assert.AreEqual(123456789, utility_meter_kwh);
Assert.AreEqual("2.1.7-Beta.2", version);
}


[TestMethod]
public void GoEMeter()
{
Expand Down
Loading
Loading