Skip to content

Commit

Permalink
Initial project commit
Browse files Browse the repository at this point in the history
  • Loading branch information
benjiro committed May 30, 2020
1 parent 7eec2b5 commit 1eff262
Show file tree
Hide file tree
Showing 23 changed files with 783 additions and 1 deletion.
45 changes: 45 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Folders
artifacts/
bin/
obj/
.dotnet/
.nuget/
.packages/
.tools/
.vs/
.vscode/
node_modules/
BenchmarkDotNet.Artifacts/
.gradle/
src/SignalR/clients/**/dist/
modules/
.ionide/

# File extensions
*.aps
*.binlog
*.dll
*.DS_Store
*.exe
*.idb
*.lib
*.log
*.pch
*.pdb
*.pidb
*.psess
*.res
*.snk
*.so
*.suo
*.tlog
*.user
*.userprefs
*.vspx

# Specific files, typically generated by tools
launchSettings.json
msbuild.ProjectImports.zip
StyleCop.Cache
UpgradeLog.htm
.idea
20 changes: 20 additions & 0 deletions GatewayClient.UnitTests/GatewayClient.UnitTests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
<PackageReference Include="RichardSzalay.MockHttp" Version="6.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\GatewayClient\GatewayClient.csproj" />
</ItemGroup>

</Project>
41 changes: 41 additions & 0 deletions GatewayClient.UnitTests/GridStatusSpec.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
namespace GatewayClient.UnitTests
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Models;
using NUnit.Framework;
using RichardSzalay.MockHttp;

public class GridStatusSpec
{
public static IEnumerable<TestCaseData> GridStatusCalls
{
get
{
yield return new TestCaseData(@"{""grid_status"":""SystemGridConnected"",""grid_services_active"":false}", new GridStatus {GridServicesActive = false, GridStatusGridStatus = "SystemGridConnected"});
yield return new TestCaseData(@"{""grid_status"":""SystemGridDisconnected"",""grid_services_active"":false}", new GridStatus {GridServicesActive = false, GridStatusGridStatus = "SystemGridDisconnected"});
yield return new TestCaseData(@"{""grid_status"":""SystemGridConnected"",""grid_services_active"":true}", new GridStatus {GridServicesActive = true, GridStatusGridStatus = "SystemGridConnected"});
}
}

[TestCaseSource("GridStatusCalls")]
public async Task GridStatusCall(string payload, GridStatus expected)
{
var mockHttp = new MockHttpMessageHandler();

mockHttp
.When("http://localhost/api/system_status/grid_status")
.Respond("application/json", payload);

var mockClient = mockHttp.ToHttpClient();
mockClient.BaseAddress = new Uri("http://localhost");

var gatewayClient = new GatewayClient(mockClient);
var gridStatus = await gatewayClient.GetGridStatus();

Assert.AreEqual(expected.GridServicesActive, gridStatus.GridServicesActive);
Assert.AreEqual(expected.GridStatusGridStatus, gridStatus.GridStatusGridStatus);
}
}
}
22 changes: 22 additions & 0 deletions GatewayClient.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatewayClient", "GatewayClient\GatewayClient.csproj", "{8388ABCC-0E9D-45A4-861E-06E32EA287F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GatewayClient.UnitTests", "GatewayClient.UnitTests\GatewayClient.UnitTests.csproj", "{85A11255-A1C1-4014-B9C8-73F58C3062DE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8388ABCC-0E9D-45A4-861E-06E32EA287F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8388ABCC-0E9D-45A4-861E-06E32EA287F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8388ABCC-0E9D-45A4-861E-06E32EA287F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8388ABCC-0E9D-45A4-861E-06E32EA287F9}.Release|Any CPU.Build.0 = Release|Any CPU
{85A11255-A1C1-4014-B9C8-73F58C3062DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85A11255-A1C1-4014-B9C8-73F58C3062DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85A11255-A1C1-4014-B9C8-73F58C3062DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85A11255-A1C1-4014-B9C8-73F58C3062DE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
100 changes: 100 additions & 0 deletions GatewayClient/GatewayClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
namespace GatewayClient
{
using System;
using System.IO;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Models;

public class GatewayClient
{
private HttpClient Client { get; }
private JsonSerializerOptions JsonOptions {get;}

/// <summary>
/// Constructs a new GatewayClient that allows reading data from a Tesla Gateway 1/2.
/// Note: HttpClient.BaseAddress must be set
/// </summary>
/// <param name="client">HttpClient</param>
/// <param name="convertDateTimeToUTC">Whether to convert read date time values from gateway api to UTC</param>
public GatewayClient(HttpClient client, bool convertDateTimeToUTC = true)
{
Client = client ?? throw new ArgumentNullException(nameof(client), "Must be valid HttpClient instance");

JsonOptions = convertDateTimeToUTC
? new JsonSerializerOptions {Converters = {new JsonDateTimeConverter()}}
: new JsonSerializerOptions();
}

private async Task<Stream> GetResponseContentStream(HttpMethod verb, string requestUri)
{
// Call given request uri and return stream of data
var request = new HttpRequestMessage(verb, requestUri);
var response = await Client.SendAsync(request);
response.EnsureSuccessStatusCode();

return await response.Content.ReadAsStreamAsync();
}

public async Task<Aggregate> GetAggregates()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/meters/aggregates");
return await JsonSerializer.DeserializeAsync<Aggregate>(contentStream, JsonOptions);
}

public async Task<SiteSpecificMeterInformation> GetSiteSpecificMeterInformation()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/meters/site");
return await JsonSerializer.DeserializeAsync<SiteSpecificMeterInformation>(contentStream, JsonOptions);
}

public async Task<SolarInformation> GetSolarInformation()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/meters/solar");
return await JsonSerializer.DeserializeAsync<SolarInformation>(contentStream, JsonOptions);
}

public async Task<SystemStatus> GetSystemStatusState()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/system_status/soe");
return await JsonSerializer.DeserializeAsync<SystemStatus>(contentStream, JsonOptions);
}

