Typos, format and async consistency

This commit is contained in:
2025-08-12 18:28:00 -07:00
parent 76ccf20c30
commit 17cb171e36
35 changed files with 1937 additions and 907 deletions

View File

@ -1,85 +1,65 @@
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()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
/// <inheritdoc/>
public void SetApiKey(string apiKey)
{
_apiKey = apiKey;
_httpClient.DefaultRequestHeaders.Add("Govee-API-Key", _apiKey);
}
/// <inheritdoc/>
public string GetApiKey()
{
return _apiKey;
}
/// <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");
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}");
}
/// <inheritdoc/>
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);
}
/// <inheritdoc/>
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 class GoveeApiService : IGoveeApiService {
private string _APIKey = string.Empty;
private readonly HttpClient _HttpClient = new();
private const string _GoveeApiAddress = "https://developer-api.govee.com/v1";
public string GetApiKey() =>
_APIKey;
public void SetApiKey(string apiKey) {
_APIKey = apiKey;
_HttpClient.DefaultRequestHeaders.Add("Govee-API-Key", _APIKey);
}
private async Task SendCommand(string deviceId, string deviceModel, string command, object commandObject)
{
var commandRequest = new GoveeApiCommand()
{
public void RemoveApiKey() {
_APIKey = string.Empty;
_ = _HttpClient.DefaultRequestHeaders.Remove("Govee-Api-Key");
}
private readonly JsonSerializerOptions _JsonOptions = new() {
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
public Task<HttpResponseMessage> ToggleStateAsync(string deviceId, string deviceModel, bool on) =>
SendCommandAsync(deviceId, deviceModel, "turn", on ? "on" : "off");
public Task<HttpResponseMessage> SetBrightnessAsync(string deviceId, string deviceModel, int value) =>
SendCommandAsync(deviceId, deviceModel, "brightness", value);
public Task<HttpResponseMessage> SetColorAsync(string deviceId, string deviceModel, RgbColor color) =>
SendCommandAsync(deviceId, deviceModel, "color", color);
public Task<HttpResponseMessage> SetColorTempAsync(string deviceId, string deviceModel, int value) =>
SendCommandAsync(deviceId, deviceModel, "colorTem", value);
public Task<GoveeResponse> GetDevicesResponseAsync() =>
_HttpClient.GetFromJsonAsync<GoveeResponse>($"{_GoveeApiAddress}/devices");
public Task<GoveeApiState> GetDeviceStateAsync(string deviceId, string deviceModel) =>
_HttpClient.GetFromJsonAsync<GoveeApiState>($"{_GoveeApiAddress}/devices/state?device={deviceId}&model={deviceModel}");
private Task<HttpResponseMessage> SendCommandAsync(string deviceId, string deviceModel, string command, object commandObject) {
Task<HttpResponseMessage> result;
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);
if (!response.IsSuccessStatusCode)
throw new Exception($"Govee Api Request failed. Status code: {response.StatusCode}, Message: {response.Content}");
StringContent httpContent = new(JsonSerializer.Serialize(commandRequest, _JsonOptions), Encoding.UTF8, "application/json");
result = _HttpClient.PutAsync($"{_GoveeApiAddress}/devices/control", httpContent);
return result;
}
}

View File

@ -1,108 +1,149 @@
using GoveeCSharpConnector.Interfaces;
using GoveeCSharpConnector.Objects;
using System.Collections.ObjectModel;
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);
var apiDevices = await _apiService.GetDevices();
var devices = apiDevices.Select(apiDevice => new GoveeDevice() { DeviceId = apiDevice.DeviceId, DeviceName = apiDevice.DeviceName, Model = apiDevice.Model, Address = "onlyAvailableOnUdpRequest" }).ToList();
if (!onlyLan)
public List<GoveeDevice> GetDevices(bool onlyLan = true) {
if (string.IsNullOrWhiteSpace(GoveeApiKey)) {
throw new Exception("No Govee Api Key Set!");
}
_APIService.SetApiKey(GoveeApiKey);
Task<GoveeResponse> goveeResponse = _APIService.GetDevicesResponseAsync();
goveeResponse.Wait();
List<GoveeApiDevice> apiDevices = goveeResponse.Result.Data.Devices;
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();
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();
}
if (!_UDPService.IsListening()) {
Task task = _UDPService.StartUdpListenerAsync();
task.Wait();
}
Task<IList<GoveeUdpDevice>> goveeUdpDevicesTask = _UDPService.GetDevicesAsync();
goveeUdpDevicesTask.Wait();
ReadOnlyCollection<GoveeUdpDevice> udpDevices = new(goveeUdpDevicesTask.Result);
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 GoveeState GetDeviceState(GoveeDevice goveeDevice, bool useUdp = true) {
if (useUdp) {
if (!_UDPService.IsListening()) {
Task task = _UDPService.StartUdpListenerAsync();
task.Wait();
}
if (string.IsNullOrWhiteSpace(goveeDevice.Address)) {
throw new Exception("Device not available via Udp/Lan");
}
Task<GoveeUdpState> goveeUdpStateTask = _UDPService.GetStateAsync(goveeDevice.Address);
goveeUdpStateTask.Wait();
return new GoveeState() {
State = goveeUdpStateTask.Result.OnOff,
Brightness = goveeUdpStateTask.Result.Brightness,
Color = goveeUdpStateTask.Result.Color,
ColorTempInKelvin = goveeUdpStateTask.Result.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);
Task<GoveeApiState> goveeApiStateTask = _APIService.GetDeviceStateAsync(goveeDevice.DeviceId, goveeDevice.Model);
goveeApiStateTask.Wait();
return new GoveeState {
State = goveeApiStateTask.Result.Properties.PowerState,
Brightness = goveeApiStateTask.Result.Properties.Brightness,
Color = goveeApiStateTask.Result.Properties.Color,
ColorTempInKelvin = goveeApiStateTask.Result.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 void 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);
Task<HttpResponseMessage> httpResponseMessageTask = _APIService.ToggleStateAsync(goveeDevice.DeviceId, goveeDevice.Model, on);
httpResponseMessageTask.Wait();
}
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 void 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);
Task<HttpResponseMessage> httpResponseMessageTask = _APIService.SetBrightnessAsync(goveeDevice.DeviceId, goveeDevice.Model, value);
httpResponseMessageTask.Wait();
}
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 void 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);
Task<HttpResponseMessage> httpResponseMessageTask = _APIService.SetColorAsync(goveeDevice.DeviceId, goveeDevice.Model, color);
httpResponseMessageTask.Wait();
}
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 void 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);
Task<HttpResponseMessage> httpResponseMessageTask = _APIService.SetColorTempAsync(goveeDevice.DeviceId, goveeDevice.Model, value);
httpResponseMessageTask.Wait();
}
}

