Compare commits

..

No commits in common. "978b384759dfdea1d93898c06239be3324823a3a" and "c14279fbbef5354715e115b0638fff128cb2ca3f" have entirely different histories.

6 changed files with 96 additions and 83 deletions

View File

@ -7,7 +7,7 @@
<Authors>Glax</Authors> <Authors>Glax</Authors>
<RepositoryUrl>https://github.com/C9Glax/CShocker</RepositoryUrl> <RepositoryUrl>https://github.com/C9Glax/CShocker</RepositoryUrl>
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<Version>2.3.0</Version> <Version>2.2.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -1,5 +1,8 @@
using CShocker.Devices.Abstract; using System.Net.Http.Headers;
using System.Text;
using CShocker.Devices.Abstract;
using CShocker.Devices.Additional; using CShocker.Devices.Additional;
using CShocker.Ranges;
using CShocker.Shockers; using CShocker.Shockers;
using CShocker.Shockers.Abstract; using CShocker.Shockers.Abstract;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -8,6 +11,8 @@ namespace CShocker.Devices.APIs;
public class OpenShockHttp : OpenShockApi public class OpenShockHttp : OpenShockApi
{ {
protected override void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration) protected override void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration)
{ {
if (shocker is not OpenShockShocker openShockShocker) if (shocker is not OpenShockShocker openShockShocker)
@ -16,19 +21,30 @@ public class OpenShockHttp : OpenShockApi
return; return;
} }
string json = "{" + HttpRequestMessage request = new (HttpMethod.Post, $"{Endpoint}/2/shockers/control")
" \"shocks\": [" + {
" {" + Headers =
$" \"id\": \"{openShockShocker.id}\"," + {
$" \"type\": {ControlActionToByte(action)}," + UserAgent = { new ProductInfoHeaderValue("CShocker", "1") },
$" \"intensity\": {intensity}," + Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
$" \"duration\": {duration}" + },
" }" + Content = new StringContent("{" +
" ]," + " \"shocks\": [" +
" \"customName\": \"CShocker\"" + " {" +
"}"; $" \"id\": \"{openShockShocker.id}\"," +
$" \"type\": {ControlActionToByte(action)}," +
ApiHttpClient.MakeAPICall(HttpMethod.Post, $"{Endpoint}/2/shockers/control", json, this.Logger, new ValueTuple<string, string>("OpenShockToken", ApiKey)); $" \"intensity\": {intensity}," +
$" \"duration\": {duration}" +
" }" +
" ]," +
" \"customName\": \"CShocker\"" +
"}", Encoding.UTF8, new MediaTypeHeaderValue("application/json"))
};
request.Headers.Add("OpenShockToken", ApiKey);
this.Logger?.Log(LogLevel.Debug, $"Request-Content: {request.Content.ReadAsStringAsync().Result}");
HttpResponseMessage response = HttpClient.Send(request);
this.Logger?.Log(!response.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
$"{request.RequestUri} response: {response.StatusCode}");
} }
private byte ControlActionToByte(ControlAction action) private byte ControlActionToByte(ControlAction action)

View File

@ -1,6 +1,7 @@
using System.IO.Ports; using System.IO.Ports;
using CShocker.Devices.Abstract; using CShocker.Devices.Abstract;
using CShocker.Devices.Additional; using CShocker.Devices.Additional;
using CShocker.Ranges;
using CShocker.Shockers; using CShocker.Shockers;
using CShocker.Shockers.Abstract; using CShocker.Shockers.Abstract;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;

View File