public async Task<SiteMaster> GetSiteMaster()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/sitemaster");
return await JsonSerializer.DeserializeAsync<SiteMaster>(contentStream, JsonOptions);
}

public async Task<PowerwallInformation> GetPowerwallInformation()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/powerwalls");
return await JsonSerializer.DeserializeAsync<PowerwallInformation>(contentStream, JsonOptions);
}

public async Task<RegistrationInformation> GetRegistrationInformation()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/customer/registration");
return await JsonSerializer.DeserializeAsync<RegistrationInformation>(contentStream, JsonOptions);
}

public async Task<GridStatus> GetGridStatus()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/system_status/grid_status");
return await JsonSerializer.DeserializeAsync<GridStatus>(contentStream, JsonOptions);
}

public async Task<SiteInformation> GetSiteInformation()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/site_info");
return await JsonSerializer.DeserializeAsync<SiteInformation>(contentStream, JsonOptions);
}

public async Task<SiteName> GetSiteName()
{
var contentStream = await GetResponseContentStream(HttpMethod.Get, "/api/site_info/site_name");
return await JsonSerializer.DeserializeAsync<SiteName>(contentStream, JsonOptions);
}
}
}
20 changes: 20 additions & 0 deletions GatewayClient/GatewayClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Title>GatewayClient</Title>
<Authors>Benjamin Evenson</Authors>
<Description>A simple httpclient implementation of the Tesla Gateway 2 api</Description>
<PackageProjectUrl>https://github.com/benjiro/GatewayClient</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/benjiro/GatewayClient/blob/master/LICENSE</PackageLicenseUrl>
<RepositoryUrl>https://github.com/benjiro/GatewayClient</RepositoryUrl>
<Nullable>disable</Nullable>
<Version>1.0.0</Version>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="System.Text.Json" Version="4.7.2" />
</ItemGroup>

</Project>
20 changes: 20 additions & 0 deletions GatewayClient/JsonDateTimeConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
namespace GatewayClient
{
using System;
using System.Diagnostics;
using System.Text.Json;
using System.Text.Json.Serialization;

public class JsonDateTimeConverter : JsonConverter<DateTime>
{
public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
return DateTime.Parse(reader.GetString()).ToUniversalTime();
}

public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
{
writer.WriteStringValue(value.ToUniversalTime());
}
}
}
28 changes: 28 additions & 0 deletions GatewayClient/Models/Aggregate.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace GatewayClient.Models
{
using System.Text.Json.Serialization;

public class Aggregate
{
[JsonPropertyName("site")]
public Site Site { get; set; }

[JsonPropertyName("battery")]
public Battery Battery { get; set; }

[JsonPropertyName("load")]
public Load Load { get; set; }

[JsonPropertyName("solar")]
public Solar Solar { get; set; }

[JsonPropertyName("busway")]
public AggregateBase Busway { get; set; }

[JsonPropertyName("frequency")]
public AggregateBase Frequency { get; set; }

[JsonPropertyName("generator")]
public AggregateBase Generator { get; set; }
}
}
10 changes: 10 additions & 0 deletions GatewayClient/Models/Battery.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace GatewayClient.Models
{
using System.Text.Json.Serialization;

public class Battery : AggregateBase
{
[JsonPropertyName("percentage")]
public double Percentage { get; set; }
}
}
Loading

0 comments on commit 1eff262

Please sign in to comment.