Skip to content

Commit d44f5a0

Browse files
Add light's color control
1 parent 6a636c6 commit d44f5a0

2 files changed

Lines changed: 91 additions & 11 deletions

File tree

Home Assistant Taskbar Menu/Entities/Entity.cs

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,16 @@ protected double GetDoubleAttribute(string name)
7575

7676
protected double ParseDouble(string value)
7777
{
78-
return double.Parse(value?.Replace(",", ".") ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture);
78+
return value?.Length == 0
79+
? 0
80+
: double.Parse(value?.Replace(",", ".") ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture);
7981
}
8082

8183
protected int ParseInt(string value)
8284
{
83-
return int.Parse(value?.Replace(",", ".") ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture);
85+
return value?.Length == 0
86+
? 0
87+
: int.Parse(value?.Replace(",", ".") ?? "0", NumberStyles.Any, CultureInfo.InvariantCulture);
8488
}
8589

8690
protected List<string> GetListAttribute(string name)
@@ -90,6 +94,12 @@ protected List<string> GetListAttribute(string name)
9094
: new List<string>();
9195
}
9296

97+
protected string GetListAttribute(string name, int index)
98+
{
99+
var attribute = GetListAttribute(name);
100+
return attribute.Count > index ? attribute[index] : "";
101+
}
102+
93103
protected virtual List<string> OffStates()
94104
{
95105
return new List<string>();
@@ -154,31 +164,50 @@ protected MenuItem CreateMenuItem(Dispatcher dispatcher, string service, string
154164
}
155165

156166
protected Slider CreateSlider(Dispatcher dispatcher, double min, double max, double value, string service,
157-
string toolTip, string attribute, double step = 1)
167+
string toolTip, string attribute, double step = 1, Action<Slider, double> changer = null,
168+
Func<double, object> converter = null)
158169
{
159170
var slider = new Slider
160171
{
161172
Minimum = min, Maximum = max, MinWidth = 100, ToolTip = toolTip, Value = value,
162173
IsSnapToTickEnabled = true,
163-
TickFrequency = step
174+
TickFrequency = step,
175+
IsMoveToPointEnabled = true
164176
};
165177
slider.PreviewMouseUp += (sender, args) =>
166178
{
167-
HaClientContext.CallService(dispatcher, this, service,
168-
Tuple.Create<string, object>(attribute, step == 1 ? (int) slider.Value : slider.Value));
179+
if (converter == null)
180+
{
181+
HaClientContext.CallService(dispatcher, this, service,
182+
Tuple.Create<string, object>(attribute, step == 1 ? (int) slider.Value : slider.Value));
183+
}
184+
else
185+
{
186+
HaClientContext.CallService(dispatcher, this, service,
187+
Tuple.Create(attribute, converter.Invoke(slider.Value)));
188+
}
169189
};
190+
191+
if (changer != null)
192+
{
193+
slider.ValueChanged += (sender, args) => changer.Invoke(slider, args.NewValue);
194+
changer.Invoke(slider, value);
195+
}
196+
170197
return slider;
171198
}
172199

173200
protected void AddSliderIfSupported(Dispatcher dispatcher, ItemsControl root, int supportedFeature, double min,
174-
double max, double value, string attribute, double step = 1)
201+
double max, double value, string attribute, double step = 1, Action<Slider, double> changer = null,
202+
Func<double, object> converter = null)
175203
{
176204
var supportedFeatures = GetSupportedFeatures();
177205
var featureToServiceMap = FeatureToServiceMap();
178206
if (supportedFeatures.Contains(supportedFeature) && featureToServiceMap.ContainsKey(supportedFeature))
179207
{
180208
var (service, header) = featureToServiceMap[supportedFeature];
181-
root.Items.Add(CreateSlider(dispatcher, min, max, value, service, header, attribute, step));
209+
root.Items.Add(CreateSlider(dispatcher, min, max, value, service, header, attribute, step, changer,
210+
converter));
182211
}
183212
}
184213

