private async Task <EntertainmentLayer> GetOrCreateEntertainmentLayerAsync() { if (entertainmentLayer != null) { return(entertainmentLayer); } var group = (await deviceInfo.Client.GetEntertainmentGroups()).FirstOrDefault(); if (group == null) { ErrorMessage = "No default entertainment group"; return(null); } Debug.WriteLine($"Group: {group.Name}"); var streamClient = new StreamingHueClient(deviceInfo.Address, localSettings.AppKey, localSettings.StreamingKey); var stream = new StreamingGroup(group.Lights); await streamClient.Connect(group.Id); streamClient.AutoUpdate(stream, globalEffectsCancelSource.Token); return(entertainmentLayer = stream.GetNewLayer(isBaseLayer: true)); }
public HueLightClient( StreamingHueClient hueClient, StreamingGroup streamingGroup) { this.hueClient = hueClient; this.streamingGroup = streamingGroup; hueLayer = streamingGroup.GetNewLayer(true); Lights = hueLayer.Select(l => new Position((float)l.LightLocation.X, (float)l.LightLocation.Y)).ToArray(); }
public static async Task <StreamingGroup> SetupAndReturnGroup() { string ip = ApplicationManager.Instance.Settings.HueBridgeIP; string key = ApplicationManager.Instance.Settings.HueKey; string entertainmentKey = ApplicationManager.Instance.Settings.HueEntertainmentKey; bool useSimulator = ApplicationManager.Instance.Settings.HueUseSimulator; StreamingGroup = null; Layers = null; StreamingHueClient = new StreamingHueClient(ip, key, entertainmentKey); var allEntertainmentGroups = await StreamingHueClient.LocalHueClient.GetEntertainmentGroups(); var entertainmentGroup = allEntertainmentGroups.FirstOrDefault(); if (entertainmentGroup == null) { throw new Exception("No Entertainment Group found."); } var stream = new StreamingGroup(entertainmentGroup.Locations); stream.IsForSimulator = useSimulator; await StreamingHueClient.Connect(entertainmentGroup.Id, simulator : useSimulator); StreamingHueClient.AutoUpdate(stream, 50); StreamingGroup = stream; var baseLayer = stream.GetNewLayer(isBaseLayer: true); var effectLayer = stream.GetNewLayer(isBaseLayer: false); Layers = new List <EntertainmentLayer>() { baseLayer, effectLayer }; baseLayer.AutoCalculateEffectUpdate(); effectLayer.AutoCalculateEffectUpdate(); return(stream); }
public async Task OnStartReading() { try { if (_config.Model.hueSettings.hueType == HueType.Basic) { if (_config.Model.hueSettings.turnLightOnIfOff) { var command = new LightCommand { On = true, TransitionTime = _frameTimeSpan }; command.TurnOn(); await _client.SendCommandAsync(command, UseRoom.Lights); } } else if (_config.Model.hueSettings.hueType == HueType.Entertainment) { _cancelSource = new CancellationTokenSource(); _cancelToken = _cancelSource.Token; _streamGroup = new StreamingGroup(UseRoom.Locations); await _streamClient.Connect(UseRoom.Id); _streamBaseLayer = _streamGroup.GetNewLayer(true); foreach (var light in _streamBaseLayer) { if (_config.Model.hueSettings.turnLightOnIfOff) { light.SetState(_cancelToken, new RGBColor(1.0, 1.0, 1.0), 0.5); } } _streamClient.ManualUpdate(_streamGroup); } } catch (Exception ex) { Console.WriteLine(ex); _ = Task.Run(() => _logger?.WriteLog(ex.ToString())); } }
public static async Task connect(CancellationToken token, string ip = null) { if (ip == null) { ip = await FindBridge(); } token.ThrowIfCancellationRequested(); var appKey = Settings.ChromaConfig.Instance.HueAppKey; var clientKey = Settings.ChromaConfig.Instance.HueClientKey; Debug.Log("Connecting to bridge..."); var client = new StreamingHueClient(ip, appKey, clientKey); token.ThrowIfCancellationRequested(); Debug.Log("Connected! Getting entertainment group..."); var group = (await client.LocalHueClient.GetEntertainmentGroups()).FirstOrDefault(); if (group == null) { Debug.Log("Group is missing!"); return; } token.ThrowIfCancellationRequested(); var entGroup = new StreamingGroup(group.Locations); Debug.Log("Found group! Connecting to lightbulbs..."); await client.Connect(group.Id); token.ThrowIfCancellationRequested(); Debug.Log("Connected to bulbs! Syncing..."); _ = client.AutoUpdate(entGroup, token); var entLayer = entGroup.GetNewLayer(true); LightInfo.setInfo(client, entLayer, token); await Task.Delay(TimeSpan.FromMilliseconds(50), token); if (Settings.ChromaConfig.Instance.LowLight == true) { entLayer.SetState(token, new RGBColor(255, 255, 255), 0.5); } }
public async Task Start() { StreamingGroup stream = await StreamingSetup.SetupAndReturnGroup(); var baseEntLayer = stream.GetNewLayer(isBaseLayer: true); var effectLayer = stream.GetNewLayer(); //Optional: calculated effects that are placed on this layer baseEntLayer.AutoCalculateEffectUpdate(new CancellationToken()); effectLayer.AutoCalculateEffectUpdate(new CancellationToken()); //Order lights based on position in the room var orderedLeft = baseEntLayer.GetLeft().OrderByDescending(x => x.LightLocation.Y).ThenBy(x => x.LightLocation.X).To2DGroup(); var orderedRight = baseEntLayer.GetRight().OrderByDescending(x => x.LightLocation.Y).ThenByDescending(x => x.LightLocation.X); var allLightsOrdered = baseEntLayer.OrderBy(x => x.LightLocation.X).ThenBy(x => x.LightLocation.Y).ToList().To2DGroup(); var allLightsOrderedFlat = baseEntLayer.OrderBy(x => x.LightLocation.X).ThenBy(x => x.LightLocation.Y).ToList(); var orderedByDistance = baseEntLayer.OrderBy(x => x.LightLocation.Distance(0, 0)).To2DGroup(); var orderedByAngle = baseEntLayer.OrderBy(x => x.LightLocation.Angle(0, 0)).To2DGroup(); var line1 = baseEntLayer.Where(x => x.LightLocation.X <= -0.6).ToList(); var line2 = baseEntLayer.Where(x => x.LightLocation.X > -0.6 && x.LightLocation.X <= -0.1).ToList(); var line3 = baseEntLayer.Where(x => x.LightLocation.X > -0.1 && x.LightLocation.X <= 0.1).ToList(); var line4 = baseEntLayer.Where(x => x.LightLocation.X > 0.1 && x.LightLocation.X <= 0.6).ToList(); var line5 = baseEntLayer.Where(x => x.LightLocation.X > 0.6).ToList(); var allLightsReverse = allLightsOrdered.ToList(); allLightsReverse.Reverse(); CancellationTokenSource cst = new CancellationTokenSource(); Console.WriteLine("Blue line on 90 degree angle"); var blueLineEffect = new HorizontalScanLineEffect(); baseEntLayer.PlaceEffect(blueLineEffect); blueLineEffect.Start(); cst = WaitCancelAndNext(cst); blueLineEffect.Stop(); //Ref<int?> stepSize = 20; //blueLineEffect.Rotate(stepSize); //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.WriteLine("Finished"); //cst = WaitCancelAndNext(cst); //blueLineEffect.Stop(); var quarter = new[] { baseEntLayer.GetLeft().GetFront(), baseEntLayer.GetLeft().GetBack(), baseEntLayer.GetRight().GetBack(), baseEntLayer.GetRight().GetFront() }.ToList(); Console.WriteLine("Random color All / All"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.All, IteratorEffectMode.All, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash on lights Cycle / Random"); quarter.FlashQuick(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Cycle, IteratorEffectMode.Random, waitTime: () => TimeSpan.FromMilliseconds(50)); cst = WaitCancelAndNext(cst); Console.WriteLine("SetColor white Single / Single"); quarter.SetColor(cst.Token, new RGBColor("FFFFFF"), IteratorEffectMode.Single, IteratorEffectMode.Single, waitTime: () => TimeSpan.FromMilliseconds(200)); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash on lights Cycle / All"); quarter.FlashQuick(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Cycle, IteratorEffectMode.All, waitTime: () => TimeSpan.FromMilliseconds(50)); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash on lights Cycle / Single"); quarter.FlashQuick(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Cycle, IteratorEffectMode.Single, waitTime: () => TimeSpan.FromMilliseconds(50)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color Cycle / All"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.Cycle, IteratorEffectMode.All, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color Cycle / AllIndividual"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.Cycle, IteratorEffectMode.AllIndividual, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color Cycle / Single"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.Cycle, IteratorEffectMode.Single, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color Cycle / Random"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.Cycle, IteratorEffectMode.Random, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color Cycle / Bounce"); quarter.SetRandomColor(cst.Token, IteratorEffectMode.Cycle, IteratorEffectMode.Bounce, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Random color on all lights"); baseEntLayer.To2DGroup().SetRandomColor(cst.Token, IteratorEffectMode.All, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); //Uncomment for demo using a secondary layer //var secondGroup = stream.GetNewLayer(); //secondGroup.FlashQuick(new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Cycle, waitTime: TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); //Group demo //Console.WriteLine("Group demo"); ////var groups = new List<IEnumerable<EntertainmentLight>>() { line1, line2, line3, line4, line5 }; //var groups = allLightsOrderedFlat.ChunkBy(5); //var groupstest = allLightsOrderedFlat.ChunkByGroupNumber(4); //groups.IteratorEffect(async (current, duration) => { // //var r = new Random(); // //var color = new RGBColor(r.NextDouble(), r.NextDouble(), r.NextDouble()); // //current.SetState(color, 1); // current.SetRandomColor(IteratorEffectMode.All, TimeSpan.FromMilliseconds(5000), duration: duration); //}, IteratorEffectMode.All, TimeSpan.FromMilliseconds(500)); //cst = WaitCancelAndNext(cst); //Random color from center Console.WriteLine("Fill white color from center"); await orderedByDistance.SetColor(cst.Token, new RGBColor("FFFFFF"), IteratorEffectMode.Single, waitTime : () => TimeSpan.FromMilliseconds(50)); cst = WaitCancelAndNext(cst); //Random color from center Console.WriteLine("Fill red color order by angle from center"); await orderedByAngle.SetColor(cst.Token, new RGBColor("FF0000"), IteratorEffectMode.Single, waitTime : () => TimeSpan.FromMilliseconds(50)); cst = WaitCancelAndNext(cst); Console.WriteLine("A pulse of random color is placed on an XY grid, matching your entertainment setup"); var randomPulseEffect = new RandomPulseEffect(); baseEntLayer.PlaceEffect(randomPulseEffect); randomPulseEffect.Start(); cst = WaitCancelAndNext(cst); randomPulseEffect.Stop(); Console.WriteLine("A pulse of random color is placed on an XY grid, matching your entertainment setup"); var randomPulseEffectNoFade = new RandomPulseEffect(false); baseEntLayer.PlaceEffect(randomPulseEffectNoFade); randomPulseEffectNoFade.Start(); cst = WaitCancelAndNext(cst); randomPulseEffectNoFade.Stop(); Console.WriteLine("Different random colors on all lights"); baseEntLayer.To2DGroup().SetRandomColor(cst.Token, IteratorEffectMode.AllIndividual, waitTime: () => TimeSpan.FromMilliseconds(500)); cst = WaitCancelAndNext(cst); Console.WriteLine("Trailing light effect with transition times"); allLightsOrdered.Flash(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FF0000"), IteratorEffectMode.Cycle, waitTime: () => TimeSpan.FromMilliseconds(500), transitionTimeOn: () => TimeSpan.FromMilliseconds(1000), transitionTimeOff: () => TimeSpan.FromMilliseconds(1000), waitTillFinished: false); cst = WaitCancelAndNext(cst); Console.WriteLine("Knight rider (works best with 6+ lights)"); allLightsOrdered.KnightRider(cst.Token); cst = WaitCancelAndNext(cst); Ref <TimeSpan> waitTime = TimeSpan.FromMilliseconds(750); Console.WriteLine("Flash lights (750ms), press enter to decrease by 200 ms"); allLightsOrdered.FlashQuick(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Cycle, waitTime: () => waitTime); Console.ReadLine(); waitTime.Value -= TimeSpan.FromMilliseconds(200); Console.WriteLine($"Flash ({waitTime.Value.TotalMilliseconds})"); Console.ReadLine(); waitTime.Value -= TimeSpan.FromMilliseconds(200); Console.WriteLine($"Flash ({waitTime.Value.TotalMilliseconds})"); Console.ReadLine(); waitTime.Value -= TimeSpan.FromMilliseconds(200); Console.WriteLine($"Flash ({waitTime.Value.TotalMilliseconds})"); Console.ReadLine(); waitTime.Value -= TimeSpan.FromMilliseconds(100); Console.WriteLine($"Flash ({waitTime.Value.TotalMilliseconds})"); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash on random lights"); allLightsOrdered.FlashQuick(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.Random, waitTime: () => waitTime); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash on ALL lights"); waitTime.Value = TimeSpan.FromMilliseconds(150); allLightsOrdered.Flash(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FFFFFF"), IteratorEffectMode.All, waitTime: () => waitTime); cst = WaitCancelAndNext(cst); Console.WriteLine("Flash effect with transition times"); baseEntLayer.GetLeft().To2DGroup().Flash(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FF0000"), IteratorEffectMode.All, waitTime: () => TimeSpan.FromSeconds(1), transitionTimeOn: () => TimeSpan.FromMilliseconds(1000), transitionTimeOff: () => TimeSpan.FromMilliseconds(1000)); await Task.Delay(2000); baseEntLayer.GetRight().To2DGroup().Flash(cst.Token, new Q42.HueApi.ColorConverters.RGBColor("FF0000"), IteratorEffectMode.All, waitTime: () => TimeSpan.FromSeconds(1), transitionTimeOn: () => TimeSpan.FromMilliseconds(1000), transitionTimeOff: () => TimeSpan.FromMilliseconds(1000)); cst = WaitCancelAndNext(cst); Console.WriteLine("A red light that is moving in vertical direction and is placed on an XY grid, matching your entertainment setup"); var redLightEffect = new RedLightEffect(); redLightEffect.Radius = 0.7; redLightEffect.Y = -0.8; redLightEffect.X = -0.8; baseEntLayer.PlaceEffect(redLightEffect); redLightEffect.Start(); Task.Run(async() => { double step = 0.2; while (true) { redLightEffect.Y += step; await Task.Delay(100); if (redLightEffect.Y >= 2) { step = -0.1; } if (redLightEffect.Y <= -2) { step = +0.1; } } }, cst.Token); cst = WaitCancelAndNext(cst); redLightEffect.Stop(); Console.WriteLine("Thank you for using Q42.Hue.Streaming. This library was developed during Christmas 2017."); await allLightsOrdered.Christmas(cst.Token); cst = WaitCancelAndNext(cst); Console.WriteLine("Press Enter to Exit"); Console.ReadLine(); }
public static async Task Setup(CancellationToken token) { var bridges = await HueBridgeDiscovery.FastDiscoveryWithNetworkScanFallbackAsync(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(30)); var bridge = bridges.FirstOrDefault(); RegisterEntertainmentResult registeredInfos; // Is the Hue credentials present ? if (!File.Exists(credentialPath)) { Console.WriteLine("No credentials found please press the bridge button"); // Wait for the user to press the link button await Task.Delay(TimeSpan.FromSeconds(30)); var client = new LocalHueClient(bridge.IpAddress); registeredInfos = await client.RegisterAsync("ScreenHueSync", Environment.MachineName, true); hueCredential = new HueCredential() { Username = registeredInfos.Username, Key = registeredInfos.StreamingClientKey }; File.WriteAllText(credentialPath, Newtonsoft.Json.JsonConvert.SerializeObject(hueCredential)); Console.WriteLine("Registration success credentials are :"); Console.WriteLine("Username : "******"Key : " + registeredInfos.StreamingClientKey); } else { hueCredential = Newtonsoft.Json.JsonConvert.DeserializeObject <HueCredential>(File.ReadAllText(credentialPath)); } registeredInfos = new RegisterEntertainmentResult() { Username = hueCredential.Username, StreamingClientKey = hueCredential.Key }; Console.WriteLine("Get client"); Client = new StreamingHueClient(bridge.IpAddress, registeredInfos.Username, registeredInfos.StreamingClientKey); //Get the entertainment group Console.WriteLine("Get entertainment group"); var all = await Client.LocalHueClient.GetEntertainmentGroups(); var group = all.Last(); //Create a streaming group Console.WriteLine("Get streaming group"); StreamingGroup = new StreamingGroup(group.Locations); //Connect to the streaming group Console.WriteLine("Connect to group"); await Client.Connect(group.Id); Console.WriteLine("Done !"); BaseLayer = StreamingGroup.GetNewLayer(true); Ready = true; //Start auto updating this entertainment group _ = Client.AutoUpdate(StreamingGroup, token, 50); }
public async Task Start() { StreamingGroup stream = await StreamingSetup.SetupAndReturnGroup(); var baseEntLayer = stream.GetNewLayer(isBaseLayer: true); var effectLayer = stream.GetNewLayer(); //Optional: calculated effects that are placed on this layer baseEntLayer.AutoCalculateEffectUpdate(new CancellationToken()); effectLayer.AutoCalculateEffectUpdate(new CancellationToken()); //Order lights based on position in the room var orderedLeft = baseEntLayer.GetLeft().OrderByDescending(x => x.LightLocation.Y).ThenBy(x => x.LightLocation.X).To2DGroup(); var orderedRight = baseEntLayer.GetRight().OrderByDescending(x => x.LightLocation.Y).ThenByDescending(x => x.LightLocation.X); var allLightsOrdered = baseEntLayer.OrderBy(x => x.LightLocation.X).ThenBy(x => x.LightLocation.Y).ToList().To2DGroup(); var allLightsOrderedFlat = baseEntLayer.OrderBy(x => x.LightLocation.X).ThenBy(x => x.LightLocation.Y).ToList(); var orderedByDistance = baseEntLayer.OrderBy(x => x.LightLocation.Distance(0, 0)).To2DGroup(); var orderedByAngle = baseEntLayer.OrderBy(x => x.LightLocation.Angle(0, 0)).To2DGroup(); var line1 = baseEntLayer.Where(x => x.LightLocation.X <= -0.6).ToList(); var line2 = baseEntLayer.Where(x => x.LightLocation.X > -0.6 && x.LightLocation.X <= -0.1).ToList(); var line3 = baseEntLayer.Where(x => x.LightLocation.X > -0.1 && x.LightLocation.X <= 0.1).ToList(); var line4 = baseEntLayer.Where(x => x.LightLocation.X > 0.1 && x.LightLocation.X <= 0.6).ToList(); var line5 = baseEntLayer.Where(x => x.LightLocation.X > 0.6).ToList(); var allLightsReverse = allLightsOrdered.ToList(); allLightsReverse.Reverse(); CancellationTokenSource cst = new CancellationTokenSource(); //Console.WriteLine("Blue line on 90 degree angle"); //var blueLineEffect = new HorizontalScanLineEffect(); //baseEntLayer.PlaceEffect(blueLineEffect); //blueLineEffect.Start(); //cst = WaitCancelAndNext(cst); //blueLineEffect.Stop(); //Ref<int?> stepSize = 20; //blueLineEffect.Rotate(stepSize); //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.ReadLine(); //stepSize.Value -= 5; //Console.WriteLine("Finished"); //cst = WaitCancelAndNext(cst); //blueLineEffect.Stop(); var quarter = new[] { baseEntLayer.GetLeft().GetFront(), baseEntLayer.GetLeft().GetBack(), baseEntLayer.GetRight().GetBack(), baseEntLayer.GetRight().GetFront() }.ToList(); baseEntLayer.SetState(cst.Token, new RGBColor("FFFFFF"), 1); cst = WaitCancelAndNext(cst); Console.WriteLine("Transition to red in 10 seconds"); baseEntLayer.SetState(cst.Token, new RGBColor("FF0000"), TimeSpan.FromSeconds(10)); Console.ReadLine(); Console.WriteLine("Transition to bri 0.25"); baseEntLayer.SetState(cst.Token, null, default, 0.25, TimeSpan.FromSeconds(1), true);
public async Task Run(CancellationToken token, string ip = null) { try { if (ip == null) { ip = await FindBridge(); } token.ThrowIfCancellationRequested(); var appKey = prefs.GetString("HueSaber", "appKey"); var clientKey = prefs.GetString("HueSaber", "clientKey"); log.Info("Connecting to bridge..."); var client = new StreamingHueClient(ip, appKey, clientKey); token.ThrowIfCancellationRequested(); log.Info("Connected! Getting entertainment group..."); var group = (await client.LocalHueClient.GetEntertainmentGroups()).ElementAtOrDefault(prefs.GetInt("HueSaber", "overrideRoom", 0)); if (group == null) { log.Error("Group is missing!"); return; } token.ThrowIfCancellationRequested(); var entGroup = new StreamingGroup(group.Locations); log.Info("Found group! Connecting to lightbulbs..."); await client.Connect(group.Id); token.ThrowIfCancellationRequested(); log.Info("Connected to bulbs! Tracking background color..."); _ = client.AutoUpdate(entGroup, token); var layer = entGroup.GetNewLayer(true); while (!token.IsCancellationRequested) { //log.Info($"Color is {currentColor}"); var color = (Color)currentColor; var miss = DateTimeOffset.UtcNow - (DateTimeOffset)missTime; var cut = DateTimeOffset.UtcNow - (DateTimeOffset)cutTime; var rgbColor = new RGBColor(color.r, color.g, color.b); var hsbColor = rgbColor.GetHSB(); if (hsbColor.Saturation > 35) { hsbColor.Saturation = 200; } var brightness = 0.7; if (miss < TimeSpan.FromMilliseconds(100)) { brightness = 0.5; } else if (cut < TimeSpan.FromMilliseconds(100)) { brightness = 1; } layer.SetState(token, hsbColor.GetRGB(), brightness, TimeSpan.FromMilliseconds(50)); await Task.Delay(TimeSpan.FromMilliseconds(1000.0 / 30.0), token); } } catch (Exception ex) { log.Error(ex); throw; } }