private async Task SetEffectsForDevices() { if (_device.OperationMode == OperationMode.Schedule) { var activeTrigger = UserSettings.Settings.GetActiveTimeTriggerForDevice(_device.Name); //Only switch effects if the effect is different from the previously activated effect if ((activeTrigger == null && _previouslyActivatedEffect != null) || (activeTrigger != null && activeTrigger.EffectName != _previouslyActivatedEffect)) { if (activeTrigger == null) { _logger.Info($"Scheduler turning device {_device.IPAddress} off"); var client = NanoleafClient.GetClientForDevice(_device); //There are no triggers so the lights can be turned off if it is not off already await client.StateEndpoint.SetStateWithStateCheckAsync(false); } else { _logger.Info($"Scheduler activating effect {activeTrigger.EffectName} with brightness {activeTrigger.Brightness} for device {_device.IPAddress}"); var orchestrator = OrchestratorCollection.GetOrchestratorForDevice(_device); await orchestrator.ActivateEffect(activeTrigger.EffectName, activeTrigger.Brightness); } _previouslyActivatedEffect = activeTrigger?.EffectName; } } }
/// <summary> /// Activates an effect by name and brightness. This can be a custom effect (e.g. screen mirror) or a effect available on the Nanoleaf device /// First deactivates any custom effects before enabling the new effect /// </summary> public async Task ActivateEffect(string effectName, int brightness) { try { var client = NanoleafClient.GetClientForDevice(Device); //DO NOT change the order of disabling effects, then setting brightness and then enabling effects if (_customEffects.HasActiveEffects(effectName)) { await _customEffects.DeactivateAllEffects(); } await client.StateEndpoint.SetBrightnessAsync(brightness); if (_customEffects.EffectIsCustomEffect(effectName)) { var customEffect = _customEffects.GetCustomEffect(effectName); if (!customEffect.IsActive()) { await customEffect.Activate(); } } else { await client.EffectsEndpoint.SetSelectedEffectAsync(effectName); } } catch (Exception e) { _logger.Error(e, $"Enabling effect failed for device {Device.Name} with trigger effect {effectName}"); } }
/// <summary> /// Initializes a new instance of the <see cref="CustomEffectsCollection"/> class. /// </summary> /// <param name="device">The device to be used to generate a <see cref="NanoleafClient"/></param> /// <param name="orchestrator">The orchestrator instance currently in use.</param> public CustomEffectsCollection(Device device, Orchestrator orchestrator) { var nanoleafClient = NanoleafClient.GetClientForDevice(device); _customEffects = new Dictionary <string, ICustomEffect>(); var customColorEffects = UserSettings.Settings.CustomEffects; if (customColorEffects != null && customColorEffects.Any()) { foreach (var customColorEffect in customColorEffects) { var effect = new CustomColorEffect(nanoleafClient, customColorEffect.Color, customColorEffect.EffectName); _customEffects.Add(effect.GetName(), effect); } } //We will not translate effect names since their names are identifiers var screenMirrorEffect = new ScreenMirrorEffect(device, orchestrator, nanoleafClient); _customEffects.Add(screenMirrorEffect.GetName(), screenMirrorEffect); var turnOffEffect = new TurnOffEffect(nanoleafClient); _customEffects.Add(turnOffEffect.GetName(), turnOffEffect); }
/// <summary> /// Initializes a new instance of the <see cref="CustomEffectsCollection"/> class. /// </summary> /// <param name="orchestrator">The orchestrator instance currently in use.</param> public CustomEffectsCollection(Orchestrator orchestrator) { var nanoleafClient = NanoleafClient.GetClientForDevice(orchestrator.Device); _customEffects = new Dictionary <string, ICustomEffect>(); var customColorEffects = UserSettings.Settings.CustomEffects; if (customColorEffects != null && customColorEffects.Any()) { foreach (var customColorEffect in customColorEffects) { var effect = new CustomColorEffect(nanoleafClient, customColorEffect.Color, customColorEffect.EffectName); _customEffects.Add(effect.GetName(), effect); } } //We will not translate effect names since their names are identifiers if (ScreenMirrorEffect.SupportedDeviceTypes.Contains(orchestrator.PanelLayout.DeviceType)) { //Only add screen mirror to supported devices var screenMirrorEffect = new ScreenMirrorEffect(orchestrator, nanoleafClient); _customEffects.Add(screenMirrorEffect.GetName(), screenMirrorEffect); } var turnOffEffect = new TurnOffEffect(nanoleafClient); _customEffects.Add(turnOffEffect.GetName(), turnOffEffect); }
public void UpdateColors() { if (UserSettings.Settings.ActiveDevice == null || _triangles == null) { return; } var client = NanoleafClient.GetClientForDevice(UserSettings.Settings.ActiveDevice); //Get colors of current effect var effect = client.EffectsEndpoint.GetEffectDetails(OrchestratorCollection.GetOrchestratorForDevice(UserSettings.Settings.ActiveDevice).GetActiveEffectName()); Dispatcher.Invoke(new Action(() => { if (effect == null) { foreach (var triangle in _triangles) { triangle.Polygon.Fill = Brushes.LightSlateGray; } } else { var colors = effect.Palette.Select(hsb => new SolidColorBrush( HsbToRgbConverter.ConvertToMediaColor(hsb.Hue, hsb.Saturation, hsb.Brightness) )).ToList(); foreach (var triangle in _triangles) { triangle.Polygon.Fill = colors[_random.Next(colors.Count)]; } } })); }
public PanelLayout(Device device) { _nanoleafClient = NanoleafClient.GetClientForDevice(device); _unscaledPolygons = new List <DrawablePanel>(); GetLayout(); }
public void UpdateColors() { if (UserSettings.Settings.ActiveDevice == null || _triangles == null) { return; } //Run code on main thread since we update the UI Dispatcher.Invoke(new Action(() => { var client = NanoleafClient.GetClientForDevice(UserSettings.Settings.ActiveDevice); var orchestrator = OrchestratorCollection.GetOrchestratorForDevice(UserSettings.Settings.ActiveDevice); //Get colors of current effect, we can display colors for nanoleaf effects or custom color effects var effectName = orchestrator.GetActiveEffectName(); var customEffect = orchestrator.GetCustomEffectFromName(effectName); List <SolidColorBrush> colors = null; if (customEffect != null) { if (customEffect is CustomColorEffect customColorEffect) { colors = new List <SolidColorBrush>() { new SolidColorBrush(Color.FromArgb(customColorEffect.Color.A, customColorEffect.Color.R, customColorEffect.Color.G, customColorEffect.Color.B)) }; } } else { var effect = client.EffectsEndpoint.GetEffectDetails(OrchestratorCollection.GetOrchestratorForDevice(UserSettings.Settings.ActiveDevice).GetActiveEffectName()); if (effect != null) { colors = effect.Palette.Select(hsb => new SolidColorBrush( HsbToRgbConverter.ConvertToMediaColor(hsb.Hue, hsb.Saturation, hsb.Brightness) )).ToList(); } } if (colors == null) { foreach (var triangle in _triangles) { triangle.Polygon.Fill = Brushes.LightSlateGray; } } else { foreach (var triangle in _triangles) { triangle.Polygon.Fill = colors[_random.Next(colors.Count)]; } } })); }
/// <summary> /// Initializes a new instance of the <see cref="CustomEffectsCollection"/> class. /// </summary> /// <param name="device">The device to be used to generate a <see cref="NanoleafClient"/></param> /// <param name="orchestrator">The orchestrator instance currently in use.</param> public CustomEffectsCollection(Device device, Orchestrator orchestrator) { var _nanoleafClient = NanoleafClient.GetClientForDevice(device); _customEffects = new Dictionary <string, ICustomEffect> { //We will not translate effect names since their names are identifiers { ScreenMirrorEffect.Name, new ScreenMirrorEffect(device, orchestrator, _nanoleafClient) }, { $"{EffectNamePreface}Turn lights off", new TurnOffEffect(_nanoleafClient) } }; }
private async Task TurnOffLights() { //Check if any lights need to be turned off foreach (var device in UserSettings.Settings.Devices) { if (device.ActiveSchedule != null && device.ActiveSchedule.TurnOffAtApplicationShutdown) { var client = NanoleafClient.GetClientForDevice(device); await client.StateEndpoint.SetStateWithStateCheckAsync(false); } } }
/// <summary> /// Activates an effect by name and brightness. This can be a custom effect (e.g. screen mirror) or a effect available on the Nanoleaf device /// First deactivates any custom effects before enabling the new effect /// </summary> public async Task ActivateEffect(string effectName, int brightness) { _logger.Info($"Orchestrator is activating effect {effectName} with brightness {brightness} for device {Device.IPAddress}"); try { var client = NanoleafClient.GetClientForDevice(Device); //DO NOT change the order of disabling effects, then setting brightness and then enabling effects if (_customEffects.HasActiveEffects(effectName)) { await _customEffects.DeactivateAllEffects(); } if (_customEffects.EffectIsCustomEffect(effectName)) { var customEffect = _customEffects.GetCustomEffect(effectName); //Special case: no need to set the brightness if we are turning off the device if (customEffect.GetType() != _turnOffEffectType) { await client.StateEndpoint.SetBrightnessAsync(brightness); } if (!customEffect.IsActive()) { await customEffect.Activate(); } } else { await client.StateEndpoint.SetBrightnessAsync(brightness); await client.EffectsEndpoint.SetSelectedEffectAsync(effectName); } //Finally, trigger effect changed callback TriggerEffectChangedCallbacks(); } catch (Exception e) { _logger.Error(e, $"Enabling effect failed for device {Device.Name} with trigger effect {effectName}"); } }
private async Task SetEffectsForDevices() { if (_orchestrator.Device.OperationMode == OperationMode.Schedule) { var activeTrigger = _orchestrator.Device.GetActiveTimeTrigger(); if (activeTrigger == null) { var client = NanoleafClient.GetClientForDevice(_orchestrator.Device); //There are no triggers so the lights can be turned off if it is not off already await client.StateEndpoint.SetStateWithStateCheckAsync(false); } else { await _orchestrator.ActivateEffect(activeTrigger.Effect, activeTrigger.Brightness); } } }
protected BaseProcessPercentageEventTrigger(ITrigger trigger, Orchestrator orchestrator, string processName) { _trigger = trigger; _orchestrator = orchestrator; _processName = processName; var client = NanoleafClient.GetClientForDevice(_orchestrator.Device); _externalControlEndpoint = client.ExternalControlEndpoint; //Check if the user has somehow messed up their percentage profile, then we create a single step percentage profile if (_orchestrator.Device.PercentageProfile == null || _orchestrator.Device.PercentageProfile.Steps.Count == 0) { _percentageProfile = new PercentageProfile(); var step = new PercentageStep(); foreach (var panel in client.LayoutEndpoint.GetLayout().PanelPositions) { step.PanelIds.Add(panel.PanelId); } _percentageProfile.Steps.Add(step); _percentagePerStep = 100f; _amountOfSteps = 1; } else { _percentageProfile = _orchestrator.Device.PercentageProfile; _amountOfSteps = _percentageProfile.Steps.Count; _percentagePerStep = 100f / _amountOfSteps; } var processCheckTimer = new Timer(60000); processCheckTimer.Elapsed += CheckProcess; processCheckTimer.AutoReset = true; processCheckTimer.Start(); _effectTimer = new Timer(100); _effectTimer.Elapsed += ApplyEffect; _effectTimer.AutoReset = true; }
/// <summary> /// Initializes a new instance of the <see cref="CustomEffectsCollection"/> class. /// </summary> /// <param name="device">The device to be used to generate a <see cref="NanoleafClient"/></param> /// <param name="orchestrator">The orchestrator instance currently in use.</param> public CustomEffectsCollection(Device device, Orchestrator orchestrator) { var nanoleafClient = NanoleafClient.GetClientForDevice(device); _customEffects = new Dictionary <string, ICustomEffect>(); var customColorEffects = UserSettings.Settings.CustomEffects; if (customColorEffects != null && customColorEffects.Any()) { foreach (var customColorEffect in customColorEffects) { _customEffects.Add($"{CustomColorNamePreface}{customColorEffect.EffectName}", new CustomColorEffect(nanoleafClient, customColorEffect.Color)); } } //We will not translate effect names since their names are identifiers _customEffects.Add(ScreenMirrorEffect.Name, new ScreenMirrorEffect(device, orchestrator, nanoleafClient)); _customEffects.Add($"{EffectNamePreface}Turn lights off", new TurnOffEffect(nanoleafClient)); }
public void UpdateColors() { if (UserSettings.Settings.ActiveDevice == null || _polygons == null) { return; } //Run code on main thread since we update the UI Dispatcher.Invoke(new Action(() => { var orchestrator = OrchestratorCollection.GetOrchestratorForDevice(UserSettings.Settings.ActiveDevice); //Get colors of current effect, we can display colors for nanoleaf effects or custom color effects var effectName = orchestrator.GetActiveEffectName(); ICustomEffect customEffect = null; if (effectName != null) { customEffect = orchestrator.GetCustomEffectFromName(effectName); } List <SolidColorBrush> colors = null; if (customEffect != null) { if (customEffect is CustomColorEffect customColorEffect) { colors = new List <SolidColorBrush>() { new SolidColorBrush(Color.FromArgb(customColorEffect.Color.A, customColorEffect.Color.R, customColorEffect.Color.G, customColorEffect.Color.B)) }; } } else { var effect = UserSettings.Settings.ActiveDevice.Effects.FirstOrDefault(effect => effect.Name == effectName); //Only retrieve palette if it is not known yet if (effect?.Palette == null) { var client = NanoleafClient.GetClientForDevice(UserSettings.Settings.ActiveDevice); effect = client.EffectsEndpoint.GetEffectDetails(effectName); if (effect != null) { //Update the effect such that the palette is known in the future UserSettings.Settings.ActiveDevice.UpdateEffect(effect); } } if (effect != null) { colors = effect.Palette.Select(hsb => new SolidColorBrush( HsbToRgbConverter.ConvertToMediaColor(hsb.Hue, hsb.Saturation, hsb.Brightness) )).ToList(); } } if (colors == null) { foreach (var polygon in _polygons) { polygon.Polygon.Fill = Brushes.LightSlateGray; } } else { foreach (var polygon in _polygons) { polygon.Polygon.Fill = colors[_random.Next(colors.Count)]; } } })); }
/// <summary> /// Builds the effects list from the given effects. /// Also updates retrieved effects for all given devices passed /// in <paramref name="orchestrators"/>. /// </summary> private void BuildEffects(IEnumerable <ICustomEffect> customEffects, IEnumerable <Effect> deviceEffects, IEnumerable <Orchestrator> orchestrators) { var effects = new List <EffectComboBoxItemViewModel>(); //Take any client. Since the dropdown will only display effects shared accross all devices, it does not matter which lights we use to query the effects var nanoleafClient = NanoleafClient.GetClientForDevice(orchestrators.First().Device); foreach (var customEffect in customEffects) { effects.Add(new EffectComboBoxItemViewModel() { EffectName = customEffect.GetName(), Width = (int)Width, Colors = customEffect.GetColors().Select(color => Color.FromArgb(color.A, color.R, color.G, color.B)), EffectType = ICustomEffect.EffectType }); } var requestFailed = false; foreach (var effect in deviceEffects) { if (requestFailed) { effects.Add(new EffectComboBoxItemViewModel() { EffectName = effect.Name, Width = (int)Width, Colors = _defaultColors, EffectType = EffectType.Unknown }); } try { //This executes a request, if 1 fails, let all others revert to blank automatically //We do this because we do not want to execute lots of requests and wait till failure for each request var effectWithPalette = effect; if (effect.Palette == null || !effect.Palette.Any()) { effectWithPalette = nanoleafClient.EffectsEndpoint.GetEffectDetails(effect.Name); //Replace the retrieved effect with the current effect such that we do not have to make this call in the future //Do this for each device in the given orchestrators foreach (var orchestrator in orchestrators) { orchestrator.Device.UpdateEffect(effectWithPalette); } } effects.Add(new EffectComboBoxItemViewModel() { EffectName = effectWithPalette.Name, Width = (int)Width, Colors = effectWithPalette.Palette.Select(palette => HsbToRgbConverter.ConvertToMediaColor(palette.Hue, palette.Saturation, palette.Brightness)), EffectType = effectWithPalette.EffectType }); } catch { requestFailed = true; effects.Add(new EffectComboBoxItemViewModel() { EffectName = effect.Name, Width = (int)Width, Colors = _defaultColors, EffectType = EffectType.Unknown }); } } Effects = new ObservableCollection <EffectComboBoxItemViewModel>(effects); OnPropertyChanged(nameof(Effects)); }