Skip to content

Commit

Permalink
Updated YeeLight integration
Browse files Browse the repository at this point in the history
force-pushed, combined commits into one and improved variable registry entries of YeeLight integration.
  • Loading branch information
snake-4 committed May 13, 2020
1 parent 660c03e commit 4151552
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 60 deletions.
128 changes: 69 additions & 59 deletions Project-Aurora/Project-Aurora/Devices/YeeLight/YeeLightDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using YeeLightAPI.YeeLightDeviceLocator;
using YeeLightAPI.YeeLightConstants;
using YeeLightAPI.YeeLightExceptions;

namespace Aurora.Devices.YeeLight
{
Expand All @@ -18,10 +21,9 @@ public class YeeLightDevice : Device
private string devicename = "YeeLight";

private bool isConnected;
private Stopwatch sw = new Stopwatch();

private Stopwatch watch = new Stopwatch();
private YeeLightAPI.YeeLight light = new YeeLightAPI.YeeLight();
private Stopwatch updateDelayStopWatch = new Stopwatch();
private Stopwatch updatePerfStopwatch = new Stopwatch();
private YeeLightAPI.YeeLightDevice light = new YeeLightAPI.YeeLightDevice();
private long lastUpdateTime = 0;
private const int lightListenPort = 55443; // The YeeLight smart bulb listens for commands on this port

Expand All @@ -47,7 +49,7 @@ public bool Initialize()
}
catch (Exception exc)
{
Global.logger.Error($"Device {devicename} encountered an error during Connecting. Exception: {exc}");
Global.logger.Error($"Device {devicename} encountered an error during connecting. Exception: {exc}");
isConnected = false;

return false;
Expand Down Expand Up @@ -79,12 +81,8 @@ public bool IsPeripheralConnected()

public bool Reconnect()
{
light.CloseConnection();

isConnected = false;

Connect(IPAddress.Parse(Global.Configuration.VarRegistry.GetVariable<string>($"{devicename}_IP")));
return true;
Shutdown();
return Initialize();
}

public void Reset()
Expand All @@ -94,13 +92,16 @@ public void Reset()

public void Shutdown()
{
light.CloseConnection();
if (light.IsConnected())
{
light.CloseConnection();
}

isConnected = false;

if (sw.IsRunning)
if (updateDelayStopWatch.IsRunning)
{
sw.Stop();
updateDelayStopWatch.Stop();
}
}

Expand All @@ -118,78 +119,85 @@ private int GetFreeTCPPort()

public void Connect(IPAddress lightIP, DoWorkEventArgs token = null)
{
try
if (light.IsConnected())
{
if (!light.isConnected())
{
IPAddress localIP;
int localListenPort = GetFreeTCPPort(); // This can be any port
return;
}

using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect(lightIP, lightListenPort);
localIP = ((IPEndPoint)socket.LocalEndPoint).Address;
}
//Can't reconnect using same device class instance
light = new YeeLightAPI.YeeLightDevice();

isConnected = light.Connect(lightIP, lightListenPort) && light.SetMusicMode(localIP, localListenPort);
}
}
catch (Exception exc)
//Auto discover a device if the IP is 0.0.0.0
if (lightIP.Equals(IPAddress.Parse("0.0.0.0")))
{
Global.logger.Error($"Device {devicename} encountered an error during Connecting. Exception: {exc}");
isConnected = false;
var devices = DeviceLocator.DiscoverDevices();
if (devices.Any())
{
light = devices.First();
lightIP = light.GetLightIPAddressAndPort().ipAddress;
}
else
{
throw new Exception("IP address is set to 0.0.0.0 and no devices have been located.");
}
}
}

