diff --git a/GoveeCSharpConnector/GoveeCSharpConnector.csproj b/GoveeCSharpConnector/GoveeCSharpConnector.csproj
index 1027ab2..132f430 100644
--- a/GoveeCSharpConnector/GoveeCSharpConnector.csproj
+++ b/GoveeCSharpConnector/GoveeCSharpConnector.csproj
@@ -12,16 +12,14 @@
https://github.com/Locxion/GoveeCSharpConnector
https://github.com/Locxion/GoveeCSharpConnector
https://github.com/Locxion/GoveeCSharpConnector/blob/main/LICENSE
+ 1.1.0
-
-
-
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Interfaces/IGoveeApiService.cs b/GoveeCSharpConnector/Interfaces/IGoveeApiService.cs
index 5d4611e..70ef2c8 100644
--- a/GoveeCSharpConnector/Interfaces/IGoveeApiService.cs
+++ b/GoveeCSharpConnector/Interfaces/IGoveeApiService.cs
@@ -10,27 +10,32 @@ public interface IGoveeApiService
///
/// Api Key as String
void SetApiKey(string apiKey);
+
///
/// Returns current set Govee Api Key
///
/// Govee Api Key as String
string GetApiKey();
+
///
/// Removes the Set Api Key and resets the HTTP Header
///
void RemoveApiKey();
+
///
/// Requests all Devices registered to Api Key Govee Account
///
/// List of GoveeApiDevices
Task> GetDevices();
+
///
/// Requests the State of a single Govee Device
///
/// Device Id Guid as string
/// Device Model Number as string
/// GoveeApiStat Object
- public Task GetDeviceState(string deviceId, string deviceModel);
+ Task GetDeviceState(string deviceId, string deviceModel);
+
///
/// Sets the On/Off state of a single Govee Device
///
@@ -38,7 +43,8 @@ public interface IGoveeApiService
/// Device Model Number as string
///
///
- public Task ToggleState(string deviceId, string deviceModel, bool on);
+ Task ToggleState(string deviceId, string deviceModel, bool on);
+
///
/// Sets the Brightness in Percent of a single Govee Device
///
@@ -46,7 +52,8 @@ public interface IGoveeApiService
/// Device Model Number as string
/// Brightness in Percent as Int
///
- public Task SetBrightness(string deviceId, string deviceModel, int value);
+ Task SetBrightness(string deviceId, string deviceModel, int value);
+
///
/// Sets a Rgb Color of a single Govee Device
///
@@ -54,7 +61,8 @@ public interface IGoveeApiService
/// Device Model Number as string
/// Rgb Color
///
- public Task SetColor(string deviceId, string deviceModel, RgbColor color);
+ Task SetColor(string deviceId, string deviceModel, RgbColor color);
+
///
/// Sets the Color Temperature of a single Govee Device
///
@@ -62,6 +70,5 @@ public interface IGoveeApiService
/// Device Model Number as string
/// Color Temp in Kelvin as Int
///
- public Task SetColorTemp(string deviceId, string deviceModel, int value);
-
+ Task SetColorTemp(string deviceId, string deviceModel, int value);
}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Interfaces/IGoveeService.cs b/GoveeCSharpConnector/Interfaces/IGoveeService.cs
new file mode 100644
index 0000000..4dfc4a3
--- /dev/null
+++ b/GoveeCSharpConnector/Interfaces/IGoveeService.cs
@@ -0,0 +1,62 @@
+using GoveeCSharpConnector.Objects;
+
+namespace GoveeCSharpConnector.Interfaces;
+
+public interface IGoveeService
+{
+ ///
+ /// Govee Api Key
+ ///
+ string GoveeApiKey { get; set; }
+
+ ///
+ /// Gets a List of Govee Devices
+ ///
+ /// If true returns that are available on Api and Lan
+ /// List of Govee Devices
+ Task> GetDevices(bool onlyLan = true);
+
+ ///
+ /// Gets the State of a GoveeDevice
+ ///
+ /// GoveeDevice
+ /// Use Udp Connection instead of the Api
+ ///
+ Task GetDeviceState(GoveeDevice goveeDevice, bool useUdp = true);
+
+ ///
+ /// Sets the On/Off State of the GoveeDevice
+ ///
+ /// GoveeDevice
+ ///
+ /// Use Udp Connection instead of the Api
+ ///
+ Task ToggleState(GoveeDevice goveeDevice, bool on, bool useUdp = true);
+
+ ///
+ /// Sets the Brightness of the GoveeDevice
+ ///
+ /// GoveeDevice
+ /// Brightness in Percent
+ /// Use Udp Connection instead of the Api
+ ///
+ Task SetBrightness(GoveeDevice goveeDevice, int value, bool useUdp = true);
+
+ ///
+ /// Sets the Color of the GoveeDevice
+ ///
+ /// GoveeDevice
+ /// RgBColor
+ /// Use Udp Connection instead of the Api
+ ///
+ Task SetColor(GoveeDevice goveeDevice, RgbColor color, bool useUdp = true);
+
+ ///
+ /// Sets the Color Temperature in Kelvin for the GoveeDevice
+ ///
+ /// GoveeDevice
+ /// Color Temp in Kelvin
+ /// Use Udp Connection instead of the Api
+ ///
+ Task SetColorTemp(GoveeDevice goveeDevice, int value, bool useUdp = true);
+}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Interfaces/IGoveeUdpService.cs b/GoveeCSharpConnector/Interfaces/IGoveeUdpService.cs
index f848ae5..2c64db2 100644
--- a/GoveeCSharpConnector/Interfaces/IGoveeUdpService.cs
+++ b/GoveeCSharpConnector/Interfaces/IGoveeUdpService.cs
@@ -49,6 +49,15 @@ public interface IGoveeUdpService
/// Port of the Device. Standard 4003
///
Task SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003);
+
+ ///
+ /// Sets the ColorTemp of the Device
+ ///
+ /// Ip Address of the Device
+ ///
+ /// Port of the Device. Standard 4003
+ ///
+ Task SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003);
///
/// Starts the Udp Listener
///
diff --git a/GoveeCSharpConnector/Objects/GoveeDevice.cs b/GoveeCSharpConnector/Objects/GoveeDevice.cs
new file mode 100644
index 0000000..55a9760
--- /dev/null
+++ b/GoveeCSharpConnector/Objects/GoveeDevice.cs
@@ -0,0 +1,9 @@
+namespace GoveeCSharpConnector.Objects;
+
+public class GoveeDevice
+{
+ public string DeviceId { get; set; }
+ public string Model { get; set; }
+ public string DeviceName { get; set; }
+ public string Address { get; set; }
+}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Objects/GoveeState.cs b/GoveeCSharpConnector/Objects/GoveeState.cs
new file mode 100644
index 0000000..7c1acc5
--- /dev/null
+++ b/GoveeCSharpConnector/Objects/GoveeState.cs
@@ -0,0 +1,11 @@
+using GoveeCSharpConnector.Enums;
+
+namespace GoveeCSharpConnector.Objects;
+
+public class GoveeState
+{
+ public PowerState State { get; set; }
+ public int Brightness { get; set; }
+ public RgbColor Color { get; set; }
+ public int ColorTempInKelvin { get; set; }
+}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Objects/Properties.cs b/GoveeCSharpConnector/Objects/Properties.cs
index 1d23366..7ecd558 100644
--- a/GoveeCSharpConnector/Objects/Properties.cs
+++ b/GoveeCSharpConnector/Objects/Properties.cs
@@ -7,6 +7,6 @@ public class Properties
public bool Online { get; set; }
public PowerState PowerState { get; set; }
public int Brightness { get; set; }
- public int? ColorTemp { get; set; }
+ public int ColorTemp { get; set; }
public RgbColor Color { get; set; }
}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Services/GoveeService.cs b/GoveeCSharpConnector/Services/GoveeService.cs
new file mode 100644
index 0000000..7a0c046
--- /dev/null
+++ b/GoveeCSharpConnector/Services/GoveeService.cs
@@ -0,0 +1,100 @@
+using GoveeCSharpConnector.Interfaces;
+using GoveeCSharpConnector.Objects;
+
+namespace GoveeCSharpConnector.Services;
+
+public class GoveeService : IGoveeService
+{
+ public string GoveeApiKey { get; set; }
+
+ private readonly IGoveeApiService _apiService;
+ private readonly IGoveeUdpService _udpService;
+
+ public GoveeService(IGoveeApiService apiService,IGoveeUdpService udpService)
+ {
+ _apiService = apiService ?? throw new ArgumentNullException(nameof(apiService));
+ _udpService = udpService ?? throw new ArgumentNullException(nameof(udpService));
+ }
+ public async Task> GetDevices(bool onlyLan = true)
+ {
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ 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)
+ 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();
+
+ return combinedDevices;
+ }
+
+ public async Task 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 };
+ }
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ 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};
+ }
+
+ 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);
+ return;
+ }
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ 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);
+ return;
+ }
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ 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);
+ return;
+ }
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ 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);
+ return;
+ }
+ if (string.IsNullOrWhiteSpace(GoveeApiKey)) throw new Exception("No Govee Api Key Set!");
+ await _apiService.SetColorTemp(goveeDevice.DeviceId, goveeDevice.Model, value);
+ }
+}
\ No newline at end of file
diff --git a/GoveeCSharpConnector/Services/GoveeUdpService.cs b/GoveeCSharpConnector/Services/GoveeUdpService.cs
index 7c9ffb1..797f334 100644
--- a/GoveeCSharpConnector/Services/GoveeUdpService.cs
+++ b/GoveeCSharpConnector/Services/GoveeUdpService.cs
@@ -38,9 +38,9 @@ public class GoveeUdpService : IGoveeUdpService
try
{
// Build Message
- var message = new GoveeUdpMessage()
+ var message = new GoveeUdpMessage
{
- msg = new msg()
+ msg = new msg
{
cmd = "scan",
data = new { account_topic = "reserve" }
@@ -76,9 +76,9 @@ public class GoveeUdpService : IGoveeUdpService
try
{
// Build Message
- var message = new GoveeUdpMessage()
+ var message = new GoveeUdpMessage
{
- msg = new msg()
+ msg = new msg
{
cmd = "devStatus",
data = new { }
@@ -107,9 +107,9 @@ public class GoveeUdpService : IGoveeUdpService
try
{
// Build Message
- var message = new GoveeUdpMessage()
+ var message = new GoveeUdpMessage
{
- msg = new msg()
+ msg = new msg
{
cmd = "turn",
data = new { value = on ? 1 : 0 }
@@ -131,9 +131,9 @@ public class GoveeUdpService : IGoveeUdpService
try
{
// Build Message
- var message = new GoveeUdpMessage()
+ var message = new GoveeUdpMessage
{
- msg = new msg()
+ msg = new msg
{
cmd = "brightness",
data = new { value = brightness }
@@ -155,9 +155,9 @@ public class GoveeUdpService : IGoveeUdpService
try
{
// Build Message
- var message = new GoveeUdpMessage()
+ var message = new GoveeUdpMessage
{
- msg = new msg()
+ msg = new msg
{
cmd = "colorwc",
data = new
@@ -173,7 +173,6 @@ public class GoveeUdpService : IGoveeUdpService
};
// Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
-
}
catch (Exception e)
{
@@ -181,6 +180,39 @@ public class GoveeUdpService : IGoveeUdpService
throw;
}
}
+
+ 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 async void StartUdpListener()
{
diff --git a/README.md b/README.md
index f15e61e..a16445f 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,7 @@

[](https://www.nuget.org/packages/GoveeCSharpConnector/)
+
# About
Simple .net Library to interface with Govee Smart Lights via their Web Api or Lan Udp connection.