Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/tuyanet.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2021-10-28 22:32:19 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2021-10-28 22:32:19 +0300
commit166034b06b29bc21376338aadbb4406782b53bbb (patch)
tree22c14739caf10b1e7eb88959937c6e39033b56dc
parenta28b63890583fc63e806ec95f5cf572db73660bf (diff)
Downgraded to .NET Standard 2.0 for better compatibility
-rw-r--r--TuyaApi.cs30
-rw-r--r--TuyaDevice.cs88
-rw-r--r--TuyaDeviceApiInfo.cs48
-rw-r--r--TuyaDeviceScanInfo.cs20
-rw-r--r--TuyaDeviceStatus.cs6
-rw-r--r--TuyaNet.csproj29
-rw-r--r--TuyaParser.cs7
-rw-r--r--TuyaScanner.cs6
8 files changed, 115 insertions, 119 deletions
diff --git a/TuyaApi.cs b/TuyaApi.cs
index 70c3487..90fbc27 100644
--- a/TuyaApi.cs
+++ b/TuyaApi.cs
@@ -1,12 +1,12 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
-using System.Text.Json;
-using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace com.clusterrr.TuyaNet
@@ -25,16 +25,16 @@ namespace com.clusterrr.TuyaNet
private class TuyaToken
{
- [JsonPropertyName("access_token")]
+ [JsonProperty("access_token")]
public string AccessToken { get; set; }
- [JsonPropertyName("expire_time")]
+ [JsonProperty("expire_time")]
public int ExpireTime { get; set; }
- [JsonPropertyName("refresh_token")]
+ [JsonProperty("refresh_token")]
public string RefreshToken { get; set; }
- [JsonPropertyName("uid")]
+ [JsonProperty("uid")]
public string Uid { get; set; }
}
@@ -113,7 +113,7 @@ namespace com.clusterrr.TuyaNet
else
{
headersStr = string.Concat(headers.Select(kv => $"{kv.Key}:{kv.Value}\n"));
- headers.Add("Signature-Headers", string.Join(':', headers.Keys));
+ headers.Add("Signature-Headers", string.Join(":", headers.Keys));
}
string payload;
@@ -160,10 +160,10 @@ namespace com.clusterrr.TuyaNet
using (var response = await httpClient.SendAsync(httpRequestMessage).ConfigureAwait(false))
{
var responseString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
- var root = JsonDocument.Parse(responseString).RootElement;
- var success = root.GetProperty("success").GetBoolean();
- if (!success) throw new InvalidDataException(root.GetProperty("msg").GetString());
- var result = root.GetProperty("result").ToString();
+ var root = JObject.Parse(responseString);
+ var success = root.GetValue("success").Value<bool>();
+ if (!success) throw new InvalidDataException(root.ContainsKey("msg") ? root.GetValue("msg").Value<string>() : null);
+ var result = root.GetValue("result").ToString();
return result;
}
}
@@ -176,7 +176,7 @@ namespace com.clusterrr.TuyaNet
{
var uri = "token?grant_type=1";
var response = await RequestAsync(uri, noToken: true);
- var token = JsonSerializer.Deserialize<TuyaToken>(response);
+ var token = JsonConvert.DeserializeObject<TuyaToken>(response);
return token;
}
@@ -201,7 +201,7 @@ namespace com.clusterrr.TuyaNet
{
var uri = $"devices/{deviceId}";
var response = await RequestAsync(uri);
- var device = JsonSerializer.Deserialize<TuyaDeviceApiInfo>(response);
+ var device = JsonConvert.DeserializeObject<TuyaDeviceApiInfo>(response);
return device;
}
@@ -215,7 +215,7 @@ namespace com.clusterrr.TuyaNet
var userId = (await GetDeviceInfoAsync(anyDeviceId)).UserId;
var uri = $"users/{userId}/devices";
var response = await RequestAsync(uri);
- var devices = JsonSerializer.Deserialize<TuyaDeviceApiInfo[]>(response);
+ var devices = JsonConvert.DeserializeObject<TuyaDeviceApiInfo[]>(response);
return devices;
}
}
diff --git a/TuyaDevice.cs b/TuyaDevice.cs
index af17e87..ef37104 100644
--- a/TuyaDevice.cs
+++ b/TuyaDevice.cs
@@ -1,10 +1,11 @@
-using System;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
using System.Text;
-using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
@@ -76,51 +77,20 @@ namespace com.clusterrr.TuyaNet
/// <returns>JSON string with added fields.</returns>
public string FillJson(string json, bool addGwId = true, bool addDevId = true, bool addUid = true, bool addTime = true)
{
- JsonElement foo;
- if (string.IsNullOrWhiteSpace(json)) json = "{}";
- using (MemoryStream memoryStream = new MemoryStream())
- {
- using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(memoryStream))
- {
- using (JsonDocument jsonDocument = JsonDocument.Parse(json))
- {
- utf8JsonWriter.WriteStartObject();
-
- if (addGwId && !jsonDocument.RootElement.TryGetProperty("gwId", out foo))
- {
- utf8JsonWriter.WritePropertyName("gwId");
- utf8JsonWriter.WriteStringValue(DeviceId);
- if (string.IsNullOrWhiteSpace(DeviceId))
- throw new ArgumentNullException("deviceId", "Device ID can't be null.");
- }
- if (addDevId && !jsonDocument.RootElement.TryGetProperty("devId", out foo))
- {
- utf8JsonWriter.WritePropertyName("devId");
- utf8JsonWriter.WriteStringValue(DeviceId);
- if (string.IsNullOrWhiteSpace(DeviceId))
- throw new ArgumentNullException("deviceId", "Device ID can't be null.");
- }
- if (addUid && !jsonDocument.RootElement.TryGetProperty("uid", out foo))
- {
- utf8JsonWriter.WritePropertyName("uid");
- utf8JsonWriter.WriteStringValue(DeviceId);
- if (string.IsNullOrWhiteSpace(DeviceId))
- throw new ArgumentNullException("deviceId", "Device ID can't be null.");
- }
- if (addTime && !jsonDocument.RootElement.TryGetProperty("t", out foo))
- {
- utf8JsonWriter.WritePropertyName("t");
- utf8JsonWriter.WriteStringValue((DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds.ToString("0"));
- }
- foreach (var testDataElement in jsonDocument.RootElement.EnumerateObject())
- {
- testDataElement.WriteTo(utf8JsonWriter);
- }
- utf8JsonWriter.WriteEndObject();
- }
- }
- return Encoding.UTF8.GetString(memoryStream.ToArray());
- }
+ if (string.IsNullOrEmpty(json))
+ json = "{}";
+ var root = JObject.Parse(json);
+ if ((addGwId || addDevId || addUid) && string.IsNullOrWhiteSpace(DeviceId))
+ throw new ArgumentNullException("deviceId", "Device ID can't be null.");
+ if (addTime && !root.ContainsKey("t"))
+ root.AddFirst(new JProperty("t", (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds.ToString("0")));
+ if (addUid && !root.ContainsKey("uid"))
+ root.AddFirst(new JProperty("uid", DeviceId));
+ if (addDevId && !root.ContainsKey("devId"))
+ root.AddFirst(new JProperty("devId", DeviceId));
+ if (addGwId && !root.ContainsKey("gwId"))
+ root.AddFirst(new JProperty("gwId", DeviceId));
+ return root.ToString();
}
/// <summary>
@@ -137,7 +107,7 @@ namespace com.clusterrr.TuyaNet
/// </summary>
/// <param name="data">Raw data to parse and decrypt.</param>
/// <returns>Instance of TuyaLocalResponse.</returns>
- public TuyaLocalResponse DecodeResponse(byte[] data)
+ public TuyaLocalResponse DecodeResponse(byte[] data)
=> TuyaParser.DecodeResponse(data, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
/// <summary>
@@ -177,7 +147,13 @@ namespace com.clusterrr.TuyaNet
await stream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
return await Receive(stream, nullRetries);
}
- catch (Exception ex) when (ex is IOException or TimeoutException)
+ catch (IOException ex)
+ {
+ // sockets sometimes drop the connection unexpectedly, so let's
+ // retry at least once
+ lastException = ex;
+ }
+ catch (TimeoutException ex)
{
// sockets sometimes drop the connection unexpectedly, so let's
// retry at least once
@@ -248,9 +224,9 @@ namespace com.clusterrr.TuyaNet
var response = await SendAsync(TuyaCommand.DP_QUERY, requestJson, retries: 2, nullRetries: 1);
if (string.IsNullOrEmpty(response.JSON))
throw new InvalidDataException("Response is empty");
- var responseJson = JsonDocument.Parse(response.JSON);
- var dps = JsonSerializer.Deserialize<Dictionary<string, object>>(responseJson.RootElement.GetProperty("dps").ToString());
- return new Dictionary<int, object>(dps.Select(kv => new KeyValuePair<int, object>(int.Parse(kv.Key), kv.Value)));
+ var root = JObject.Parse(response.JSON);
+ var dps = JsonConvert.DeserializeObject<Dictionary<string, object>>(root.GetValue("dps").ToString());
+ return dps.ToDictionary(kv => int.Parse(kv.Key), kv => kv.Value);
}
/// <summary>
@@ -273,14 +249,14 @@ namespace com.clusterrr.TuyaNet
{
{ "dps", dps }
};
- string requestJson = JsonSerializer.Serialize(cmd);
+ string requestJson = JsonConvert.SerializeObject(cmd);
requestJson = FillJson(requestJson);
var response = await SendAsync(TuyaCommand.CONTROL, requestJson, retries: 2, nullRetries: 1);
if (string.IsNullOrEmpty(response.JSON))
throw new InvalidDataException("Response is empty");
- var responseJson = JsonDocument.Parse(response.JSON);
- var newDps = JsonSerializer.Deserialize<Dictionary<string, object>>(responseJson.RootElement.GetProperty("dps").ToString());
- return new Dictionary<int, object>(newDps.Select(kv => new KeyValuePair<int, object>(int.Parse(kv.Key), kv.Value)));
+ var root = JObject.Parse(response.JSON);
+ var newDps = JsonConvert.DeserializeObject<Dictionary<string, object>>(root.GetValue("dps").ToString());
+ return newDps.ToDictionary(kv => int.Parse(kv.Key), kv => kv.Value);
}
/// <summary>
diff --git a/TuyaDeviceApiInfo.cs b/TuyaDeviceApiInfo.cs
index 5fd1b29..2b1a3e8 100644
--- a/TuyaDeviceApiInfo.cs
+++ b/TuyaDeviceApiInfo.cs
@@ -1,5 +1,5 @@
-using System.Collections.Generic;
-using System.Text.Json.Serialization;
+using Newtonsoft.Json;
+using System.Collections.Generic;
namespace com.clusterrr.TuyaNet
{
@@ -8,70 +8,70 @@ namespace com.clusterrr.TuyaNet
/// </summary>
public class TuyaDeviceApiInfo
{
- [JsonPropertyName("active_time")]
+ [JsonProperty("active_time")]
public int ActiveTime { get; set; }
- [JsonPropertyName("biz_type")]
+ [JsonProperty("biz_type")]
public int BizType { get; set; }
- [JsonPropertyName("category")]
+ [JsonProperty("category")]
public string Category { get; set; }
- [JsonPropertyName("create_time")]
+ [JsonProperty("create_time")]
public int CreateTime { get; set; }
- [JsonPropertyName("icon")]
+ [JsonProperty("icon")]
public string Icon { get; set; }
- [JsonPropertyName("id")]
+ [JsonProperty("id")]
public string Id { get; set; }
- [JsonPropertyName("ip")]
+ [JsonProperty("ip")]
public string Ip { get; set; }
- [JsonPropertyName("lat")]
+ [JsonProperty("lat")]
public string Lat { get; set; }
- [JsonPropertyName("local_key")]
+ [JsonProperty("local_key")]
public string LocalKey { get; set; }
- [JsonPropertyName("lon")]
+ [JsonProperty("lon")]
public string Lon { get; set; }
- [JsonPropertyName("model")]
+ [JsonProperty("model")]
public string Model { get; set; }
- [JsonPropertyName("name")]
+ [JsonProperty("name")]
public string Name { get; set; }
- [JsonPropertyName("online")]
+ [JsonProperty("online")]
public bool Online { get; set; }
- [JsonPropertyName("owner_id")]
+ [JsonProperty("owner_id")]
public string OwnerId { get; set; }
- [JsonPropertyName("product_id")]
+ [JsonProperty("product_id")]
public string ProductId { get; set; }
- [JsonPropertyName("product_name")]
+ [JsonProperty("product_name")]
public string ProductName { get; set; }
- [JsonPropertyName("status")]
+ [JsonProperty("status")]
public List<TuyaDeviceStatus> Status { get; set; }
- [JsonPropertyName("sub")]
+ [JsonProperty("sub")]
public bool Sub { get; set; }
- [JsonPropertyName("time_zone")]
+ [JsonProperty("time_zone")]
public string TimeZone { get; set; }
- [JsonPropertyName("uid")]
+ [JsonProperty("uid")]
public string UserId { get; set; }
- [JsonPropertyName("update_time")]
+ [JsonProperty("update_time")]
public int UpdateTime { get; set; }
- [JsonPropertyName("uuid")]
+ [JsonProperty("uuid")]
public string Uuid { get; set; }
public override string ToString() => Name;
diff --git a/TuyaDeviceScanInfo.cs b/TuyaDeviceScanInfo.cs
index 84befad..6c513a2 100644
--- a/TuyaDeviceScanInfo.cs
+++ b/TuyaDeviceScanInfo.cs
@@ -1,5 +1,5 @@
-using System;
-using System.Text.Json.Serialization;
+using Newtonsoft.Json;
+using System;
namespace com.clusterrr.TuyaNet
{
@@ -8,28 +8,28 @@ namespace com.clusterrr.TuyaNet
/// </summary>
public class TuyaDeviceScanInfo : IEquatable<TuyaDeviceScanInfo>
{
- [JsonPropertyName("ip")]
+ [JsonProperty("ip")]
public string IP { get; set; } = null;
- [JsonPropertyName("gwId")]
+ [JsonProperty("gwId")]
public string GwId { get; set; } = null;
- [JsonPropertyName("active")]
+ [JsonProperty("active")]
public int Active { get; set; } = 0;
- [JsonPropertyName("ability")]
+ [JsonProperty("ability")]
public int Ability { get; set; } = 0;
- [JsonPropertyName("mode")]
+ [JsonProperty("mode")]
public int Mode { get; set; } = 0;
- [JsonPropertyName("encrypt")]
+ [JsonProperty("encrypt")]
public bool Encryption { get; set; } = false;
- [JsonPropertyName("productKey")]
+ [JsonProperty("productKey")]
public string ProductKey { get; set; } = null;
- [JsonPropertyName("version")]
+ [JsonProperty("version")]
public string Version { get; set; } = null;
public bool Equals(TuyaDeviceScanInfo other)
diff --git a/TuyaDeviceStatus.cs b/TuyaDeviceStatus.cs
index d772afa..6d4ecff 100644
--- a/TuyaDeviceStatus.cs
+++ b/TuyaDeviceStatus.cs
@@ -1,4 +1,4 @@
-using System.Text.Json.Serialization;
+using Newtonsoft.Json;
namespace com.clusterrr.TuyaNet
{
@@ -10,13 +10,13 @@ namespace com.clusterrr.TuyaNet
/// <summary>
/// DPS number
/// </summary>
- [JsonPropertyName("code")]
+ [JsonProperty("code")]
public string Code { get; set; }
/// <summary>
/// DPS value.
/// </summary>
- [JsonPropertyName("value")]
+ [JsonProperty("value")]
public object Value { get; set; }
}
}
diff --git a/TuyaNet.csproj b/TuyaNet.csproj
index 590da8b..2a7aa1f 100644
--- a/TuyaNet.csproj
+++ b/TuyaNet.csproj
@@ -1,15 +1,30 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
- <TargetFramework>net5.0</TargetFramework>
+ <TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace>com.clusterrr.TuyaNet</RootNamespace>
+ <AssemblyName>TuyaNet</AssemblyName>
+ <PackageId>Tuya.Net</PackageId>
<Authors>Alexey "Cluster" Avdyukhin</Authors>
+ <Product>Tuya.Net</Product>
<Description>.NET library to interface with Tuya WiFi smart devices.</Description>
- <Copyright>(c) Cluster, 2021</Copyright>
- <PackageProjectUrl>https://github.com/ClusterM/tuyanet</PackageProjectUrl>
- <RepositoryUrl>https://github.com/ClusterM/tuyanet.git</RepositoryUrl>
- <RepositoryType>GIT</RepositoryType>
- <PackageId>TuyaNet</PackageId>
+ <PackageLicenseFile>LICENSE</PackageLicenseFile>
+ <PackageProjectUrl>https://github.com/ClusterM/tuyanet/</PackageProjectUrl>
+ <RepositoryUrl>https://github.com/ClusterM/tuyanet/</RepositoryUrl>
+ <RepositoryType>Git</RepositoryType>
+ <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
+ <PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
</PropertyGroup>
+ <ItemGroup>
+ <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="LICENSE">
+ <Pack>True</Pack>
+ <PackagePath></PackagePath>
+ </None>
+ </ItemGroup>
+
</Project>
diff --git a/TuyaParser.cs b/TuyaParser.cs
index 8930454..8e22b19 100644
--- a/TuyaParser.cs
+++ b/TuyaParser.cs
@@ -1,4 +1,5 @@
-using System;
+using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -57,6 +58,10 @@ namespace com.clusterrr.TuyaNet
internal static byte[] CreatePayload(TuyaCommand command, string json, byte[] key, TuyaProtocolVersion protocolVersion = TuyaProtocolVersion.V33)
{
+ // Remove spaces and newlines
+ var root = JObject.Parse(json);
+ json = root.ToString(Newtonsoft.Json.Formatting.None);
+
byte[] payload = Encoding.UTF8.GetBytes(json);
if (protocolVersion == TuyaProtocolVersion.V33)
diff --git a/TuyaScanner.cs b/TuyaScanner.cs
index 7e2e1d2..440fe94 100644
--- a/TuyaScanner.cs
+++ b/TuyaScanner.cs
@@ -1,10 +1,10 @@
-using System;
+using Newtonsoft.Json;
+using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
-using System.Text.Json;
using System.Threading;
namespace com.clusterrr.TuyaNet
@@ -129,7 +129,7 @@ namespace com.clusterrr.TuyaNet
private void Parse(string json)
{
- var deviceInfo = JsonSerializer.Deserialize<TuyaDeviceScanInfo>(json);
+ var deviceInfo = JsonConvert.DeserializeObject<TuyaDeviceScanInfo>(json);
OnDeviceInfoReceived?.Invoke(this, deviceInfo);
if ((OnNewDeviceInfoReceived) != null && !devices.Contains(deviceInfo))
{