public bool UpdateDevice(DeviceColorComposition colorComposition, DoWorkEventArgs e, bool forced = false)
{
if (e.Cancel)
//If it isn't then set the IP to the provided IP address
else
{
return false;
light.SetLightIPAddressAndPort(lightIP, YeeLightAPI.YeeLightConstants.Constants.DefaultCommandPort);
}

watch.Restart();
IPAddress localIP;
int localMusicModeListenPort = GetFreeTCPPort(); // This can be any free port

// Connect if needed
if (!isConnected)
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
Connect(IPAddress.Parse(Global.Configuration.VarRegistry.GetVariable<string>($"{devicename}_IP")), e);
socket.Connect(lightIP, lightListenPort);
localIP = ((IPEndPoint)socket.LocalEndPoint).Address;
}

light.Connect();
light.SetMusicMode(localIP, (ushort)localMusicModeListenPort, true);
isConnected = light.IsConnected();
}

public bool UpdateDevice(DeviceColorComposition colorComposition, DoWorkEventArgs e, bool forced = false)
{
if (e.Cancel)
{
return false;
}

updatePerfStopwatch.Restart();

// Reduce sending based on user config
if (!sw.IsRunning)
if (!updateDelayStopWatch.IsRunning)
{
sw.Start();
updateDelayStopWatch.Start();
}

if (e.Cancel)
if (updateDelayStopWatch.ElapsedMilliseconds > Global.Configuration.VarRegistry.GetVariable<int>($"{devicename}_send_delay"))
{
return false;
}

if (sw.ElapsedMilliseconds > Global.Configuration.VarRegistry.GetVariable<int>($"{devicename}_send_delay"))
{
Color targetColor = colorComposition.keyColors.FirstOrDefault(pair =>
{
return pair.Key == Global.Configuration.VarRegistry.GetVariable<DeviceKeys>($"{devicename}_devicekey");
}).Value;

light.SetColor(targetColor.R, targetColor.G, targetColor.B);
sw.Restart();
}
if ((targetColor.R + targetColor.G + targetColor.B) > 0)
{
light.SetColor(targetColor.R, targetColor.G, targetColor.B);
}

if (e.Cancel)
{
return false;
}
updatePerfStopwatch.Stop();
lastUpdateTime = updatePerfStopwatch.ElapsedMilliseconds + updateDelayStopWatch.ElapsedMilliseconds;
updateDelayStopWatch.Restart();

watch.Stop();
lastUpdateTime = watch.ElapsedMilliseconds;
if (e.Cancel)
{
return false;
}
}

return true;
}
Expand All @@ -208,10 +216,12 @@ public VariableRegistry GetRegisteredVariables()
{
if (default_registry == null)
{
var devKeysEnumAsEnumerable = Enum.GetValues(typeof(DeviceKeys)).Cast<DeviceKeys>();

default_registry = new VariableRegistry();
default_registry.Register($"{devicename}_devicekey", DeviceKeys.Peripheral, "Key to Use", DeviceKeys.MOUSEPADLIGHT15, DeviceKeys.Peripheral);
default_registry.Register($"{devicename}_send_delay", 100, "Send delay (ms)");
default_registry.Register($"{devicename}_IP", "0.0.0.0", "YeeLight IP");
default_registry.Register($"{devicename}_devicekey", DeviceKeys.Peripheral_Logo, "Key to Use", devKeysEnumAsEnumerable.Max(), devKeysEnumAsEnumerable.Min());
default_registry.Register($"{devicename}_send_delay", 35, "Send delay (ms)");
default_registry.Register($"{devicename}_IP", "0.0.0.0", "YeeLight IP", null, null, "If set to 0.0.0.0, it will try to discover a YeeLight and connect to it.");
}

return default_registry;
Expand Down
2 changes: 1 addition & 1 deletion Project-Aurora/Project-Aurora/Project-Aurora.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2675,7 +2675,7 @@
<Version>2.9.15603.14400</Version>
</PackageReference>
<PackageReference Include="YeeLightAPI_SnakePin">
<Version>0.0.1</Version>
<Version>0.0.6</Version>
</PackageReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
Expand Down

0 comments on commit 4151552

Please sign in to comment.