Version 1.1.0 (#3)

* Delete .gitignore

* Added Readme, Added Nuget Infos in Project

* Added GoveeService that unites Api and Udp Service

Added ColorTemp Method to Udp Service

* Added UdpListener check

* Added ApiKey check

* Moved Class and changed Namespace

* Update GoveeCSharpConnector.csproj
This commit is contained in:
Markus Bender
2024-02-03 00:57:33 +01:00
committed by GitHub
parent 602926c43e
commit bb01b3342d
10 changed files with 250 additions and 21 deletions

View File

@ -12,16 +12,14 @@
<PackageProjectUrl>https://github.com/Locxion/GoveeCSharpConnector</PackageProjectUrl> <PackageProjectUrl>https://github.com/Locxion/GoveeCSharpConnector</PackageProjectUrl>
<RepositoryUrl>https://github.com/Locxion/GoveeCSharpConnector</RepositoryUrl> <RepositoryUrl>https://github.com/Locxion/GoveeCSharpConnector</RepositoryUrl>
<PackageLicenseUrl>https://github.com/Locxion/GoveeCSharpConnector/blob/main/LICENSE</PackageLicenseUrl> <PackageLicenseUrl>https://github.com/Locxion/GoveeCSharpConnector/blob/main/LICENSE</PackageLicenseUrl>
<Version>1.1.0</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" /> <PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
<PackageReference Include="System.Reactive" Version="6.0.0" /> <PackageReference Include="System.Reactive" Version="6.0.0" />
<PackageReference Include="System.Text.Json" Version="8.0.1" /> <PackageReference Include="System.Text.Json" Version="8.0.1" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Properties\" /> <Folder Include="Properties\" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -10,27 +10,32 @@ public interface IGoveeApiService
/// </summary> /// </summary>
/// <param name="apiKey">Api Key as String</param> /// <param name="apiKey">Api Key as String</param>
void SetApiKey(string apiKey); void SetApiKey(string apiKey);
/// <summary> /// <summary>
/// Returns current set Govee Api Key /// Returns current set Govee Api Key
/// </summary> /// </summary>
/// <returns>Govee Api Key as String</returns> /// <returns>Govee Api Key as String</returns>
string GetApiKey(); string GetApiKey();
/// <summary> /// <summary>
/// Removes the Set Api Key and resets the HTTP Header /// Removes the Set Api Key and resets the HTTP Header
/// </summary> /// </summary>
void RemoveApiKey(); void RemoveApiKey();
/// <summary> /// <summary>
/// Requests all Devices registered to Api Key Govee Account /// Requests all Devices registered to Api Key Govee Account
/// </summary> /// </summary>
/// <returns>List of GoveeApiDevices</returns> /// <returns>List of GoveeApiDevices</returns>
Task<List<GoveeApiDevice>> GetDevices(); Task<List<GoveeApiDevice>> GetDevices();
/// <summary> /// <summary>
/// Requests the State of a single Govee Device /// Requests the State of a single Govee Device
/// </summary> /// </summary>
/// <param name="deviceId">Device Id Guid as string</param> /// <param name="deviceId">Device Id Guid as string</param>
/// <param name="deviceModel">Device Model Number as string</param> /// <param name="deviceModel">Device Model Number as string</param>
/// <returns>GoveeApiStat Object</returns> /// <returns>GoveeApiStat Object</returns>
public Task<GoveeApiState> GetDeviceState(string deviceId, string deviceModel); Task<GoveeApiState> GetDeviceState(string deviceId, string deviceModel);
/// <summary> /// <summary>
/// Sets the On/Off state of a single Govee Device /// Sets the On/Off state of a single Govee Device
/// </summary> /// </summary>
@ -38,7 +43,8 @@ public interface IGoveeApiService
/// <param name="deviceModel">Device Model Number as string</param> /// <param name="deviceModel">Device Model Number as string</param>
/// <param name="on"></param> /// <param name="on"></param>
/// <returns></returns> /// <returns></returns>
public Task ToggleState(string deviceId, string deviceModel, bool on); Task ToggleState(string deviceId, string deviceModel, bool on);
/// <summary> /// <summary>
/// Sets the Brightness in Percent of a single Govee Device /// Sets the Brightness in Percent of a single Govee Device
/// </summary> /// </summary>
@ -46,7 +52,8 @@ public interface IGoveeApiService
/// <param name="deviceModel">Device Model Number as string</param> /// <param name="deviceModel">Device Model Number as string</param>
/// <param name="value">Brightness in Percent as Int</param> /// <param name="value">Brightness in Percent as Int</param>
/// <returns></returns> /// <returns></returns>
public Task SetBrightness(string deviceId, string deviceModel, int value); Task SetBrightness(string deviceId, string deviceModel, int value);
/// <summary> /// <summary>
/// Sets a Rgb Color of a single Govee Device /// Sets a Rgb Color of a single Govee Device
/// </summary> /// </summary>
@ -54,7 +61,8 @@ public interface IGoveeApiService
/// <param name="deviceModel">Device Model Number as string</param> /// <param name="deviceModel">Device Model Number as string</param>
/// <param name="color">Rgb Color</param> /// <param name="color">Rgb Color</param>
/// <returns></returns> /// <returns></returns>
public Task SetColor(string deviceId, string deviceModel, RgbColor color); Task SetColor(string deviceId, string deviceModel, RgbColor color);
/// <summary> /// <summary>
/// Sets the Color Temperature of a single Govee Device /// Sets the Color Temperature of a single Govee Device
/// </summary> /// </summary>
@ -62,6 +70,5 @@ public interface IGoveeApiService
/// <param name="deviceModel">Device Model Number as string</param> /// <param name="deviceModel">Device Model Number as string</param>
/// <param name="value">Color Temp in Kelvin as Int</param> /// <param name="value">Color Temp in Kelvin as Int</param>
/// <returns></returns> /// <returns></returns>
public Task SetColorTemp(string deviceId, string deviceModel, int value); Task SetColorTemp(string deviceId, string deviceModel, int value);
} }

