Format and typos

This commit is contained in:
2025-08-11 18:56:14 -07:00
parent 76ccf20c30
commit 4c6755df31
34 changed files with 1604 additions and 511 deletions

View File

@ -1,84 +1,58 @@
using System.Net.Http.Json;
using GoveeCSharpConnector.Interfaces;
using GoveeCSharpConnector.Objects;
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using GoveeCSharpConnector.Interfaces;
using GoveeCSharpConnector.Objects;
namespace GoveeCSharpConnector.Services;
public class GoveeApiService : IGoveeApiService
{
private string _apiKey = string.Empty;
private const string GoveeApiAddress = "https://developer-api.govee.com/v1";
private readonly HttpClient _httpClient = new();
private readonly JsonSerializerOptions? _jsonOptions = new()
{
public class GoveeApiService : IGoveeApiService {
private string _APIKey = string.Empty;
private const string _GoveeApiAddress = "https://developer-api.govee.com/v1";
private readonly HttpClient _HttpClient = new();
private readonly JsonSerializerOptions _JsonOptions = new() {
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
/// <inheritdoc/>
public void SetApiKey(string apiKey)
{
_apiKey = apiKey;
_httpClient.DefaultRequestHeaders.Add("Govee-API-Key", _apiKey);
public void SetApiKey(string apiKey) {
_APIKey = apiKey;
_HttpClient.DefaultRequestHeaders.Add("Govee-API-Key", _APIKey);
}
/// <inheritdoc/>
public string GetApiKey()
{
return _apiKey;
public string GetApiKey() => _APIKey;
/// <inheritdoc/>
public void RemoveApiKey() {
_APIKey = string.Empty;
_ = _HttpClient.DefaultRequestHeaders.Remove("Govee-Api-Key");
}
/// <inheritdoc/>
public void RemoveApiKey()
{
_apiKey = string.Empty;
_httpClient.DefaultRequestHeaders.Remove("Govee-Api-Key");
}
/// <inheritdoc/>
public async Task<List<GoveeApiDevice>> GetDevices()
{
var response = await _httpClient.GetFromJsonAsync<GoveeResponse>($"{GoveeApiAddress}/devices");
public async Task<List<GoveeApiDevice>> GetDevices() {
GoveeResponse response = await _HttpClient.GetFromJsonAsync<GoveeResponse>($"{_GoveeApiAddress}/devices");
return response.Data.Devices;
}
/// <inheritdoc/>
public async Task<GoveeApiState> GetDeviceState(string deviceId, string deviceModel)
{
return await _httpClient.GetFromJsonAsync<GoveeApiState>($"{GoveeApiAddress}/devices/state?device={deviceId}&model={deviceModel}");
}
public async Task<GoveeApiState> GetDeviceState(string deviceId, string deviceModel) => await _HttpClient.GetFromJsonAsync<GoveeApiState>($"{_GoveeApiAddress}/devices/state?device={deviceId}&model={deviceModel}");
/// <inheritdoc/>
public async Task ToggleState(string deviceId, string deviceModel, bool on)
{
await SendCommand(deviceId, deviceModel, "turn", on ? "on" : "off");
}
public async Task ToggleState(string deviceId, string deviceModel, bool on) => await SendCommand(deviceId, deviceModel, "turn", on ? "on" : "off");
/// <inheritdoc/>
public async Task SetBrightness(string deviceId, string deviceModel, int value)
{
await SendCommand(deviceId, deviceModel, "brightness", value);
}
public async Task SetBrightness(string deviceId, string deviceModel, int value) => await SendCommand(deviceId, deviceModel, "brightness", value);
/// <inheritdoc/>
public async Task SetColor(string deviceId, string deviceModel, RgbColor color)
{
await SendCommand(deviceId, deviceModel, "color", color);
}
public async Task SetColor(string deviceId, string deviceModel, RgbColor color) => await SendCommand(deviceId, deviceModel, "color", color);
/// <inheritdoc/>
public async Task SetColorTemp(string deviceId, string deviceModel, int value)
{
await SendCommand(deviceId, deviceModel, "colorTem", value);
}
public async Task SetColorTemp(string deviceId, string deviceModel, int value) => await SendCommand(deviceId, deviceModel, "colorTem", value);
private async Task SendCommand(string deviceId, string deviceModel, string command, object commandObject)
{
var commandRequest = new GoveeApiCommand()
{
private async Task SendCommand(string deviceId, string deviceModel, string command, object commandObject) {
GoveeApiCommand commandRequest = new() {
Device = deviceId,
Model = deviceModel,
Cmd = new Command()
{
Cmd = new Command() {
Name = command,
Value = commandObject
}
};
var httpContent = new StringContent(JsonSerializer.Serialize(commandRequest, _jsonOptions), Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{GoveeApiAddress}/devices/control", httpContent);
StringContent httpContent = new(JsonSerializer.Serialize(commandRequest, _JsonOptions), Encoding.UTF8, "application/json");
HttpResponseMessage response = await _HttpClient.PutAsync($"{_GoveeApiAddress}/devices/control", httpContent);
if (!response.IsSuccessStatusCode)
throw new Exception($"Govee Api Request failed. Status code: {response.StatusCode}, Message: {response.Content}");
}

View File

@ -3,106 +3,102 @@ using GoveeCSharpConnector.Objects;
namespace GoveeCSharpConnector.Services;
public class GoveeService : IGoveeService
{
public class GoveeService(IGoveeApiService apiService, IGoveeUdpService udpService) : IGoveeService {
public string GoveeApiKey { get; set; }
private readonly IGoveeApiService _apiService;
private readonly IGoveeUdpService _udpService;
private readonly IGoveeApiService _APIService = apiService ?? throw new ArgumentNullException(nameof(apiService));
private readonly IGoveeUdpService _UDPService = udpService ?? throw new ArgumentNullException(nameof(udpService));
public GoveeService(IGoveeApiService apiService,IGoveeUdpService udpService)
{
_apiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
_udpService = udpService ?? throw new ArgumentNullException(nameof(udpService));
}
public async Task<List<GoveeDevice>> GetDevices(bool onlyLan = true)
{
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
public async Task<List<GoveeDevice>> GetDevices(bool onlyLan = true) {
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_APIService.SetApiKey(GoveeApiKey);
var apiDevices = await _apiService.GetDevices();
var devices = apiDevices.Select(apiDevice => new GoveeDevice() { DeviceId = apiDevice.DeviceId, DeviceName = apiDevice.DeviceName, Model = apiDevice.Model, Address = "onlyAvailableOnUdpRequest" }).ToList();
List<GoveeApiDevice> apiDevices = await _APIService.GetDevices();
List<GoveeDevice> devices = apiDevices.Select(apiDevice => new GoveeDevice() { DeviceId = apiDevice.DeviceId, DeviceName = apiDevice.DeviceName, Model = apiDevice.Model, Address = "onlyAvailableOnUdpRequest" }).ToList();
if (!onlyLan)
return devices;
if (!_udpService.IsListening())
_udpService.StartUdpListener();
var udpDevices = await _udpService.GetDevices();
if (!_UDPService.IsListening())
_UDPService.StartUdpListener();
var combinedDevices = (from goveeDevice in devices let matchingDevice = udpDevices.FirstOrDefault(x => x.device == goveeDevice.DeviceId)
where matchingDevice is not null select
new GoveeDevice { DeviceId = goveeDevice.DeviceId, DeviceName = goveeDevice.DeviceName, Model = goveeDevice.Model, Address = matchingDevice.ip }).ToList();
List<GoveeUdpDevice> udpDevices = await _UDPService.GetDevices();
List<GoveeDevice> combinedDevices = (from goveeDevice in devices
let matchingDevice = udpDevices.FirstOrDefault(x => x.Device == goveeDevice.DeviceId)
where matchingDevice is not null
select
new GoveeDevice { DeviceId = goveeDevice.DeviceId, DeviceName = goveeDevice.DeviceName, Model = goveeDevice.Model, Address = matchingDevice.IP }).ToList();
return combinedDevices;
}
public async Task<GoveeState> GetDeviceState(GoveeDevice goveeDevice, bool useUdp = true)
{
if (useUdp)
{
if (!_udpService.IsListening())
_udpService.StartUdpListener();
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) throw new Exception("Device not available via Udp/Lan");
var udpState = await _udpService.GetState(goveeDevice.Address);
return new GoveeState() { State = udpState.onOff, Brightness = udpState.brightness, Color = udpState.color, ColorTempInKelvin = udpState.colorTempInKelvin };
public async Task<GoveeState> GetDeviceState(GoveeDevice goveeDevice, bool useUdp = true) {
if (useUdp) {
if (!_UDPService.IsListening())
_UDPService.StartUdpListener();
if (string.IsNullOrWhiteSpace(goveeDevice.Address))
throw new Exception("Device not available via Udp/Lan");
GoveeUdpState udpState = await _UDPService.GetState(goveeDevice.Address);
return new GoveeState() { State = udpState.OnOff, Brightness = udpState.Brightness, Color = udpState.Color, ColorTempInKelvin = udpState.ColorTempInKelvin };
}
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
var apiState = await _apiService.GetDeviceState(goveeDevice.DeviceId, goveeDevice.Model);
return new GoveeState{State = apiState.Properties.PowerState, Brightness = apiState.Properties.Brightness, Color = apiState.Properties.Color, ColorTempInKelvin = apiState.Properties.ColorTemp};
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_APIService.SetApiKey(GoveeApiKey);
GoveeApiState apiState = await _APIService.GetDeviceState(goveeDevice.DeviceId, goveeDevice.Model);
return new GoveeState { State = apiState.Properties.PowerState, Brightness = apiState.Properties.Brightness, Color = apiState.Properties.Color, ColorTempInKelvin = apiState.Properties.ColorTemp };
}
public async Task ToggleState(GoveeDevice goveeDevice, bool on, bool useUdp = true)
{
if (useUdp)
{
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) throw new Exception("Device not available via Udp/Lan");
await _udpService.ToggleDevice(goveeDevice.Address, on);
public async Task ToggleState(GoveeDevice goveeDevice, bool on, bool useUdp = true) {
if (useUdp) {
if (string.IsNullOrWhiteSpace(goveeDevice.Address))
throw new Exception("Device not available via Udp/Lan");
_UDPService.ToggleDevice(goveeDevice.Address, on);
return;
}
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
await _apiService.ToggleState(goveeDevice.DeviceId, goveeDevice.Model, on);
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_APIService.SetApiKey(GoveeApiKey);
await _APIService.ToggleState(goveeDevice.DeviceId, goveeDevice.Model, on);
}
public async Task SetBrightness(GoveeDevice goveeDevice, int value, bool useUdp = true)
{
if (useUdp)
{
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) throw new Exception("Device not available via Udp/Lan");
await _udpService.SetBrightness(goveeDevice.Address, value);
public async Task SetBrightness(GoveeDevice goveeDevice, int value, bool useUdp = true) {
if (useUdp) {
if (string.IsNullOrWhiteSpace(goveeDevice.Address))
throw new Exception("Device not available via Udp/Lan");
_UDPService.SetBrightness(goveeDevice.Address, value);
return;
}
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
await _apiService.SetBrightness(goveeDevice.DeviceId, goveeDevice.Model, value);
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_APIService.SetApiKey(GoveeApiKey);
await _APIService.SetBrightness(goveeDevice.DeviceId, goveeDevice.Model, value);
}
public async Task SetColor(GoveeDevice goveeDevice, RgbColor color, bool useUdp = true)
{
if (useUdp)
{
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) throw new Exception("Device not available via Udp/Lan");
await _udpService.SetColor(goveeDevice.Address, color);
public async Task SetColor(GoveeDevice goveeDevice, RgbColor color, bool useUdp = true) {
if (useUdp) {
if (string.IsNullOrWhiteSpace(goveeDevice.Address))
throw new Exception("Device not available via Udp/Lan");
_UDPService.SetColor(goveeDevice.Address, color);
return;
}
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
await _apiService.SetColor(goveeDevice.DeviceId, goveeDevice.Model, color);
_APIService.SetApiKey(GoveeApiKey);
await _APIService.SetColor(goveeDevice.DeviceId, goveeDevice.Model, color);
}
public async Task SetColorTemp(GoveeDevice goveeDevice, int value, bool useUdp = true)
{
if (useUdp)
{
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) throw new Exception("Device not available via Udp/Lan");
await _udpService.SetColorTemp(goveeDevice.Address, value);
public async Task SetColorTemp(GoveeDevice goveeDevice, int value, bool useUdp = true) {
if (useUdp) {
if (string.IsNullOrWhiteSpace(goveeDevice.Address))
throw new Exception("Device not available via Udp/Lan");
_UDPService.SetColorTemp(goveeDevice.Address, value);
return;
}
if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
_apiService.SetApiKey(GoveeApiKey);
await _apiService.SetColorTemp(goveeDevice.DeviceId, goveeDevice.Model, value);
if (string.IsNullOrWhiteSpace(GoveeApiKey))
throw new Exception("No Govee Api Key Set!");
_APIService.SetApiKey(GoveeApiKey);
await _APIService.SetColorTemp(goveeDevice.DeviceId, goveeDevice.Model, value);
}
}

View File

@ -1,95 +1,79 @@
using System.Net;
using GoveeCSharpConnector.Interfaces;
using GoveeCSharpConnector.Objects;
using System.Net;
using System.Net.Sockets;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using System.Text;
using System.Text.Json;
using GoveeCSharpConnector.Interfaces;
using GoveeCSharpConnector.Objects;
namespace GoveeCSharpConnector.Services;
public class GoveeUdpService : IGoveeUdpService
{
private const string GoveeMulticastAddress = "239.255.255.250";
private const int GoveeMulticastPortListen = 4002;
private const int GoveeMulticastPortSend = 4001;
private readonly UdpClient _udpClient = new();
private bool _udpListenerActive = true;
public class GoveeUdpService : IGoveeUdpService {
private const string _GoveeMulticastAddress = "239.255.255.250";
private const int _GoveeMulticastPortListen = 4002;
private const int _GoveeMulticastPortSend = 4001;
private readonly UdpClient _UDPClient = new();
private bool _UDPListenerActive = true;
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1);
private readonly Subject<string> _messageSubject = new();
private readonly Subject<GoveeUdpDevice> _scanResultSubject = new();
private readonly Subject<GoveeUdpState> _stateResultSubject = new();
private readonly SemaphoreSlim _Semaphore = new(1, 1);
private readonly Subject<string> _MessageSubject = new();
private readonly Subject<GoveeUdpDevice> _ScanResultSubject = new();
private readonly Subject<GoveeUdpState> _StateResultSubject = new();
public IObservable<string> Messages => _messageSubject;
public IObservable<string> Messages => _MessageSubject;
public GoveeUdpService()
{
SetupUdpClientListener();
}
public GoveeUdpService() => SetupUdpClientListener();
/// <inheritdoc/>
public async Task<List<GoveeUdpDevice>> GetDevices(TimeSpan? timeout = null)
{
if (!_udpListenerActive)
public async Task<List<GoveeUdpDevice>> GetDevices(TimeSpan? timeout = null) {
if (!_UDPListenerActive)
throw new Exception("Udp Listener not started!");
// Block this Method until current call reaches end of Method
await _semaphore.WaitAsync();
_Semaphore.Wait();
try
{
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "scan",
data = new { account_topic = "reserve" }
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "scan",
Data = new { account_topic = "reserve" }
}
};
// Subscribe to ScanResultSubject
var devicesTask = _scanResultSubject
Task<IList<GoveeUdpDevice>> devicesTask = _ScanResultSubject
.TakeUntil(Observable.Timer(timeout ?? TimeSpan.FromMilliseconds(250)))
.ToList()
.ToTask();
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), GoveeMulticastAddress, GoveeMulticastPortSend);
SendUdpMessage(JsonSerializer.Serialize(message), _GoveeMulticastAddress, _GoveeMulticastPortSend);
// Return List
return (await devicesTask).ToList();
}
catch (Exception e)
{
return [.. (await devicesTask)];
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
finally
{
} finally {
// Release Method Block
_semaphore.Release();
_ = _Semaphore.Release();
}
}
/// <inheritdoc/>
public async Task<GoveeUdpState> GetState(string deviceAddress, int uniCastPort = 4003, TimeSpan? timeout = null)
{
if (!_udpListenerActive)
public async Task<GoveeUdpState> GetState(string deviceAddress, int uniCastPort = 4003, TimeSpan? timeout = null) {
if (!_UDPListenerActive)
throw new Exception("Udp Listener not started!");
try
{
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "devStatus",
data = new { }
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "devStatus",
Data = new { }
}
};
// Subscribe to ScanResultSubject
var devicesTask = _stateResultSubject
Task<GoveeUdpState> devicesTask = _StateResultSubject
.TakeUntil(Observable.Timer(timeout ?? TimeSpan.FromMilliseconds(250)))
.ToTask();
@ -98,75 +82,56 @@ public class GoveeUdpService : IGoveeUdpService
// Return state
return await devicesTask;
}
catch (Exception e)
{
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async Task ToggleDevice(string deviceAddress, bool on, int uniCastPort = 4003)
{
try
{
public void ToggleDevice(string deviceAddress, bool on, int uniCastPort = 4003) {
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "turn",
data = new { value = on ? 1 : 0 }
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "turn",
Data = new { value = on ? 1 : 0 }
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async Task SetBrightness(string deviceAddress, int brightness, int uniCastPort = 4003)
{
try
{
public void SetBrightness(string deviceAddress, int brightness, int uniCastPort = 4003) {
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "brightness",
data = new { value = brightness }
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "brightness",
Data = new { value = brightness }
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async Task SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003)
{
try
{
public void SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003) {
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "colorwc",
data = new
{ color = new
{
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "colorwc",
Data = new {
color = new {
r = color.R,
g = color.G,
b = color.B
@ -177,131 +142,103 @@ public class GoveeUdpService : IGoveeUdpService
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
}
public async Task SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003)
{
try
{
public void SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003) {
try {
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "colorwc",
data = new
{
color = new
{
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "colorwc",
Data = new {
color = new {
r = 0,
g = 0,
b = 0
},
colorTempInKelvin = colorTempInKelvin
colorTempInKelvin
}
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async void StartUdpListener()
{
_udpListenerActive = true;
public async void StartUdpListener() {
_UDPListenerActive = true;
await StartListener();
}
/// <inheritdoc/>
public bool IsListening()
{
return _udpListenerActive;
}
public bool IsListening() => _UDPListenerActive;
/// <inheritdoc/>
public void StopUdpListener()
{
_udpListenerActive = false;
_udpClient.DropMulticastGroup(IPAddress.Parse(GoveeMulticastAddress));
_udpClient.Close();
public void StopUdpListener() {
_UDPListenerActive = false;
_UDPClient.DropMulticastGroup(IPAddress.Parse(_GoveeMulticastAddress));
_UDPClient.Close();
}
private static void SendUdpMessage(string message, string receiverAddress, int receiverPort)
{
var client = new UdpClient();
try
{
private static void SendUdpMessage(string message, string receiverAddress, int receiverPort) {
UdpClient client = new();
try {
byte[] data = Encoding.UTF8.GetBytes(message);
client.Send(data, data.Length, receiverAddress, receiverPort);
}
catch (Exception e)
{
_ = client.Send(data, data.Length, receiverAddress, receiverPort);
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
finally
{
} finally {
client.Close();
}
}
private async void SetupUdpClientListener()
{
_udpClient.ExclusiveAddressUse = false;
var localEndPoint = new IPEndPoint(IPAddress.Any, GoveeMulticastPortListen);
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_udpClient.Client.Bind(localEndPoint);
private async void SetupUdpClientListener() {
_UDPClient.ExclusiveAddressUse = false;
IPEndPoint localEndPoint = new(IPAddress.Any, _GoveeMulticastPortListen);
_UDPClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_UDPClient.Client.Bind(localEndPoint);
await StartListener();
}
private async Task StartListener()
{
try
{
_udpClient.JoinMulticastGroup(IPAddress.Parse(GoveeMulticastAddress));
private async Task StartListener() {
try {
_UDPClient.JoinMulticastGroup(IPAddress.Parse(_GoveeMulticastAddress));
Task.Run(async () =>
{
while (_udpListenerActive)
{
var remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
var data = _udpClient.Receive(ref remoteEndPoint);
await Task.Run(() => {
while (_UDPListenerActive) {
IPEndPoint remoteEndPoint = new(IPAddress.Any, 0);
byte[] data = _UDPClient.Receive(ref remoteEndPoint);
var message = Encoding.UTF8.GetString(data);
string message = Encoding.UTF8.GetString(data);
UdPMessageReceived(message);
_messageSubject.OnNext(message);
_MessageSubject.OnNext(message);
}
return Task.CompletedTask;
});
}
catch(Exception ex)
{
} catch (Exception ex) {
throw ex;
}
}
private void UdPMessageReceived(string message)
{
var response = JsonSerializer.Deserialize<GoveeUdpMessage>(message);
switch (response.msg.cmd)
{
private void UdPMessageReceived(string message) {
GoveeUdpMessage response = JsonSerializer.Deserialize<GoveeUdpMessage>(message);
switch (response.Msg.Cmd) {
case "scan":
var device = JsonSerializer.Deserialize<GoveeUdpDevice>(response.msg.data.ToString());
_scanResultSubject.OnNext(device);
GoveeUdpDevice device = JsonSerializer.Deserialize<GoveeUdpDevice>(response.Msg.Data.ToString());
_ScanResultSubject.OnNext(device);
break;
case "devStatus":
var state = JsonSerializer.Deserialize<GoveeUdpState>(response.msg.data.ToString());
_stateResultSubject.OnNext(state);
GoveeUdpState state = JsonSerializer.Deserialize<GoveeUdpState>(response.Msg.Data.ToString());
_StateResultSubject.OnNext(state);
break;
}
}