diff options
author | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2021-10-27 16:47:50 +0300 |
---|---|---|
committer | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2021-10-27 16:47:50 +0300 |
commit | cffc3a33ba3211f431861d5a78716cdcee5bdd09 (patch) | |
tree | b025583d86b33a9f47baa4456626ce85a0dbc855 /TuyaDevice.cs | |
parent | 56ba3bf92decc1fd166d2207bd8326dfc32e2e0a (diff) |
New device methods
Diffstat (limited to 'TuyaDevice.cs')
-rw-r--r-- | TuyaDevice.cs | 74 |
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;
+ }
}
}
|