Rewrite Hierachy that shockers now contain the api they use.
This commit is contained in:
parent
9596811ae7
commit
65059f66ed
5
CShocker.sln.DotSettings.user
Normal file
5
CShocker.sln.DotSettings.user
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||||
|
<s:Boolean x:Key="/Default/AddReferences/RecentPaths/=C_003A_005CUsers_005CGlax_005CRiderProjects_005CGlaxLogger_005CGlaxLogger_005Cbin_005CDebug_005Cnet7_002E0_005CGlaxLogger_002Edll/@EntryIndexedValue">True</s:Boolean>
|
||||||
|
<s:String x:Key="/Default/Environment/AssemblyExplorer/XmlDocument/@EntryValue"><AssemblyExplorer>
|
||||||
|
<Assembly Path="C:\Users\Glax\RiderProjects\GlaxLogger\GlaxLogger\bin\Debug\net7.0\GlaxLogger.dll" />
|
||||||
|
</AssemblyExplorer></s:String></wpf:ResourceDictionary>
|
@ -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.0.2</Version>
|
<Version>2.1.0</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -7,13 +7,13 @@ using CShocker.Shockers;
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Shockers.Abstract;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CShocker.Devices;
|
namespace CShocker.Devices.APIs;
|
||||||
|
|
||||||
public class OpenShockHttp : OpenShockDevice
|
public class OpenShockHttp : OpenShockApi
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
protected override void ControlInternal(ControlAction action, IShocker 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)
|
||||||
{
|
{
|
@ -6,9 +6,9 @@ using CShocker.Shockers;
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Shockers.Abstract;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CShocker.Devices;
|
namespace CShocker.Devices.APIs;
|
||||||
|
|
||||||
public class OpenShockSerial : OpenShockDevice
|
public class OpenShockSerial : OpenShockApi
|
||||||
{
|
{
|
||||||
private const int BaudRate = 115200;
|
private const int BaudRate = 115200;
|
||||||
public SerialPortInfo SerialPortI;
|
public SerialPortInfo SerialPortI;
|
||||||
@ -18,10 +18,18 @@ public class OpenShockSerial : OpenShockDevice
|
|||||||
{
|
{
|
||||||
this.SerialPortI = serialPortI;
|
this.SerialPortI = serialPortI;
|
||||||
this._serialPort = new SerialPort(serialPortI.PortName, BaudRate);
|
this._serialPort = new SerialPort(serialPortI.PortName, BaudRate);
|
||||||
this._serialPort.Open();
|
try
|
||||||
|
{
|
||||||
|
this._serialPort.Open();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
this.Logger?.Log(LogLevel.Error, e.Message);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ControlInternal(ControlAction action, IShocker 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)
|
||||||
{
|
{
|
@ -7,9 +7,9 @@ using CShocker.Shockers;
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Shockers.Abstract;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CShocker.Devices;
|
namespace CShocker.Devices.APIs;
|
||||||
|
|
||||||
public class PiShockHttp : PiShockDevice
|
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;
|
||||||
@ -22,7 +22,7 @@ public class PiShockHttp : PiShockDevice
|
|||||||
this.ApiKey = apiKey;
|
this.ApiKey = apiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ControlInternal(ControlAction action, IShocker shocker, int intensity, int duration)
|
protected override void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration)
|
||||||
{
|
{
|
||||||
if (shocker is not PiShockShocker piShockShocker)
|
if (shocker is not PiShockShocker piShockShocker)
|
||||||
{
|
{
|
@ -5,9 +5,9 @@ using CShocker.Ranges;
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Shockers.Abstract;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace CShocker.Devices;
|
namespace CShocker.Devices.APIs;
|
||||||
|
|
||||||
public class PiShockSerial : PiShockDevice
|
public class PiShockSerial : PiShockApi
|
||||||
{
|
{
|
||||||
private const int BaudRate = 115200;
|
private const int BaudRate = 115200;
|
||||||
public SerialPortInfo SerialPortI;
|
public SerialPortInfo SerialPortI;
|
||||||
@ -20,7 +20,7 @@ public class PiShockSerial : PiShockDevice
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ControlInternal(ControlAction action, IShocker shocker, int intensity, int duration)
|
protected override void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration)
|
||||||
{
|
{
|
||||||
string json = "{" +
|
string json = "{" +
|
||||||
"\"cmd\": \"operate\"," +
|
"\"cmd\": \"operate\"," +
|
@ -5,20 +5,20 @@ using Microsoft.Extensions.Logging;
|
|||||||
|
|
||||||
namespace CShocker.Devices.Abstract;
|
namespace CShocker.Devices.Abstract;
|
||||||
|
|
||||||
public abstract class Device : IDisposable
|
public abstract class Api : IDisposable
|
||||||
{
|
{
|
||||||
// ReSharper disable 4 times MemberCanBePrivate.Global external use
|
// ReSharper disable 4 times MemberCanBePrivate.Global external use
|
||||||
public readonly IntensityRange IntensityRange;
|
public readonly IntensityRange IntensityRange;
|
||||||
public readonly DurationRange DurationRange;
|
public readonly DurationRange DurationRange;
|
||||||
protected ILogger? Logger;
|
protected ILogger? Logger;
|
||||||
public readonly DeviceApi ApiType;
|
public readonly DeviceApi ApiType;
|
||||||
private readonly Queue<ValueTuple<ControlAction, IShocker, int, int>> _queue = new();
|
private readonly Queue<ValueTuple<ControlAction, Shocker, int, int>> _queue = new();
|
||||||
private bool _workQueue = true;
|
private bool _workQueue = true;
|
||||||
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
// ReSharper disable once PrivateFieldCanBeConvertedToLocalVariable
|
||||||
private readonly Thread _workQueueThread;
|
private readonly Thread _workQueueThread;
|
||||||
private const short CommandDelay = 50;
|
private const short CommandDelay = 50;
|
||||||
|
|
||||||
public void Control(ControlAction action, int? intensity = null, int? duration = null, params IShocker[] shockers)
|
internal void Control(ControlAction action, int? intensity = null, int? duration = null, params Shocker[] shockers)
|
||||||
{
|
{
|
||||||
int i = intensity ?? IntensityRange.GetRandomRangeValue();
|
int i = intensity ?? IntensityRange.GetRandomRangeValue();
|
||||||
int d = duration ?? DurationRange.GetRandomRangeValue();
|
int d = duration ?? DurationRange.GetRandomRangeValue();
|
||||||
@ -27,16 +27,16 @@ public abstract class Device : IDisposable
|
|||||||
this.Logger?.Log(LogLevel.Information, "Doing nothing");
|
this.Logger?.Log(LogLevel.Information, "Doing nothing");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
foreach (IShocker shocker in shockers)
|
foreach (Shocker shocker in shockers)
|
||||||
{
|
{
|
||||||
this.Logger?.Log(LogLevel.Debug, $"Enqueueing {action} {(intensity is not null ? $"Overwrite {i}" : $"{i}")} {(duration is not null ? $"Overwrite {d}" : $"{d}")}");
|
this.Logger?.Log(LogLevel.Debug, $"Enqueueing {action} {(intensity is not null ? $"Overwrite {i}" : $"{i}")} {(duration is not null ? $"Overwrite {d}" : $"{d}")}");
|
||||||
_queue.Enqueue(new(action, shocker, i ,d));
|
_queue.Enqueue(new(action, shocker, i ,d));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void ControlInternal(ControlAction action, IShocker shocker, int intensity, int duration);
|
protected abstract void ControlInternal(ControlAction action, Shocker shocker, int intensity, int duration);
|
||||||
|
|
||||||
protected Device(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, ILogger? logger = null)
|
protected Api(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, ILogger? logger = null)
|
||||||
{
|
{
|
||||||
this.IntensityRange = intensityRange;
|
this.IntensityRange = intensityRange;
|
||||||
this.DurationRange = durationRange;
|
this.DurationRange = durationRange;
|
||||||
@ -71,10 +71,10 @@ public abstract class Device : IDisposable
|
|||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
return obj is Device d && Equals(d);
|
return obj is Api d && Equals(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected bool Equals(Device other)
|
protected bool Equals(Api other)
|
||||||
{
|
{
|
||||||
return IntensityRange.Equals(other.IntensityRange) && DurationRange.Equals(other.DurationRange) && ApiType == other.ApiType;
|
return IntensityRange.Equals(other.IntensityRange) && DurationRange.Equals(other.DurationRange) && ApiType == other.ApiType;
|
||||||
}
|
}
|
@ -7,13 +7,14 @@ using Newtonsoft.Json.Linq;
|
|||||||
|
|
||||||
namespace CShocker.Devices.Abstract;
|
namespace CShocker.Devices.Abstract;
|
||||||
|
|
||||||
public abstract class OpenShockDevice : Device
|
public abstract class OpenShockApi : Api
|
||||||
{
|
{
|
||||||
protected readonly HttpClient HttpClient = new();
|
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";
|
||||||
|
|
||||||
public OpenShockDevice(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, string apiKey, string endpoint = "https://api.shocklink.net", ILogger? logger = null) : base(intensityRange, durationRange, apiType, logger)
|
public OpenShockApi(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, string apiKey, string endpoint = DefaultEndpoint, ILogger? logger = null) : base(intensityRange, durationRange, apiType, logger)
|
||||||
{
|
{
|
||||||
this.Endpoint = endpoint;
|
this.Endpoint = endpoint;
|
||||||
this.ApiKey = apiKey;
|
this.ApiKey = apiKey;
|
||||||
@ -21,10 +22,10 @@ public abstract class OpenShockDevice : Device
|
|||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj)
|
||||||
{
|
{
|
||||||
return obj is OpenShockDevice osd && Equals(osd);
|
return obj is OpenShockApi osd && Equals(osd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Equals(OpenShockDevice other)
|
private bool Equals(OpenShockApi other)
|
||||||
{
|
{
|
||||||
return base.Equals(other) && Endpoint == other.Endpoint && ApiKey == other.ApiKey;
|
return base.Equals(other) && Endpoint == other.Endpoint && ApiKey == other.ApiKey;
|
||||||
}
|
}
|
||||||
@ -34,12 +35,18 @@ public abstract class OpenShockDevice : Device
|
|||||||
return HashCode.Combine(Endpoint, ApiKey);
|
return HashCode.Combine(Endpoint, ApiKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OpenShockShocker> GetShockers()
|
public List<OpenShockShocker> GetShockers(string apiKey, string apiEndpoint = DefaultEndpoint,
|
||||||
|
ILogger? logger = null)
|
||||||
|
{
|
||||||
|
return GetShockers(apiKey, this, apiEndpoint, logger);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<OpenShockShocker> GetShockers(string apiKey, OpenShockApi api, string apiEndpoint = DefaultEndpoint, ILogger? logger = null)
|
||||||
{
|
{
|
||||||
List<OpenShockShocker> shockers = new();
|
List<OpenShockShocker> shockers = new();
|
||||||
|
|
||||||
HttpClient httpClient = new();
|
HttpClient httpClient = new();
|
||||||
HttpRequestMessage requestOwnShockers = new (HttpMethod.Get, $"{Endpoint}/1/shockers/own")
|
HttpRequestMessage requestOwnShockers = new (HttpMethod.Get, $"{apiEndpoint}/1/shockers/own")
|
||||||
{
|
{
|
||||||
Headers =
|
Headers =
|
||||||
{
|
{
|
||||||
@ -47,21 +54,24 @@ public abstract class OpenShockDevice : Device
|
|||||||
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
|
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
requestOwnShockers.Headers.Add("OpenShockToken", ApiKey);
|
requestOwnShockers.Headers.Add("OpenShockToken", apiKey);
|
||||||
this.Logger?.Log(LogLevel.Debug, $"Requesting {requestOwnShockers.RequestUri}");
|
logger?.Log(LogLevel.Debug, $"Requesting {requestOwnShockers.RequestUri}");
|
||||||
HttpResponseMessage ownResponse = httpClient.Send(requestOwnShockers);
|
HttpResponseMessage ownResponse = httpClient.Send(requestOwnShockers);
|
||||||
this.Logger?.Log(!ownResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
|
logger?.Log(!ownResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
|
||||||
$"{requestOwnShockers.RequestUri} response: {ownResponse.StatusCode}");
|
$"{requestOwnShockers.RequestUri} response: {ownResponse.StatusCode}");
|
||||||
if (!ownResponse.IsSuccessStatusCode)
|
if (!ownResponse.IsSuccessStatusCode)
|
||||||
return shockers;
|
return shockers;
|
||||||
|
|
||||||
StreamReader ownShockerStreamReader = new(ownResponse.Content.ReadAsStream());
|
StreamReader ownShockerStreamReader = new(ownResponse.Content.ReadAsStream());
|
||||||
string ownShockerJson = ownShockerStreamReader.ReadToEnd();
|
string ownShockerJson = ownShockerStreamReader.ReadToEnd();
|
||||||
this.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 => t.ToObject<OpenShockShocker>()));
|
shockers.AddRange(ownShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t =>
|
||||||
|
{
|
||||||
|
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>());
|
||||||
|
}));
|
||||||
|
|
||||||
HttpRequestMessage requestSharedShockers = new (HttpMethod.Get, $"{Endpoint}/1/shockers/shared")
|
HttpRequestMessage requestSharedShockers = new (HttpMethod.Get, $"{apiEndpoint}/1/shockers/shared")
|
||||||
{
|
{
|
||||||
Headers =
|
Headers =
|
||||||
{
|
{
|
||||||
@ -69,19 +79,22 @@ public abstract class OpenShockDevice : Device
|
|||||||
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
|
Accept = { new MediaTypeWithQualityHeaderValue("application/json") }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
requestSharedShockers.Headers.Add("OpenShockToken", ApiKey);
|
requestSharedShockers.Headers.Add("OpenShockToken", apiKey);
|
||||||
this.Logger?.Log(LogLevel.Debug, $"Requesting {requestSharedShockers.RequestUri}");
|
logger?.Log(LogLevel.Debug, $"Requesting {requestSharedShockers.RequestUri}");
|
||||||
HttpResponseMessage sharedResponse = httpClient.Send(requestSharedShockers);
|
HttpResponseMessage sharedResponse = httpClient.Send(requestSharedShockers);
|
||||||
this.Logger?.Log(!sharedResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
|
logger?.Log(!sharedResponse.IsSuccessStatusCode ? LogLevel.Error : LogLevel.Debug,
|
||||||
$"{requestSharedShockers.RequestUri} response: {sharedResponse.StatusCode}");
|
$"{requestSharedShockers.RequestUri} response: {sharedResponse.StatusCode}");
|
||||||
if (!sharedResponse.IsSuccessStatusCode)
|
if (!sharedResponse.IsSuccessStatusCode)
|
||||||
return shockers;
|
return shockers;
|
||||||
|
|
||||||
StreamReader sharedShockerStreamReader = new(sharedResponse.Content.ReadAsStream());
|
StreamReader sharedShockerStreamReader = new(sharedResponse.Content.ReadAsStream());
|
||||||
string sharedShockerJson = sharedShockerStreamReader.ReadToEnd();
|
string sharedShockerJson = sharedShockerStreamReader.ReadToEnd();
|
||||||
this.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 => t.ToObject<OpenShockShocker>()));
|
shockers.AddRange(sharedShockerListJObj.SelectTokens("$.data..shockers[*]").Select(t =>
|
||||||
|
{
|
||||||
|
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>());
|
||||||
|
}));
|
||||||
return shockers;
|
return shockers;
|
||||||
}
|
}
|
||||||
}
|
}
|
12
CShocker/Devices/Abstract/PiShockApi.cs
Normal file
12
CShocker/Devices/Abstract/PiShockApi.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using CShocker.Devices.Additional;
|
||||||
|
using CShocker.Ranges;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace CShocker.Devices.Abstract;
|
||||||
|
|
||||||
|
public abstract class PiShockApi : Api
|
||||||
|
{
|
||||||
|
protected PiShockApi(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, ILogger? logger = null) : base(intensityRange, durationRange, apiType, logger)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
using CShocker.Devices.Additional;
|
|
||||||
using CShocker.Ranges;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace CShocker.Devices.Abstract;
|
|
||||||
|
|
||||||
public abstract class PiShockDevice : Device
|
|
||||||
{
|
|
||||||
protected PiShockDevice(IntensityRange intensityRange, DurationRange durationRange, DeviceApi apiType, ILogger? logger = null) : base(intensityRange, durationRange, apiType, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
5
CShocker/Devices/Additional/DeviceJsonConverter.cs → CShocker/Devices/Additional/ApiJsonConverter.cs
5
CShocker/Devices/Additional/DeviceJsonConverter.cs → CShocker/Devices/Additional/ApiJsonConverter.cs
@ -1,15 +1,16 @@
|
|||||||
using CShocker.Devices.Abstract;
|
using CShocker.Devices.Abstract;
|
||||||
|
using CShocker.Devices.APIs;
|
||||||
using CShocker.Ranges;
|
using CShocker.Ranges;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
namespace CShocker.Devices.Additional;
|
namespace CShocker.Devices.Additional;
|
||||||
|
|
||||||
public class DeviceJsonConverter : JsonConverter
|
public class ApiJsonConverter : JsonConverter
|
||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return (objectType == typeof(Device));
|
return (objectType == typeof(Api));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
@ -1,5 +1,24 @@
|
|||||||
namespace CShocker.Shockers.Abstract;
|
using CShocker.Devices.Abstract;
|
||||||
|
using CShocker.Devices.Additional;
|
||||||
|
|
||||||
public interface IShocker
|
namespace CShocker.Shockers.Abstract;
|
||||||
|
|
||||||
|
public abstract class Shocker : IDisposable
|
||||||
{
|
{
|
||||||
|
public Api Api { get; }
|
||||||
|
|
||||||
|
internal Shocker(Api api)
|
||||||
|
{
|
||||||
|
this.Api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Control(ControlAction action, int? intensity = null, int? duration = null)
|
||||||
|
{
|
||||||
|
this.Api.Control(action, intensity, duration, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Api.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,4 +1,5 @@
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Devices.Abstract;
|
||||||
|
using CShocker.Shockers.Abstract;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
|
||||||
@ -8,7 +9,7 @@ public class ShockerJsonConverter : JsonConverter
|
|||||||
{
|
{
|
||||||
public override bool CanConvert(Type objectType)
|
public override bool CanConvert(Type objectType)
|
||||||
{
|
{
|
||||||
return (objectType == typeof(IShocker));
|
return (objectType == typeof(Shocker));
|
||||||
}
|
}
|
||||||
|
|
||||||
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
public override object ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
|
||||||
@ -16,22 +17,22 @@ public class ShockerJsonConverter : JsonConverter
|
|||||||
JObject jo = JObject.Load(reader);
|
JObject jo = JObject.Load(reader);
|
||||||
if (jo.ContainsKey("model")) //OpenShockShocker
|
if (jo.ContainsKey("model")) //OpenShockShocker
|
||||||
{
|
{
|
||||||
return new OpenShockShocker()
|
return new OpenShockShocker(
|
||||||
{
|
jo.SelectToken("api")!.ToObject<Api>()!,
|
||||||
name = jo.SelectToken("name")!.Value<string>()!,
|
jo.SelectToken("name")!.Value<string>()!,
|
||||||
id = jo.SelectToken("id")!.Value<string>()!,
|
jo.SelectToken("id")!.Value<string>()!,
|
||||||
rfId = jo.SelectToken("rfId")!.Value<short>(),
|
jo.SelectToken("rfId")!.Value<short>(),
|
||||||
model = (OpenShockShocker.OpenShockModel)jo.SelectToken("model")!.Value<byte>(),
|
(OpenShockShocker.OpenShockModel)jo.SelectToken("model")!.Value<byte>(),
|
||||||
createdOn = jo.SelectToken("createdOn")!.Value<DateTime>(),
|
jo.SelectToken("createdOn")!.Value<DateTime>(),
|
||||||
isPaused = jo.SelectToken("isPaused")!.Value<bool>()
|
jo.SelectToken("isPaused")!.Value<bool>()
|
||||||
};
|
);
|
||||||
}
|
}
|
||||||
else //PiShockShocker
|
else //PiShockShocker
|
||||||
{
|
{
|
||||||
return new PiShockShocker()
|
return new PiShockShocker(
|
||||||
{
|
jo.SelectToken("api")!.ToObject<Api>()!,
|
||||||
Code = jo.SelectToken("Code")!.Value<string>()!
|
jo.SelectToken("Code")!.Value<string>()!
|
||||||
};
|
);
|
||||||
}
|
}
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using CShocker.Devices.Abstract;
|
||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Shockers.Abstract;
|
||||||
|
|
||||||
namespace CShocker.Shockers;
|
namespace CShocker.Shockers;
|
||||||
|
|
||||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||||
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
[SuppressMessage("ReSharper", "InconsistentNaming")]
|
||||||
public struct OpenShockShocker : IShocker
|
public class OpenShockShocker : Shocker
|
||||||
{
|
{
|
||||||
public string name, id;
|
public string name, id;
|
||||||
public short rfId;
|
public short rfId;
|
||||||
@ -13,6 +14,18 @@ public struct OpenShockShocker : IShocker
|
|||||||
public DateTime createdOn;
|
public DateTime createdOn;
|
||||||
public bool isPaused;
|
public bool isPaused;
|
||||||
|
|
||||||
|
public OpenShockShocker(Api api, string name, string id, short rfId, OpenShockModel model, DateTime createdOn, bool isPaused) : base (api)
|
||||||
|
{
|
||||||
|
if (api is not OpenShockApi)
|
||||||
|
throw new Exception($"API-Type {api.GetType().FullName} is not usable with Shocker {this.GetType().FullName}");
|
||||||
|
this.name = name;
|
||||||
|
this.id = id;
|
||||||
|
this.rfId = rfId;
|
||||||
|
this.model = model;
|
||||||
|
this.createdOn = createdOn;
|
||||||
|
this.isPaused = isPaused;
|
||||||
|
}
|
||||||
|
|
||||||
public enum OpenShockModel : byte
|
public enum OpenShockModel : byte
|
||||||
{
|
{
|
||||||
CaiXianlin = 0,
|
CaiXianlin = 0,
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
using CShocker.Shockers.Abstract;
|
using CShocker.Devices.Abstract;
|
||||||
|
using CShocker.Shockers.Abstract;
|
||||||
|
|
||||||
namespace CShocker.Shockers;
|
namespace CShocker.Shockers;
|
||||||
|
|
||||||
public struct PiShockShocker : IShocker
|
public class PiShockShocker : Shocker
|
||||||
{
|
{
|
||||||
public string Code;
|
public string Code;
|
||||||
|
|
||||||
@ -20,4 +21,11 @@ public struct PiShockShocker : IShocker
|
|||||||
{
|
{
|
||||||
return Code.GetHashCode();
|
return Code.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PiShockShocker(Api api, string code) : base(api)
|
||||||
|
{
|
||||||
|
if (api is not PiShockApi)
|
||||||
|
throw new Exception($"API-Type {api.GetType().FullName} is not usable with Shocker {this.GetType().FullName}");
|
||||||
|
Code = code;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,65 +0,0 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
|
||||||
|
|
||||||
namespace TestApp;
|
|
||||||
|
|
||||||
public class Logger : ILogger
|
|
||||||
{
|
|
||||||
private LogLevel _enabledLoglevel;
|
|
||||||
private readonly ConsoleColor _defaultForegroundColor = Console.ForegroundColor;
|
|
||||||
private readonly ConsoleColor _defaultBackgroundColor = Console.BackgroundColor;
|
|
||||||
|
|
||||||
public Logger(LogLevel logLevel = LogLevel.Trace)
|
|
||||||
{
|
|
||||||
_enabledLoglevel = logLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateLogLevel(LogLevel logLevel)
|
|
||||||
{
|
|
||||||
this._enabledLoglevel = logLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
|
|
||||||
{
|
|
||||||
if (!IsEnabled(logLevel))
|
|
||||||
return;
|
|
||||||
Console.ForegroundColor = ForegroundColorForLogLevel(logLevel);
|
|
||||||
Console.BackgroundColor = BackgroundColorForLogLevel(logLevel);
|
|
||||||
Console.Write(logLevel.ToString()[..3].ToUpper());
|
|
||||||
Console.ResetColor();
|
|
||||||
// ReSharper disable once LocalizableElement
|
|
||||||
Console.Write($" [{DateTime.UtcNow:HH:mm:ss.fff}] ");
|
|
||||||
Console.WriteLine(formatter.Invoke(state, exception));
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool IsEnabled(LogLevel logLevel)
|
|
||||||
{
|
|
||||||
return logLevel >= _enabledLoglevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IDisposable? BeginScope<TState>(TState state) where TState : notnull
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConsoleColor ForegroundColorForLogLevel(LogLevel logLevel)
|
|
||||||
{
|
|
||||||
return logLevel switch
|
|
||||||
{
|
|
||||||
LogLevel.Error or LogLevel.Critical => ConsoleColor.Black,
|
|
||||||
LogLevel.Debug => ConsoleColor.Black,
|
|
||||||
LogLevel.Information => ConsoleColor.White,
|
|
||||||
_ => _defaultForegroundColor
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private ConsoleColor BackgroundColorForLogLevel(LogLevel logLevel)
|
|
||||||
{
|
|
||||||
return logLevel switch
|
|
||||||
{
|
|
||||||
LogLevel.Error or LogLevel.Critical => ConsoleColor.Red,
|
|
||||||
LogLevel.Debug => ConsoleColor.Yellow,
|
|
||||||
LogLevel.Information => ConsoleColor.Black,
|
|
||||||
_ => _defaultBackgroundColor
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,35 +1,33 @@
|
|||||||
using CShocker.Devices;
|
using CShocker.Devices.Abstract;
|
||||||
using CShocker.Devices.Abstract;
|
|
||||||
using CShocker.Devices.Additional;
|
using CShocker.Devices.Additional;
|
||||||
|
using CShocker.Devices.APIs;
|
||||||
using CShocker.Ranges;
|
using CShocker.Ranges;
|
||||||
using CShocker.Shockers;
|
using CShocker.Shockers;
|
||||||
using CShocker.Shockers.Abstract;
|
using GlaxLogger;
|
||||||
using CShocker.Shockers.Additional;
|
using Microsoft.Extensions.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using TestApp;
|
|
||||||
|
|
||||||
Logger logger = new ();
|
Logger logger = new (LogLevel.Trace);
|
||||||
List<OpenShockShocker> shockers = new();
|
|
||||||
|
|
||||||
Console.WriteLine("OpenShock API Key:");
|
Console.WriteLine("OpenShock API Key:");
|
||||||
string? apiKey = Console.ReadLine();
|
string? apiKey = Console.ReadLine();
|
||||||
while(apiKey is null || apiKey.Length < 1)
|
while(apiKey is null || apiKey.Length < 1)
|
||||||
apiKey = Console.ReadLine();
|
apiKey = Console.ReadLine();
|
||||||
|
|
||||||
|
|
||||||
OpenShockHttp openShockHttp = new (new IntensityRange(30, 50), new DurationRange(1000, 1000), apiKey, logger: logger);
|
|
||||||
shockers = openShockHttp.GetShockers();
|
|
||||||
openShockHttp.Control(ControlAction.Vibrate, 20, 1000, shockers.First());
|
|
||||||
|
|
||||||
File.WriteAllText("devices.json", JsonConvert.SerializeObject(openShockHttp));
|
|
||||||
OpenShockHttp deserialized = JsonConvert.DeserializeObject<OpenShockHttp>(File.ReadAllText("devices.json"))!;
|
|
||||||
Thread.Sleep(1100); //Wait for previous to end
|
|
||||||
deserialized.Control(ControlAction.Vibrate, 20, 1000, shockers.First());
|
|
||||||
openShockHttp.Dispose();
|
|
||||||
deserialized.Dispose();
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
OpenShockHttp openShockHttp = new (new IntensityRange(30, 50), new DurationRange(1000, 1000), apiKey, logger: logger);
|
||||||
|
OpenShockShocker shocker = openShockHttp.GetShockers(apiKey).First();
|
||||||
|
shocker.Control(ControlAction.Vibrate, 20, 1000);
|
||||||
|
|
||||||
|
File.WriteAllText("shockers.json", JsonConvert.SerializeObject(shocker));
|
||||||
|
OpenShockShocker deserialized = JsonConvert.DeserializeObject<OpenShockShocker>(File.ReadAllText("shockers.json"), new ApiJsonConverter())!;
|
||||||
|
Thread.Sleep(1100); //Wait for previous to end
|
||||||
|
deserialized.Control(ControlAction.Vibrate, 20, 1000);
|
||||||
|
shocker.Dispose();
|
||||||
|
deserialized.Dispose();
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#pragma warning disable CA1416
|
#pragma warning disable CA1416
|
||||||
List<SerialPortInfo> serialPorts = SerialHelper.GetSerialPorts();
|
List<SerialPortInfo> serialPorts = SerialHelper.GetSerialPorts();
|
||||||
|
|
||||||
@ -49,15 +47,11 @@ while (!int.TryParse(selectedPortStr, out selectedPort) || selectedPort < 0 || s
|
|||||||
}
|
}
|
||||||
|
|
||||||
OpenShockSerial openShockSerial = new(new IntensityRange(30, 50), new DurationRange(1000, 1000),serialPorts[selectedPort], apiKey, logger: logger);
|
OpenShockSerial openShockSerial = new(new IntensityRange(30, 50), new DurationRange(1000, 1000),serialPorts[selectedPort], apiKey, logger: logger);
|
||||||
shockers = openShockSerial.GetShockers();
|
OpenShockShocker shocker = openShockSerial.GetShockers(apiKey).First();
|
||||||
openShockSerial.Control(ControlAction.Vibrate, 20, 1000, shockers.First());
|
shocker.Control(ControlAction.Vibrate, 20, 1000);
|
||||||
File.WriteAllText("devices.json", JsonConvert.SerializeObject(openShockSerial));
|
File.WriteAllText("shockers.json", JsonConvert.SerializeObject(shocker));
|
||||||
OpenShockHttp deserialized = JsonConvert.DeserializeObject<OpenShockHttp>(File.ReadAllText("devices.json"))!;
|
OpenShockShocker deserialized = JsonConvert.DeserializeObject<OpenShockShocker>(File.ReadAllText("shockers.json"), new ApiJsonConverter())!;
|
||||||
openShockSerial.Dispose();
|
shocker.Dispose();
|
||||||
deserialized.Dispose();
|
deserialized.Dispose();
|
||||||
*/
|
|
||||||
|
|
||||||
foreach(OpenShockShocker s in shockers)
|
logger.Dispose();
|
||||||
Console.Write(s);
|
|
||||||
File.WriteAllText("shockers.json", JsonConvert.SerializeObject(shockers));
|
|
||||||
List<IShocker> deserializedShockers = JsonConvert.DeserializeObject<List<IShocker>>(File.ReadAllText("shockers.json"), new ShockerJsonConverter())!;
|
|
@ -11,4 +11,10 @@
|
|||||||
<ProjectReference Include="..\CShocker\CShocker.csproj" />
|
<ProjectReference Include="..\CShocker\CShocker.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="GlaxLogger">
|
||||||
|
<HintPath>..\..\GlaxLogger\GlaxLogger\bin\Debug\net7.0\GlaxLogger.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user