Compare commits

48 Commits
Author SHA1 Message Date
kennyboy55 1e59d104ff Added white background to splash screen 2015-12-14 11:50:37 +01:00
kennyboy55 dbf529123f Added auto refreshing 2015-12-11 13:48:05 +01:00
kennyboy55 5860432c7e Added group support 2015-12-11 13:47:44 +01:00
kennyboy55 c7f3e946ee Added settings for auto refresh 2015-12-11 13:46:58 +01:00
kennyboy55 542e6879bc Added settings for auto refresh 2015-12-11 13:46:04 +01:00
kennyboy55 d0c799a821 Added hostname 2015-12-11 13:40:59 +01:00
kennyboy55 b0e77c3fb8 Complete rewrite of binding. Added groups. Added auto refresh and background updating. Better handling of multiple lights. 2015-12-11 01:16:39 +01:00
kennyboy55 a65ae57d7b Added todo for 'public release' 8th of januari 2015-12-08 12:41:07 +01:00
kennyboy55 907e4a2a36 Improved multi-edit interface 2015-12-07 10:43:55 +01:00
kennyboy55 f4ff363cb9 Improved Interface 2015-12-04 17:51:52 +01:00
Yorick Rommers ad65c72747 added multiselect 2015-12-04 14:49:24 +01:00
kennyboy55 482ebc828b Fixed disco mode 2015-12-03 12:48:08 +01:00
Yorick Rommers 0b8688ed7b merge 2015-12-03 12:42:16 +01:00
Yorick Rommers 10d936eef0 disco added 2015-12-03 12:41:17 +01:00
kennyboy55 1334c23fea Merge remote-tracking branch 'origin/dev' into dev 2015-12-03 12:00:17 +01:00
kennyboy55 0e0edae19c Added new converter 2015-12-03 11:34:21 +01:00
Yorick Rommers eb6d794806 Merge branch 'dev' of https://github.com/yorickr/huehuehue into dev 2015-12-03 11:33:38 +01:00
Yorick Rommers 4fd750f8e0 excepted light 2015-12-03 11:33:25 +01:00
kennyboy55 adfff4f035 UI Fixes 2015-12-03 11:13:36 +01:00
kennyboy55 2dfc29591d Added progress rings and error feedback 2015-12-02 22:27:30 +01:00
kennyboy55 a77bf79119 Added progress indications 2015-12-02 21:48:48 +01:00
kennyboy55 f2b760e549 Added new light methods 2015-12-02 20:50:53 +01:00
kennyboy55 7c531b5c89 Fix dark mode 2015-12-02 10:17:54 +01:00
kennyboy55 6343d239a4 Added themes, refined layout, bugfixes 2015-12-01 23:14:37 +01:00
kennyboy55 e5ae43c9ee Bugfixes, added logo's, cool stuff 2015-12-01 17:49:06 +01:00
kennyboy55 ae63b92fd1 Merge remote-tracking branch 'origin/dev' into dev
Conflicts:
	HueUWP/MainPage.xaml.cs
2015-12-01 15:59:03 +01:00
kennyboy55 4888eedde6 Changed port/ip set moment 2015-12-01 15:58:29 +01:00
Yorick Rommers b5f262b30a fixed networkhandler 2015-12-01 15:57:34 +01:00
kennyboy55 1794718ed4 Added settings page 2015-12-01 15:56:35 +01:00
Yorick Rommers d8bd6194ff fixed bug in addalllights 2015-12-01 15:38:25 +01:00
Yorick Rommers c8af704c9b sliders working 2015-12-01 15:00:49 +01:00
kennyboy55 e21233484b Added sliders 2015-12-01 14:14:21 +01:00
kennyboy55 d30645926b Merge remote-tracking branch 'origin/dev' into dev 2015-12-01 14:10:52 +01:00
kennyboy55 a098c1738c Added converter and more pages 2015-12-01 13:18:00 +01:00
Yorick Rommers 597309ca72 color fix 2015-12-01 13:08:40 +01:00
Yorick Rommers 1109d90dca Merge branch 'dev' of https://github.com/yorickr/huehuehue into dev 2015-12-01 12:44:33 +01:00
Yorick Rommers 5d6dd99b97 color working 2015-12-01 12:44:25 +01:00
kennyboy55 011b145672 Added buttons and text, binding to toggleswitch 2015-12-01 12:42:53 +01:00
Yorick Rommers f615d01b82 added slider for testing 2015-11-30 13:20:33 +01:00
Yorick Rommers 7c3a84d4cf Toggle light working 2015-11-30 11:40:17 +01:00
Yorick Rommers ccd5f25f9e added lgihts to gui 2015-11-27 15:03:50 +01:00
kennyboy55 2e381c8073 Merge remote-tracking branch 'origin/dev' into dev
Conflicts:
	HueUWP/MainPage.xaml.cs
