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-27 16:47:50 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2021-10-27 16:47:50 +0300
commitcffc3a33ba3211f431861d5a78716cdcee5bdd09 (patch)
treeb025583d86b33a9f47baa4456626ce85a0dbc855 /TuyaDevice.cs
parent56ba3bf92decc1fd166d2207bd8326dfc32e2e0a (diff)
New device methods
Diffstat (limited to 'TuyaDevice.cs')
-rw-r--r--TuyaDevice.cs74
1 files changed, 66 insertions, 8 deletions
diff --git a/TuyaDevice.cs b/TuyaDevice.cs
index 7fd10d6..748219d 100644
--- a/TuyaDevice.cs
+++ b/TuyaDevice.cs
@@ -5,25 +5,28 @@ using System.Linq;
using System.Net.Sockets;
using System.Security.Cryptography;
using System.Text;
+using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace com.clusterrr.TuyaNet
{
- public class TuyaDevice
+ public class TuyaDevice : IDisposable
{
- public TuyaDevice(string ip, string localKey, TuyaProtocolVersion protocolVersion = TuyaProtocolVersion.V33, int port = 6668, int receiveTimeout = 250)
+ public TuyaDevice(string ip, string localKey, string deviceId = null, TuyaProtocolVersion protocolVersion = TuyaProtocolVersion.V33, int port = 6668, int receiveTimeout = 250)
{
IP = ip;
LocalKey = localKey;
+ DeviceId = deviceId;
ProtocolVersion = protocolVersion;
Port = port;
ReceiveTimeout = receiveTimeout;
}
- public string IP { get; set; }
- public string LocalKey { get; set; }
- public int Port { get; set; } = 6668;
+ public string IP { get; private set; }
+ public string LocalKey { get; private set; }
+ public int Port { get; private set; } = 6668;
+ public string DeviceId { get; private set; } = null;
public TuyaProtocolVersion ProtocolVersion { get; set; }
public int ReceiveTimeout { get; set; }
public bool PermanentConnection { get; set; } = false;
@@ -32,9 +35,11 @@ namespace com.clusterrr.TuyaNet
public byte[] CreatePayload(TuyaCommand command, string json)
=> TuyaParser.CreatePayload(command, json, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
+
public TuyaLocalResponse DecodeResponse(byte[] data)
- => TuyaParser.DecodeResponse(data, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
- public async Task<TuyaLocalResponse> Send(TuyaCommand command, string json, int tries = 2, int nullRetries = 1)
+
+ => TuyaParser.DecodeResponse(data, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
+ public async Task<TuyaLocalResponse> SendAsync(TuyaCommand command, string json, int tries = 2, int nullRetries = 1)
=> DecodeResponse(await SendAsync(CreatePayload(command, json), tries, nullRetries));
public async Task<byte[]> SendAsync(byte[] data, int tries = 2, int nullRetries = 1)
@@ -56,7 +61,7 @@ namespace com.clusterrr.TuyaNet
await stream.WriteAsync(data, 0, data.Length).ConfigureAwait(false);
return await Receive(stream, nullRetries);
}
- catch (IOException ex)
+ catch (Exception ex) when (ex is IOException or TimeoutException)
{
// sockets sometimes drop the connection unexpectedly, so let's
// retry at least once
@@ -116,5 +121,58 @@ namespace com.clusterrr.TuyaNet
}
return result;
}
+
+ public async Task<Dictionary<int, object>> GetDps(string deviceId = null)
+ {
+ deviceId = deviceId ?? DeviceId;
+ if (string.IsNullOrEmpty(deviceId))
+ throw new ArgumentException("deviceId is not specified", "deviceId");
+ var cmd = new Dictionary<string, object>
+ {
+ { "gwId", deviceId },
+ { "devId", deviceId },
+ { "uid", deviceId },
+ { "t", (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds.ToString("0") }
+ };
+ string requestJson = JsonSerializer.Serialize(cmd);
+ var response = await SendAsync(TuyaCommand.CONTROL, requestJson, tries: 2, nullRetries: 2);
+ 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)));
+ }
+
+ public async Task<Dictionary<int, object>> SetDps(int dpsNumber, object value, string deviceId = null)
+ => await SetDps(new Dictionary<int, object> { { dpsNumber, value } }, deviceId);
+
+ public async Task<Dictionary<int, object>> SetDps(Dictionary<int, object> dps, string deviceId = null)
+ {
+ deviceId = deviceId ?? DeviceId;
+ if (string.IsNullOrEmpty(deviceId))
+ throw new ArgumentException("deviceId is not specified", "deviceId");
+ var cmd = new Dictionary<string, object>
+ {
+ { "gwId", deviceId },
+ { "devId", deviceId },
+ { "uid", deviceId },
+ { "t", (DateTime.Now - new DateTime(1970, 1, 1)).TotalSeconds.ToString("0") },
+ { "dps", dps }
+ };
+ string requestJson = JsonSerializer.Serialize(cmd);
+ var response = await SendAsync(TuyaCommand.CONTROL, requestJson, tries: 2, nullRetries: 2);
+ 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)));
+ }
+
+ public void Dispose()
+ {
+ client?.Close();
+ client?.Dispose();
+ client = null;
+ }
}
}