commit 66f5b7ee0a897ab24d7ab506f23ce5f6c2b7bf8d Author: Chris Kaczor Date: Mon Mar 26 16:22:22 2018 -0400 Initial commit to GitHub diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3e352b1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,157 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. + +# User-specific files +*.suo +*.user +*.sln.docstates + +# Build results + +[Dd]ebug/ +[Rr]elease/ +x64/ +build/ +[Bb]in/ +[Oo]bj/ + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +!packages/*/build/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +*_i.c +*_p.c +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.log +*.scc + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opensdf +*.sdf +*.cachefile + +# Visual Studio profiler +*.psess +*.vsp +*.vspx + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# NCrunch +*.ncrunch* +.*crunch*.local.xml + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.Publish.xml + +# NuGet Packages Directory +packages/ + +# Windows Azure Build Output +csx +*.build.csdef + +# Windows Store app package directory +AppPackages/ + +# Others +sql/ +*.Cache +ClientBin/ +[Ss]tyle[Cc]op.* +~$* +*~ +*.dbmdl +*.[Pp]ublish.xml +*.pfx +*.publishsettings + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file to a newer +# Visual Studio version. Backup files are not needed, because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +App_Data/*.mdf +App_Data/*.ldf + + +#LightSwitch generated files +GeneratedArtifacts/ +_Pvt_Extensions/ +ModelManifest.xml + +# ========================= +# Windows detritus +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Mac desktop service store files +.DS_Store + +.vs/ \ No newline at end of file diff --git a/App.config b/App.config new file mode 100644 index 0000000..3d87d88 --- /dev/null +++ b/App.config @@ -0,0 +1,24 @@ + + + + +
+ + + + + + + + + True + + + + + + http://chip + + + + \ No newline at end of file diff --git a/App.xaml b/App.xaml new file mode 100644 index 0000000..fad5dfd --- /dev/null +++ b/App.xaml @@ -0,0 +1,7 @@ + + + + + diff --git a/App.xaml.cs b/App.xaml.cs new file mode 100644 index 0000000..923c519 --- /dev/null +++ b/App.xaml.cs @@ -0,0 +1,34 @@ +using FloatingStatusWindowLibrary; +using HomeStatusWindow.Properties; +using System.Diagnostics; +using System.Windows; + +namespace HomeStatusWindow +{ + public partial class App + { + private WindowSource _windowSource; + + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + + StartManager.ManageAutoStart = true; + StartManager.AutoStartEnabled = !Debugger.IsAttached && Settings.Default.AutoStart; + StartManager.AutoStartChanged += (value => + { + Settings.Default.AutoStart = value; + Settings.Default.Save(); + }); + + _windowSource = new WindowSource(); + } + + protected override void OnExit(ExitEventArgs e) + { + _windowSource.Dispose(); + + base.OnExit(e); + } + } +} diff --git a/HomeStatusWindow.csproj b/HomeStatusWindow.csproj new file mode 100644 index 0000000..7b6dfb4 --- /dev/null +++ b/HomeStatusWindow.csproj @@ -0,0 +1,116 @@ + + + + + Debug + AnyCPU + {8F5381F5-9192-4607-93D0-E415AF6BDD00} + WinExe + Properties + HomeStatusWindow + HomeStatusWindow + v4.6 + 512 + {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 4 + true + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + 4.0 + + + + + + + + MSBuild:Compile + Designer + + + + + App.xaml + Code + + + + + Code + + + True + True + Resources.resx + + + True + Settings.settings + True + + + ResXFileCodeGenerator + Resources.Designer.cs + Designer + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + + Designer + + + + + + + + 1.0.0.9 + + + 1.0.5 + + + + + + + + \ No newline at end of file diff --git a/HomeStatusWindow.sln b/HomeStatusWindow.sln new file mode 100644 index 0000000..aab33a2 --- /dev/null +++ b/HomeStatusWindow.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HomeStatusWindow", "HomeStatusWindow.csproj", "{8F5381F5-9192-4607-93D0-E415AF6BDD00}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8F5381F5-9192-4607-93D0-E415AF6BDD00}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F5381F5-9192-4607-93D0-E415AF6BDD00}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F5381F5-9192-4607-93D0-E415AF6BDD00}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F5381F5-9192-4607-93D0-E415AF6BDD00}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..de8cb70 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Chris Kaczor + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..e8ef6fa --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -0,0 +1,55 @@ +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Windows; + +// 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("HomeStatusWindow")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("HomeStatusWindow")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +//In order to begin building localizable applications, set +//CultureYouAreCodingWith in your .csproj file +//inside a . For example, if you are using US english +//in your source files, set the to en-US. Then uncomment +//the NeutralResourceLanguage attribute below. Update the "en-US" in +//the line below to match the UICulture setting in the project file. + +//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] + + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] + + +// 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")] diff --git a/Properties/Resources.Designer.cs b/Properties/Resources.Designer.cs new file mode 100644 index 0000000..8e2b58e --- /dev/null +++ b/Properties/Resources.Designer.cs @@ -0,0 +1,136 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace HomeStatusWindow.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("HomeStatusWindow.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Icon similar to (Icon). + /// + internal static System.Drawing.Icon ApplicationIcon { + get { + object obj = ResourceManager.GetObject("ApplicationIcon", resourceCulture); + return ((System.Drawing.Icon)(obj)); + } + } + + /// + /// Looks up a localized string similar to <font color='red'>Disconnected</font>. + /// + internal static string Disconnected { + get { + return ResourceManager.GetString("Disconnected", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Dryer: {0}. + /// + internal static string DryerStatus { + get { + return ResourceManager.GetString("DryerStatus", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Loading.... + /// + internal static string Loading { + get { + return ResourceManager.GetString("Loading", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Home Monitor. + /// + internal static string Name { + get { + return ResourceManager.GetString("Name", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <font color='green'>Off</font>. + /// + internal static string Off { + get { + return ResourceManager.GetString("Off", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to <font color='yellow'>On</font>. + /// + internal static string On { + get { + return ResourceManager.GetString("On", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Washer: {0}. + /// + internal static string WasherStatus { + get { + return ResourceManager.GetString("WasherStatus", resourceCulture); + } + } + } +} diff --git a/Properties/Resources.resx b/Properties/Resources.resx new file mode 100644 index 0000000..26837c6 --- /dev/null +++ b/Properties/Resources.resx @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + ..\Resources\Home.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + + <font color='red'>Disconnected</font> + + + Dryer: {0} + + + Loading... + + + Home Monitor + + + <font color='green'>Off</font> + + + <font color='yellow'>On</font> + + + Washer: {0} + + \ No newline at end of file diff --git a/Properties/Settings.Designer.cs b/Properties/Settings.Designer.cs new file mode 100644 index 0000000..eaf1078 --- /dev/null +++ b/Properties/Settings.Designer.cs @@ -0,0 +1,62 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace HomeStatusWindow.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("True")] + public bool AutoStart { + get { + return ((bool)(this["AutoStart"])); + } + set { + this["AutoStart"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string WindowSettings { + get { + return ((string)(this["WindowSettings"])); + } + set { + this["WindowSettings"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("http://chip")] + public string ServerAddress { + get { + return ((string)(this["ServerAddress"])); + } + set { + this["ServerAddress"] = value; + } + } + } +} diff --git a/Properties/Settings.settings b/Properties/Settings.settings new file mode 100644 index 0000000..c0c83cc --- /dev/null +++ b/Properties/Settings.settings @@ -0,0 +1,15 @@ + + + + + + True + + + + + + http://chip + + + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d8d89cf --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# HomeStatusWindow + +A "floating" status window that shows the status of various household devices. + +## Authors + +* **Chris Kaczor** - *Initial work* - https://github.com/ckaczor - https://chriskaczor.com + +## License + +This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details. diff --git a/Resources/Home.ico b/Resources/Home.ico new file mode 100644 index 0000000..e68bd6f Binary files /dev/null and b/Resources/Home.ico differ diff --git a/Status.cs b/Status.cs new file mode 100644 index 0000000..6d4999a --- /dev/null +++ b/Status.cs @@ -0,0 +1,12 @@ +namespace HomeStatusWindow +{ + // ReSharper disable once ClassNeverInstantiated.Global + public class Status + { + // ReSharper disable once UnusedAutoPropertyAccessor.Global + public bool? Washer { get; set; } + + // ReSharper disable once UnusedAutoPropertyAccessor.Global + public bool? Dryer { get; set; } + } +} diff --git a/WindowSource.cs b/WindowSource.cs new file mode 100644 index 0000000..16e4a41 --- /dev/null +++ b/WindowSource.cs @@ -0,0 +1,127 @@ +using FloatingStatusWindowLibrary; +using HomeStatusWindow.Properties; +using Newtonsoft.Json; +using Quobject.SocketIoClientDotNet.Client; +using System; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Threading; + +namespace HomeStatusWindow +{ + public class WindowSource : IWindowSource, IDisposable + { + private readonly FloatingStatusWindow _floatingStatusWindow; + private readonly Dispatcher _dispatcher; + + private Socket _socket; + + internal WindowSource() + { + _dispatcher = Dispatcher.CurrentDispatcher; + + _floatingStatusWindow = new FloatingStatusWindow(this); + _floatingStatusWindow.SetText(Resources.Loading); + + Task.Factory.StartNew(Initialize); + } + + public void Dispose() + { + Terminate(); + + _floatingStatusWindow.Save(); + _floatingStatusWindow.Dispose(); + } + + public void ShowSettings() + { + } + + public void Refresh() + { + } + + public void ShowAbout() + { + } + + public string Name => Resources.Name; + + public bool HasSettingsMenu => false; + public bool HasRefreshMenu => false; + public bool HasAboutMenu => false; + + public System.Drawing.Icon Icon => Resources.ApplicationIcon; + + public string WindowSettings + { + get => Settings.Default.WindowSettings; + set + { + Settings.Default.WindowSettings = value; + Settings.Default.Save(); + } + } + + private readonly Status _fullStatus = new Status(); + + private void Initialize() + { + // Create the socket + _socket = IO.Socket(Settings.Default.ServerAddress); + + // Setup for status events + _socket.On("status", UpdateText); + + _socket.On(Socket.EVENT_CONNECT, () => _socket.Emit("getStatus")); + _socket.On(Socket.EVENT_DISCONNECT, () => SetText(Resources.Disconnected)); + } + + private void Terminate() + { + _socket?.Disconnect(); + } + + private void UpdateText(object data) + { + var json = (string)data; + + var status = JsonConvert.DeserializeObject(json); + + if (status.Dryer.HasValue) + _fullStatus.Dryer = status.Dryer; + + if (status.Washer.HasValue) + _fullStatus.Washer = status.Washer; + + var text = GetText(_fullStatus); + + SetText(text); + } + + private void SetText(string text) + { + // Update the window on the main thread + _dispatcher.Invoke(() => _floatingStatusWindow.SetText(text)); + } + + private static string GetText(Status status) + { + try + { + var output = new StringBuilder(); + + output.AppendFormat(Resources.DryerStatus, status.Dryer.GetValueOrDefault() ? Resources.On : Resources.Off); + output.AppendLine(); + output.AppendFormat(Resources.WasherStatus, status.Washer.GetValueOrDefault() ? Resources.On : Resources.Off); + + return output.ToString(); + } + catch (Exception ex) + { + return ex.Message; + } + } + } +}