Home Assistant Taskbar Menu/Entities/Light.cs

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
using System.Collections.Generic;
1+
using System;
2+
using System.Collections.Generic;
23
using System.Windows.Controls;
34
using System.Windows.Input;
5+
using System.Windows.Media;
46
using System.Windows.Threading;
57
using Home_Assistant_Taskbar_Menu.Connection;
68
using MaterialDesignThemes.Wpf;
@@ -64,11 +66,17 @@ protected override MenuItem ToMenuItem(Dispatcher dispatcher, string name)
6466
GetIntAttribute("brightness"), "brightness");
6567
AddSliderIfSupported(dispatcher, root, SupportedFeatures.ColorTemp, GetIntAttribute("min_mireds"),
6668
GetIntAttribute("max_mireds"), GetIntAttribute("color_temp", GetIntAttribute("min_mireds")),
67-
"color_temp");
69+
"color_temp",
70+
changer: (slider, value) => slider.Foreground = new SolidColorBrush(FromMireds(slider, value)));
6871
AddSliderIfSupported(dispatcher, root, SupportedFeatures.WhiteValue, 0, 255,
6972
GetIntAttribute("white_value"), "white_value");
73+
AddSliderIfSupported(dispatcher, root, SupportedFeatures.SupportColor, 0, 360,
74+
ParseDouble(GetListAttribute("hs_color", 0)), "hs_color", 1,
75+
(slider, value) => slider.Foreground = new SolidColorBrush(FromHue(value)),
76+
converter: value => new[] {(int) value, 100});
7077
}
7178

79+
7280
return root;
7381
}
7482

@@ -90,16 +98,59 @@ private static class SupportedFeatures
9098

9199
public static List<int> All = new List<int>
92100
{
93-
Brightness, ColorTemp, WhiteValue
101+
Brightness, ColorTemp, WhiteValue, SupportColor
94102
};
95103

96104
public static Dictionary<int, (string service, string header)> ServiceMap =
97105
new Dictionary<int, (string service, string header)>
98106
{
99107
{Brightness, (service: "turn_on", header: "Brightness")},
100108
{ColorTemp, (service: "turn_on", header: "Color Temperature")},
109+
{SupportColor, (service: "turn_on", header: "Color")},
101110
{WhiteValue, (service: "turn_on", header: "White Value")}
102111
};
103112
}
113+
114+
private Color FromHue(double hue)
115+
{
116+
int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
117+
double f = hue / 60 - Math.Floor(hue / 60);
118+
119+
byte v = 255;
120+
byte p = 0;
121+
byte q = (byte) (255 * (1 - f));
122+
byte t = (byte) (255 * (1 - (1 - f)));
123+
124+
switch (hi)
125+
{
126+
case 0:
127+
return Color.FromArgb(255, v, t, p);
128+
case 1:
129+
return Color.FromArgb(255, q, v, p);
130+
case 2:
131+
return Color.FromArgb(255, p, v, t);
132+
case 3:
133+
return Color.FromArgb(255, p, q, v);
134+
case 4:
135+
return Color.FromArgb(255, t, p, v);
136+
default:
137+
return Color.FromArgb(255, v, p, q);
138+
}
139+
}
140+
141+
private Color FromMireds(Slider slider, double mireds)
142+
{
143+
double percent = (mireds - slider.Minimum) / (slider.Maximum - slider.Minimum);
144+
if (percent >= 0.5)
145+
{
146+
percent = 2 * (percent - 0.5);
147+
return Color.Add(Color.Multiply(Colors.White, (float) (1 - percent)),
148+
Color.Multiply(Color.FromRgb(255, 160, 0), (float) percent));
149+
}
150+
151+
percent = 2 * percent;
152+
return Color.Add(Color.Multiply(Color.FromRgb(166, 209, 255), (float) (1 - percent)),
153+
Color.Multiply(Colors.White, (float) percent));
154+
}
104155
}
105156
}

0 commit comments

Comments
 (0)