View File

@ -0,0 +1,62 @@
using GoveeCSharpConnector.Objects;
namespace GoveeCSharpConnector.Interfaces;
public interface IGoveeService
{
/// <summary>
/// Govee Api Key
/// </summary>
string GoveeApiKey { get; set; }
/// <summary>
/// Gets a List of Govee Devices
/// </summary>
/// <param name="onlyLan">If true returns that are available on Api and Lan</param>
/// <returns>List of Govee Devices</returns>
Task<List<GoveeDevice>> GetDevices(bool onlyLan = true);
/// <summary>
/// Gets the State of a GoveeDevice
/// </summary>
/// <param name="goveeDevice">GoveeDevice</param>
/// <param name="useUdp">Use Udp Connection instead of the Api</param>
/// <returns></returns>
Task<GoveeState> GetDeviceState(GoveeDevice goveeDevice, bool useUdp = true);
/// <summary>
/// Sets the On/Off State of the GoveeDevice
/// </summary>
/// <param name="goveeDevice">GoveeDevice</param>
/// <param name="on"></param>
/// <param name="useUdp">Use Udp Connection instead of the Api</param>
/// <returns></returns>
Task ToggleState(GoveeDevice goveeDevice, bool on, bool useUdp = true);
/// <summary>
/// Sets the Brightness of the GoveeDevice
/// </summary>
/// <param name="goveeDevice">GoveeDevice</param>
/// <param name="value">Brightness in Percent</param>
/// <param name="useUdp">Use Udp Connection instead of the Api</param>
/// <returns></returns>
Task SetBrightness(GoveeDevice goveeDevice, int value, bool useUdp = true);
/// <summary>
/// Sets the Color of the GoveeDevice
/// </summary>
/// <param name="goveeDevice">GoveeDevice</param>
/// <param name="color">RgBColor</param>
/// <param name="useUdp">Use Udp Connection instead of the Api</param>
/// <returns></returns>
Task SetColor(GoveeDevice goveeDevice, RgbColor color, bool useUdp = true);
/// <summary>
/// Sets the Color Temperature in Kelvin for the GoveeDevice
/// </summary>
/// <param name="goveeDevice">GoveeDevice</param>
/// <param name="value">Color Temp in Kelvin</param>
/// <param name="useUdp">Use Udp Connection instead of the Api</param>
/// <returns></returns>
Task SetColorTemp(GoveeDevice goveeDevice, int value, bool useUdp = true);
}

View File