@ -1,5 +1,8 @@
using CShocker.Devices.Abstract; using System.Net.Http.Headers;
using System.Text;
using CShocker.Devices.Abstract;
using CShocker.Devices.Additional; using CShocker.Devices.Additional;
using CShocker.Ranges;
using CShocker.Shockers; using CShocker.Shockers;
using CShocker.Shockers.Abstract; using CShocker.Shockers.Abstract;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -10,6 +13,7 @@ public class PiShockHttp : PiShockApi
{ {
// ReSharper disable twice MemberCanBePrivate.Global external usage // ReSharper disable twice MemberCanBePrivate.Global external usage
public string Username, Endpoint, ApiKey; public string Username, Endpoint, ApiKey;
protected readonly HttpClient HttpClient = new();
public PiShockHttp(string apiKey, string username, string endpoint = "https://do.pishock.com/api/apioperate", ILogger? logger = null) : base(DeviceApi.PiShockHttp, logger) public PiShockHttp(string apiKey, string username, string endpoint = "https://do.pishock.com/api/apioperate", ILogger? logger = null) : base(DeviceApi.PiShockHttp, logger)
{ {
@ -25,18 +29,27 @@ public class PiShockHttp : PiShockApi
this.Logger?.Log(LogLevel.Warning, $"Shocker {shocker} is not {typeof(OpenShockShocker).FullName}"); this.Logger?.Log(LogLevel.Warning, $"Shocker {shocker} is not {typeof(OpenShockShocker).FullName}");
return; return;
} }
string json = "{" + HttpRequestMessage request = new (HttpMethod.Post, $"{Endpoint}")
$"\"Username\":\"{Username}\"," + {
"\"Name\":\"CShocker\"," + Headers =
$"\"Code\":\"{piShockShocker.Code}\"," + {
$"\"Intensity\":\"{intensity}\"," + UserAgent = { new ProductInfoHeaderValue("CShocker", "1") },
$"\"Duration\":\"{duration / 1000}\"," + //duration is in seconds no ms Accept = { new MediaTypeWithQualityHeaderValue("text/plain") }
$"\"Apikey\":\"{ApiKey}\"," + },
$"\"Op\":\"{ControlActionToByte(action)}\"" + Content = new StringContent("{" +
"}"; $"\"Username\":\"{Username}\"," +
"\"Name\":\"CShocker\"," +
ApiHttpClient.MakeAPICall(HttpMethod.Post, $"{Endpoint}", json, this.Logger); $"\"Code\":\"{piShockShocker.Code}\"," +
$"\"Intensity\":\"{intensity}\"," +
$"\"Duration\":\"{duration/1000}\"," + //duration is in seconds no ms
$"\"Apikey\":\"{ApiKey}\"," +
$"\"Op\":\"{ControlActionToByte(action)}\"" +
"}", Encoding.UTF8, new MediaTypeHeaderValue("application/json"))
};
HttpResponseMessage response = HttpClient.Send(request);
this.Logger?.Log(!response.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
$"{request.RequestUri} response: {response.StatusCode}");
} }
private byte ControlActionToByte(ControlAction action) private byte ControlActionToByte(ControlAction action)

View File