2015-11-27 13:36:08 +01:00
kennyboy55 9e26f98979 Added layout 2015-11-27 13:29:20 +01:00
Yorick Rommers 5f46913360 Added global settings, added register function 2015-11-27 13:27:01 +01:00
Yorick Rommers badecbeac3 Added APIHandler 2015-11-27 12:35:52 +01:00
kennyboy55 56885c4001 Added databinding example 2015-11-27 12:27:08 +01:00
Yorick Rommers 5a1dc5e980 Basic json working 2015-11-24 15:40:09 +01:00
kennyboy55 403aacf788 Initial commit 2015-11-24 13:08:16 +01:00
44 changed files with 17285 additions and 0 deletions
+267
View File
@@ -0,0 +1,267 @@
using HueUWP.Helpers;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
using Windows.Storage;
using HueUWP.Lights;
using Windows.Networking.Connectivity;
using Windows.Networking;
namespace HueUWP
{
public class APIHandler
{
bool discomode = false;
public APIHandler()
{
}
public async Task<String> Register()
{
var hostNames = NetworkInformation.GetHostNames();
var hostName = hostNames.FirstOrDefault(name => name.Type == HostNameType.DomainName)?.DisplayName ?? "Unknown Device";
try
{
var json = await NetworkHandler.RegisterName("YK Hue", hostName);
json = json.Replace("[", "").Replace("]", "");
JObject o = JObject.Parse(json);
string id = o["success"]["username"].ToString();
App.LOCAL_SETTINGS.Values["id"] = id;
return "success";
}
catch (Exception e)
{
Debug.WriteLine("Could not register.");
return "error";
}
}
public async Task<String> UpdateGroup(Light g)
{
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;
if(g.HueEnabled)
g.Hue = (int)state["hue"];
if(g.BrightnessEnabled)
g.Brightness = (int)state["bri"];
if(g.SaturationEnabled)
g.Saturation = (int)state["sat"];
return "success";
}
public async Task<String> UpdateLight(Light l)
{
string json = await NetworkHandler.Light(l.ID);
JObject o = JObject.Parse(json);
Debug.WriteLine(o);
var state = o["state"];
l.IsOn = ((string)state["on"]).ToLower() == "true" ? true : false;
if(l.HueEnabled)
l.Hue = (int)state["hue"];
if(l.BrightnessEnabled)
l.Brightness = (int)state["bri"];
if(l.SaturationEnabled)
l.Saturation = (int)state["sat"];
return "success";
}
public async Task<String> SetLightState(Light l)
{
string json = "error";
if (l is LightSingle)
json = await NetworkHandler.SetLight(l.ID, l.IsOn);
return json;
}
public async Task<String> SetLightColor(Light l, bool instant = false)
{
if(l is LightSingle && l.IsOn)
{
var json = await NetworkHandler.SetLight(l.ID, l.Hue, l.Saturation, l.Brightness, instant);
return "success";
}
return "error";
}
public async Task<String> SetGroupState(Light l)
{
string json = "error";
if (l is LightGroup)
json = await NetworkHandler.SetGroup(l.ID, l.IsOn);
return json;
}
public async Task<String> 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<String> Groups(ObservableCollection<Light> groups)
{
try
{
var json = await NetworkHandler.Groups();
JObject o = JObject.Parse(json);
foreach (var i in o)
{
var groupjson = await NetworkHandler.Group(Int32.Parse(i.Key));
JObject o2 = JObject.Parse(groupjson);
var state = o2["action"];
Light g = new LightGroup(Int32.Parse(i.Key), (string)o2["name"]);
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";
}
catch (Exception e)
{
Debug.WriteLine(e.StackTrace);
Debug.WriteLine("Could not get all groups.");
return "error";
}
}
public async Task<String> Lights(ObservableCollection<Light> lights)
{
//List<Light> _lights = new List<Light>();
try {
var json = await NetworkHandler.Lights();
JObject o = JObject.Parse(json);
foreach(var i in o)
{
var light = o["" + i.Key];
var state = light["state"];
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())
{
l.HueEnabled = true;
l.Hue = (int)state["hue"];
}
else
l.HueEnabled = false;
//Brightness
if (!state["bri"].IsNullOrEmpty())
{
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<Light>(_lights);
//}
return "success";
}
catch(Exception e)
{
Debug.WriteLine(e.StackTrace);
Debug.WriteLine("Could not get all lights.");
return "error";
}
}
public async void DiscoMode(ObservableCollection<Light> 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;
}
}
}
+17
View File
@@ -0,0 +1,17 @@
<Application
x:Class="HueUWP.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP">
<!-- RequestedTheme="Dark" -->
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Dark" Source="Themes/DarkTheme.xaml"/>
<ResourceDictionary x:Key="Light" Source="Themes/LightTheme.xaml"/>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
+152
View File
@@ -0,0 +1,152 @@
using HueUWP.Views;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage;
using Windows.UI.Core;
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
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
public static ApplicationDataContainer LOCAL_SETTINGS = ApplicationData.Current.LocalSettings;
Frame rootFrame;
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
this.Suspending += OnSuspending;
}
private static APIHandler _api;
public static APIHandler api
{
get {
if (_api == null)
_api = new APIHandler();
return _api;
}
}
/// <summary>
/// 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.
/// </summary>
/// <param name="e">Details about the launch request and process.</param>
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
#if DEBUG
if (System.Diagnostics.Debugger.IsAttached)
{
this.DebugSettings.EnableFrameRateCounter = false;
}
#endif
rootFrame = Window.Current.Content as Frame;
// Do not repeat app initialization when the Window already has content,
// just ensure that the window is active
if (rootFrame == null)
{
// Create a Frame to act as the navigation context and navigate to the first page
rootFrame = new Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
rootFrame.Navigated += RootFrame_Navigated;
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
// 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(LightsView), e.Arguments);
}
if(LOCAL_SETTINGS.Values["ip"] == null)
LOCAL_SETTINGS.Values["ip"] = "145.48.205.190";
if (LOCAL_SETTINGS.Values["port"] == null)
LOCAL_SETTINGS.Values["port"] = 80;
if (LOCAL_SETTINGS.Values["autorefresh"] == null)
LOCAL_SETTINGS.Values["autorefresh"] = true;
// Ensure the current window is active
Window.Current.Activate();
}
private void RootFrame_Navigated(object sender, NavigationEventArgs e)
{
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility =
rootFrame.CanGoBack ?
AppViewBackButtonVisibility.Visible :
AppViewBackButtonVisibility.Collapsed;
}
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
if (rootFrame.CanGoBack)
{
e.Handled = true;
rootFrame.GoBack();
}
}
/// <summary>
/// Invoked when Navigation to a certain page fails
/// </summary>
/// <param name="sender">The Frame which failed navigation</param>
/// <param name="e">Details about the navigation failure</param>
void OnNavigationFailed(object sender, NavigationFailedEventArgs e)
{
throw new Exception("Failed to load Page " + e.SourcePageType.FullName);
}
/// <summary>
/// Invoked when application execution is being suspended. Application state is saved
/// without knowing whether the application will be terminated or resumed with the contents
/// of memory still intact.
/// </summary>
/// <param name="sender">The source of the suspend request.</param>
/// <param name="e">Details about the suspend request.</param>
private void OnSuspending(object sender, SuspendingEventArgs e)
{
var deferral = e.SuspendingOperation.GetDeferral();
//TODO: Save application state and stop any background activity
deferral.Complete();
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

+198
View File
@@ -0,0 +1,198 @@
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));
}
}
}
+31
View File
@@ -0,0 +1,31 @@
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HueUWP.Helpers
{
public static class Extensions
{
public static string ToDelimitedString<T>(this IEnumerable<T> source, Func<T, string> func)
{
return ToDelimitedString(source, ", ", func);
}
public static string ToDelimitedString<T>(this IEnumerable<T> source, string delimiter, Func<T, string> func)
{
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);
}
}
}
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml.Data;
namespace HueUWP.Helpers
{
public class NullableBooleanConverter : IValueConverter
{
//From bool to nullable
public object Convert(object value, Type targetType, object parameter, string language)
{
bool b = (bool)value;
bool? be = b as bool?;
return be;
}
//From nullable to bool
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
bool? b = (bool?)value;
bool be = false;
if (b.HasValue)
be = (bool)b;
return be;
}
}
}
+33
View File
@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
namespace HueUWP.Helpers
{
class VisibilityConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
bool b = (bool)value;
if (b)
return Visibility.Visible;
else
return Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
Visibility v = (Visibility)value;
if (v == Visibility.Visible)
return true;
else
return false;
}
}
}
+200
View File
@@ -0,0 +1,200 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProjectGuid>{88414ECD-0462-41DE-ABA9-462D2F154595}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>HueUWP</RootNamespace>
<AssemblyName>HueUWP</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion>10.0.10240.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.10240.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<EnableDotNetNativeCompatibleProfile>true</EnableDotNetNativeCompatibleProfile>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<PackageCertificateKeyFile>HueUWP_TemporaryKey.pfx</PackageCertificateKeyFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\ARM\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<OutputPath>bin\ARM\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>ARM</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x64\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x64</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<NoWarn>;2008</NoWarn>
<DebugType>full</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<OutputPath>bin\x86\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>;2008</NoWarn>
<DebugType>pdbonly</DebugType>
<PlatformTarget>x86</PlatformTarget>
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .Net Framework and Windows SDK are automatically included -->
<None Include="project.json" />
</ItemGroup>
<ItemGroup>
<Compile Include="Lights\LightGroupListDataSource.cs" />
<Compile Include="Views\AboutView.xaml.cs">
<DependentUpon>AboutView.xaml</DependentUpon>
</Compile>
<Compile Include="APIHandler.cs" />
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\ColorUtil.cs" />
<Compile Include="Helpers\NullableBooleanConverter.cs" />
<Compile Include="Helpers\VisibilityConverter.cs" />
<Compile Include="Views\DetailView.xaml.cs">
<DependentUpon>DetailView.xaml</DependentUpon>
</Compile>
<Compile Include="Helpers\Extensions.cs" />
<Compile Include="Lights\Light.cs" />
<Compile Include="Lights\LightGroup.cs" />
<Compile Include="Lights\LightListDataSource.cs" />
<Compile Include="Lights\LightMulti.cs" />
<Compile Include="Lights\LightSingle.cs" />
<Compile Include="Views\GroupsView.xaml.cs">
<DependentUpon>GroupsView.xaml</DependentUpon>
</Compile>
<Compile Include="Views\LightsView.xaml.cs">
<DependentUpon>LightsView.xaml</DependentUpon>
</Compile>
<Compile Include="MultiEdit.xaml.cs">
<DependentUpon>MultiEdit.xaml</DependentUpon>
</Compile>
<Compile Include="NetworkHandler.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Views\SettingsView.xaml.cs">
<DependentUpon>SettingsView.xaml</DependentUpon>
</Compile>
<Compile Include="SettingsViewModel.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="HueUWP_TemporaryKey.pfx" />
</ItemGroup>
<ItemGroup>
<Content Include="Properties\Default.rd.xml" />
<Content Include="Assets\LockScreenLogo.scale-200.png" />
<Content Include="Assets\SplashScreen.scale-200.png" />
<Content Include="Assets\Square150x150Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.scale-200.png" />
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
<Content Include="Assets\StoreLogo.png" />
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
<Content Include="Todo.txt" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Views\AboutView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\DetailView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\GroupsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\LightsView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="MultiEdit.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\SettingsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\DarkTheme.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
<Page Include="Themes\LightTheme.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Page>
</ItemGroup>
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' &lt; '14.0' ">
<VisualStudioVersion>14.0</VisualStudioVersion>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
+40
View File
@@ -0,0 +1,40 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HueUWP", "HueUWP.csproj", "{88414ECD-0462-41DE-ABA9-462D2F154595}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.ActiveCfg = Debug|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.Build.0 = Debug|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|ARM.Deploy.0 = Debug|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.ActiveCfg = Debug|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.Build.0 = Debug|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x64.Deploy.0 = Debug|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.ActiveCfg = Debug|x86
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.Build.0 = Debug|x86
{88414ECD-0462-41DE-ABA9-462D2F154595}.Debug|x86.Deploy.0 = Debug|x86
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.ActiveCfg = Release|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.Build.0 = Release|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|ARM.Deploy.0 = Release|ARM
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.ActiveCfg = Release|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.Build.0 = Release|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x64.Deploy.0 = Release|x64
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.ActiveCfg = Release|x86
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.Build.0 = Release|x86
{88414ECD-0462-41DE-ABA9-462D2F154595}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
+85
View File
@@ -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<String> Update();
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
+31
View File
@@ -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<String> Update()
{
return await App.api.UpdateGroup(this);
}
}
}
+45
View File
@@ -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
{
class LightGroupListDataSource
{
private ObservableCollection<Light> _groups;
public LightGroupListDataSource()
{
_groups = new ObservableCollection<Light>();
}
public async Task<String> LoadGroups()
{
return await App.api.Groups(_groups);
}
public ObservableCollection<Light> GetGroups()
{
return _groups;
}
public void Clear()
{
_groups.Clear();
}
public async Task<String> UpdateGroups()
{
foreach (Light g in _groups)
{
await g.Update();
await Task.Delay(TimeSpan.FromMilliseconds(100));
}
return "success";
}
}
}
+46
View File
@@ -0,0 +1,46 @@
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<Light> _lights;
public LightListDataSource()
{
_lights = new ObservableCollection<Light>();
}
public async Task<String> LoadLights()
{
return await App.api.Lights(_lights);
}
public ObservableCollection<Light> GetLights()
{
return _lights;
}
public void Clear()
{
_lights.Clear();
}
public async Task<String> UpdateLights()
{
foreach(Light l in _lights)
{
await l.Update();
await Task.Delay(TimeSpan.FromMilliseconds(100));
}
return "success";
}
}
}
+58
View File
@@ -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<Light> _lights;
public LightMulti(List<Light> 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<String> 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; });
}
}
}
+37
View File
@@ -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, instant);
}
public override async Task<String> Update()
{
return await App.api.UpdateLight(this);
}
}
}
+61
View File
@@ -0,0 +1,61 @@
<Page
x:Class="HueUWP.MultiEdit"
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.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"
mc:Ignorable="d">
<Page.Resources>
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
<convert:VisibilityConverter x:Key="VisibilityConverter"/>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0" Text="Miltiple Lights"/>
</RelativePanel>
<RelativePanel Grid.Row="1">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="14" Name="LightsSelectedField" Margin="20,10,0,0" Text="" TextWrapping="WrapWholeWords"/>
</RelativePanel>
<RelativePanel Grid.Row="2">
<Rectangle Fill="Red" Name="ColorRectangle" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,10,0,10" />
</RelativePanel>
<StackPanel Grid.Row="3">
<ToggleSwitch Margin="20,10,0,10" Name="OnOffButton" Toggled="ToggleSwitch_Toggled" IsOn="False">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
<StackPanel Grid.Row="4">
<StackPanel Margin="20,10,20,0" Visibility="Visible">
<TextBlock FontSize="18">Hue</TextBlock>
<Slider Maximum="65535" Name="HueSlider" Value="30000" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
</StackPanel>
<StackPanel Margin="20,10,20,0" Visibility="Visible">
<TextBlock FontSize="18">Saturation</TextBlock>
<Slider Maximum="254" Name="SaturationSlider" Value="254" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released" />
</StackPanel>
<StackPanel Margin="20,10,20,0">
<TextBlock FontSize="18">Brightness</TextBlock>
<Slider Maximum="254" Name="BrightnessSlider" Value="254" ValueChanged="Slider_ValueChanged" PointerCaptureLost="Slider_Released"/>
</StackPanel>
</StackPanel>
</Grid>
</Page>
+85
View File
@@ -0,0 +1,85 @@
using HueUWP.Helpers;
using HueUWP.Lights;
using HueUWP.Views;
using Newtonsoft.Json;
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
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MultiEdit : Page
{
IList<Light> lights = new List<Light>();
LightsView main;
public MultiEdit()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
main = e.Parameter as LightsView;
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);
//}
LightsSelectedField.Text = lights.ToDelimitedString(l => l.Name);
}
private void Slider_ValueChanged(object sender, RangeBaseValueChangedEventArgs e)
{
//l.UpdateColor();
}
private void Slider_Released(object sender, PointerRoutedEventArgs e)
{
foreach (var l in lights)
{
l.Hue = (int)HueSlider.Value;
l.Saturation = (int)SaturationSlider.Value;
l.Brightness = (int)BrightnessSlider.Value;
ColorRectangle.Fill = new SolidColorBrush(ColorUtil.getColor(l));
l.SetColor();
}
}
private void ToggleSwitch_Toggled(object sender, RoutedEventArgs e)
{
ToggleSwitch button = ((ToggleSwitch)sender);
foreach (var l in lights)
{
l.SetState();
}
}
}
}
+202
View File
@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.UI.Popups;
using Windows.Web.Http;
namespace HueUWP
{
public class NetworkHandler
{
public NetworkHandler()
{
}
private static async Task<String> Put(string path, string json)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
//System.Diagnostics.Debug.WriteLine("PUT:\n" + path +"\n"+json);
try
{
HttpClient client = new HttpClient();
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
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)
{
return "error";
}
string jsonResponse = await response.Content.ReadAsStringAsync();
//System.Diagnostics.Debug.WriteLine(jsonResponse);
return jsonResponse;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return "error";
}
}
private static async Task<String> Post(string path, string json)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
try
{
HttpClient client = new HttpClient();
HttpStringContent content = new HttpStringContent(json, Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
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)
{
return "error";
}
string jsonResponse = await response.Content.ReadAsStringAsync();
//System.Diagnostics.Debug.WriteLine(jsonResponse);
return jsonResponse;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return "error";
}
}
private static async Task<String> Get(string path)
{
var cts = new CancellationTokenSource();
cts.CancelAfter(5000);
try
{
HttpClient client = new HttpClient();
//HttpStringContent content = new HttpStringContent($"{{\"devicetype\":\"Test#Test\"}}", Windows.Storage.Streams.UnicodeEncoding.Utf8, "application /json");
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)
{
return "error";
}
string jsonResponse = await response.Content.ReadAsStringAsync();
//System.Diagnostics.Debug.WriteLine(jsonResponse);
return jsonResponse;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return "error";
}
}
public static async Task<String> Lights()
{
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/lights");
if (string.IsNullOrEmpty(response))
return "error";
return response;
}
public static async Task<String> 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<String> 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<String> 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<String> 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 static async Task<String> RegisterName(string AppName, string UserName)
{
var response = await Post("",$"{{\"devicetype\":\"{AppName}#{UserName}\"}}");
if (string.IsNullOrEmpty(response))
return "error";
return response;
}
public static async Task<String> Groups()
{
var response = await Get($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups");
if (string.IsNullOrEmpty(response))
return "error";
return response;
}
public static async Task<String> 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<String> SetGroup(int groupid, string json)
{
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}/action", json);
return response;
}
public static async Task<String> SetGroup(int groupid, bool state)
{
string json = $"{{\"on\": { ((state) ? "true" : "false") }}}";
var response = await Put($"{(String)App.LOCAL_SETTINGS.Values["id"]}/groups/{groupid}/action", json);
return response;
}
public static async Task<String> 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}/action", json);
return response;
}
}
}
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
<Identity Name="ce9a0222-308a-470c-a219-f3b5a133de19" Publisher="CN=Paul de Mast" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="ce9a0222-308a-470c-a219-f3b5a133de19" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>CarCheckInUWP</DisplayName>
<PublisherDisplayName>Paul de Mast</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate" />
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="HueUWP.App">
<uap:VisualElements DisplayName="YK Hue" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Philips Hue Light UWP Application" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\SplashScreen.png" BackgroundColor="white" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
</Capabilities>
</Package>
+29
View File
@@ -0,0 +1,29 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("HueUWP")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("HueUWP")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: ComVisible(false)]
+31
View File
@@ -0,0 +1,31 @@
<!--
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most
developers. However, you can modify these parameters to modify the behavior of the .NET Native
optimizer.
Runtime Directives are documented at http://go.microsoft.com/fwlink/?LinkID=391919
To fully enable reflection for App1.MyClass and all of its public/private members
<Type Name="App1.MyClass" Dynamic="Required All"/>
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" />
Using the Namespace directive to apply reflection policy to all the types in a particular namespace
<Namespace Name="DataClasses.ViewModels" Seralize="All" />
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
<!--
An Assembly element with Name="*Application*" applies to all assemblies in
the application package. The asterisks are not wildcards.
-->
<Assembly Name="*Application*" Dynamic="Required All" />
<!-- Add your application specific runtime directives here. -->
</Application>
</Directives>
+49
View File
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Storage;
namespace HueUWP
{
public class SettingsViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string IP
{
get { return App.LOCAL_SETTINGS.Values["ip"] as string; }
set { App.LOCAL_SETTINGS.Values["ip"] = value; NotifyPropertyChanged(nameof(IP)); }
}
public string PORT
{
get { return Convert.ToInt32(App.LOCAL_SETTINGS.Values["port"]).ToString(); }
set { App.LOCAL_SETTINGS.Values["port"] = int.Parse(value); NotifyPropertyChanged(nameof(PORT)); }
}
public bool AUTOREFRESH
{
get { return (bool)(App.LOCAL_SETTINGS.Values["autorefresh"]); }
set { App.LOCAL_SETTINGS.Values["autorefresh"] = value; NotifyPropertyChanged(nameof(AUTOREFRESH)); }
}
public string ID
{
get { return App.LOCAL_SETTINGS.Values["id"] as string; }
}
public void Update()
{
NotifyPropertyChanged(nameof(ID));
}
}
}
+9
View File
@@ -0,0 +1,9 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Themes">
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="White" />
</Style>
</ResourceDictionary>
+5
View File
@@ -0,0 +1,5 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Themes">
</ResourceDictionary>
+4
View File
@@ -0,0 +1,4 @@
Todo
- 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.
+26
View File
@@ -0,0 +1,26 @@
<Page
x:Class="HueUWP.Views.AboutView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">About</TextBlock>
</RelativePanel>
<StackPanel Grid.Row="1">
<TextBlock Margin="20,10,20,0">Made by Kenneth and Yorick.</TextBlock>
<HyperlinkButton Margin="20,10,20,0" Content="Yorick Rommers" NavigateUri="http://imegumii.space"/>
<HyperlinkButton Margin="20,10,20,0" Content="Kenneth van Ewijk" NavigateUri="http://kvanewijk.nl/"/>
</StackPanel>
</Grid>
</Page>
+30
View File
@@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
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
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class AboutView : Page
{
public AboutView()
{
this.InitializeComponent();
}
}
}
+61
View File
@@ -0,0 +1,61 @@
<Page
x:Class="HueUWP.Views.DetailView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Views"
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"
mc:Ignorable="d">
<Page.Resources>
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
<convert:VisibilityConverter x:Key="VisibilityConverter"/>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0" Text="{Binding Name}"/>
</RelativePanel>
<RelativePanel Grid.Row="1">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="14" Margin="20,10,0,0" Text="{Binding Type}" TextWrapping="WrapWholeWords"/>
</RelativePanel>
<RelativePanel Grid.Row="2">
<Rectangle Fill="{Binding Color}" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True" Height="20" Margin="0,10,0,10" />
</RelativePanel>
<StackPanel Grid.Row="3">
<ToggleSwitch Margin="20,10,0,10" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
<StackPanel Grid.Row="4">
<StackPanel Margin="20,10,20,0" Visibility="{Binding HueEnabled, Converter={StaticResource VisibilityConverter}}">
<TextBlock FontSize="18">Hue</TextBlock>
<Slider Maximum="65535" Value="{Binding Hue, Mode=TwoWay}" PointerCaptureLost="Slider_Released"/>
</StackPanel>
<StackPanel Margin="20,10,20,0" Visibility="{Binding SaturationEnabled, Converter={StaticResource VisibilityConverter}}">
<TextBlock FontSize="18">Saturation</TextBlock>
<Slider Maximum="254" Value="{Binding Saturation, Mode=TwoWay}" PointerCaptureLost="Slider_Released" />
</StackPanel>
<StackPanel Margin="20,10,20,0" Visibility="{Binding BrightnessEnabled, Converter={StaticResource VisibilityConverter}}">
<TextBlock FontSize="18">Brightness</TextBlock>
<Slider Maximum="254" Value="{Binding Brightness, Mode=TwoWay}" PointerCaptureLost="Slider_Released"/>
</StackPanel>
</StackPanel>
</Grid>
</Page>
+68
View File
@@ -0,0 +1,68 @@
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
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
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();
}
}
}
+58
View File
@@ -0,0 +1,58 @@
<Page
x:Class="HueUWP.Views.GroupsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Views"
xmlns:convert="using:HueUWP.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d">
<Page.Resources>
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Hue Groups</TextBlock>
</RelativePanel>
<RelativePanel Grid.Row="1" Visibility="Visible" Name="FeedbackPanel">
<ProgressRing Height="60" Width="60" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin=" 0,10,0,10" IsActive="True" Name="Loading" />
<TextBlock RelativePanel.AlignLeftWithPanel="True" Name="ErrorMessage" Margin="20,10,0,10"/>
</RelativePanel>
<RelativePanel Grid.Row="2" Margin="0,10,0,0" Name="GroupListPanel">
<ListView x:Name="GroupsList" ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="GroupsList_ItemClick" SelectionMode="Extended" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
<ListView.ItemTemplate>
<DataTemplate x:Name="ListViewDataTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle Width="30" Height="30" Fill="{Binding Color}" Margin="10,0,0,0"/>
<StackPanel Orientation="Vertical" Width="140" Margin="10,0,0,0" >
<TextBlock Text="{Binding Name}" FontSize="24" />
<TextBlock Text="{Binding Type}" FontSize="14" />
</StackPanel>
<ToggleSwitch Margin="10,0,00,0" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
</Grid>
</Page>
+124
View File
@@ -0,0 +1,124 @@
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
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class GroupsView : Page
{
private LightGroupListDataSource _groupsViewModel;
public ObservableCollection<Light> 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();
}
private void StartTimer()
{
if ((bool)App.LOCAL_SETTINGS.Values["autorefresh"])
{
QuietReloadGroups();
timer.Start();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New)
ReloadGroups();
else
{
GroupsList.SelectedItems.Clear();
StartTimer();
}
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;
StartTimer();
}
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();
}
}
}
+111
View File
@@ -0,0 +1,111 @@
<Page
x:Class="HueUWP.Views.LightsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Views"
xmlns:convert="using:HueUWP.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
mc:Ignorable="d">
<Page.Resources>
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Hue Lights</TextBlock>
</RelativePanel>
<RelativePanel Grid.Row="1" Visibility="Visible" Name="FeedbackPanel">
<ProgressRing Height="60" Width="60" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin=" 0,10,0,10" IsActive="True" Name="Loading" />
<TextBlock RelativePanel.AlignLeftWithPanel="True" Name="ErrorMessage" Margin="20,10,0,10"/>
</RelativePanel>
<RelativePanel Grid.Row="2" Margin="0,10,0,0" Name="LightListPanel">
<ListView x:Name="LightsList" ItemsSource="{Binding}" IsItemClickEnabled="True" ItemClick="LightsList_ItemClick" SelectionMode="Extended" RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True" RelativePanel.AlignLeftWithPanel="True" RelativePanel.AlignRightWithPanel="True">
<ListView.ItemTemplate>
<DataTemplate x:Name="ListViewDataTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle Width="30" Height="30" Fill="{Binding Color}" Margin="10,0,0,0"/>
<StackPanel Orientation="Vertical" Width="140" Margin="10,0,0,0" >
<TextBlock Text="{Binding Name}" FontSize="24" />
<TextBlock Text="{Binding Type}" FontSize="14" />
</StackPanel>
<ToggleSwitch Margin="10,0,00,0" Toggled="ToggleSwitch_Toggled" IsOn="{Binding IsOn, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativePanel>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<!-- Update values -->
<AppBarButton Label="Change values" Name="ValuesButton" Click="ValuesButton_Click" Visibility="Collapsed">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE70F;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Update on/off -->
<AppBarButton Label="On" Name="OnOffButton" Click="OnOffButton_Click" Visibility="Collapsed">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8B1;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Group -->
<AppBarToggleButton Label="Select" Name="GroupButton" Click="GroupButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE73A;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<AppBarSeparator Name="Seperator" />
<!-- Disco -->
<AppBarToggleButton Label="Disco" Name="DiscoButton" Click="DiscoButton_Click">
<AppBarToggleButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE8D6;"/>
</AppBarToggleButton.Icon>
</AppBarToggleButton>
<!-- Settings -->
<AppBarButton Label="Settings" Name="SettingsButton" Click="SettingsButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE713;"/>
</AppBarButton.Icon>
</AppBarButton>
<!-- Refresh -->
<AppBarButton Label="Refresh" Name="RefreshButton" Click="RefreshButton_Click">
<AppBarButton.Icon>
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE72C;"/>
</AppBarButton.Icon>
</AppBarButton>
<CommandBar.SecondaryCommands>
<AppBarButton Label="About" Click="AboutButton_Click"/>
<AppBarButton Label="Groups" Click="GroupsButton_Click"/>
</CommandBar.SecondaryCommands>
</CommandBar>
</Page.BottomAppBar>
</Page>
+249
View File
@@ -0,0 +1,249 @@
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.Core;
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<Light> LightsViewModel
{
get { return _lightsViewModel.GetLights(); }
}
DispatcherTimer timer;
public LightsView()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Enabled;
SystemNavigationManager.GetForCurrentView().BackRequested += OnBackRequested;
Application.Current.Suspending += Current_Suspending;
Application.Current.Resuming += Current_Resuming;
_lightsViewModel = new LightListDataSource();
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(8);
timer.Tick += Timer_Tick;
}
private void Current_Resuming(object sender, object e)
{
if ((bool)DiscoButton.IsChecked)
App.api.DiscoMode(_lightsViewModel.GetLights());
}
private void Current_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
{
App.api.DiscoMode(false);
}
private void OnBackRequested(object sender, BackRequestedEventArgs e)
{
if((bool)GroupButton.IsChecked)
{
GroupButton.IsChecked = false;
GroupButton_Click(this, new RoutedEventArgs());
e.Handled = true;
}
}
private void Timer_Tick(object sender, object e)
{
QuietReloadLights();
}
private void StartTimer()
{
if ((bool)App.LOCAL_SETTINGS.Values["autorefresh"])
{
QuietReloadLights();
timer.Start();
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.New)
ReloadLights();
else
{
LightsList.SelectedItems.Clear();
StartTimer();
}
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;
StartTimer();
}
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<Light>().ToList() );
rootframe.Navigate(typeof(DetailView), multilight);
}
}
}
}
}
+65
View File
@@ -0,0 +1,65 @@
<Page
x:Class="HueUWP.Views.SettingsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HueUWP.Views"
xmlns:convert="using:HueUWP.Helpers"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<!--DataContext="{Binding SettingsViewModel, RelativeSource={RelativeSource Self}}"-->
<Page.Resources>
<convert:NullableBooleanConverter x:Key="BoolConverter"/>
</Page.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<RelativePanel Grid.Row="0">
<TextBlock RelativePanel.AlignLeftWithPanel="True" FontSize="24" Margin="20,10,0,0">Settings</TextBlock>
</RelativePanel>
<RelativePanel Grid.Row="1">
<ScrollViewer RelativePanel.AlignBottomWithPanel="True" RelativePanel.AlignTopWithPanel="True">
<StackPanel>
<StackPanel Margin="20, 10, 20, 0">
<TextBlock FontSize="16">Automatic Refreshing</TextBlock>
<ToggleSwitch Margin="0,10,0,10" IsOn="{x:Bind SettingsViewModel.AUTOREFRESH, Mode=TwoWay, Converter={StaticResource BoolConverter}}">
<ToggleSwitch.OffContent>Off</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>On</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>
<StackPanel Margin="20, 10, 20, 0">
<TextBlock FontSize="16">Server IP</TextBlock>
<TextBox Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.IP, Mode=TwoWay}" PlaceholderText="145.48.205.190"/>
</StackPanel>
<StackPanel Margin="20, 10, 20, 0">
<TextBlock FontSize="16">Server Port</TextBlock>
<TextBox Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.PORT, Mode=TwoWay}" PlaceholderText="80" />
</StackPanel>
<StackPanel Margin="20, 10, 20, 0">
<TextBlock FontSize="16">User ID</TextBlock>
<TextBox Name="IDBox" Margin="0,10,0,10" Text="{x:Bind SettingsViewModel.ID, Mode=OneWay}" IsEnabled="False"/>
<StackPanel Orientation="Horizontal" Margin="0,10,0,10">
<Button Click="UpdateID_Click">
<StackPanel Orientation="Horizontal">
<TextBlock FontFamily="Segoe MDL2 Assets" FontSize="15" Margin="5, 9, 5, 5" Text="&#xE72C;" />
<TextBlock FontSize="15" Margin="5" Text="Request new" />
</StackPanel>
</Button>
<ProgressRing Height="35" Width="35" Margin="20, 0, 0, 0" IsActive="False" Name="UserIdProgress" />
</StackPanel>
</StackPanel>
</StackPanel>
</ScrollViewer>
</RelativePanel>
</Grid>
</Page>
+49
View File
@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Threading.Tasks;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
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
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class SettingsView : Page
{
public SettingsViewModel SettingsViewModel = new SettingsViewModel();
public SettingsView()
{
this.InitializeComponent();
//SettingsViewModel = new SettingsViewModel();
}
private async void UpdateID_Click(object sender, RoutedEventArgs e)
{
IDBox.Background = default(Brush);
UserIdProgress.IsActive = true;
string s = await App.api.Register();
if (s == "error")
IDBox.Background = new SolidColorBrush(Colors.Red);
else
SettingsViewModel.Update();
UserIdProgress.IsActive = false;
}
}
}
+17
View File
@@ -0,0 +1,17 @@
{
"dependencies": {
"Microsoft.NETCore.UniversalWindowsPlatform": "5.0.0",
"Newtonsoft.Json": "7.0.1"
},
"frameworks": {
"uap10.0": {}
},
"runtimes": {
"win10-arm": {},
"win10-arm-aot": {},
"win10-x86": {},
"win10-x86-aot": {},
"win10-x64": {},
"win10-x64-aot": {}
}
}
+14653
View File
File diff suppressed because it is too large Load Diff