@ -49,6 +49,15 @@ public interface IGoveeUdpService
/// <param name="uniCastPort">Port of the Device. Standard 4003</param> /// <param name="uniCastPort">Port of the Device. Standard 4003</param>
/// <returns></returns> /// <returns></returns>
Task SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003); Task SetColor(string deviceAddress, RgbColor color, int uniCastPort = 4003);
/// <summary>
/// Sets the ColorTemp of the Device
/// </summary>
/// <param name="deviceAddress">Ip Address of the Device</param>
/// <param name="colorTempInKelvin"></param>
/// <param name="uniCastPort">Port of the Device. Standard 4003</param>
/// <returns></returns>
Task SetColorTemp(string deviceAddress, int colorTempInKelvin, int uniCastPort = 4003);
/// <summary> /// <summary>
/// Starts the Udp Listener /// Starts the Udp Listener
/// </summary> /// </summary>

View File

@ -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; }
}

View File

@ -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; }
}

View File

@ -7,6 +7,6 @@ public class Properties
public bool Online { get; set; } public bool Online { get; set; }
public PowerState PowerState { get; set; } public PowerState PowerState { get; set; }
public int Brightness { get; set; } public int Brightness { get; set; }
public int? ColorTemp { get; set; } public int ColorTemp { get; set; }
public RgbColor Color { get; set; } public RgbColor Color { get; set; }
} }

View File

@ -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<List<GoveeDevice>> 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<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 };
}
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);
}
}

View File

@ -38,9 +38,9 @@ public class GoveeUdpService : IGoveeUdpService
try try
{ {
// Build Message // Build Message
var message = new GoveeUdpMessage() var message = new GoveeUdpMessage
{ {
msg = new msg() msg = new msg
{ {
cmd = "scan", cmd = "scan",
data = new { account_topic = "reserve" } data = new { account_topic = "reserve" }
@ -76,9 +76,9 @@ public class GoveeUdpService : IGoveeUdpService
try try
{ {
// Build Message // Build Message
var message = new GoveeUdpMessage() var message = new GoveeUdpMessage
{ {
msg = new msg() msg = new msg
{ {
cmd = "devStatus", cmd = "devStatus",
data = new { } data = new { }
@ -107,9 +107,9 @@ public class GoveeUdpService : IGoveeUdpService
try try
{ {
// Build Message // Build Message
var message = new GoveeUdpMessage() var message = new GoveeUdpMessage
{ {
msg = new msg() msg = new msg
{ {
cmd = "turn", cmd = "turn",
data = new { value = on ? 1 : 0 } data = new { value = on ? 1 : 0 }
@ -131,9 +131,9 @@ public class GoveeUdpService : IGoveeUdpService
try try
{ {
// Build Message // Build Message
var message = new GoveeUdpMessage() var message = new GoveeUdpMessage
{ {
msg = new msg() msg = new msg
{ {
cmd = "brightness", cmd = "brightness",
data = new { value = brightness } data = new { value = brightness }
@ -155,9 +155,9 @@ public class GoveeUdpService : IGoveeUdpService
try try
{ {
// Build Message // Build Message
var message = new GoveeUdpMessage() var message = new GoveeUdpMessage
{ {
msg = new msg() msg = new msg
{ {
cmd = "colorwc", cmd = "colorwc",
data = new data = new
@ -173,7 +173,6 @@ public class GoveeUdpService : IGoveeUdpService
}; };
// Send Message // Send Message
SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort); SendUdpMessage(JsonSerializer.Serialize(message), deviceAddress, uniCastPort);
} }
catch (Exception e) catch (Exception e)
{ {
@ -181,6 +180,39 @@ public class GoveeUdpService : IGoveeUdpService
throw; 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;
}
}
/// <inheritdoc/> /// <inheritdoc/>
public async void StartUdpListener() public async void StartUdpListener()
{ {

View File

@ -2,6 +2,7 @@
![netStandard2.0](https://img.shields.io/badge/.NET%20Standard-2.0-blueviolet) ![netStandard2.0](https://img.shields.io/badge/.NET%20Standard-2.0-blueviolet)
[![Nuget](https://img.shields.io/nuget/v/GoveeCSharpConnector?cacheSeconds=50)](https://www.nuget.org/packages/GoveeCSharpConnector/) [![Nuget](https://img.shields.io/nuget/v/GoveeCSharpConnector?cacheSeconds=50)](https://www.nuget.org/packages/GoveeCSharpConnector/)
# About # About
Simple .net Library to interface with Govee Smart Lights via their Web Api or Lan Udp connection. Simple .net Library to interface with Govee Smart Lights via their Web Api or Lan Udp connection.