diff options
author | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2021-10-26 15:53:30 +0300 |
---|---|---|
committer | Alexey 'Cluster' Avdyukhin <clusterrr@clusterrr.com> | 2021-10-26 15:53:30 +0300 |
commit | e7b97d1ba238cfdf0ae7c60b8b21367104ff5e6e (patch) | |
tree | ef5bec06ae2b64f16972b1d05aa853c94f3d2162 /TuyaScanner.cs | |
parent | a72b427c2ccfbbacd563e5890ef10c22e2a6409e (diff) |
TuyaScanner
Diffstat (limited to 'TuyaScanner.cs')
-rw-r--r-- | TuyaScanner.cs | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/TuyaScanner.cs b/TuyaScanner.cs new file mode 100644 index 0000000..657da7a --- /dev/null +++ b/TuyaScanner.cs @@ -0,0 +1,123 @@ +using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+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 TuyaScanner
+ {
+ private const ushort UDP_PORT31 = 6666; // Tuya 3.1 UDP Port
+ private const ushort UDP_PORTS33 = 6667; // Tuya 3.3 encrypted UDP Port
+ private const string UDP_KEY = "yGAdlopoPVldABfn";
+
+ private bool running = false;
+ private UdpClient udpServer31 = null;
+ private UdpClient udpServer33 = null;
+ private Thread udpListener31 = null;
+ private Thread udpListener33 = null;
+ private List<TuyaDeviceInfo> devices = new List<TuyaDeviceInfo>();
+
+ public event EventHandler<TuyaDeviceInfo> OnDeviceInfoReceived;
+ public event EventHandler<TuyaDeviceInfo> OnNewDeviceInfoReceived;
+
+ public void Start()
+ {
+ Stop();
+ running = true;
+ devices.Clear();
+ udpServer31 = new UdpClient(UDP_PORT31);
+ udpServer33 = new UdpClient(UDP_PORTS33);
+ udpListener31 = new Thread(UdpListener31Thread);
+ udpListener33 = new Thread(UdpListener33Thread);
+ udpListener31.Start(udpServer31);
+ udpListener33.Start(udpServer33);
+ }
+
+ public void Stop()
+ {
+ running = false;
+ if (udpServer31 != null)
+ {
+ udpServer31.Dispose();
+ udpServer31 = null;
+ }
+ if (udpServer33 != null)
+ {
+ udpServer33.Dispose();
+ udpServer33 = null;
+ }
+ udpListener31 = null;
+ udpListener33 = null;
+ }
+
+ private void UdpListener31Thread(object o)
+ {
+ var udpServer = o as UdpClient;
+ byte[] udp_key;
+ using (var md5 = MD5.Create())
+ {
+ udp_key = md5.ComputeHash(Encoding.ASCII.GetBytes(UDP_KEY));
+ }
+
+ while (running)
+ {
+ try
+ {
+ IPEndPoint ep = null;
+ var data = udpServer.Receive(ref ep);
+ var response = TuyaParser.DecodeResponse(data, udp_key, TuyaProtocolVersion.V31);
+ Parse(response.JSON);
+ }
+ catch
+ {
+ if (!running) return;
+ throw;
+ }
+ }
+ }
+
+ private void UdpListener33Thread(object o)
+ {
+ var udpServer = o as UdpClient;
+ byte[] udp_key;
+ using (var md5 = MD5.Create())
+ {
+ udp_key = md5.ComputeHash(Encoding.ASCII.GetBytes(UDP_KEY));
+ }
+
+ while (running)
+ {
+ try
+ {
+ IPEndPoint ep = null;
+ var data = udpServer.Receive(ref ep);
+ var response = TuyaParser.DecodeResponse(data, udp_key, TuyaProtocolVersion.V33);
+ Parse(response.JSON);
+ }
+ catch
+ {
+ if (!running) return;
+ throw;
+ }
+ }
+ }
+
+ private void Parse(string json)
+ {
+ var deviceInfo = JsonSerializer.Deserialize<TuyaDeviceInfo>(json);
+ OnDeviceInfoReceived?.Invoke(this, deviceInfo);
+ if ((OnNewDeviceInfoReceived) != null && !devices.Contains(deviceInfo))
+ {
+ devices.Add(deviceInfo);
+ OnNewDeviceInfoReceived?.Invoke(this, deviceInfo);
+ }
+ }
+ }
+}
|