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 17:34:46 +0300
committerAlexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com>2021-10-27 17:36:41 +0300
commit3960735f1b6a00c8d732b20db55e204e8abf0d04 (patch)
treeb0c44cdf41d3d9145732ea7844515d29f5b58c1a /TuyaDevice.cs
parentcffc3a33ba3211f431861d5a78716cdcee5bdd09 (diff)
Comments and minor fixes
Diffstat (limited to 'TuyaDevice.cs')
-rw-r--r--TuyaDevice.cs91
1 files changed, 85 insertions, 6 deletions
diff --git a/TuyaDevice.cs b/TuyaDevice.cs
index 748219d..414eeb4 100644
--- a/TuyaDevice.cs
+++ b/TuyaDevice.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Sockets;
-using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Threading;
@@ -11,8 +10,20 @@ using System.Threading.Tasks;
namespace com.clusterrr.TuyaNet
{
+ /// <summary>
+ /// Connection with Tuya device.
+ /// </summary>
public class TuyaDevice : IDisposable
{
+ /// <summary>
+ /// Creates a new instance of the TuyaDevice class.
+ /// </summary>
+ /// <param name="ip">IP address of device.</param>
+ /// <param name="localKey">Local key of device (obtained via API).</param>
+ /// <param name="deviceId">Device ID.</param>
+ /// <param name="protocolVersion">Protocol version.</param>
+ /// <param name="port">TCP port of device.</param>
+ /// <param name="receiveTimeout">Receive timeout.</param>
public TuyaDevice(string ip, string localKey, string deviceId = null, TuyaProtocolVersion protocolVersion = TuyaProtocolVersion.V33, int port = 6668, int receiveTimeout = 250)
{
IP = ip;
@@ -23,25 +34,72 @@ namespace com.clusterrr.TuyaNet
ReceiveTimeout = receiveTimeout;
}
+ /// <summary>
+ /// IP address of device.
+ /// </summary>
public string IP { get; private set; }
+ /// <summary>
+ /// Local key of device.
+ /// </summary>
public string LocalKey { get; private set; }
- public int Port { get; private set; } = 6668;
+ /// <summary>
+ /// Device ID.
+ /// </summary>
public string DeviceId { get; private set; } = null;
+ /// <summary>
+ /// TCP port of device.
+ /// </summary>
+ public int Port { get; private set; } = 6668;
+ /// <summary>
+ /// Protocol version.
+ /// </summary>
public TuyaProtocolVersion ProtocolVersion { get; set; }
+ /// <summary>
+ /// Receive timeout.
+ /// </summary>
public int ReceiveTimeout { get; set; }
+ /// <summary>
+ /// Permanent connection (connect and stay connected).
+ /// </summary>
public bool PermanentConnection { get; set; } = false;
private TcpClient client = null;
+ /// <summary>
+ /// Creates encoded and encrypted payload data from JSON string.
+ /// </summary>
+ /// <param name="command">Tuya command ID.</param>
+ /// <param name="json">String with JSON to send.</param>
+ /// <returns>Raw data.</returns>
public byte[] CreatePayload(TuyaCommand command, string json)
=> TuyaParser.CreatePayload(command, json, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
- public TuyaLocalResponse DecodeResponse(byte[] data)
-
+ /// <summary>
+ /// Parses and decrypts payload data from received bytes.
+ /// </summary>
+ /// <param name="data">.</param>
+ /// <returns>Instance of TuyaLocalResponse.</returns>
+ public TuyaLocalResponse DecodeResponse(byte[] data)
=> TuyaParser.DecodeResponse(data, Encoding.UTF8.GetBytes(LocalKey), ProtocolVersion);
+
+ /// <summary>
+ /// Sends JSON string to device and reads response.
+ /// </summary>
+ /// <param name="command">Tuya command ID.</param>
+ /// <param name="json">JSON string.</param>
+ /// <param name="command">Tuya command ID.</param>
+ /// <param name="json">String with JSON to send.</param>
+ /// <returns>Parsed and decrypred received data as instance of TuyaLocalResponse.</returns>
public async Task<TuyaLocalResponse> SendAsync(TuyaCommand command, string json, int tries = 2, int nullRetries = 1)
=> DecodeResponse(await SendAsync(CreatePayload(command, json), tries, nullRetries));
+ /// <summary>
+ /// Sends raw data over to device and read response.
+ /// </summary>
+ /// <param name="data">Raw data to send.</param>
+ /// <param name="tries">Number of retries.</param>
+ /// <param name="nullRetries">Number of retries in case of null answer.</param>
+ /// <returns>Received data (raw).</returns>
public async Task<byte[]> SendAsync(byte[] data, int tries = 2, int nullRetries = 1)
{
Exception lastException = null;
@@ -122,6 +180,11 @@ namespace com.clusterrr.TuyaNet
return result;
}
+ /// <summary>
+ /// Requests current DPS status.
+ /// </summary>
+ /// <param name="deviceId">Device ID, required only if constuctor was called without it.</param>
+ /// <returns>Dictionary of DPS numbers and values.</returns>
public async Task<Dictionary<int, object>> GetDps(string deviceId = null)
{
deviceId = deviceId ?? DeviceId;
@@ -135,7 +198,7 @@ namespace com.clusterrr.TuyaNet
{ "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);
+ var response = await SendAsync(TuyaCommand.CONTROL, requestJson, tries: 2, nullRetries: 1);
if (string.IsNullOrEmpty(response.JSON))
throw new InvalidDataException("Response is empty");
var responseJson = JsonDocument.Parse(response.JSON);
@@ -143,9 +206,22 @@ namespace com.clusterrr.TuyaNet
return new Dictionary<int, object>(dps.Select(kv => new KeyValuePair<int, object>(int.Parse(kv.Key), kv.Value)));
}
+ /// <summary>
+ /// Sets DPS to specified value.
+ /// </summary>
+ /// <param name="dpsNumber">DPS number.</param>
+ /// <param name="value">Value.</param>
+ /// <param name="deviceId">Device ID, required only if constuctor was called without it.</param>
+ /// <returns></returns>
public async Task<Dictionary<int, object>> SetDps(int dpsNumber, object value, string deviceId = null)
=> await SetDps(new Dictionary<int, object> { { dpsNumber, value } }, deviceId);
+ /// <summary>
+ /// Sets DPS to specified value.
+ /// </summary>
+ /// <param name="dps">Dictionary of DPS numbers and values to set.</param>
+ /// <param name="deviceId">Device ID, required only if constuctor was called without it.</param>
+ /// <returns></returns>
public async Task<Dictionary<int, object>> SetDps(Dictionary<int, object> dps, string deviceId = null)
{
deviceId = deviceId ?? DeviceId;
@@ -160,7 +236,7 @@ namespace com.clusterrr.TuyaNet
{ "dps", dps }
};
string requestJson = JsonSerializer.Serialize(cmd);
- var response = await SendAsync(TuyaCommand.CONTROL, requestJson, tries: 2, nullRetries: 2);
+ var response = await SendAsync(TuyaCommand.CONTROL, requestJson, tries: 2, nullRetries: 1);
if (string.IsNullOrEmpty(response.JSON))
throw new InvalidDataException("Response is empty");
var responseJson = JsonDocument.Parse(response.JSON);
@@ -168,6 +244,9 @@ namespace com.clusterrr.TuyaNet
return new Dictionary<int, object>(newDps.Select(kv => new KeyValuePair<int, object>(int.Parse(kv.Key), kv.Value)));
}
+ /// <summary>
+ /// Disposes object.
+ /// </summary>
public void Dispose()
{
client?.Close();