diff --git a/HueUWP/APIHandler.cs b/HueUWP/APIHandler.cs index ce24744..663c08b 100755 --- a/HueUWP/APIHandler.cs +++ b/HueUWP/APIHandler.cs @@ -1,4 +1,5 @@ -using Newtonsoft.Json.Linq; +using HueUWP.Helpers; +using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -8,6 +9,7 @@ using System.Text; using System.Threading.Tasks; using System.Threading; using Windows.Storage; +using HueUWP.Lights; namespace HueUWP { @@ -15,21 +17,19 @@ namespace HueUWP { bool discomode = false; - NetworkHandler nwh; - public APIHandler(NetworkHandler nwh) + public APIHandler() { - this.nwh = nwh; } public async Task Register() { try { - var json = await nwh.RegisterName("YK Hue", "YK"); + var json = await NetworkHandler.RegisterName("YK Hue", "YK"); json = json.Replace("[", "").Replace("]", ""); JObject o = JObject.Parse(json); string id = o["success"]["username"].ToString(); - MainPage.LOCAL_SETTINGS.Values["id"] = id; + App.LOCAL_SETTINGS.Values["id"] = id; return "success"; } catch (Exception e) @@ -39,90 +39,183 @@ namespace HueUWP } } - public async void SetLightState(Light l) + public async Task UpdateGroup(Light g) { - var json = await nwh.SetLightInfo(l.ID, $"{{\"on\": {((l.IsOn) ? "true" : "false")}}}"); - Debug.WriteLine(json); + string json = await NetworkHandler.Group(g.ID); + JObject o = JObject.Parse(json); + var state = o["action"]; + + g.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false; + g.Hue = (int)state["hue"]; + g.Brightness = (int)state["bri"]; + g.Saturation = (int)state["sat"]; + + return "success"; + } - public async void SetLightState(List lights) + public async Task UpdateLight(Light l) { - lights.ForEach(l => SetLightState(l)); + string json = await NetworkHandler.Light(l.ID); + JObject o = JObject.Parse(json); + var state = o["state"]; + + l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false; + l.Hue = (int)state["hue"]; + l.Brightness = (int)state["bri"]; + l.Saturation = (int)state["sat"]; + + return "success"; } - public async void DiscoMode(ObservableCollection lights) + public async Task SetLightState(Light l) { - discomode = true; - Random rnd = new Random(); - while(discomode) + string json = "error"; + if (l is LightSingle) + json = await NetworkHandler.SetLight(l.ID, l.IsOn); + return json; + } + + + public async Task SetLightColor(Light l, bool instant = false) + { + if(l is LightSingle && l.IsOn) { - lights.ToList().ForEach(l => + var json = await NetworkHandler.SetLight(l.ID, l.Hue, l.Saturation, l.Brightness, instant); + return "success"; + } + return "error"; + } + + public async Task SetGroupState(Light l) + { + string json = "error"; + if (l is LightGroup) + json = await NetworkHandler.SetGroup(l.ID, l.IsOn); + return json; + } + + + public async Task SetGroupColor(Light l, bool instant = false) + { + if (l is LightGroup && l.IsOn) + { + var json = await NetworkHandler.SetGroup(l.ID, l.Hue, l.Saturation, l.Brightness, instant); + return "success"; + } + + return "error"; + } + + public async Task Groups(ObservableCollection groups) + { + try + { + var json = await NetworkHandler.Groups(); + JObject o = JObject.Parse(json); + foreach (var i in o) { - l.Hue = rnd.Next(0, 65535); - l.Brightness = rnd.Next(128, 254); - l.Saturation = 254; - l.UpdateColorDisco(); - }); - //"transitiontime": 0 - await Task.Delay(TimeSpan.FromMilliseconds(400)); - } - - } + var groupjson = await NetworkHandler.Group(Int32.Parse(i.Key)); + JObject o2 = JObject.Parse(groupjson); + var state = o2["action"]; - public async void DiscoMode(bool on) - { - discomode = on; - } + Light g = new LightGroup(Int32.Parse(i.Key), (string)o2["name"]); - public async Task SetLightValues(Light l) - { - if(l.IsOn) - { - Debug.WriteLine(l.Hue); - var json = await nwh.SetLightInfo(l.ID, $"{{\"bri\": {l.Brightness},\"hue\": {(l.Hue)},\"sat\": {l.Saturation}}}"); - Debug.WriteLine(json); + g.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false; + + //Hue + if (!state["hue"].IsNullOrEmpty()) + { + g.HueEnabled = true; + g.Hue = (int)state["hue"]; + } + else + g.HueEnabled = false; + + //Brightness + if (!state["bri"].IsNullOrEmpty()) + { + g.BrightnessEnabled = true; + g.Brightness = (int)state["bri"]; + } + else + g.BrightnessEnabled = false; + + //Saturation + if (!state["sat"].IsNullOrEmpty()) + { + g.SaturationEnabled = true; + g.Saturation = (int)state["sat"]; + } + else + g.SaturationEnabled = false; + + groups.Add(g); + + } return "success"; } - - return "error"; - } - public async Task SetInstantLightValues(Light l) - { - if (l.IsOn) + catch (Exception e) { - Debug.WriteLine(l.Hue); - var json = await nwh.SetLightInfo(l.ID, $"{{\"bri\": {l.Brightness},\"hue\": {(l.Hue)},\"sat\": {l.Saturation}, \"transitiontime\" : 0}}"); - Debug.WriteLine(json); - return "success"; + Debug.WriteLine(e.StackTrace); + Debug.WriteLine("Could not get all groups."); + return "error"; } - - return "error"; } - public async void SetLightValues(List lights) + public async Task Lights(ObservableCollection lights) { - lights.ForEach(l => SetLightValues(l)); - } - public async Task GetAllLights(ObservableCollection alllights) - { - // List lightlist = new List(); + //List _lights = new List(); + try { - var json = await nwh.AllLights(); + var json = await NetworkHandler.Lights(); JObject o = JObject.Parse(json); foreach(var i in o) { var light = o["" + i.Key]; var state = light["state"]; - if ((String)light["type"] != "Dimmable light") + + Light l = new LightSingle(Int32.Parse(i.Key), (string)light["name"], (string)light["type"]); + + l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false; + + //Hue + if (!state["hue"].IsNullOrEmpty()) { - alllights.Add(new Light() { api = this, ID = Int32.Parse(i.Key), Brightness = (int)state["bri"], SaturationEnabled = true, HueEnabled = true, IsOn = ((string)state["on"]).ToLower() == "true" ? true : false, Hue = (int)state["hue"], Saturation = (int)state["sat"], Name = (string)light["name"], Type = (string)light["type"] }); + l.HueEnabled = true; + l.Hue = (int)state["hue"]; } else + l.HueEnabled = false; + + //Brightness + if (!state["bri"].IsNullOrEmpty()) { - alllights.Add(new Light() { api = this, ID = Int32.Parse(i.Key), Brightness = (int)state["bri"], SaturationEnabled = false,HueEnabled = false,IsOn = ((string)state["on"]).ToLower() == "true" ? true : false, Hue =0, Saturation = 0, Name = (string)light["name"], Type = (string)light["type"] }); - }//Debug.WriteLine("Added light number " + i + " " + state["on"]); + l.BrightnessEnabled = true; + l.Brightness = (int)state["bri"]; + } + else + l.BrightnessEnabled = false; + + //Saturation + if (!state["sat"].IsNullOrEmpty()) + { + l.SaturationEnabled = true; + l.Saturation = (int)state["sat"]; + } + else + l.SaturationEnabled = false; + + lights.Add(l); } + + //if(_lights.Count > 0) + //{ + // _lights.OrderBy(l => l.Name); + // lights = new ObservableCollection(_lights); + //} + return "success"; } catch(Exception e) @@ -133,6 +226,27 @@ namespace HueUWP } } + public async void DiscoMode(ObservableCollection lights) + { + discomode = true; + Random rnd = new Random(); + while (discomode) + { + lights.ToList().Where(l => l.IsOn == true).ToList().ForEach(l => + { + l.Hue = rnd.Next(0, 65535); + l.Brightness = rnd.Next(214, 254); + l.Saturation = 254; + l.SetColor(true); + }); + await Task.Delay(TimeSpan.FromMilliseconds(lights.Count * 100)); + } + } + + public async void DiscoMode(bool on) + { + discomode = on; + } } } diff --git a/HueUWP/App.xaml.cs b/HueUWP/App.xaml.cs index 8d7314f..bc56b4e 100644 --- a/HueUWP/App.xaml.cs +++ b/HueUWP/App.xaml.cs @@ -1,4 +1,5 @@ -using System; +using HueUWP.Views; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -37,6 +38,18 @@ namespace HueUWP this.Suspending += OnSuspending; } + private static APIHandler _api; + + public static APIHandler api + { + get { + if (_api == null) + _api = new APIHandler(); + return _api; + } + } + + /// /// Invoked when the application is launched normally by the end user. Other entry points /// will be used such as when the application is launched to open a specific file. @@ -79,7 +92,7 @@ namespace HueUWP // When the navigation stack isn't restored navigate to the first page, // configuring the new page by passing required information as a navigation // parameter - rootFrame.Navigate(typeof(MainPage), e.Arguments); + rootFrame.Navigate(typeof(LightsView), e.Arguments); } if(LOCAL_SETTINGS.Values["ip"] == null) diff --git a/HueUWP/ColorUtil.cs b/HueUWP/Helpers/ColorUtil.cs old mode 100755 new mode 100644 similarity index 96% rename from HueUWP/ColorUtil.cs rename to HueUWP/Helpers/ColorUtil.cs index f469c54..cd0be93 --- a/HueUWP/ColorUtil.cs +++ b/HueUWP/Helpers/ColorUtil.cs @@ -1,197 +1,198 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Windows.UI; - -namespace HueUWP -{ - public static class ColorUtil - { - - public static Color getColor(Light light) - { - double hue = ((double)light.Hue * 360.0f) / 65535.0f; - double sat = (double)light.Saturation / 255.0f; - double val = (double)light.Brightness/ 255.0f; - - int r, g, b; - HsvToRgb(hue, sat, val, out r, out g, out b); - return Color.FromArgb(255, Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)); - } - - public static void RGBtoHSV(double r, double g, double b, out double h, out double s, out double v) - { - double min, max, delta; - - min = Math.Min(r, Math.Min(g, b)); - max = Math.Max(r, Math.Max(g, b)); - - v = max; // v - delta = max - min; - - if (max != 0) - s = delta / max; // s - else - { - // r = g = b = 0 // s = 0, v is undefined - s = 0; - h = -1; - return; - } - - if (r == max) - h = (g - b) / delta; // between yellow & magenta - else if (g == max) - h = 2 + (b - r) / delta; // between cyan & yellow - else - h = 4 + (r - g) / delta; // between magenta & cyan - - h *= 60; // degrees - - if (h < 0) - h += 360; - } - - private static void HsvToRgb(double h, double S, double V, out int r, out int g, out int b) - { - double H = h; - while (H < 0) - { - H += 360; - } - while (H >= 360) - { - H -= 360; - } - - double R, G, B; - if (V <= 0) - R = G = B = 0; - else if (S <= 0) - R = G = B = V; - else - { - double hf = H / 60.0; - int i = (int)Math.Floor(hf); - double f = hf - i; - double pv = V * (1 - S); - double qv = V * (1 - S * f); - double tv = V * (1 - S * (1 - f)); - switch (i) - { - // Red is the dominant color - case 0: - R = V; - G = tv; - B = pv; - break; - // Green is the dominant color - case 1: - R = qv; - G = V; - B = pv; - break; - case 2: - R = pv; - G = V; - B = tv; - break; - // Blue is the dominant color - case 3: - R = pv; - G = qv; - B = V; - break; - case 4: - R = tv; - G = pv; - B = V; - break; - // Red is the dominant color - case 5: - R = V; - G = pv; - B = qv; - break; - // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. - case 6: - R = V; - G = tv; - B = pv; - break; - case -1: - R = V; - G = pv; - B = qv; - break; - // The color is not defined, we should throw an error. - default: - //LFATAL("i Value error in Pixel conversion, Value is %d", i); - R = G = B = V; // Just pretend its black/white - break; - } - } - - r = Clamp((int)(R * 255.0)); - g = Clamp((int)(G * 255.0)); - b = Clamp((int)(B * 255.0)); - } - - private static int Clamp(int i) - { - if (i < 0) return 0; - if (i > 255) return 255; - return i; - } - - public static Color HsvToRgb(double hue, double sat, double val) - { - - double h = ((double)hue * 360.0f) / 65535.0f; - double s = (double)sat / 255.0f; - double v = (double)val / 255.0f; - - int hi = (int)Math.Floor(h / 60.0) % 6; - double f = (h / 60.0) - Math.Floor(h / 60.0); - - double p = v * (1.0 - s); - double q = v * (1.0 - (f * s)); - double t = v * (1.0 - ((1.0 - f) * s)); - - Color ret; - - switch (hi) - { - case 0: - ret = GetRgb(v, t, p); - break; - case 1: - ret = GetRgb(q, v, p); - break; - case 2: - ret = GetRgb(p, v, t); - break; - case 3: - ret = GetRgb(p, q, v); - break; - case 4: - ret = GetRgb(t, p, v); - break; - case 5: - ret = GetRgb(v, p, q); - break; - default: - ret = Color.FromArgb(0xFF, 0x00, 0x00, 0x00); - break; - } - return ret; - } - - public static Color GetRgb(double r, double g, double b) - { - return Color.FromArgb(255, (byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0)); - } - } -} +using HueUWP.Lights; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Windows.UI; + +namespace HueUWP.Helpers +{ + public static class ColorUtil + { + + public static Color getColor(Light light) + { + double hue = ((double)light.Hue * 360.0f) / 65535.0f; + double sat = (double)light.Saturation / 255.0f; + double val = (double)light.Brightness/ 255.0f; + + int r, g, b; + HsvToRgb(hue, sat, val, out r, out g, out b); + return Color.FromArgb(255, Convert.ToByte(r), Convert.ToByte(g), Convert.ToByte(b)); + } + + public static void RGBtoHSV(double r, double g, double b, out double h, out double s, out double v) + { + double min, max, delta; + + min = Math.Min(r, Math.Min(g, b)); + max = Math.Max(r, Math.Max(g, b)); + + v = max; // v + delta = max - min; + + if (max != 0) + s = delta / max; // s + else + { + // r = g = b = 0 // s = 0, v is undefined + s = 0; + h = -1; + return; + } + + if (r == max) + h = (g - b) / delta; // between yellow & magenta + else if (g == max) + h = 2 + (b - r) / delta; // between cyan & yellow + else + h = 4 + (r - g) / delta; // between magenta & cyan + + h *= 60; // degrees + + if (h < 0) + h += 360; + } + + private static void HsvToRgb(double h, double S, double V, out int r, out int g, out int b) + { + double H = h; + while (H < 0) + { + H += 360; + } + while (H >= 360) + { + H -= 360; + } + + double R, G, B; + if (V <= 0) + R = G = B = 0; + else if (S <= 0) + R = G = B = V; + else + { + double hf = H / 60.0; + int i = (int)Math.Floor(hf); + double f = hf - i; + double pv = V * (1 - S); + double qv = V * (1 - S * f); + double tv = V * (1 - S * (1 - f)); + switch (i) + { + // Red is the dominant color + case 0: + R = V; + G = tv; + B = pv; + break; + // Green is the dominant color + case 1: + R = qv; + G = V; + B = pv; + break; + case 2: + R = pv; + G = V; + B = tv; + break; + // Blue is the dominant color + case 3: + R = pv; + G = qv; + B = V; + break; + case 4: + R = tv; + G = pv; + B = V; + break; + // Red is the dominant color + case 5: + R = V; + G = pv; + B = qv; + break; + // Just in case we overshoot on our math by a little, we put these here. Since its a switch it won't slow us down at all to put these here. + case 6: + R = V; + G = tv; + B = pv; + break; + case -1: + R = V; + G = pv; + B = qv; + break; + // The color is not defined, we should throw an error. + default: + //LFATAL("i Value error in Pixel conversion, Value is %d", i); + R = G = B = V; // Just pretend its black/white + break; + } + } + + r = Clamp((int)(R * 255.0)); + g = Clamp((int)(G * 255.0)); + b = Clamp((int)(B * 255.0)); + } + + private static int Clamp(int i) + { + if (i < 0) return 0; + if (i > 255) return 255; + return i; + } + + public static Color HsvToRgb(double hue, double sat, double val) + { + + double h = ((double)hue * 360.0f) / 65535.0f; + double s = (double)sat / 255.0f; + double v = (double)val / 255.0f; + + int hi = (int)Math.Floor(h / 60.0) % 6; + double f = (h / 60.0) - Math.Floor(h / 60.0); + + double p = v * (1.0 - s); + double q = v * (1.0 - (f * s)); + double t = v * (1.0 - ((1.0 - f) * s)); + + Color ret; + + switch (hi) + { + case 0: + ret = GetRgb(v, t, p); + break; + case 1: + ret = GetRgb(q, v, p); + break; + case 2: + ret = GetRgb(p, v, t); + break; + case 3: + ret = GetRgb(p, q, v); + break; + case 4: + ret = GetRgb(t, p, v); + break; + case 5: + ret = GetRgb(v, p, q); + break; + default: + ret = Color.FromArgb(0xFF, 0x00, 0x00, 0x00); + break; + } + return ret; + } + + public static Color GetRgb(double r, double g, double b) + { + return Color.FromArgb(255, (byte)(r * 255.0), (byte)(g * 255.0), (byte)(b * 255.0)); + } + } +} diff --git a/HueUWP/Extensions.cs b/HueUWP/Helpers/Extensions.cs similarity index 52% rename from HueUWP/Extensions.cs rename to HueUWP/Helpers/Extensions.cs index ae7c639..2ed92df 100644 --- a/HueUWP/Extensions.cs +++ b/HueUWP/Helpers/Extensions.cs @@ -1,10 +1,11 @@ -using System; +using Newtonsoft.Json.Linq; +using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -namespace HueUWP +namespace HueUWP.Helpers { public static class Extensions { @@ -17,5 +18,14 @@ namespace HueUWP { return String.Join(delimiter, source.Select(func).ToArray()); } - } + + public static bool IsNullOrEmpty(this JToken token) + { + return (token == null) || + (token.Type == JTokenType.Array && !token.HasValues) || + (token.Type == JTokenType.Object && !token.HasValues) || + (token.Type == JTokenType.String && token.ToString() == String.Empty) || + (token.Type == JTokenType.Null); + } + } } diff --git a/HueUWP/Converters/NullableBooleanConverter.cs b/HueUWP/Helpers/NullableBooleanConverter.cs similarity index 96% rename from HueUWP/Converters/NullableBooleanConverter.cs rename to HueUWP/Helpers/NullableBooleanConverter.cs index 32fbc1b..b823b23 100644 --- a/HueUWP/Converters/NullableBooleanConverter.cs +++ b/HueUWP/Helpers/NullableBooleanConverter.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Windows.UI.Xaml.Data; -namespace HueUWP.Converters +namespace HueUWP.Helpers { public class NullableBooleanConverter : IValueConverter { diff --git a/HueUWP/Converters/VisibilityConverter.cs b/HueUWP/Helpers/VisibilityConverter.cs similarity index 96% rename from HueUWP/Converters/VisibilityConverter.cs rename to HueUWP/Helpers/VisibilityConverter.cs index a64099c..2ae5414 100644 --- a/HueUWP/Converters/VisibilityConverter.cs +++ b/HueUWP/Helpers/VisibilityConverter.cs @@ -6,7 +6,7 @@ using System.Threading.Tasks; using Windows.UI.Xaml; using Windows.UI.Xaml.Data; -namespace HueUWP.Converters +namespace HueUWP.Helpers { class VisibilityConverter : IValueConverter { diff --git a/HueUWP/HueUWP.csproj b/HueUWP/HueUWP.csproj index 8c3e07c..dac55d3 100644 --- a/HueUWP/HueUWP.csproj +++ b/HueUWP/HueUWP.csproj @@ -93,30 +93,38 @@ - + + AboutView.xaml App.xaml - - - - + + + + DetailView.xaml - - - - MainPage.xaml + + + + + + + + GroupsView.xaml + + + LightsView.xaml MultiEdit.xaml - + SettingsView.xaml @@ -143,15 +151,19 @@ MSBuild:Compile Designer - + Designer MSBuild:Compile - + Designer MSBuild:Compile - + + Designer + MSBuild:Compile + + MSBuild:Compile Designer @@ -159,7 +171,7 @@ Designer MSBuild:Compile - + Designer MSBuild:Compile diff --git a/HueUWP/Light.cs b/HueUWP/Light.cs deleted file mode 100644 index c26613c..0000000 --- a/HueUWP/Light.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.ComponentModel; -using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Input; -using Windows.UI.Xaml.Media; - -namespace HueUWP -{ - public class Light : INotifyPropertyChanged - { - public int ID { get; set; } - public string Name { get; set; } - public string Type { get; set; } - - public bool HueEnabled - { - get; set; - } - public bool SaturationEnabled { get; set; } - - private bool _isOn; - - public bool IsOn - { - get { return _isOn; } - set { _isOn = value; NotifyPropertyChanged(nameof(IsOn)); } - } - - //Hue - private double _hue; - public double Hue - { - get { return _hue; } - set { _hue = value; NotifyPropertyChanged(nameof(Hue)); NotifyPropertyChanged(nameof(Color)); } - } - - //Brightness - private double _brightness; - public double Brightness - { - get { return _brightness; } - set { _brightness = value; NotifyPropertyChanged(nameof(Brightness)); NotifyPropertyChanged(nameof(Color)); } - } - - //Saturation - private double _saturation; - public double Saturation - { - get { return _saturation; } - set { _saturation = value; NotifyPropertyChanged(nameof(Saturation)); NotifyPropertyChanged(nameof(Color)); } - } - - public APIHandler api { get; set; } - - public SolidColorBrush Color - { - get { return new SolidColorBrush(HueUWP.ColorUtil.HsvToRgb(Hue, Saturation, Brightness)); } - } - - public Light() - { - } - - public void UpdateState(bool on) - { - NotifyPropertyChanged(nameof(UpdateState)); - this.IsOn = on; - api.SetLightState(this); - - } - - public void UpdateColor() - { - api.SetLightValues(this); - } - - public void UpdateColorDisco() - { - api.SetInstantLightValues(this); - } - - public void UpdateColor(int h, int s, int b) - { - //double h; double s; double v; - //ColorUtil.RGBtoHSV(r,g,b, out h,out s,out v); - this.Hue = h; this.Saturation = s; this.Brightness = b; - api.SetLightValues(this); - } - - - public event PropertyChangedEventHandler PropertyChanged; - - private void NotifyPropertyChanged(string propertyName) - { - PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); - } - - } - - public class LightDataSource - { - private static ObservableCollection _lights - = new ObservableCollection(); - - public static ObservableCollection GetLights() - { - return _lights; - } - } - - - - -} diff --git a/HueUWP/Lights/Light.cs b/HueUWP/Lights/Light.cs new file mode 100644 index 0000000..1c201e1 --- /dev/null +++ b/HueUWP/Lights/Light.cs @@ -0,0 +1,85 @@ +using HueUWP.Helpers; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Windows.UI.Xaml.Media; + +namespace HueUWP.Lights +{ + public abstract class Light : INotifyPropertyChanged + { + public int ID { get; private set; } + public string Name { get; private set; } + public string Type { get; private set; } + + public bool HueEnabled {get; set; } + public bool SaturationEnabled { get; set; } + public bool BrightnessEnabled { get; set; } + + public Light(int id, string name, string type) + { + this.ID = id; + this.Name = name; + this.Type = type; + } + + //IsOn + protected bool _isOn = false; + public bool IsOn + { + get { return _isOn; } + set { _isOn = value; NotifyPropertyChanged(nameof(IsOn)); } + } + + //Hue + protected int _hue = 0; + public int Hue + { + get { return _hue; } + set { _hue = value; NotifyPropertyChanged(nameof(Hue)); NotifyPropertyChanged(nameof(Color)); } + } + + //Brightness + protected int _brightness = 0; + public int Brightness + { + get { return _brightness; } + set { _brightness = value; NotifyPropertyChanged(nameof(Brightness)); NotifyPropertyChanged(nameof(Color)); } + } + + //Saturation + protected int _saturation = 0; + public int Saturation + { + get { return _saturation; } + set { _saturation = value; NotifyPropertyChanged(nameof(Saturation)); NotifyPropertyChanged(nameof(Color)); } + } + + public SolidColorBrush Color + { + get { return new SolidColorBrush(ColorUtil.HsvToRgb(Hue, Saturation, Brightness)); } + } + + public abstract void SetState(); + + public abstract void SetColor(bool instant = false); + + public abstract Task Update(); + + public event PropertyChangedEventHandler PropertyChanged; + + protected virtual void NotifyPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + } + + +} diff --git a/HueUWP/Lights/LightGroup.cs b/HueUWP/Lights/LightGroup.cs new file mode 100644 index 0000000..de5bc68 --- /dev/null +++ b/HueUWP/Lights/LightGroup.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HueUWP.Lights +{ + class LightGroup : Light + { + public LightGroup(int id, string name) : base(id, name, "Group") + { + + } + + public override void SetColor(bool instant = false) + { + App.api.SetGroupColor(this, instant); + } + + public override void SetState() + { + App.api.SetGroupState(this); + } + + public override async Task Update() + { + return await App.api.UpdateGroup(this); + } + } +} diff --git a/HueUWP/Lights/LightGroupListDataSource.cs b/HueUWP/Lights/LightGroupListDataSource.cs new file mode 100644 index 0000000..01a96c3 --- /dev/null +++ b/HueUWP/Lights/LightGroupListDataSource.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HueUWP.Lights +{ + class LightGroupListDataSource + { + private ObservableCollection _groups; + + public LightGroupListDataSource() + { + _groups = new ObservableCollection(); + } + + public async Task LoadGroups() + { + return await App.api.Groups(_groups); + } + + public ObservableCollection GetGroups() + { + return _groups; + } + + public void Clear() + { + _groups.Clear(); + } + + public async Task UpdateGroups() + { + foreach (Light g in _groups) + { + await g.Update(); + } + + return "success"; + } + } +} diff --git a/HueUWP/Lights/LightListDataSource.cs b/HueUWP/Lights/LightListDataSource.cs new file mode 100644 index 0000000..9ee32d3 --- /dev/null +++ b/HueUWP/Lights/LightListDataSource.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HueUWP.Lights +{ + + public class LightListDataSource + { + private ObservableCollection _lights; + + public LightListDataSource() + { + _lights = new ObservableCollection(); + } + + public async Task LoadLights() + { + return await App.api.Lights(_lights); + } + + public ObservableCollection GetLights() + { + return _lights; + } + + public void Clear() + { + _lights.Clear(); + } + + public async Task UpdateLights() + { + foreach(Light l in _lights) + { + await l.Update(); + } + + return "success"; + } + } +} diff --git a/HueUWP/Lights/LightMulti.cs b/HueUWP/Lights/LightMulti.cs new file mode 100644 index 0000000..b8311a9 --- /dev/null +++ b/HueUWP/Lights/LightMulti.cs @@ -0,0 +1,58 @@ +using HueUWP.Helpers; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HueUWP.Lights +{ + class LightMulti : Light + { + private List _lights; + + public LightMulti(List lights) : base(0, "Multiple Lights", (lights.ToDelimitedString(l => l.Name))) + { + _lights = lights; + Light l = _lights.First(); + + SaturationEnabled = true; + HueEnabled = true; + BrightnessEnabled = true; + + _isOn = l.IsOn; + + _hue = l.Hue; + _brightness = l.Brightness; + _saturation = l.Saturation; + + NotifyPropertyChanged(nameof(IsOn)); + NotifyPropertyChanged(nameof(Hue)); + NotifyPropertyChanged(nameof(Saturation)); + NotifyPropertyChanged(nameof(Brightness)); + } + + public override void SetColor(bool instant = false) + { + _lights.ForEach(l => { l.SetColor(instant); }); + } + + public override void SetState() + { + _lights.ForEach(l => { l.SetState(); }); + } + + public override async Task Update() + { + //Do nothing, performance reasons + return "success"; + } + + protected override void NotifyPropertyChanged(string propertyName) + { + base.NotifyPropertyChanged(propertyName); + _lights.ForEach(l => { l.IsOn = IsOn; l.Hue = Hue; l.Saturation = Saturation; l.Brightness = Brightness; }); + } + } +} diff --git a/HueUWP/Lights/LightSingle.cs b/HueUWP/Lights/LightSingle.cs new file mode 100644 index 0000000..5547e42 --- /dev/null +++ b/HueUWP/Lights/LightSingle.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Input; +using Windows.UI.Xaml.Media; + +namespace HueUWP.Lights +{ + public class LightSingle : Light + { + public LightSingle(int id, string name, string type) : base (id, name, type) + { + } + + public override void SetState() + { + App.api.SetLightState(this); + } + + public override void SetColor(bool instant = false) + { + App.api.SetLightColor(this); + } + + public override async Task Update() + { + return await App.api.UpdateLight(this); + } + } + + +} diff --git a/HueUWP/MultiEdit.xaml b/HueUWP/MultiEdit.xaml index d10e3b7..5e2accc 100755 --- a/HueUWP/MultiEdit.xaml +++ b/HueUWP/MultiEdit.xaml @@ -3,7 +3,7 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HueUWP" - xmlns:convert="using:HueUWP.Converters" + xmlns:convert="using:HueUWP.Helpers" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:ctrl="using:Windows.UI.Xaml.Controls.Control" diff --git a/HueUWP/MultiEdit.xaml.cs b/HueUWP/MultiEdit.xaml.cs index 9979401..fa93b06 100755 --- a/HueUWP/MultiEdit.xaml.cs +++ b/HueUWP/MultiEdit.xaml.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +using HueUWP.Helpers; +using HueUWP.Lights; +using HueUWP.Views; +using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Diagnostics; @@ -25,7 +28,7 @@ namespace HueUWP public sealed partial class MultiEdit : Page { IList lights = new List(); - MainPage main; + LightsView main; public MultiEdit() { @@ -34,18 +37,18 @@ namespace HueUWP protected override void OnNavigatedTo(NavigationEventArgs e) { - main = e.Parameter as MainPage; + main = e.Parameter as LightsView; - HueSlider.Value = ((Light) main.GetListView().SelectedItems[0]).Hue; - SaturationSlider.Value = ((Light)main.GetListView().SelectedItems[0]).Saturation; - BrightnessSlider.Value = ((Light)main.GetListView().SelectedItems[0]).Brightness; - OnOffButton.IsOn = ((Light)main.GetListView().SelectedItems[0]).IsOn; + HueSlider.Value = 0; + SaturationSlider.Value = 0; + BrightnessSlider.Value = 0; + OnOffButton.IsOn = false; - foreach (var v in main.GetListView().SelectedItems) - { - Light l = (Light)v; - lights.Add(l); - } + //foreach (var v in main.GetListView().SelectedItems) + //{ + // Light l = (Light)v; + // lights.Add(l); + //} LightsSelectedField.Text = lights.ToDelimitedString(l => l.Name); } @@ -58,25 +61,25 @@ namespace HueUWP private void Slider_Released(object sender, PointerRoutedEventArgs e) { - foreach(var l in lights) + foreach (var l in lights) { - l.Hue = HueSlider.Value; - l.Saturation = SaturationSlider.Value; - l.Brightness = BrightnessSlider.Value; + l.Hue = (int)HueSlider.Value; + l.Saturation = (int)SaturationSlider.Value; + l.Brightness = (int)BrightnessSlider.Value; ColorRectangle.Fill = new SolidColorBrush(ColorUtil.getColor(l)); - l.UpdateColor(); + l.SetColor(); } } private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) { ToggleSwitch button = ((ToggleSwitch)sender); - foreach(var l in lights) + foreach (var l in lights) { - - l.UpdateState(button.IsOn); + + l.SetState(); } - + } } } diff --git a/HueUWP/NetworkHandler.cs b/HueUWP/NetworkHandler.cs index e6dede6..f49e834 100755 --- a/HueUWP/NetworkHandler.cs +++ b/HueUWP/NetworkHandler.cs @@ -11,15 +11,12 @@ namespace HueUWP { public class NetworkHandler { - //string (string) MainPage.LOCAL_SETTINGS.Values["ip"]; - //int (int)MainPage.LOCAL_SETTINGS.Values["port"]; public NetworkHandler() { - //this.(string) MainPage.LOCAL_SETTINGS.Values["ip"] = (string) MainPage.LOCAL_SETTINGS.Values["(string) MainPage.LOCAL_SETTINGS.Values["ip"]"]; - //this.(int)MainPage.LOCAL_SETTINGS.Values["port"] = (int)MainPage.LOCAL_SETTINGS.Values["(int)MainPage.LOCAL_SETTINGS.Values["port"]"]; + } - private async Task Put(string path, string json) + private static async Task Put(string path, string json) { var cts = new CancellationTokenSource(); cts.CancelAfter(5000); @@ -31,7 +28,7 @@ namespace HueUWP HttpClient client = new HttpClient(); HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json"); - Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path); + Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path); var response = await client.PutAsync(uriLampState, content).AsTask(cts.Token); if (!response.IsSuccessStatusCode) @@ -53,7 +50,7 @@ namespace HueUWP } - private async Task Post(string path, string json) + private static async Task Post(string path, string json) { var cts = new CancellationTokenSource(); cts.CancelAfter(5000); @@ -63,7 +60,7 @@ namespace HueUWP HttpClient client = new HttpClient(); HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json"); - Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path); + Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path); var response = await client.PostAsync(uriLampState, content).AsTask(cts.Token); if (!response.IsSuccessStatusCode) @@ -84,7 +81,7 @@ namespace HueUWP } } - private async Task Get(string path) + private static async Task Get(string path) { var cts = new CancellationTokenSource(); cts.CancelAfter(5000); @@ -94,7 +91,7 @@ namespace HueUWP HttpClient client = new HttpClient(); //HttpStringContent content = new HttpStringContent($"{{\"devicetype\":\"Test#Test\"}}", Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json"); - Uri uriLampState = new Uri($"http://{(string) MainPage.LOCAL_SETTINGS.Values["ip"]}:{(int)MainPage.LOCAL_SETTINGS.Values["port"]}/api/" + path); + Uri uriLampState = new Uri($"http://{(string) App.LOCAL_SETTINGS.Values["ip"]}:{(int)App.LOCAL_SETTINGS.Values["port"]}/api/" + path); var response = await client.GetAsync(uriLampState).AsTask(cts.Token); if (!response.IsSuccessStatusCode) @@ -115,14 +112,46 @@ namespace HueUWP } } - public async Task SetLightInfo(int lightid, string json) + public static async Task Lights() { - var response = await Put($"{(String)MainPage.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json); + var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights"); + if (string.IsNullOrEmpty(response)) + return "error"; + return response; + } + + public static async Task Light(int id) + { + var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{id}"); + if (string.IsNullOrEmpty(response)) + return "error"; + return response; + } + + public static async Task SetLight(int lightid, string json) + { + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json); + return response; + } + + public static async Task SetLight(int lightid, bool state) + { + string json = $"{{\"on\": { ((state) ? "true" : "false") }}}"; + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json); + return response; + } + + public static async Task SetLight(int lightid, int hue, int saturation, int brightness, bool instant = false) + { + string json = $"{{\"hue\": {(hue)},\"bri\": {brightness},\"sat\": {saturation} {(instant ? ",\"transitiontime\":0" : "")}}}"; + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights/{lightid}/state", json); return response; } - public async Task RegisterName(string AppName, string UserName) + + + public static async Task RegisterName(string AppName, string UserName) { var response = await Post("",$"{{\"devicetype\":\"{AppName}#{UserName}\"}}"); if (string.IsNullOrEmpty(response)) @@ -130,13 +159,44 @@ namespace HueUWP return response; } - public async Task AllLights() + + + + public static async Task Groups() { - var response = await Get($"{(String)MainPage.LOCAL_SETTINGS.Values["id"]}/lights"); + var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups"); if (string.IsNullOrEmpty(response)) return "error"; return response; } + public static async Task Group(int id) + { + var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{id}"); + if (string.IsNullOrEmpty(response)) + return "error"; + return response; + } + + public static async Task SetGroup(int groupid, string json) + { + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}", json); + return response; + } + + public static async Task SetGroup(int groupid, bool state) + { + string json = $"{{\"on\": { ((state) ? "true" : "false") }}}"; + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}", json); + return response; + } + + public static async Task SetGroup(int groupid, int hue, int saturation, int brightness, bool instant = false) + { + string json = $"{{\"hue\": {(hue)},\"bri\": {brightness},\"sat\": {saturation} {(instant ? ",\"transitiontime\":0" : "")}}}"; + var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}", json); + return response; + } + } } diff --git a/HueUWP/SettingsViewModel.cs b/HueUWP/SettingsViewModel.cs index 9dc9d02..b579e40 100644 --- a/HueUWP/SettingsViewModel.cs +++ b/HueUWP/SettingsViewModel.cs @@ -11,8 +11,6 @@ namespace HueUWP { public class SettingsViewModel : INotifyPropertyChanged { - private static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings; - public event PropertyChangedEventHandler PropertyChanged; private void NotifyPropertyChanged(string propertyName) @@ -22,19 +20,19 @@ namespace HueUWP public string IP { - get { Debug.WriteLine(LOCAL_SETTINGS.Values["ip"]); return LOCAL_SETTINGS.Values["ip"] as string; } - set { LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); } + get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["ip"]); return App.LOCAL_SETTINGS.Values["ip"] as string; } + set { App.LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); } } public string PORT { - get { Debug.WriteLine(LOCAL_SETTINGS.Values["port"]); return Convert.ToInt32(LOCAL_SETTINGS.Values["port"]).ToString(); } - set { LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); } + get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["port"]); return Convert.ToInt32(App.LOCAL_SETTINGS.Values["port"]).ToString(); } + set { App.LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); } } public string ID { - get { Debug.WriteLine(LOCAL_SETTINGS.Values["id"]); return LOCAL_SETTINGS.Values["id"] as string; } + get { Debug.WriteLine(App.LOCAL_SETTINGS.Values["id"]); return App.LOCAL_SETTINGS.Values["id"] as string; } } public void Update() diff --git a/HueUWP/Todo.txt b/HueUWP/Todo.txt index 5b7bf67..638a41b 100644 --- a/HueUWP/Todo.txt +++ b/HueUWP/Todo.txt @@ -1,6 +1,4 @@ Todo - - Binding in multiple edit mode. Doen door meerdere soorten models mee te geven bij het navigeren naar de detail pagina. - About pagina mooier maken. - Group view pagina -> Mainpage moet dan eigenlijk een lamp list ding worden, en die kan je dan ook aanroepen met een group. - - Disco mode beter maken. - - Automatisch refreshing. \ No newline at end of file + \ No newline at end of file diff --git a/HueUWP/AboutView.xaml b/HueUWP/Views/AboutView.xaml similarity index 93% rename from HueUWP/AboutView.xaml rename to HueUWP/Views/AboutView.xaml index 4cba0ac..d22a099 100644 --- a/HueUWP/AboutView.xaml +++ b/HueUWP/Views/AboutView.xaml @@ -1,8 +1,8 @@  diff --git a/HueUWP/AboutView.xaml.cs b/HueUWP/Views/AboutView.xaml.cs similarity index 97% rename from HueUWP/AboutView.xaml.cs rename to HueUWP/Views/AboutView.xaml.cs index 3889eeb..e874341 100644 --- a/HueUWP/AboutView.xaml.cs +++ b/HueUWP/Views/AboutView.xaml.cs @@ -15,7 +15,7 @@ using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 -namespace HueUWP +namespace HueUWP.Views { /// /// An empty page that can be used on its own or navigated to within a Frame. diff --git a/HueUWP/DetailView.xaml b/HueUWP/Views/DetailView.xaml similarity index 80% rename from HueUWP/DetailView.xaml rename to HueUWP/Views/DetailView.xaml index 95fcd3f..169248d 100644 --- a/HueUWP/DetailView.xaml +++ b/HueUWP/Views/DetailView.xaml @@ -1,9 +1,9 @@  - + - + Off On @@ -43,17 +43,17 @@ Hue - + Saturation - + - + Brightness - + diff --git a/HueUWP/DetailView.xaml.cs b/HueUWP/Views/DetailView.xaml.cs similarity index 72% rename from HueUWP/DetailView.xaml.cs rename to HueUWP/Views/DetailView.xaml.cs index 2134b8c..f753ca8 100644 --- a/HueUWP/DetailView.xaml.cs +++ b/HueUWP/Views/DetailView.xaml.cs @@ -1,58 +1,68 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; - -// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 - -namespace HueUWP -{ - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class DetailView : Page - { - Light l; - - public DetailView() - { - this.InitializeComponent(); - } - - protected override void OnNavigatedTo(NavigationEventArgs e) - { - l = e.Parameter as Light; - this.DataContext = l; - } - - - private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e) - { - //l.UpdateColor(); - } - - private void Slider_Released(object sender, PointerRoutedEventArgs e) - { - l.UpdateColor(); - } - - private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) - { - ToggleSwitch button = ((ToggleSwitch)sender); - Light light = (Light)button.DataContext; - if (light != null) - light.UpdateState(button.IsOn); - } - } -} +using HueUWP.Lights; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +namespace HueUWP.Views +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class DetailView : Page + { + Light l; + DispatcherTimer timer; + + public DetailView() + { + this.InitializeComponent(); + timer = new DispatcherTimer(); + timer.Interval = TimeSpan.FromSeconds(3); + timer.Tick += Timer_Tick; + } + + private void Timer_Tick(object sender, object e) + { + l.Update(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + l = e.Parameter as Light; + this.DataContext = l; + timer.Start(); + } + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + timer.Stop(); + } + + private void Slider_Released(object sender, PointerRoutedEventArgs e) + { + l.SetColor(); + } + + private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) + { + ToggleSwitch button = ((ToggleSwitch)sender); + Light light = (Light)button.DataContext; + if (light != null) + light.SetState(); + } + } +} diff --git a/HueUWP/Views/GroupsView.xaml b/HueUWP/Views/GroupsView.xaml new file mode 100644 index 0000000..7a394d3 --- /dev/null +++ b/HueUWP/Views/GroupsView.xaml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + Hue Groups + + + + + + + + + + + + + + + + + + + + + + Off + On + + + + + + + + + + + diff --git a/HueUWP/Views/GroupsView.xaml.cs b/HueUWP/Views/GroupsView.xaml.cs new file mode 100644 index 0000000..f29125d --- /dev/null +++ b/HueUWP/Views/GroupsView.xaml.cs @@ -0,0 +1,109 @@ +using HueUWP.Lights; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 + +namespace HueUWP.Views +{ + /// + /// An empty page that can be used on its own or navigated to within a Frame. + /// + public sealed partial class GroupsView : Page + { + + private LightGroupListDataSource _groupsViewModel; + public ObservableCollection GroupsViewModel + { + get { return _groupsViewModel.GetGroups(); } + } + + DispatcherTimer timer; + + public GroupsView() + { + this.InitializeComponent(); + this.NavigationCacheMode = NavigationCacheMode.Enabled; + + _groupsViewModel = new LightGroupListDataSource(); + + timer = new DispatcherTimer(); + timer.Interval = TimeSpan.FromSeconds(60); + timer.Tick += Timer_Tick; + } + + private void Timer_Tick(object sender, object e) + { + QuietReloadGroups(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + ReloadGroups(); + this.DataContext = GroupsViewModel; + } + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + timer.Stop(); + } + + private async void ReloadGroups() + { + timer.Stop(); + ErrorMessage.Text = ""; + FeedbackPanel.Visibility = Visibility.Visible; + _groupsViewModel.Clear(); + + + Loading.IsActive = true; + string s = await _groupsViewModel.LoadGroups(); + + if (s == "error") + ErrorMessage.Text = "There was a problem connecting..."; + else if (_groupsViewModel.GetGroups().Count < 1) + ErrorMessage.Text = "No groups found..."; + else + { + FeedbackPanel.Visibility = Visibility.Collapsed; + timer.Start(); + } + + Loading.IsActive = false; + } + + private async void QuietReloadGroups() + { + string s = await _groupsViewModel.UpdateGroups(); + } + + private void GroupsList_ItemClick(object sender, ItemClickEventArgs e) + { + Light g = e.ClickedItem as Light; + Frame rootframe = Window.Current.Content as Frame; + if (g != null) + rootframe.Navigate(typeof(DetailView), g); + } + + private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) + { + ToggleSwitch button = ((ToggleSwitch)sender); + Light group = (Light)button.DataContext; + if (group != null) + group.SetState(); + } + } +} diff --git a/HueUWP/MainPage.xaml b/HueUWP/Views/LightsView.xaml similarity index 67% rename from HueUWP/MainPage.xaml rename to HueUWP/Views/LightsView.xaml index d5d3bf4..4cad379 100644 --- a/HueUWP/MainPage.xaml +++ b/HueUWP/Views/LightsView.xaml @@ -1,113 +1,111 @@ - - - - - - - - - - - - - - - Hue Lights - - - - - - - - - - - - - - - - - - - - - - - Off - On - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + Hue Lights + + + + + + + + + + + + + + + + + + + + + + Off + On + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/HueUWP/MainPage.xaml.cs b/HueUWP/Views/LightsView.xaml.cs similarity index 61% rename from HueUWP/MainPage.xaml.cs rename to HueUWP/Views/LightsView.xaml.cs index cfd5ac5..970e64f 100644 --- a/HueUWP/MainPage.xaml.cs +++ b/HueUWP/Views/LightsView.xaml.cs @@ -1,202 +1,207 @@ -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Runtime.InteropServices.WindowsRuntime; -using System.Threading.Tasks; -using Windows.Foundation; -using Windows.Foundation.Collections; -using Windows.Storage; -using Windows.UI.Xaml; -using Windows.UI.Xaml.Controls; -using Windows.UI.Xaml.Controls.Primitives; -using Windows.UI.Xaml.Data; -using Windows.UI.Xaml.Input; -using Windows.UI.Xaml.Media; -using Windows.UI.Xaml.Navigation; - -// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409 - -namespace HueUWP -{ - - - - /// - /// An empty page that can be used on its own or navigated to within a Frame. - /// - public sealed partial class MainPage : Page - { - public static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings; - - private ObservableCollection _lightsViewModel = LightDataSource.GetLights(); - - public APIHandler api; - - public ObservableCollection LightsViewModel - { - get { return this._lightsViewModel; } - } - - public MainPage() - { - this.InitializeComponent(); - //LOCAL_SETTINGS.Values["ip"] = "localhost"; - //LOCAL_SETTINGS.Values["port"] = 8000; - NetworkHandler nwh = new NetworkHandler(); - api = new APIHandler(nwh); - - - } - - protected override void OnNavigatedTo(NavigationEventArgs e) - { - Load_Lights(); - } - - private async void Load_Lights() - { - ErrorMessage.Text = ""; - FeedbackPanel.Visibility = Visibility.Visible; - _lightsViewModel.Clear(); - - Loading.IsActive = true; - await Task.Delay(TimeSpan.FromMilliseconds(200)); - string s = await api.GetAllLights(_lightsViewModel); - - if (s == "error") - ErrorMessage.Text = "There was a problem connecting..."; - else if (_lightsViewModel.Count < 1) - ErrorMessage.Text = "No lights found..."; - else - FeedbackPanel.Visibility = Visibility.Collapsed; - - Loading.IsActive = false; - } - - public void ToggleSwitch_Tapped(object sender, TappedRoutedEventArgs e) - { - Debug.WriteLine("Hello again"); - ToggleSwitch button = ((ToggleSwitch)sender); - Light light = (Light)button.DataContext; - Debug.WriteLine("Hello"); - if(light != null) - light.UpdateState(button.IsOn); - } - - private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) - { - ToggleSwitch button = ((ToggleSwitch)sender); - Light light = (Light)button.DataContext; - if(light != null) - light.UpdateState(button.IsOn); - } - - private void SettingsButton_Click(object sender, RoutedEventArgs e) - { - Frame rootframe = Window.Current.Content as Frame; - rootframe.Navigate(typeof(SettingsView), api); - } - - private void RefreshButton_Click(object sender, RoutedEventArgs e) - { - Load_Lights(); - } - - private void myListView_ItemClick(object sender, ItemClickEventArgs e) - { - Light l = e.ClickedItem as Light; - Frame rootframe = Window.Current.Content as Frame; - if (l != null) - rootframe.Navigate(typeof(DetailView), l); - } - - private void AboutButton_Click(object sender, RoutedEventArgs e) - { - Frame rootframe = Window.Current.Content as Frame; - rootframe.Navigate(typeof(AboutView)); - } - - private void DiscoButton_Click(object sender, RoutedEventArgs e) - { - if ((bool)DiscoButton.IsChecked) - api.DiscoMode(_lightsViewModel); - else - api.DiscoMode(false); - } - - private void GroupButton_Click(object sender, RoutedEventArgs e) - { - - if ((bool)GroupButton.IsChecked) - { - myListView.IsItemClickEnabled = false; - myListView.SelectionMode = ListViewSelectionMode.Multiple; - OnOffButton.Visibility = Visibility.Visible; - ValuesButton.Visibility = Visibility.Visible; - - Seperator.Visibility = Visibility.Collapsed; - DiscoButton.Visibility = Visibility.Collapsed; - RefreshButton.Visibility = Visibility.Collapsed; - SettingsButton.Visibility = Visibility.Collapsed; - } - else - { - myListView.IsItemClickEnabled = true; - myListView.SelectionMode = ListViewSelectionMode.Single; - OnOffButton.Visibility = Visibility.Collapsed; - ValuesButton.Visibility = Visibility.Collapsed; - - Seperator.Visibility = Visibility.Visible; - DiscoButton.Visibility = Visibility.Visible; - RefreshButton.Visibility = Visibility.Visible; - SettingsButton.Visibility = Visibility.Visible; - } - - } - - private void OnOffButton_Click(object sender, RoutedEventArgs e) - { - bool first = false; - - if(OnOffButton.Label == "Off") - { - first = false; - OnOffButton.Label = "On"; - } - else - { - first = true; - OnOffButton.Label = "Off"; - } - - if ((bool)GroupButton.IsChecked) - { - foreach(var v in myListView.SelectedItems) - { - ((Light)v).UpdateState(first); - } - } - } - - public ListView GetListView() - { - return myListView; - } - - //hue.imegumii.space - private void ValuesButton_Click(object sender, RoutedEventArgs e) - { - if ((bool)GroupButton.IsChecked) - { - Frame rootframe = Window.Current.Content as Frame; - if (myListView.SelectedItems != null) - rootframe.Navigate(typeof(MultiEdit), this); - } - } - } -} +using HueUWP.Lights; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices.WindowsRuntime; +using System.Threading.Tasks; +using Windows.Foundation; +using Windows.Foundation.Collections; +using Windows.Storage; +using Windows.UI.Xaml; +using Windows.UI.Xaml.Controls; +using Windows.UI.Xaml.Controls.Primitives; +using Windows.UI.Xaml.Data; +using Windows.UI.Xaml.Input; +using Windows.UI.Xaml.Media; +using Windows.UI.Xaml.Navigation; + +namespace HueUWP.Views +{ + public sealed partial class LightsView : Page + { + private LightListDataSource _lightsViewModel; + public ObservableCollection LightsViewModel + { + get { return _lightsViewModel.GetLights(); } + } + + DispatcherTimer timer; + + public LightsView() + { + this.InitializeComponent(); + this.NavigationCacheMode = NavigationCacheMode.Enabled; + + _lightsViewModel = new LightListDataSource(); + + timer = new DispatcherTimer(); + timer.Interval = TimeSpan.FromSeconds(8); + timer.Tick += Timer_Tick; + } + + private void Timer_Tick(object sender, object e) + { + QuietReloadLights(); + } + + protected override void OnNavigatedTo(NavigationEventArgs e) + { + ReloadLights(); + this.DataContext = LightsViewModel; + } + + protected override void OnNavigatedFrom(NavigationEventArgs e) + { + timer.Stop(); + } + + private async void QuietReloadLights() + { + string s = await _lightsViewModel.UpdateLights(); + } + + private async void ReloadLights() + { + timer.Stop(); + ErrorMessage.Text = ""; + FeedbackPanel.Visibility = Visibility.Visible; + _lightsViewModel.Clear(); + + Loading.IsActive = true; + string s = await _lightsViewModel.LoadLights(); + + if (s == "error") + ErrorMessage.Text = "There was a problem connecting..."; + else if (_lightsViewModel.GetLights().Count < 1) + ErrorMessage.Text = "No lights found..."; + else + { + FeedbackPanel.Visibility = Visibility.Collapsed; + timer.Start(); + } + + Loading.IsActive = false; + } + + private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e) + { + ToggleSwitch button = ((ToggleSwitch)sender); + Light light = (Light)button.DataContext; + if(light != null) + light.SetState(); + } + + private void SettingsButton_Click(object sender, RoutedEventArgs e) + { + Frame rootframe = Window.Current.Content as Frame; + rootframe.Navigate(typeof(SettingsView)); + } + + private void RefreshButton_Click(object sender, RoutedEventArgs e) + { + ReloadLights(); + } + + private void LightsList_ItemClick(object sender, ItemClickEventArgs e) + { + Light l = e.ClickedItem as Light; + Frame rootframe = Window.Current.Content as Frame; + if (l != null) + rootframe.Navigate(typeof(DetailView), l); + } + + private void AboutButton_Click(object sender, RoutedEventArgs e) + { + Frame rootframe = Window.Current.Content as Frame; + rootframe.Navigate(typeof(AboutView)); + } + + private void GroupsButton_Click(object sender, RoutedEventArgs e) + { + Frame rootframe = Window.Current.Content as Frame; + rootframe.Navigate(typeof(GroupsView)); + } + + private void DiscoButton_Click(object sender, RoutedEventArgs e) + { + if ((bool)DiscoButton.IsChecked) + App.api.DiscoMode(_lightsViewModel.GetLights()); + else + App.api.DiscoMode(false); + } + + private void GroupButton_Click(object sender, RoutedEventArgs e) + { + + if ((bool)GroupButton.IsChecked) + { + LightsList.IsItemClickEnabled = false; + LightsList.SelectionMode = ListViewSelectionMode.Multiple; + OnOffButton.Visibility = Visibility.Visible; + ValuesButton.Visibility = Visibility.Visible; + + Seperator.Visibility = Visibility.Collapsed; + DiscoButton.Visibility = Visibility.Collapsed; + RefreshButton.Visibility = Visibility.Collapsed; + SettingsButton.Visibility = Visibility.Collapsed; + } + else + { + LightsList.IsItemClickEnabled = true; + LightsList.SelectionMode = ListViewSelectionMode.Single; + OnOffButton.Visibility = Visibility.Collapsed; + ValuesButton.Visibility = Visibility.Collapsed; + + Seperator.Visibility = Visibility.Visible; + DiscoButton.Visibility = Visibility.Visible; + RefreshButton.Visibility = Visibility.Visible; + SettingsButton.Visibility = Visibility.Visible; + } + + } + + private void OnOffButton_Click(object sender, RoutedEventArgs e) + { + bool toggle = false; + + if(OnOffButton.Label == "Off") + { + toggle = false; + OnOffButton.Label = "On"; + } + else + { + toggle = true; + OnOffButton.Label = "Off"; + } + + if ((bool)GroupButton.IsChecked) + { + foreach(var v in LightsList.SelectedItems) + { + ((Light)v).IsOn = toggle; + ((Light)v).SetState(); + } + } + } + + private void ValuesButton_Click(object sender, RoutedEventArgs e) + { + if ((bool)GroupButton.IsChecked) + { + Frame rootframe = Window.Current.Content as Frame; + if (LightsList.SelectedItems != null) + { + Light multilight = new LightMulti( LightsList.SelectedItems.Cast().ToList() ); + rootframe.Navigate(typeof(DetailView), multilight); + } + + } + } + } +} diff --git a/HueUWP/SettingsView.xaml b/HueUWP/Views/SettingsView.xaml similarity index 96% rename from HueUWP/SettingsView.xaml rename to HueUWP/Views/SettingsView.xaml index 35670cf..24057a7 100644 --- a/HueUWP/SettingsView.xaml +++ b/HueUWP/Views/SettingsView.xaml @@ -1,8 +1,8 @@  diff --git a/HueUWP/SettingsView.xaml.cs b/HueUWP/Views/SettingsView.xaml.cs similarity index 85% rename from HueUWP/SettingsView.xaml.cs rename to HueUWP/Views/SettingsView.xaml.cs index 79fdd81..cf51337 100644 --- a/HueUWP/SettingsView.xaml.cs +++ b/HueUWP/Views/SettingsView.xaml.cs @@ -17,7 +17,7 @@ using Windows.UI.Xaml.Navigation; // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238 -namespace HueUWP +namespace HueUWP.Views { /// /// An empty page that can be used on its own or navigated to within a Frame. @@ -26,8 +26,6 @@ namespace HueUWP { public SettingsViewModel SettingsViewModel = new SettingsViewModel(); - private APIHandler api; - public SettingsView() { this.InitializeComponent(); @@ -39,7 +37,7 @@ namespace HueUWP IDBox.Background = default(Brush); UserIdProgress.IsActive = true; - string s = await api.Register(); + string s = await App.api.Register(); if (s == "error") IDBox.Background = new SolidColorBrush(Colors.Red); else @@ -47,10 +45,5 @@ namespace HueUWP UserIdProgress.IsActive = false; } - - protected override void OnNavigatedTo(NavigationEventArgs e) - { - api = e.Parameter as APIHandler; - } } }