@ -1,4 +1,5 @@
using CShocker.Devices.Additional; using System.Net.Http.Headers;
using CShocker.Devices.Additional;
using CShocker.Ranges; using CShocker.Ranges;
using CShocker.Shockers; using CShocker.Shockers;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -8,6 +9,7 @@ namespace CShocker.Devices.Abstract;
public abstract class OpenShockApi : Api public abstract class OpenShockApi : Api
{ {
protected readonly HttpClient HttpClient = new();
public string Endpoint { get; init; } public string Endpoint { get; init; }
public string ApiKey { get; init; } public string ApiKey { get; init; }
private const string DefaultEndpoint = "https://api.shocklink.net"; private const string DefaultEndpoint = "https://api.shocklink.net";
@ -41,8 +43,21 @@ public abstract class OpenShockApi : Api
public static List<OpenShockShocker> GetShockers(string apiKey, OpenShockApi api, string apiEndpoint = DefaultEndpoint, ILogger? logger = null) public static List<OpenShockShocker> GetShockers(string apiKey, OpenShockApi api, string apiEndpoint = DefaultEndpoint, ILogger? logger = null)
{ {
List<OpenShockShocker> shockers = new(); List<OpenShockShocker> shockers = new();
HttpResponseMessage ownResponse = ApiHttpClient.MakeAPICall(HttpMethod.Get, $"{apiEndpoint}/1/shockers/own", null, logger, new ValueTuple<string, string>("OpenShockToken", apiKey)); HttpClient httpClient = new();
HttpRequestMessage requestOwnShockers = new (HttpMethod.Get, $"{apiEndpoint}/1/shockers/own")
{
Headers =
{
UserAgent = { new ProductInfoHeaderValue("CShocker", "1") },
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
}
};
requestOwnShockers.Headers.Add("OpenShockToken", apiKey);
logger?.Log(LogLevel.Debug, $"Requesting {requestOwnShockers.RequestUri}");
HttpResponseMessage ownResponse = httpClient.Send(requestOwnShockers);
logger?.Log(!ownResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
$"{requestOwnShockers.RequestUri} response: {ownResponse.StatusCode}");
if (!ownResponse.IsSuccessStatusCode) if (!ownResponse.IsSuccessStatusCode)
return shockers; return shockers;
@ -51,13 +66,23 @@ public abstract class OpenShockApi : Api
logger?.Log(LogLevel.Debug,ownShockerJson); logger?.Log(LogLevel.Debug,ownShockerJson);
JObject ownShockerListJObj = JObject.Parse(ownShockerJson); JObject ownShockerListJObj = JObject.Parse(ownShockerJson);
shockers.AddRange(ownShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t => shockers.AddRange(ownShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t =>
new OpenShockShocker( {
api, return new OpenShockShocker(api, t["name"]!.Value<string>()!, t["id"]!.Value<string>()!, t["rfId"]!.Value<short>(), Enum.Parse<OpenShockShocker.OpenShockModel>(t["model"]!.Value<string>()!), t["createdOn"]!.ToObject<DateTime>(), t["isPaused"]!.Value<bool>());
t["name"]!.Value<string>()!, t["id"]!.Value<string>()!, t["rfId"]!.Value<short>(), }));
Enum.Parse<OpenShockShocker.OpenShockModel>(t["model"]!.Value<string>()!),
t["createdOn"]!.ToObject<DateTime>(), t["isPaused"]!.Value<bool>())));
HttpResponseMessage sharedResponse = ApiHttpClient.MakeAPICall(HttpMethod.Get, $"{apiEndpoint}/1/shockers/shared", null, logger, new ValueTuple<string, string>("OpenShockToken", apiKey)); HttpRequestMessage requestSharedShockers = new (HttpMethod.Get, $"{apiEndpoint}/1/shockers/shared")
{
Headers =
{
UserAgent = { new ProductInfoHeaderValue("CShocker", "1") },
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
}
};
requestSharedShockers.Headers.Add("OpenShockToken", apiKey);
logger?.Log(LogLevel.Debug, $"Requesting {requestSharedShockers.RequestUri}");
HttpResponseMessage sharedResponse = httpClient.Send(requestSharedShockers);
logger?.Log(!sharedResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
$"{requestSharedShockers.RequestUri} response: {sharedResponse.StatusCode}");
if (!sharedResponse.IsSuccessStatusCode) if (!sharedResponse.IsSuccessStatusCode)
return shockers; return shockers;
@ -65,12 +90,10 @@ public abstract class OpenShockApi : Api
string sharedShockerJson = sharedShockerStreamReader.ReadToEnd(); string sharedShockerJson = sharedShockerStreamReader.ReadToEnd();
logger?.Log(LogLevel.Debug, sharedShockerJson); logger?.Log(LogLevel.Debug, sharedShockerJson);
JObject sharedShockerListJObj = JObject.Parse(sharedShockerJson); JObject sharedShockerListJObj = JObject.Parse(sharedShockerJson);
shockers.AddRange(sharedShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t => shockers.AddRange(sharedShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t =>
new OpenShockShocker( {
api, return new OpenShockShocker(api, t["name"]!.Value<string>()!, t["id"]!.Value<string>()!, t["rfId"]!.Value<short>(),Enum.Parse<OpenShockShocker.OpenShockModel>(t["model"]!.Value<string>()!), t["createdOn"]!.ToObject<DateTime>(), t["isPaused"]!.Value<bool>());
t["name"]!.Value<string>()!, t["id"]!.Value<string>()!, t["rfId"]!.Value<short>(), }));
Enum.Parse<OpenShockShocker.OpenShockModel>(t["model"]!.Value<string>()!),
t["createdOn"]!.ToObject<DateTime>(), t["isPaused"]!.Value<bool>())));
return shockers; return shockers;
} }
} }

View File

@ -1,40 +0,0 @@
using System.Diagnostics;
using System.Net.Http.Headers;
using System.Reflection;
using System.Text;
using Microsoft.Extensions.Logging;
namespace CShocker.Devices.Additional;
public static class ApiHttpClient
{
internal static HttpResponseMessage MakeAPICall(HttpMethod method, string uri, string? jsonContent, ILogger? logger = null, params ValueTuple<string, string>[] customHeaders)
{
Assembly assembly = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
ProductInfoHeaderValue userAgent = new (fvi.ProductName ?? fvi.FileName, fvi.ProductVersion);
HttpRequestMessage request = new (method, uri)
{
Headers =
{
UserAgent = { userAgent },
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
}
};
if (jsonContent is not null && jsonContent.Length > 0)
request.Content =
new StringContent(jsonContent, Encoding.UTF8, new MediaTypeHeaderValue("application/json"));
foreach ((string, string) customHeader in customHeaders)
request.Headers.Add(customHeader.Item1, customHeader.Item2);
logger?.Log(LogLevel.Debug, $"Request-URI: {request.RequestUri}\n\r" +
$"Request-Headers: \n\t{string.Join("\n\t", request.Headers.Select(h => $"{h.Key} {string.Join(", ", h.Value)}"))}\n\r" +
$"Request-Content: {request.Content?.ReadAsStringAsync().Result}");
HttpClient httpClient = new();
HttpResponseMessage response = httpClient.Send(request);
logger?.Log(!response.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
$"{request.RequestUri} response: {response.StatusCode}");
httpClient.Dispose();
return response;
}
}