View File

@ -1,308 +1,213 @@
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 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 bool _UDPListenerActive = true;
private readonly UdpClient _UDPClient = new();
private const int _GoveeMulticastPortSend = 4001;
private const int _GoveeMulticastPortListen = 4002;
private const string _GoveeMulticastAddress = "239.255.255.250";
public IObservable<string> Messages => _messageSubject;
private readonly Subject<string> _MessageSubject = new();
private readonly SemaphoreSlim _SemaphoreSlim = new(1, 1);
private readonly Subject<GoveeUdpDevice> _ScanResultSubject = new();
private readonly Subject<GoveeUdpState> _StateResultSubject = new();
public GoveeUdpService()
{
SetupUdpClientListener();
}
public bool IsListening() =>
_UDPListenerActive;
/// <inheritdoc/>
public async Task<List<GoveeUdpDevice>> GetDevices(TimeSpan? timeout = null)
{
if (!_udpListenerActive)
public GoveeUdpService() =>
SetupUdpClientListenerAsync();
public IObservable<string> Messages =>
_MessageSubject;
public Task<IList<GoveeUdpDevice>> GetDevicesAsync(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();
try
{
_SemaphoreSlim.Wait();
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 devicesTask;
} catch (Exception e) {
Console.WriteLine(e);
throw;
}
finally
{
} finally {
// Release Method Block
_semaphore.Release();
_ = _SemaphoreSlim.Release();
}
}
/// <inheritdoc/>
public async Task<GoveeUdpState> GetState(string deviceAddress, int uniCastPort = 4003, TimeSpan? timeout = null)
{
if (!_udpListenerActive)
public Task<GoveeUdpState> GetStateAsync(string deviceAddress, int uniCastPort = 4003, TimeSpan? timeout = null) {
if (!_UDPListenerActive) {
throw new Exception("Udp Listener not started!");
try
{
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "devStatus",
data = new { }
}
// Build Message
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "devStatus",
Data = new { }
}
};
// Subscribe to ScanResultSubject
Task<GoveeUdpState> devicesTask = _StateResultSubject
.TakeUntil(Observable.Timer(timeout ?? TimeSpan.FromMilliseconds(250)))
.ToTask();
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
// Return state
return devicesTask;
}
public void ToggleDevice(string deviceAddress, bool on, int uniCastPort = 4003) {
// Build Message
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "turn",
Data = new { value = on ? 1 : 0 }
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
public void SetBrightness(string deviceAddress, int brightness, int uniCastPort = 4003) {
// Build Message
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "brightness",
Data = new { value = brightness }
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
public void SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003) {
// Build Message
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "colorwc",
Data = new {
color = new {
r = color.R,
g = color.G,
b = color.B
},
colorTempInKelvin = 0
}
};
// Subscribe to ScanResultSubject
var devicesTask = _stateResultSubject
.TakeUntil(Observable.Timer(timeout ?? TimeSpan.FromMilliseconds(250)))
.ToTask();
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
// Return state
return await devicesTask;
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
/// <inheritdoc/>
public async Task 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 }
public void SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003) {
// Build Message
GoveeUdpMessage message = new() {
Msg = new Msg {
Cmd = "colorwc",
Data = new {
color = new {
r = 0,
g = 0,
b = 0
},
colorTempInKelvin
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async Task SetBrightness(string deviceAddress, int brightness, int uniCastPort = 4003)
{
try
{
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "brightness",
data = new { value = brightness }
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
/// <inheritdoc/>
public async Task SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003)
{
try
{
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "colorwc",
data = new
{ color = new
{
r = color.R,
g = color.G,
b = color.B
},
colorTempInKelvin = 0
}
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
public async Task SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003)
{
try
{
// Build Message
var message = new GoveeUdpMessage
{
msg = new msg
{
cmd = "colorwc",
data = new
{
color = new
{
r = 0,
g = 0,
b = 0
},
colorTempInKelvin = colorTempInKelvin
}
}
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
public Task StartUdpListenerAsync() {
_UDPListenerActive = true;
return StartListenerAsync();
}
/// <inheritdoc/>
public async void StartUdpListener()
{
_udpListenerActive = true;
await StartListener();
}
/// <inheritdoc/>
public bool IsListening()
{
return _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)
{
Console.WriteLine(e);
Task<int> task = client.SendAsync(data, data.Length, receiverAddress, receiverPort);
task.Wait();
} catch (Exception) {
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);
await StartListener();
private Task SetupUdpClientListenerAsync() {
_UDPClient.ExclusiveAddressUse = false;
IPEndPoint localEndPoint = new(IPAddress.Any, _GoveeMulticastPortListen);
_UDPClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_UDPClient.Client.Bind(localEndPoint);
return StartListenerAsync();
}
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);
var message = Encoding.UTF8.GetString(data);
UdPMessageReceived(message);
_messageSubject.OnNext(message);
}
});
}
catch(Exception ex)
{
throw ex;
}
private Task StartListenerAsync() {
_UDPClient.JoinMulticastGroup(IPAddress.Parse(_GoveeMulticastAddress));
return StartListenerTask();
}
private void UdPMessageReceived(string message)
{
var response = JsonSerializer.Deserialize<GoveeUdpMessage>(message);
switch (response.msg.cmd)
{
private Task StartListenerTask() {
while (_UDPListenerActive) {
IPEndPoint remoteEndPoint = new(IPAddress.Any, 0);
byte[] data = _UDPClient.Receive(ref remoteEndPoint);
string message = Encoding.UTF8.GetString(data);
UdPMessageReceived(message);
_MessageSubject.OnNext(message);
}
return Task.CompletedTask;
}
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;
}
}
}