adding source code as checkpoint for further editing/refinement.

This commit is contained in:
Mark Snyder 2018-06-27 14:56:40 -07:00
Родитель 5b3f8fe651
Коммит edb5806fa6
183 изменённых файлов: 8148 добавлений и 0 удалений

63
Demos/Kegocnizer/CS/Admin.UWP/.gitattributes поставляемый Normal file
Просмотреть файл

@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain

261
Demos/Kegocnizer/CS/Admin.UWP/.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,261 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# DNX
project.lock.json
project.fragment.lock.json
artifacts/
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# 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
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
#*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignoreable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
node_modules/
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# 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
*.mdf
*.ldf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc

Просмотреть файл

@ -0,0 +1,31 @@
<Page
x:Class="Admin.UWP.Admin_App1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical" >
<Image Source="ms-appx:///Assets/beer.png" Stretch="Uniform" Height="160" HorizontalAlignment="Center"/>
<TextBlock x:Name="KegTitle" x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" Margin="0,1,0,0" >
<StackPanel Orientation="Vertical" Margin="19,6,-19,-6" VerticalAlignment="Center">
<TextBlock x:Name="AdminScan1" x:Uid="AdminScan1" Text="{Binding [AdminScan1]}" Style="{StaticResource AppBodyTextBlockStyle}" Margin="60,0,60,0" HorizontalTextAlignment="Center"/>
<TextBlock x:Name="AdminScan2" x:Uid="AdminScan2" Text="{Binding [AdminScan2]}" Style="{StaticResource AppBodyTextBlockStyle}" Margin="60,0,60,0" HorizontalTextAlignment="Center"/>
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Diagnostics;
using Windows.Devices.Gpio;
using Windows.UI.Core;
using System.Threading.Tasks;
using System.Runtime;
using Keg.DAL.Models;
using Windows.UI.Xaml.Input;
using System.Text;
using Keg.DAL;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App1 : Page
{
public Admin_App1()
{
this.InitializeComponent();
Window.Current.CoreWindow.KeyDown += OnKeyDown;
}
private StringBuilder sb = new StringBuilder();
public async void OnKeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs e)
{
if (e.VirtualKey == Windows.System.VirtualKey.Enter)
{
var k = await User.GetUserByHashcode(Hasher.GetSmartCardHash(sb.ToString()));
Dictionary<string, string> admin = new Dictionary<string, string>();
admin.Add($"Admin id: {sb.ToString()} ", $"Hash: {Hasher.GetSmartCardHash(sb.ToString())} ");
if (k != null && k.IsApprover)
{
KegLogger.KegLogTrace("Admin Login successful", "App1:OnKeyDown", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, admin);
Window.Current.CoreWindow.KeyDown -= OnKeyDown;
this.Frame.Navigate(typeof(Admin_App2));
}
else
{
KegLogger.KegLogTrace("Admin Login unsuccessful", "App1:OnKeyDown", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, admin);
}
sb.Clear();
return;
}
sb.Append((int)e.VirtualKey - 48);
}
private async void AddAdminUser(string hashcode)
{
User u = new User();
{
u.HashCode = hashcode;
u.IsApprover = true;
}
User.AddUserAsync(u);
}
public enum NotifyType
{
StatusMessage,
ErrorMessage
};
}
}

Просмотреть файл

@ -0,0 +1,33 @@
<Page
x:Class="Admin.UWP.Admin_App2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical">
<Image Source="ms-appx:///Assets/beer.png" Stretch="Uniform" Height="160" HorizontalAlignment="Center"/>
<TextBlock x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" Margin="0,1,0,0" >
<StackPanel Orientation="Vertical" Height="639" VerticalAlignment="Center" >
<TextBlock x:Uid="Welcome" Text="{Binding [Welcome]}" Style="{StaticResource AppBodyTextBlockStyle}" Margin="60,0,60,0"/>
<Button x:Uid="AdminAction1" Content="{Binding [AdminAction1]}" Style="{StaticResource AppButtonStyle}" Click="Button_Click" Margin="0,10,0,0"/>
<HyperlinkButton x:Uid="AdminAction2" Content="{Binding [AdminAction2]}" Style="{StaticResource AppHyperlinkStyle}" Click="HyperlinkButton_Click"/>
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,39 @@
using System;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System.Diagnostics;
using Windows.Devices.Gpio;
using Windows.UI.Core;
using System.Threading.Tasks;
using System.Runtime;
using Keg.DAL;
using Keg.DAL.Models;
using Windows.UI.Xaml.Input;
using System.Text;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App2 : Page
{
public Admin_App2()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Admin_App3));
}
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Admin_App6));
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
<Page
x:Class="Admin.UWP.Admin_App3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical" >
<Button Grid.Column="0" x:Name="BackButton" Content="{StaticResource IconBack}" Background="Transparent" BorderThickness="0" BorderBrush="Transparent"
FontFamily="{StaticResource IconFontFamily}" FontSize="24"
Margin="24,0,0,0" Height="48" Width="48" VerticalAlignment="Top" FontWeight="ExtraBold" FontStretch="ExtraExpanded" Click="BackButton_Click"/>
<Image Source="ms-appx:///Assets/beer.png" Stretch="Uniform" Height="160" HorizontalAlignment="Center"/>
<TextBlock x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" Margin="0,1,0,0" >
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<TextBlock x:Uid="ScanBadge" Text="{Binding [ScanBadge]}" Style="{StaticResource AppBodyTextBlockStyle}"/>
<Image Source="Assets/id.png" HorizontalAlignment="Center" Height="423" Width="343"/>
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,69 @@
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;
using System.Diagnostics;
using System.Threading.Tasks;
using Keg.DAL.Models;
using Keg.DAL;
using System.Text;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App3 : Page
{
public Admin_App3()
{
this.InitializeComponent();
Window.Current.CoreWindow.KeyDown += OnKeyDown;
}
private StringBuilder sb = new StringBuilder();
public void OnKeyDown(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.KeyEventArgs e)
{
if (e.VirtualKey == Windows.System.VirtualKey.Enter)
{
Dictionary<string, string> user = new Dictionary<string, string>();
user.Add($"User id: {sb.ToString()} ", $"Hash: {Hasher.GetSmartCardHash(sb.ToString())} ");
if (sb.Length != 0)
{
User u = new User();
{
u.HashCode = Hasher.GetSmartCardHash(sb.ToString());
u.IsApprover = false;
}
KegLogger.KegLogTrace($"Adding user User id: { sb.ToString()} Hash: { Hasher.GetSmartCardHash(sb.ToString())}", "App3:OnKeyDown", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, null);
User.AddUserAsync(u);
Window.Current.CoreWindow.KeyDown -= OnKeyDown;
this.Frame.Navigate(typeof(Admin_App4));
}
sb.Clear();
return;
}
sb.Append((int)e.VirtualKey - 48);
}
private void BackButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Admin_App2));
}
}
}

Просмотреть файл

@ -0,0 +1,32 @@
<Page
x:Class="Admin.UWP.Admin_App4"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical" >
<TextBlock x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" Margin="0,1,0,0" >
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<TextBlock x:Uid="AddUser1" Text="{Binding [AddUser1]}" Style="{StaticResource AppTitleTextBlockStyle}" />
<Image Source="Assets/beer.gif" HorizontalAlignment="Center" Height="405" Margin="509,0,495,0" Width="496" />
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,38 @@
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;
using System.Threading.Tasks;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App4 : Page
{
public Admin_App4()
{
this.InitializeComponent();
NavigateNext();
}
private async void NavigateNext()
{
await Task.Delay(3000);
this.Frame.Navigate(typeof(Admin_App5));
}
}
}

Просмотреть файл

@ -0,0 +1,35 @@
<Page
x:Class="Admin.UWP.Admin_App5"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical" >
<Button Grid.Column="0" x:Name="BackButton" Content="{StaticResource IconBack}" Background="Transparent" BorderThickness="0" BorderBrush="Transparent"
FontFamily="{StaticResource IconFontFamily}" FontSize="24"
Margin="24,0,0,0" Height="48" Width="48" VerticalAlignment="Top" FontWeight="ExtraBold" FontStretch="ExtraExpanded" Click="BackButton_Click"/>
<TextBlock x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" Margin="0,1,0,0" >
<StackPanel Orientation="Vertical" VerticalAlignment="Top">
<TextBlock x:Uid="AddUser2" Text="{Binding [AddUser2]}" Style="{StaticResource AppBodyTextBlockStyle}"/>
<Image Source="Assets/checkmark.png" HorizontalAlignment="Center" Height="405" Margin="509,0,495,0" Width="496" />
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,35 @@
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 https://go.microsoft.com/fwlink/?LinkId=234238
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App5 : Page
{
public Admin_App5()
{
this.InitializeComponent();
}
private void BackButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Admin_App2));
}
}
}

Просмотреть файл

@ -0,0 +1,50 @@
<Page
x:Class="Admin.UWP.Admin_App6"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="0.5*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<!-- Header row -->
<Grid Grid.Row="0" x:Name="HeaderRow" >
<StackPanel Orientation="Vertical" >
<Button Grid.Column="0" x:Name="BackButton" Content="{StaticResource IconBack}" Background="Transparent" BorderThickness="0" BorderBrush="Transparent"
FontFamily="{StaticResource IconFontFamily}" FontSize="24"
Margin="24,0,0,0" Height="48" Width="48" VerticalAlignment="Top" FontWeight="ExtraBold" FontStretch="ExtraExpanded" Click="BackButton_Click"/>
<TextBlock x:Uid="KegTitle" Text="{Binding [KegTitle]}" Style="{StaticResource AppTitleTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1" x:Name="DataRow" >
<StackPanel Orientation="Vertical" >
<TextBlock x:Uid="OfficeHours" Text="{Binding [OfficeHours]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Center">
<ComboBox x:Name="cBox1" Style="{StaticResource AppComboBoxStyle}" />
<ComboBox x:Name="cBox2" Style="{StaticResource AppComboBoxStyle}" />
<TextBlock x:Uid="To" Text="{Binding [To]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
<ComboBox x:Name="cBox3" Style="{StaticResource AppComboBoxStyle}" />
<ComboBox x:Name="cBox4" Style="{StaticResource AppComboBoxStyle}" />
</StackPanel>
<TextBlock x:Uid="EventDuration" Text="{Binding [EventDuration]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
<ComboBox x:Name="cBox5" Style="{StaticResource AppComboBoxStyle}" />
<TextBlock x:Uid="Minutes" Text="{Binding [Minutes]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
<TextBlock x:Uid="ConsumptionLimit" Text="{Binding [ConsumptionLimit]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" >
<ComboBox x:Name="cBox6" Style="{StaticResource AppComboBoxStyle}" />
<TextBlock x:Uid="Pints" Text="{Binding [Pints]}" Style="{StaticResource AppBodyTextBlockStyle}" HorizontalTextAlignment="Center"/>
</StackPanel>
<Button Content="Save Settings" Style="{StaticResource AppButtonStyle}" HorizontalAlignment="Center" VerticalAlignment="Center" Click="SaveSettings" Margin="0,200,0,0"/>
</StackPanel>
</Grid>
</Grid>
</Page>

Просмотреть файл

@ -0,0 +1,115 @@
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;
using Newtonsoft.Json;
using System.Diagnostics;
using System.Net.Http;
using Keg.DAL;
// The Blank Page item template is documented at https://go.microsoft.com/fwlink/?LinkId=234238
namespace Admin.UWP
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class Admin_App6 : Page
{
private class KegConfig
{
[JsonProperty("maxeventdurationminutes")]
public int MaxEventDurationMinutes { get; set; }
[JsonProperty("maxuserouncesperhour")]
public int MaxUserOuncesPerHour { get; set; }
[JsonProperty("corehours")]
public string CoreHours { get; set; }
[JsonProperty("coredays")]
public string CoreDays { get { return "Mon, Tue, Wed, Thu, Fri"; } }
}
private void PopulateComboBox()
{
List<string> timeIntervals = new List<string>();
TimeSpan startTime = new TimeSpan(1, 0, 0);
DateTime startDate = new DateTime(DateTime.MinValue.Ticks); // Date to be used to get shortTime format.
for (int i = 0; i < 12; i++)
{
int minutesToBeAdded = 60 * i; // Increasing minutes by 30 minutes interval
TimeSpan timeToBeAdded = new TimeSpan(0, minutesToBeAdded, 0);
TimeSpan t = startTime.Add(timeToBeAdded);
DateTime result = startDate + t;
timeIntervals.Add(result.ToString("HH:mm")); // Use Date.ToShortTimeString() method to get the desired format
}
cBox1.ItemsSource = timeIntervals;
cBox1.SelectedIndex = timeIntervals.Count() / 2;
cBox2.ItemsSource = new List<string> { "AM", "PM" };
cBox2.SelectedIndex = 0;
cBox3.ItemsSource = timeIntervals;
cBox3.SelectedIndex = (timeIntervals.Count() / 2) + 4;
cBox4.ItemsSource = new List<string> { "AM", "PM" };
cBox4.SelectedIndex = 1;
List<int> minutes = new List<int>();
for(int i = 1; i < 24; i++ )
{
minutes.Add(i * 60);
}
cBox5.ItemsSource = minutes;
cBox5.SelectedIndex = 1;
cBox6.ItemsSource = new List<int> { 1, 2, 3, 4, 5, 6 };
cBox6.SelectedIndex = 3;
}
public Admin_App6()
{
this.InitializeComponent();
PopulateComboBox();
}
private static async void SaveKegConfigAsync(KegConfig config)
{
var client = new System.Net.Http.HttpClient();
string url = $"https://kegocnizerdemofunctions.azurewebsites.net/api/kegconfig";
var data = JsonConvert.SerializeObject(config);
StringContent content = new StringContent(data, System.Text.Encoding.UTF8, "application/json");
KegLogger.KegLogTrace($"Save Keg Config MaxEventDuration : {config.MaxEventDurationMinutes} MaxUserOuncesPerHour: {config.MaxUserOuncesPerHour} CoreHours: {config.CoreHours}",
"App6:SaveSettings", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, null);
var result = await client.PostAsync(url, content);
}
private void SaveSettings(object sender, RoutedEventArgs e)
{
KegConfig config = new KegConfig();
config.MaxEventDurationMinutes = (int)cBox5.SelectedItem;
config.MaxUserOuncesPerHour = (int)cBox6.SelectedItem;
config.CoreHours = GetCoreHours(cBox1.SelectedItem.ToString() + cBox2.SelectedItem.ToString() + ";" + cBox3.SelectedItem.ToString() + cBox4.SelectedItem.ToString());
SaveKegConfigAsync(config);
}
private string GetCoreHours(String timeString)
{
string EventDuration = null;
String[] timeStrings = timeString.Split(';');
DateTime dt1 = DateTime.ParseExact(timeStrings[0], "hh:mmtt", System.Globalization.CultureInfo.CurrentCulture);
DateTime dt2 = DateTime.ParseExact(timeStrings[1], "hh:mmtt", System.Globalization.CultureInfo.CurrentCulture);
EventDuration = dt1.Hour + "T" + dt2.Hour;
return EventDuration;
}
private void BackButton_Click(object sender, RoutedEventArgs e)
{
this.Frame.Navigate(typeof(Admin_App2));
}
}
}

Просмотреть файл

@ -0,0 +1,212 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.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>{B048E94D-9407-422D-A213-1D79061D7A63}</ProjectGuid>
<OutputType>AppContainerExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Admin.UWP</RootNamespace>
<AssemblyName>Admin.UWP</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview>
<PackageCertificateKeyFile>TestSmartCardApp_TemporaryKey.pfx</PackageCertificateKeyFile>
</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>
<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>
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain>
</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>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="Admin-App2.xaml.cs">
<DependentUpon>Admin-App2.xaml</DependentUpon>
</Compile>
<Compile Include="Admin-App3.xaml.cs">
<DependentUpon>Admin-App3.xaml</DependentUpon>
</Compile>
<Compile Include="Admin-App4.xaml.cs">
<DependentUpon>Admin-App4.xaml</DependentUpon>
</Compile>
<Compile Include="Admin-App5.xaml.cs">
<DependentUpon>Admin-App5.xaml</DependentUpon>
</Compile>
<Compile Include="Admin-App6.xaml.cs">
<DependentUpon>Admin-App6.xaml</DependentUpon>
</Compile>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="Admin-App1.xaml.cs">
<DependentUpon>Admin-App1.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<AppxManifest Include="Package.appxmanifest">
<SubType>Designer</SubType>
</AppxManifest>
<None Include="Admin.UWP_TemporaryKey.pfx" />
<PRIResource Include="Strings\en-US\Resources.resw" />
</ItemGroup>
<ItemGroup>
<Content Include="Assets\beer.gif" />
<Content Include="Assets\beer.png" />
<Content Include="Assets\checkmark.png" />
<Content Include="Assets\id.png" />
<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\Wide310x150Logo.scale-200.png" />
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Page Include="Admin-App2.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Admin-App3.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Admin-App4.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Admin-App5.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Admin-App6.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Admin-App1.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Styles.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<SDKReference Include="WindowsDesktop, Version=10.0.16299.0">
<Name>Windows Desktop Extensions for the UWP</Name>
</SDKReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights">
<Version>2.6.4</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.0.8</Version>
</PackageReference>
<PackageReference Include="Moq">
<Version>4.8.2</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<WCFMetadata Include="Connected Services\" />
</ItemGroup>
<ItemGroup>
<Reference Include="Keg.DAL, Version=1.0.0.0, Culture=neutral, processorArchitecture=AMD64">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\Keg.DAL\bin\x64\Release\Keg.DAL.dll</HintPath>
</Reference>
</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>

Просмотреть файл

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2027
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.UWP", "Admin.UWP.csproj", "{B048E94D-9407-422D-A213-1D79061D7A63}"
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
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|ARM.ActiveCfg = Debug|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|ARM.Build.0 = Debug|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|ARM.Deploy.0 = Debug|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x64.ActiveCfg = Debug|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x64.Build.0 = Debug|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x64.Deploy.0 = Debug|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x86.ActiveCfg = Debug|x86
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x86.Build.0 = Debug|x86
{B048E94D-9407-422D-A213-1D79061D7A63}.Debug|x86.Deploy.0 = Debug|x86
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|ARM.ActiveCfg = Release|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|ARM.Build.0 = Release|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|ARM.Deploy.0 = Release|ARM
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x64.ActiveCfg = Release|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x64.Build.0 = Release|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x64.Deploy.0 = Release|x64
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x86.ActiveCfg = Release|x86
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x86.Build.0 = Release|x86
{B048E94D-9407-422D-A213-1D79061D7A63}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4ADA610B-7B5E-4394-AA10-49C67B0F5129}
EndGlobalSection
EndGlobal

Просмотреть файл

@ -0,0 +1,12 @@
<Application
x:Class="Admin.UWP.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary Source="Styles.xaml" />
</Application.Resources>
</Application>

Просмотреть файл

@ -0,0 +1,111 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Resources;
using Windows.ApplicationModel.Resources.Core;
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;
using Windows.Globalization;
using Windows.System.UserProfile;
using Keg.DAL;
using Microsoft.ApplicationInsights.DataContracts;
using Windows.Security.ExchangeActiveSyncProvisioning;
using Moq;
namespace Admin.UWP
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
/// <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;
}
/// <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)
{
Frame 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;
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(Admin_App1), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
EasClientDeviceInformation deviceInfo;
string _productName = null;
deviceInfo = new EasClientDeviceInformation();
_productName = deviceInfo.SystemProductName;
KegLogger.KegLogTrace("Admin App Loaded", "App:Initialize", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, null);
}
/// <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)
{
KegLogger.KegLogException(e.Exception, "App:NavigationFailed", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Error);
}
/// <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();
}
}
}

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LargeTile.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.3 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LargeTile.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LargeTile.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.8 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LargeTile.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.5 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LargeTile.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 24 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/LockScreenLogo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SmallTile.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SmallTile.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SmallTile.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SmallTile.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SmallTile.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/SplashScreen.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.5 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 518 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 8.6 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 976 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Square44x44Logo.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.0 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Square44x44Logo.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.3 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Square44x44Logo.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Square44x44Logo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.1 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Square44x44Logo.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 413 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 595 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.2 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.8 KiB

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 764 B

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.1 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.backup.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.5 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 1.9 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.1 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/StoreLogo.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Wide310x150Logo.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.2 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Wide310x150Logo.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.7 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Wide310x150Logo.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 3.3 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Wide310x150Logo.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/Wide310x150Logo.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 40 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.8 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.7 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 6.0 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.6 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 11 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/beer.scale-400.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 29 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/checkmark.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 4.4 KiB

Двоичные данные
Demos/Kegocnizer/CS/Admin.UWP/Assets/id.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 12 KiB

Просмотреть файл

@ -0,0 +1,35 @@
<?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="e5517a7a-ad96-447e-b78d-209f930900da" Publisher="CN=iotkeg" Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="e5517a7a-ad96-447e-b78d-209f930900da" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
<Properties>
<DisplayName>KegAdmin</DisplayName>
<PublisherDisplayName>iotkeg</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="Admin.UWP.App">
<uap:VisualElements DisplayName="KegAdmin" Square150x150Logo="Assets\Square150x150Logo.png" Square44x44Logo="Assets\Square44x44Logo.png" Description="Admin app for Kegocnizer" BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="Kegocnizer" Square310x310Logo="Assets\LargeTile.png" Square71x71Logo="Assets\SmallTile.png">
</uap:DefaultTile>
<uap:SplashScreen Image="Assets\beer.png" />
<uap:InitialRotationPreference>
<uap:Rotation Preference="portrait" />
<uap:Rotation Preference="landscape" />
<uap:Rotation Preference="portraitFlipped" />
<uap:Rotation Preference="landscapeFlipped" />
</uap:InitialRotationPreference>
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="sharedUserCertificates" />
</Capabilities>
</Package>

Просмотреть файл

@ -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("KegAdmin")]
[assembly: AssemblyDescription("Admin app for Kegocnizer")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Kegocnizer")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[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)]

Просмотреть файл

@ -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 https://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" Serialize="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>

Просмотреть файл

@ -0,0 +1,168 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AddUser1.Text" xml:space="preserve">
<value>Adding user to the system...</value>
</data>
<data name="AddUser2.Text" xml:space="preserve">
<value>User has been added!</value>
</data>
<data name="AdminAction1.Content" xml:space="preserve">
<value>Add new user</value>
</data>
<data name="AdminAction2.Content" xml:space="preserve">
<value>Manage settings</value>
</data>
<data name="AdminScan1.Text" xml:space="preserve">
<value>Please scan your badge</value>
</data>
<data name="AdminScan2.Text" xml:space="preserve">
<value>to confirm administrative permissions.</value>
</data>
<data name="ConsumptionLimit.Text" xml:space="preserve">
<value>Consumption limit per user:</value>
</data>
<data name="EventDuration.Text" xml:space="preserve">
<value>Change event duration:</value>
</data>
<data name="KegTitle.Text" xml:space="preserve">
<value>Kegocnizer</value>
</data>
<data name="KegTitleImage" xml:space="preserve">
<value>ms-appx:///Assets/beer.png</value>
</data>
<data name="Minutes.Text" xml:space="preserve">
<value>minutes</value>
</data>
<data name="OfficeHours.Text" xml:space="preserve">
<value>Change office hours:</value>
</data>
<data name="Pints.Text" xml:space="preserve">
<value>pints</value>
</data>
<data name="ScanBadge.Text" xml:space="preserve">
<value>Scan new user's badge</value>
</data>
<data name="To.Text" xml:space="preserve">
<value>to</value>
</data>
<data name="Welcome.Text" xml:space="preserve">
<value>Welcome!</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,57 @@
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Admin.UWP">
<!--Theme-->
<SolidColorBrush x:Key="ApplicationPageBackgroundThemeBrush" Color="#F1C744"/>
<!--Fonts-->
<Style x:Key="AppTitleTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="70" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
</Style>
<Style x:Key="AppBodyTextBlockStyle" TargetType="TextBlock" BasedOn="{StaticResource BaseTextBlockStyle}">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="45"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,10,0,0" />
</Style>
<Style x:Key="AppButtonStyle" TargetType="Button">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="FontSize" Value="50"/>
</Style>
<Style x:Key="AppHyperlinkStyle" TargetType="HyperlinkButton">
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="FontSize" Value="50"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,10,0,0" />
</Style>
<Style x:Key="AppComboBoxStyle" TargetType="ComboBox">
<Setter Property="FontSize" Value="30"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Background" Value="White"/>
<Setter Property="Margin" Value="10,20,20,0" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="5" />
<Setter Property="Width" Value="150" />
</Style>
<!--Icons-->
<FontFamily x:Key="IconFontFamily">Segoe MDL2 Assets</FontFamily>
<FontFamily x:Key="IoTIconFontFamily">ms-appx:///Assets/Fonts/IOTMDL2.1.35.ttf#IOT MDL2 Assets</FontFamily>
<x:String x:Key="IconBlock">&#xE25B;</x:String>
<x:String x:Key="IconBack">&#xE016;</x:String>
</ResourceDictionary>

Просмотреть файл

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Keg.DAL
{
public static class Constants
{
/*
* Demo Keys
*/
///// <summary>
///// Update this with Azure Functions Url
///// </summary>
//public const string COSMOSAzureFunctionsURL = "https://kegocnizerdemofunctions.azurewebsites.net/api/";
///// <summary>
///// KegConfig Guid Entiry enables to retrieve Configurations from Cloud
///// </summary>
//public static readonly string KEGSETTINGSGUID = "6fd83ffd-601a-48b0-bff9-566250928e8d";
////Change this Key as required.
//public static readonly string INSTRUMENTKEY = "e86b04e5-ecd0-4b44-a595-d416f0611a8b";
/*
* Deployed Keys
*/
/// <summary>
/// Update this with Azure Functions Url
/// </summary>
public const string COSMOSAzureFunctionsURL = "https://wsdkegfunctions.azurewebsites.net/api/";
/// <summary>
/// KegConfig Guid Entiry enables to retrieve Configurations from Cloud. Typically Keg Admin tool will help getting this Guid
/// </summary>
public static readonly string KEGSETTINGSGUID = "2a9d4c3a-75d7-4222-9827-5704efb24b54";
//Change this Key as required.
public static readonly string INSTRUMENTKEY = "6d8fbbea-ecf0-4827-b6ff-c79199ba869e";
}
}

Просмотреть файл

@ -0,0 +1,73 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Keg.DAL
{
public class FixedSizedQueue<T> : IReadOnlyCollection<T>
{
private object LOCK = new object();
ConcurrentQueue<T> queue;
private int _count;
public int MaxSize { get; set; }
public int Count { get { return _count; } }
public FixedSizedQueue(int maxSize, IEnumerable<T> items = null)
{
this.MaxSize = maxSize;
if (items == null)
{
queue = new ConcurrentQueue<T>();
}
else
{
queue = new ConcurrentQueue<T>(items);
EnsureLimitConstraint();
}
}
public void Enqueue(T obj)
{
queue.Enqueue(obj);
_count++;
EnsureLimitConstraint();
}
private void EnsureLimitConstraint()
{
if (queue.Count > MaxSize)
{
lock (LOCK)
{
T overflow;
while (queue.Count > MaxSize)
{
queue.TryDequeue(out overflow);
_count--;
}
}
}
}
public T[] ToArray()
{
return queue.ToArray();
}
public IEnumerator<T> GetEnumerator()
{
return queue.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return queue.GetEnumerator();
}
}
}

Просмотреть файл

@ -0,0 +1,163 @@
using Keg.DAL.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL
{
public class Flow
{
public IDictionary<string, object> CalibrationSettings { get; set; }
public const string FlowGPIOPinNumberSetting = @"FlowGPIOPinNumber"; // a string, valued e.g., SPI0 or SPI1 to indicate which SPI bus is being used
public const string FlowCalibrationFactorSetting = @"FlowCalibrationFactor"; // a float (as string), such as "0.05" for 'factor' in (reading * factor) + offset
public const string FlowCalibrationOffsetSetting = @"FlowCalibrationOffset"; // a float (as string), such as "14.0" for 'offset' in (reading * factor) + offset
private Measurement lastMeasurement; // this value accumulates over time. Consumers should note the starting measurement and then compare that to a future measurement.
//RPI
private static readonly Int32 FLOWGPIOPIN = 3; //PIN5
public Models.Measurement GetFlow()
{
return lastMeasurement;
}
public event EventHandler<MeasurementChangedEventArgs> FlowChanged;
protected virtual void OnFlowChanged(MeasurementChangedEventArgs e)
{
FlowChanged?.Invoke(this, e);
}
public Flow()
{
CalibrationSettings = new Dictionary<string, object>(GetDefaultCalibrationSettings());
lastMeasurement = new Measurement(0.0f, Measurement.UnitsOfMeasure.Ounces);
}
public Flow(IDictionary<string, object> calibrationSettings)
: this()
{
foreach (string key in calibrationSettings.Keys)
{
if (key.Equals(FlowGPIOPinNumberSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(FlowCalibrationFactorSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(FlowCalibrationOffsetSetting, StringComparison.OrdinalIgnoreCase))
{
CalibrationSettings[key] = calibrationSettings[key].ToString();
}
}
}
// the purpose of this object is to allow someone an easy way to generate the proper
// default calibration settings that this sensor interface object supports.
// in this case, it supports a Measurement that indicates how many degrees to add
// to readings to account for variations in the tolerance of the actual circuitry.
public static IDictionary<string, object> GetDefaultCalibrationSettings()
{
return new Dictionary<string, object>
{
{ FlowGPIOPinNumberSetting, FLOWGPIOPIN.ToString() },
{ FlowCalibrationFactorSetting, ".0045" },
{ FlowCalibrationOffsetSetting, "0" }
};
}
private GpioPin _pin;
private bool IsInitialized { get; set; }
public void Initialize()
{
if (IsInitialized)
return;
//IsInitialized = true;
int pinNumber = Int32.Parse(CalibrationSettings[FlowGPIOPinNumberSetting].ToString());
var c = GpioController.GetDefault();
if (c != null)
{
try
{
_pin = c.OpenPin(pinNumber);
if (_pin != null)
{
if (_pin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
_pin.SetDriveMode(GpioPinDriveMode.InputPullUp);
_pin.ValueChanged += _pin_ValueChanged;
}
}
catch(Exception ex)
{
Debug.WriteLine($"Exception:{ex.Message}");
KegLogger.KegLogException(ex, "Flow:Initialize", SeverityLevel.Critical);
KegLogger.KegLogTrace(ex.Message, "Flow:Initialize", SeverityLevel.Error,
new Dictionary<string, string>() {
{"PinNumber", CalibrationSettings[FlowGPIOPinNumberSetting].ToString() }
});
//Pin used exception
//TODO
}
}
IsInitialized = true;
}
private int _second = -1;
private float _persecond = 0.0f;
private void _pin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
{
Debug.WriteLine($"Flow Pinchanged:{args.Edge}");
var task = Task.Run(() => {
if (args.Edge == GpioPinEdge.RisingEdge)
{
int second = DateTime.Now.Second;
if (second != _second)
{
Debug.WriteLine($"{_persecond} per-second");
_second = second;
int offset = Int32.Parse(CalibrationSettings[FlowCalibrationOffsetSetting].ToString());
float factor = float.Parse(CalibrationSettings[FlowCalibrationFactorSetting].ToString());
lastMeasurement.Amount += _persecond * factor + offset;
_persecond = 0.0f;
OnFlowChanged(new MeasurementChangedEventArgs(lastMeasurement));
//_second = second;
//_persecond = 0.0f;
}
_persecond++;
}
});
}
private Timer _timer;
public void Initialize(int initialDelay, int period)
{
Initialize();
_timer = new Timer(OnTimer, null, initialDelay, period);
}
public void ResetFlow()
{
lastMeasurement.Amount = 0.0f;
}
public void Dispose()
{
var timer = _timer;
_timer = null;
timer?.Dispose();
}
private void OnTimer(object state)
{
OnFlowChanged(new MeasurementChangedEventArgs(lastMeasurement));
}
}
}

Просмотреть файл

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Gpio;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL
{
public class FlowControl
{
public IDictionary<string, object> CalibrationSettings { get; set; }
public const string FlowControlGpioPinNumberSetting = @"FlowControlGPIOPinNumber"; // an integer, like 18
private GpioPin _pin;
private GpioPinValue _isActive;
//RPI
private static readonly Int32 FLOWCONTROLGPIOPIN = 18; //PIN 12
public bool IsActive
{
get { return _isActive == GpioPinValue.High; }
set
{
if ((_isActive == GpioPinValue.High) != value || _pin == null)
{
_isActive = value ? GpioPinValue.High : GpioPinValue.Low;
try
{
if (_pin == null)
{
int pinNumber = FLOWCONTROLGPIOPIN; // default
if (CalibrationSettings.ContainsKey(FlowControlGpioPinNumberSetting))
pinNumber = Int32.Parse(CalibrationSettings[FlowControlGpioPinNumberSetting].ToString());
Debug.WriteLine($"Flow Control:Initializing pin {pinNumber}.");
var c = GpioController.GetDefault();
if (c != null)
{
_pin = c.OpenPin(pinNumber);
_pin.SetDriveMode(GpioPinDriveMode.Output);
}
}
if (_pin != null)
{
Debug.WriteLine($"Setting flow control to {_isActive}.");
_pin.Write(_isActive);
}
}
catch (Exception ex)
{
Debug.WriteLine("Flow Control:Error setting flow control value, " + ex.Message);
KegLogger.KegLogException(ex, "FlowControl:IsActive", SeverityLevel.Critical);
KegLogger.KegLogTrace(ex.Message, "FlowControl:IsActive", SeverityLevel.Error,
new Dictionary<string, string>() {
{"PinNumber", CalibrationSettings[FlowControlGpioPinNumberSetting].ToString() }
});
}
}
}
}
public event EventHandler<FlowControlChangedEventArgs> FlowControlChanged;
protected virtual void OnFlowControlChanged(FlowControlChangedEventArgs e)
{
FlowControlChanged?.Invoke(this, e);
}
// the purpose of this object is to allow someone an easy way to generate the proper
// default calibration settings that this sensor interface object supports.
// in this case, it supports a Measurement that indicates how many degrees to add
// to readings to account for variations in the tolerance of the actual circuitry.
public static IDictionary<string, object> GetDefaultCalibrationSettings()
{
return new Dictionary<string, object>
{
{ FlowControlGpioPinNumberSetting, FLOWCONTROLGPIOPIN.ToString() },
};
}
public FlowControl()
{
CalibrationSettings = new Dictionary<string, object>();
}
public FlowControl(IDictionary<string, object> calibrationSettings)
: this()
{
CalibrationSettings.Add(FlowControlGpioPinNumberSetting, (calibrationSettings.ContainsKey(FlowControlGpioPinNumberSetting)) ? calibrationSettings[FlowControlGpioPinNumberSetting] as string : "");
}
private Timer _timer;
public void Initialize(int initialDelay, int period)
{
Initialize();
_timer = new Timer(OnTimer, null, initialDelay, period);
}
public void Initialize()
{
var gpio = GpioController.GetDefault();
if (gpio == null)
{
_pin = null;
Debug.WriteLine("Flow Control:Unable to initialize, no GPIO controller.");
KegLogger.KegLogTrace("Custom: Flow Control:Unable to initialize, no GPIO controller.",
"FlowControl:Initialize", SeverityLevel.Error,
new Dictionary<string, string>() {
{"PinNumber", CalibrationSettings[FlowControlGpioPinNumberSetting].ToString() },
{"IsActive", _isActive.ToString() }
});
return;
}
if(_pin == null)
{
try
{
_pin = gpio.OpenPin(Int32.Parse(CalibrationSettings[FlowControlGpioPinNumberSetting].ToString()), GpioSharingMode.Exclusive);
_pin.Write(_isActive);
_pin.SetDriveMode(GpioPinDriveMode.Output);
}
catch(Exception ex)
{
Debug.WriteLine($"Flow Control:Unable to initialize, PIN Null.{ex.Message}");
KegLogger.KegLogException(ex, "FlowControl:Initialize", SeverityLevel.Critical);
KegLogger.KegLogTrace(ex.Message, "FlowControl:Initialize", SeverityLevel.Critical,
new Dictionary<string, string>() {
{"PinNumber", CalibrationSettings[FlowControlGpioPinNumberSetting].ToString() },
{"IsActive", _isActive.ToString() }
});
}
}
}
public void Dispose()
{
var timer = _timer;
_timer = null;
timer?.Dispose();
}
private void OnTimer(object state)
{
OnFlowControlChanged(new FlowControlChangedEventArgs(IsActive));
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
using System;
namespace Keg.DAL
{
public class FlowControlChangedEventArgs : EventArgs
{
public Boolean Flowing { get; set; }
public FlowControlChangedEventArgs(Boolean flowing)
{
Flowing = flowing;
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace Keg.DAL
{
public class Hasher
{
public static string GetSmartCardHash(string SmartCardId)
{
if (SmartCardId == null)
return SmartCardId;
SHA256 crypt = SHA256.Create();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(SmartCardId));
foreach (byte b in crypto)
{
hash.Append(b.ToString("x2"));
}
return hash.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;
namespace Keg.DAL.Helpers
{
public class Hasher
{
public static string GetSmartCardHash(string SmartCardId)
{
if (SmartCardId == null)
return SmartCardId;
SHA256 crypt = SHA256.Create();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(SmartCardId));
foreach (byte b in crypto)
{
hash.Append(b.ToString("x2"));
}
return hash.ToString();
}
}
}

Просмотреть файл

@ -0,0 +1,157 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.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)' == '' ">AnyCPU</Platform>
<ProjectGuid>{9FD08840-1057-4AF7-92AB-21C710121B5F}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Keg.DAL</RootNamespace>
<AssemblyName>Keg.DAL</AssemblyName>
<DefaultLanguage>en-US</DefaultLanguage>
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier>
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.16299.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.16299.0</TargetPlatformMinVersion>
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<PlatformTarget>x86</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
<PlatformTarget>x86</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'">
<PlatformTarget>ARM</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<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>
</PropertyGroup>
<PropertyGroup>
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
</PropertyGroup>
<ItemGroup>
<Compile Include="Constants.cs" />
<Compile Include="FixedSizedQueue.cs" />
<Compile Include="Flow.cs" />
<Compile Include="FlowControl.cs" />
<Compile Include="FlowControlChangedEventArgs.cs" />
<Compile Include="Hasher.cs" />
<Compile Include="KegLogger.cs" />
<Compile Include="MeasurementChangedEventArgs.cs" />
<Compile Include="Models\KegSettings.cs" />
<Compile Include="Models\Measurement.cs" />
<Compile Include="Models\User.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Temperature.cs" />
<Compile Include="Weight.cs" />
<EmbeddedResource Include="Properties\Keg.DAL.rd.xml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ApplicationInsights">
<Version>2.5.1</Version>
</PackageReference>
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
<Version>6.0.8</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>11.0.2</Version>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Sensors.Temperature\Sensors.Temperature.vcxproj">
<Project>{2cd70a4f-9eed-4cda-9e07-1a2bd33b4976}</Project>
<Name>Sensors.Temperature</Name>
</ProjectReference>
<ProjectReference Include="..\Sensors.Weight\Sensors.Weight.csproj">
<Project>{76fb0145-f64b-4d6a-a94f-365e5dc3231f}</Project>
<Name>Sensors.Weight</Name>
</ProjectReference>
</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>

Просмотреть файл

@ -0,0 +1,212 @@
using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using Windows.Security.ExchangeActiveSyncProvisioning;
using System.Reflection;
namespace Keg.DAL
{
public static class KegLogger
{
private static readonly TelemetryClient telemetryClient = null;
public enum DeviceTypes { RPI2, RPI3, MBM, DB410, GenericBoard, Unknown };
static DeviceTypes _type = DeviceTypes.Unknown;
static string _productName = null;
static EasClientDeviceInformation deviceInfo;
static KegLogger()
{
Init();
//KegConfig kegConfig = GlobalSettings.GetKegSetting("fdaeadba-4027-407d-bd9a-dd679c223f65").Result;
//Telemetry
TelemetryConfiguration teleConfig = new TelemetryConfiguration
{
InstrumentationKey = Constants.INSTRUMENTKEY
};
teleConfig.TelemetryChannel.DeveloperMode = false;
if(Constants.INSTRUMENTKEY.Trim().Length == 0 )
{
teleConfig.DisableTelemetry = true;
}
//override as needed
// true: disable telemetry, false: enables telemetry
teleConfig.DisableTelemetry = false;
telemetryClient = new TelemetryClient(teleConfig);
telemetryClient.Context.User.Id = deviceInfo.FriendlyName;
telemetryClient.Context.Device.Type = _type.ToString();
telemetryClient.Context.Device.Model = _productName;
telemetryClient.Context.Device.Id = deviceInfo.Id.ToString();
telemetryClient.Context.Device.OemName = deviceInfo.SystemManufacturer;
//Each reboot starts a new session
telemetryClient.Context.Session.Id = Guid.NewGuid().ToString();
if (!ulong.TryParse(Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamilyVersion, out ulong version))
{
//var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
//OSVersion.Text = loader.GetString("OSVersionNotAvailable");
telemetryClient.Context.Device.OperatingSystem = deviceInfo.OperatingSystem;
}
else
{
telemetryClient.Context.Device.OperatingSystem = String.Format(CultureInfo.InvariantCulture, "{4}-IoTCore v{0}.{1}.{2}.{3}",
(version & 0xFFFF000000000000) >> 48,
(version & 0x0000FFFF00000000) >> 32,
(version & 0x00000000FFFF0000) >> 16,
version & 0x000000000000FFFF,
deviceInfo.OperatingSystem);
}
KegLogTrace("App Started", "KegLogger", SeverityLevel.Information, null);
}
static void Init()
{
if (_type == DeviceTypes.Unknown)
{
deviceInfo = new EasClientDeviceInformation();
_productName = deviceInfo.FriendlyName;
if (deviceInfo.SystemProductName.IndexOf("MinnowBoard", StringComparison.OrdinalIgnoreCase) >= 0)
{
_type = DeviceTypes.MBM;
}
else if (deviceInfo.SystemProductName.IndexOf("Raspberry", StringComparison.OrdinalIgnoreCase) >= 0)
{
if (deviceInfo.SystemProductName.IndexOf("Pi 3", StringComparison.OrdinalIgnoreCase) >= 0)
{
_type = DeviceTypes.RPI3;
}
else
{
_type = DeviceTypes.RPI2;
}
}
else if (deviceInfo.SystemProductName == "SBC")
{
_type = DeviceTypes.DB410;
}
else
{
_type = DeviceTypes.GenericBoard;
}
}
}
public static bool IsRaspberryPi
{
get
{
return Type == DeviceTypes.RPI2 || Type == DeviceTypes.RPI3;
}
}
public static DeviceTypes Type
{
get
{
Init();
return _type;
}
}
// this might return null
public static string ProductName
{
get
{
Init();
return _productName;
}
}
public static async void KegLogTrace(string message, string method, SeverityLevel severityLevel = SeverityLevel.Information, IDictionary<string, string> properties = null)
{
await Task.Run(() =>
{
telemetryClient.Context.Operation.Name = method;
telemetryClient.TrackTrace(message, severityLevel, properties);
});
}
public static void KegLogEvent(string message, string method, IDictionary<string, string> properties)
{
telemetryClient.Context.Operation.Name = method;
telemetryClient.TrackEvent(message, properties, null);
}
public static void KegLogMetrics(string message, string method, string metricName, double metricValue)
{
var sample = new MetricTelemetry
{
Name = metricName,
Sum = metricValue
};
sample.Context.Operation.Name = method;
telemetryClient.Context.Operation.Name = method;
telemetryClient.TrackMetric(sample);
}
public static void KegLogMetrics(string message, string method, MetricTelemetry metric)
{
metric.Context.Operation.Name = method;
telemetryClient.Context.Operation.Name = method;
telemetryClient.TrackMetric(metric);
}
public static void KegLogException(Exception exception, string method, IDictionary<string, string> properties)
{
telemetryClient.Context.Operation.Name = method;
//exception.StackTrace = Environment.StackTrace;
//ExceptionTelemetry exceptionTelemetry = new ExceptionTelemetry();
//exceptionTelemetry.Context.Operation.Name = method;
//exceptionTelemetry.Exception = exception;
telemetryClient.TrackException(exception, properties, null);
}
public static void KegLogException(Exception exception, string method, SeverityLevel? severityLevel)
{
//telemetryClient.Context.Operation.Name = method;
//exception.StackTrace = Environment.StackTrace;
ExceptionTelemetry exceptionTelemetry = new ExceptionTelemetry();
exceptionTelemetry.Context.Operation.Name = method;
exceptionTelemetry.Exception = exception;
exceptionTelemetry.SeverityLevel = severityLevel;
telemetryClient.TrackException(exceptionTelemetry);
}
}
}

Просмотреть файл

@ -0,0 +1,13 @@
using System;
namespace Keg.DAL
{
public class MeasurementChangedEventArgs : EventArgs
{
public Models.Measurement Measurement { get; set; }
public MeasurementChangedEventArgs(Models.Measurement measurement)
{
this.Measurement = measurement;
}
}
}

Просмотреть файл

@ -0,0 +1,217 @@
using Keg.DAL;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL.Models
{
/// <summary>
/// Class Designed to hold the values from CosmosDB related to KegConfig Only
/// </summary>
public class KegConfig
{
/// <summary>
/// Hardcoded class for KegConfig Type
/// </summary>
[JsonProperty("type")]
public string Type { get { return "KegConfig"; } }
/// <summary>
/// Identifier
/// </summary>
[JsonProperty("id")]
public string Id { get; set; }
/// <summary>
/// Maximum Event Duration In Minutes
/// </summary>
[JsonProperty("maxeventdurationminutes")]
public int MaxEventDurationMinutes { get; set; }
/// <summary>
/// Maximum Ounces to be consumed in UserConsumptionReset Minutes
/// </summary>
[JsonProperty("maxuserouncesperhour")]
public int MaxUserOuncesPerHour { get; set; }
/// <summary>
/// Core Business Hours ( Not allowed)
/// </summary>
[JsonProperty("corehours")]
public string CoreHours { get; set; }
/// <summary>
/// Core Days allowed
/// </summary>
[JsonProperty("coredays")]
public string CoreDays { get; set; }
/// <summary>
/// Maintenance Mode Flag
/// </summary>
[JsonProperty("maintenance")]
public bool MaintenanceMode { get; set; }
/// <summary>
/// Weight Callibration Factor
/// </summary>
[JsonProperty("weightcalibrationfactor")]
public float WeightCalibrationFactor { get; set; }
/// <summary>
/// Weight Callibration Offset
/// </summary>
[JsonProperty("weightcalibrationoffset")]
public float WeightCalibrationOffset { get; set; }
/// <summary>
/// Maxiumum volume in the Keg
/// </summary>
[JsonProperty("maxkegvolumeinpints")]
public float MaxKegVolumeInPints { get; set; }
/// <summary>
/// Maximum Weight Of Keg allowed
/// </summary>
[JsonProperty("maxkegweight")]
public float MaxKegWeight { get; set; }
/// <summary>
/// Weight of Empty Keg
/// </summary>
[JsonProperty("emptykegweight")]
public float EmptyKegWeight { get; set; }
/// <summary>
/// Maximum visitors allowed per Event
/// </summary>
[JsonProperty("maxvisitorsperevent")]
public Int32 MaxPersonsPerEvent { get; set; }
/// <summary>
/// User Consumption Limit Reset
/// </summary>
[JsonProperty("userconsumptionresetminutes")]
public Int32 UserConsumptionReset { get; set; }
/// <summary>
/// Flow Callibration Number
/// </summary>
[JsonProperty("flowcalibrationfactor")]
public float FlowCalibrationFactor { get; set; }
/// <summary>
/// Flow Callibration Offset
/// </summary>
[JsonProperty("flowcalibrationoffset")]
public float FlowCalibrationOffset { get; set; }
}
public static class GlobalSettings
{
public static string UrlCombine(params string[] urls)
{
string result = "";
foreach (var url in urls)
{
if (result.Length > 0 && url.Length > 0)
result += '/';
result += url.Trim('/');
}
return result;
}
private static bool CheckValidUrl()
{
try
{
//TODO: Add Validation
//Constants.COSMOSAzureFunctionsURL
return true;
}
catch(Exception ex)
{
KegLogger.KegLogException(ex, "GlobalSettings:GetKegSetting", SeverityLevel.Critical);
throw ex;
}
}
public static async Task<IEnumerable<KegConfig>> GetKegSettings()
{
if(!CheckValidUrl())
{
return null;
}
var client = new System.Net.Http.HttpClient();
string url = UrlCombine(Constants.COSMOSAzureFunctionsURL,"kegconfig");
var response = await client.GetAsync(url);
var body = await response.Content.ReadAsStringAsync();
List<KegConfig> list = JsonConvert.DeserializeObject<List<KegConfig>>(body);
return list;
}
public static async Task<KegConfig> GetKegSetting(string id)
{
if (!CheckValidUrl())
{
return null;
}
var myClientHandler = new HttpClientHandler
{
Credentials = System.Net.CredentialCache.DefaultCredentials
};
var client = new HttpClient(myClientHandler)
{
Timeout = TimeSpan.FromSeconds(60)
};
//var client = new Windows.Web.Http.HttpClient();
string url = UrlCombine(Constants.COSMOSAzureFunctionsURL, "kegconfig", id);
try
{
var response = await client.GetAsync(new Uri(url));
var body = await response.Content.ReadAsStringAsync();
List<KegConfig> list = JsonConvert.DeserializeObject<List<KegConfig>>(body);
return list.FirstOrDefault();
}
catch(TaskCanceledException tEx)
{
KegLogger.KegLogException(tEx, "GlobalSettings:GetKegSetting", SeverityLevel.Critical);
throw tEx;
}
catch(HttpRequestException hEx)
{
KegLogger.KegLogException(hEx, "GlobalSettings:GetKegSetting", SeverityLevel.Critical);
throw hEx;
}
}
/// <summary>
/// Test Method and not to be used.
/// </summary>
/// <param name="item"></param>
public static async void SetKegSettings(this KegConfig item)
{
var client = new System.Net.Http.HttpClient();
string url = UrlCombine(Constants.COSMOSAzureFunctionsURL, "kegconfig");
StringContent content = new StringContent(JsonConvert.SerializeObject(item));
var response = await client.PostAsync(url, content);
var body = await response.Content.ReadAsStringAsync();
}
}
}

Просмотреть файл

@ -0,0 +1,43 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Keg.DAL.Models
{
public class Measurement
{
public enum UnitsOfMeasure { Pounds, Ounces, Kilograms, Milliliters, Celsius, Fahrenheit }
[JsonProperty("amount")]
public float Amount { get; set; }
[JsonProperty("units")]
public UnitsOfMeasure Units { get; set; }
[JsonProperty("timestamp")]
public DateTime Timestamp { get; set; }
public Measurement() { }
public Measurement(float amount, UnitsOfMeasure units)
{
Amount = amount;
Units = units;
Timestamp = DateTime.Now;
}
public Measurement(float amount, UnitsOfMeasure units, DateTime timestamp)
: this(amount, units)
{
Timestamp = timestamp;
}
public override String ToString()
{
return $"{Amount} {Units}";
}
}
}

Просмотреть файл

@ -0,0 +1,60 @@
using Keg.DAL;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL.Models
{
public class User
{
[JsonProperty("type")]
public string Type { get { return "KegUser"; } }
[JsonProperty("hashcode")]
public string HashCode { get; set; }
[JsonProperty("isapprover")]
public bool IsApprover { get; set; }
public static async Task<User> GetUserByHashcode(string hashcode)
{
try
{
var client = new System.Net.Http.HttpClient();
string url = $"{GlobalSettings.UrlCombine(Constants.COSMOSAzureFunctionsURL, "keguser", hashcode)}";
//string url = $"https://kegocnizerfunctions.azurewebsites.net/api/keguser/{hashcode}";
var response = await client.GetAsync(url);
var body = await response.Content.ReadAsStringAsync();
List<User> list = JsonConvert.DeserializeObject<List<User>>(body);
return list.FirstOrDefault();
}
catch(Exception ex)
{
KegLogger.KegLogException(ex, "User:GetUserByHashcode", SeverityLevel.Critical);
return null;
}
}
public static async void AddUserAsync(User item)
{
try
{
var client = new System.Net.Http.HttpClient();
string url = $"{GlobalSettings.UrlCombine(Constants.COSMOSAzureFunctionsURL, "keguser")}";
//string url = $"https://kegocnizerfunctions.azurewebsites.net/api/keguser";
StringContent content = new StringContent(JsonConvert.SerializeObject(item));
var response = await client.PostAsync(url, content);
var body = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
KegLogger.KegLogException(ex, "User:AddUserAsync", SeverityLevel.Critical);
}
}
}
}

Просмотреть файл

@ -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("Keg.DAL")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Keg.DAL")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[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)]

Просмотреть файл

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
https://go.microsoft.com/fwlink/?LinkID=391919
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Keg.DAL">
<!-- add directives for your library here -->
</Library>
</Directives>

Просмотреть файл

@ -0,0 +1,186 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Keg.DAL.Models;
using Windows.Devices.Gpio;
using Sensors.Temperature;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL
{
public class Temperature : IDisposable
{
//RPI
private static readonly Int32 TEMPERATUREDATAPIN = 4; //PIN 7
//MBM
//const Int32 TEMPERATUREDATAPIN = 9;
public IDictionary<string, object> CalibrationSettings { get; set; }
public const string AdjustTemperatureSetting = @"AdjustTemperature"; // a Measurement object, such as {-2, Fahrenheit}
public const string TempGpioPinNumberSetting = @"TempGPIOPinNumber"; // an integer, such as 5 or 9 or 17
public const string PreferredTemperatureUnits = @"TemperatureUnits"; // a Measurement.Units enum value, such as "Celsius" or "Fahrenheit"
private GpioPin _pin;
private Dht11 _dht11;
private Measurement _lastMeasurement;
// takes an instant reading or returns the average accumulated value, and returns
// the interpreted value adjusted by calibration settings.
public async Task<Models.Measurement> GetTemperature()
{
Measurement result = _lastMeasurement;
try
{
if (_pin == null || _dht11 == null)
{
int pinNumber = TEMPERATUREDATAPIN; // default
if (CalibrationSettings.ContainsKey(TempGpioPinNumberSetting))
pinNumber = Int32.Parse(CalibrationSettings[TempGpioPinNumberSetting].ToString());
var c = GpioController.GetDefault();
if (c != null)
{
_pin = c.OpenPin(pinNumber, GpioSharingMode.Exclusive);
if (_pin != null)
_dht11 = new Dht11(_pin, GpioPinDriveMode.Input);
}
}
if(_dht11 == null )
{
return null;
}
DhtReading reading = await _dht11.GetReadingAsync().AsTask();
for (int retries = 0; retries < 10; retries++)
{
if (reading.TimedOut)
Debug.Write(".");
else if (!reading.IsValid)
Debug.Write("x");
else
break;
}
if (reading.IsValid)
{
//Debug.WriteLine($"Temp reading = {reading.Temperature}");
Measurement.UnitsOfMeasure units = Measurement.UnitsOfMeasure.Fahrenheit;
if (CalibrationSettings.ContainsKey(PreferredTemperatureUnits))
units = (Measurement.UnitsOfMeasure)Enum.Parse(typeof(Measurement.UnitsOfMeasure), CalibrationSettings[PreferredTemperatureUnits].ToString());
Measurement adjust = new Measurement(0.0f, Measurement.UnitsOfMeasure.Fahrenheit);
if (CalibrationSettings.ContainsKey(AdjustTemperatureSetting))
adjust = CalibrationSettings[AdjustTemperatureSetting] as Measurement;
float temperature = (float)reading.Temperature;
temperature = Convert(Measurement.UnitsOfMeasure.Celsius, units, temperature);
adjust.Amount = Convert(adjust.Units, units, adjust.Amount);
adjust.Units = units;
temperature += adjust.Amount; // now that we know they are in the same (preferred) units
result = new Measurement(temperature, units);
_lastMeasurement = result;
OnTemperatureChanged(new MeasurementChangedEventArgs(result));
}
else
{
KegLogger.KegLogException(new TemperatureException("Custom: Unable to Read temperature."), "GetTemperature", SeverityLevel.Warning);
Debug.WriteLine($"Unable to read temperature.");
}
}
catch(Exception ex)
{
Debug.WriteLine("Error, " + ex.Message);
KegLogger.KegLogException(ex, "GetTemperature", SeverityLevel.Critical);
}
return result;
}
private float Convert(Measurement.UnitsOfMeasure from, Measurement.UnitsOfMeasure to, float value)
{
float result = 0.0f;
if (from == to)
result = value;
else if (from == Measurement.UnitsOfMeasure.Celsius)
result = value * 9 / 5 + 32;
else
result = (value - 32) * 5 / 9;
return result;
}
public event EventHandler<MeasurementChangedEventArgs> TemperatureChanged;
protected virtual void OnTemperatureChanged(MeasurementChangedEventArgs e)
{
TemperatureChanged?.Invoke(this, e);
}
// the purpose of this object is to allow someone an easy way to generate the proper
// default calibration settings that this sensor interface object supports.
// in this case, it supports a Measurement that indicates how many degrees to add
// to readings to account for variations in the tolerance of the actual circuitry.
public static IDictionary<string,object> GetDefaultCalibrationSettings()
{
return new Dictionary<string, object>
{
{ AdjustTemperatureSetting, new Measurement(0, Measurement.UnitsOfMeasure.Fahrenheit) },
{ TempGpioPinNumberSetting, TEMPERATUREDATAPIN.ToString() },
{ PreferredTemperatureUnits, "Fahrenheit" }
};
}
// default constructor
public Temperature()
{
CalibrationSettings = new Dictionary<string, object>();
}
public Temperature(IDictionary<string,object> calibrationSettings)
: this()
{
//AdjustTemperatureSetting
CalibrationSettings.Add(AdjustTemperatureSetting, (calibrationSettings.ContainsKey(AdjustTemperatureSetting)) ? calibrationSettings[AdjustTemperatureSetting] as Measurement : new Measurement(0.0f, Measurement.UnitsOfMeasure.Celsius));
//TempGpioPinNumberSetting
CalibrationSettings.Add(TempGpioPinNumberSetting, (calibrationSettings.ContainsKey(TempGpioPinNumberSetting)) ? calibrationSettings[TempGpioPinNumberSetting] : TEMPERATUREDATAPIN);
//PreferredTemperatureUnits
CalibrationSettings.Add(PreferredTemperatureUnits, (calibrationSettings.ContainsKey(PreferredTemperatureUnits)) ? calibrationSettings[PreferredTemperatureUnits] : Measurement.UnitsOfMeasure.Celsius.ToString());
}
private Timer _timer;
public void Initialize(int initialDelay, int period)
{
_timer = new Timer(OnTimer, null, initialDelay, period);
}
public void Dispose()
{
var timer = _timer;
_timer = null;
timer?.Dispose();
}
private async void OnTimer(object state)
{
OnTemperatureChanged(new MeasurementChangedEventArgs(await GetTemperature()));
}
}
[Serializable()]
public class TemperatureException : System.Exception
{
public TemperatureException() : base() { }
public TemperatureException(string message) : base(message) { }
public TemperatureException(string message, System.Exception inner) : base(message, inner) { }
protected TemperatureException(System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
{
}
}
}

Просмотреть файл

@ -0,0 +1,224 @@
using Keg.DAL.Models;
using Sensors.Weight;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using Windows.Devices.Gpio;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.DAL
{
public class Weight
{
public IDictionary<string, object> CalibrationSettings { get; set; }
public const string WeightClockGpioPinNumberSetting = @"WeightClockGPIOPinNumber"; // an integer, such as 5 or 9 or 17
public const string WeightDataGpioPinNumberSetting = @"WeightDataGPIOPinNumber"; // an integer, such as 5 or 9 or 17
public const string AdjustWeightFactorSetting = @"AdjustWeightFactor"; // in integer
public const string AdjustWeightOffsetSetting = @"AdjustWeightOffset"; // an integer
public const string PreferredWeightUnits = @"PreferredWeightUnits"; // a supported Measurement.UnitsOfMeasure value, like "Pounds"
//RPI
const string WEIGHTCLOCKGPIOPINNUMBER = "21"; //PIN 40
const string WEIGHTDATAGPIOPINNUMBER = "12"; //PIN 32
//private double calibrationConstant; use AdjustWeightSetting instead
private HX711 device;
private GpioPin dataPin;
private GpioPin clockPin;
public FixedSizedQueue<Measurement> PriorMeasurements { get; set; }
public Measurement GetWeight(bool single =false)
{
try
{
if (clockPin == null || dataPin == null)
{
return null;
}
// TODO: sample sensors and report weight -- mocked for now
//return new Measurement(165.0f, Measurement.UnitsOfMeasure.Pounds);
device = new HX711(clockPin, dataPin);
var w = _GetOutputData();
Debug.WriteLine($"Single:{w}");
var c = Calibrated(w);
if(!CheckAnomaly(c))
{
PriorMeasurements.Enqueue(new Measurement(c, Measurement.UnitsOfMeasure.Ounces));
}
Debug.WriteLine($"Current Avg:{PriorMeasurements.Average(i => i.Amount)}");
#if DEBUG
foreach (var item in PriorMeasurements)
{
Debug.WriteLine($" {item.Amount}");
}
#endif
if (single)
return new Measurement(w, Measurement.UnitsOfMeasure.Ounces);
else
return new Measurement(PriorMeasurements.Average(i => i.Amount), Measurement.UnitsOfMeasure.Ounces);
}
catch(Exception ex)
{
Debug.WriteLine($"Error,{ex.Message}");
KegLogger.KegLogException(ex, "Weight:GetWeight", SeverityLevel.Critical);
KegLogger.KegLogTrace(ex.Message, "Weight:GetWeight", SeverityLevel.Warning,
new Dictionary<string, string>() {
{"ClockPin", CalibrationSettings[WeightClockGpioPinNumberSetting].ToString() },
{"DataPin", CalibrationSettings[WeightDataGpioPinNumberSetting].ToString() }
});
}
return null;
}
private bool CheckAnomaly(float newValue)
{
if(PriorMeasurements.Count > 2 && newValue > PriorMeasurements.Average(i => i.Amount) * 2)
{
Debug.WriteLine($" Anomaly: {newValue}");
KegLogger.KegLogTrace("Anomaly Detected!", "Weight:GetWeight", SeverityLevel.Error,
new Dictionary<string, string>() {
{"Weight", newValue.ToString() }
});
return true;
} else
{
return false;
}
}
private float Calibrated(float w)
{
//Debug.WriteLine($"Weight:{w}");
Debug.WriteLine($"Weight Factor:{CalibrationSettings[AdjustWeightFactorSetting]}, Weight Offset:{CalibrationSettings[AdjustWeightOffsetSetting]}");
var a = float.Parse(CalibrationSettings[AdjustWeightFactorSetting].ToString());
var b = float.Parse(CalibrationSettings[AdjustWeightOffsetSetting].ToString()); b = b == 0 ? 1 : b;
//Debug.WriteLine($"Calibrated:{ (a - (w / b))*100 })");
//return (a - (w / b))*100;
Debug.WriteLine($"Calibrated:{ ((w * a) + b) }");
return (w * a) + b;
}
// the purpose of this object is to allow someone an easy way to generate the proper
// default calibration settings that this sensor interface object supports.
// in this case, it supports a Measurement that indicates how many degrees to add
// to readings to account for variations in the tolerance of the actual circuitry.
public static IDictionary<string, object> GetDefaultCalibrationSettings()
{
return new Dictionary<string, object>
{
{ AdjustWeightFactorSetting, "1" },
{ AdjustWeightOffsetSetting, "0" },
{ WeightClockGpioPinNumberSetting, WEIGHTCLOCKGPIOPINNUMBER },
{ WeightDataGpioPinNumberSetting, WEIGHTDATAGPIOPINNUMBER },
{ PreferredWeightUnits, "Ounces" }
};
}
public event EventHandler<MeasurementChangedEventArgs> WeightChanged;
protected virtual void OnWeightChanged(MeasurementChangedEventArgs e)
{
WeightChanged?.Invoke(this, e);
}
public Weight()
{
CalibrationSettings = new Dictionary<string, object>(GetDefaultCalibrationSettings());
PriorMeasurements = new FixedSizedQueue<Measurement>(10);
}
public Weight(IDictionary<string, object> calibrationSettings)
: this()
{
foreach(string key in calibrationSettings.Keys)
{
if (key.Equals(WeightClockGpioPinNumberSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(WeightDataGpioPinNumberSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(AdjustWeightFactorSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(AdjustWeightOffsetSetting, StringComparison.OrdinalIgnoreCase)
|| key.Equals(PreferredWeightUnits, StringComparison.OrdinalIgnoreCase))
{
CalibrationSettings[key] = calibrationSettings[key].ToString();
}
}
}
public void Initialize()
{
if (device == null)
{
GpioController controller = GpioController.GetDefault();
GpioOpenStatus status;
if (controller != null
&& controller.TryOpenPin(Int32.Parse(CalibrationSettings[WeightClockGpioPinNumberSetting].ToString()), GpioSharingMode.Exclusive, out clockPin, out status)
&& controller.TryOpenPin(Int32.Parse(CalibrationSettings[WeightDataGpioPinNumberSetting].ToString()), GpioSharingMode.Exclusive, out dataPin, out status))
{
device = new HX711(clockPin, dataPin);
}
else
device = null;
}
if (device != null)
device.PowerOn();
}
private int _GetOutputData()
{
Initialize();
int result = 0;
if (device != null)
{
result = device.Read();
}
device.PowerDown();
return result;
}
//public string GetReading()
//{
// string numberFormat = "G" + Precision;
// return LeadingUnit + ((_GetOutputData() - Offset) / CalibrationConstant).ToString(numberFormat) + TrailingUnit;
//}
private Timer _timer;
public void Initialize(int initialDelay, int period)
{
if (device != null)
{
_timer = new Timer(OnTimer, null, initialDelay, period);
}
}
public void Dispose()
{
var timer = _timer;
_timer = null;
timer?.Dispose();
}
private void OnTimer(object state)
{
var measurement = GetWeight();
if(measurement != null )
{
Debug.WriteLine($" OnTimer:{measurement.Amount}");
PriorMeasurements.Enqueue(measurement);
//var result = new Measurement( PriorMeasurements.Average(i => i.Amount), Measurement.UnitsOfMeasure.Ounces);
this.OnWeightChanged(new MeasurementChangedEventArgs(measurement));
}
}
}
}

Просмотреть файл

@ -0,0 +1,12 @@
<Application
x:Class="Keg.UWP.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Keg.UWP"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary Source="Styles.xaml" />
</Application.Resources>
</Application>

Просмотреть файл

@ -0,0 +1,218 @@
using Keg.DAL;
using Keg.DAL.Models;
using Keg.UWP.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.ApplicationModel.Resources.Core;
using Windows.Globalization;
using Windows.System.UserProfile;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Microsoft.ApplicationInsights.DataContracts;
namespace Keg.UWP
{
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
sealed partial class App : Application
{
//public static ResourceLoader resourceLoader;
//public Temperature _temperature { get; set; }
public static readonly bool IgnoreCoreHours = false;
internal static Dictionary<string, object> calibration;
public static Temperature _temperature;
public static Weight _weight;
public static Flow _flow;
public static FlowControl _flowControl;
//public static TelemetryClient telemetryClient;
/// <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;
try
{
Task.Run(() => Common.GetKegSettings()).Wait();
}
catch(Exception ex)
{
//Azure Down
//TODO
Debug.WriteLine($"Exception:{ex.Message}");
KegLogger.KegLogException(ex, "App:App", SeverityLevel.Critical);
throw ex;
}
InitializeCallibrations();
}
internal void InitializeCallibrations()
{
calibration = new Dictionary<string, object>();
try
{
// to initialize a sensor measurement object, we pass it a calibration object
// eventually, these will come from a specific Cosmos document that the app will passthru
foreach (var c in Weight.GetDefaultCalibrationSettings()) calibration[c.Key] = c.Value;
foreach (var c in FlowControl.GetDefaultCalibrationSettings()) calibration[c.Key] = c.Value;
foreach (var c in Temperature.GetDefaultCalibrationSettings()) calibration[c.Key] = c.Value;
foreach (var c in Flow.GetDefaultCalibrationSettings()) calibration[c.Key] = c.Value;
calibration[Weight.AdjustWeightFactorSetting] = Common.KegSettings.WeightCalibrationFactor.ToString();
calibration[Weight.AdjustWeightOffsetSetting] = Common.KegSettings.WeightCalibrationOffset.ToString();
if (calibration.ContainsKey(Temperature.AdjustTemperatureSetting))
{
calibration[Temperature.AdjustTemperatureSetting] = new Measurement(-2.0f, Measurement.UnitsOfMeasure.Fahrenheit);
}
else
{
calibration.Add(Temperature.AdjustTemperatureSetting, new Measurement(-2.0f, Measurement.UnitsOfMeasure.Fahrenheit));
}
//Flow Calibration
calibration[Flow.FlowCalibrationFactorSetting] = Common.KegSettings.FlowCalibrationFactor.ToString();
calibration[Flow.FlowCalibrationOffsetSetting] = Common.KegSettings.FlowCalibrationOffset.ToString();
App._flowControl = new FlowControl(App.calibration);
App._flowControl.Initialize(1000, 1000);
App._flow = new Flow(App.calibration);
App._flow.Initialize(1000, 1000);
//Objects Initializations
App._temperature = new Temperature(App.calibration);
//App._temperature.TemperatureChanged += OnTemperatureChange;
App._temperature.Initialize(1000, 10000);
App._weight = new Weight(App.calibration);
//App._weight.WeightChanged += OnWeightChange;
App._weight.Initialize();
//App._weight.Initialize(1000, 50000);
App._weight.Initialize(1000, 10000);
KegLogger.KegLogTrace("Kegocnizer App Loaded", "AppLoad", Microsoft.ApplicationInsights.DataContracts.SeverityLevel.Information, null);
}
catch (Exception ex)
{
Dictionary<string, string> log = new Dictionary<string, string>();
foreach (var item in calibration)
{
log.Add(item.Key, item.Value.ToString());
}
KegLogger.KegLogTrace(ex.Message, "App:InitializeCallibrations", SeverityLevel.Critical, log);
KegLogger.KegLogException(ex, "App:InitializeCallibrations", SeverityLevel.Critical);
#if !DEBUG
throw;
#endif
}
}
/// <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)
{
Frame 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();
//Set Default Primary Language
//Setting this, will be directly reflected in ApplicationLanguages.Languages
ApplicationLanguages.PrimaryLanguageOverride = GlobalizationPreferences.Languages[0];
// Set the default language
rootFrame.Language = "en-US";
//resourceLoader = Windows.ApplicationModel.Resources.ResourceLoader.GetForCurrentView();
// Refresh the resources in new language
ResourceContext.GetForCurrentView().Reset();
ResourceContext.GetForViewIndependentUse().Reset();
rootFrame.NavigationFailed += OnNavigationFailed;
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
//TODO: Load state from previously suspended application
}
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (e.PrelaunchActivated == false)
{
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(MainPage), e.Arguments);
}
// Ensure the current window is active
Window.Current.Activate();
}
}
/// <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)
{
//Exception ex = new Exception("Failed to load Page " + e.SourcePageType.FullName);
KegLogger.KegLogException(e.Exception, "App:OnNavigationFailed", SeverityLevel.Critical);
KegLogger.KegLogTrace(e.Exception.Message, "App:OnNavigationFailed", SeverityLevel.Critical,
new Dictionary<string, string>() {
{"SourcePage", e.SourcePageType.FullName }
});
throw e.Exception;
}
/// <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();
}
}
}

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/Fonts/IOTMDL2.1.35.ttf Normal file

Двоичный файл не отображается.

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/Fonts/SegMDL2.1.18.ttf Normal file

Двоичный файл не отображается.

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/LargeTile.scale-100.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 5.6 KiB

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/LargeTile.scale-125.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 7.7 KiB

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/LargeTile.scale-150.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 9.7 KiB

Двоичные данные
Demos/Kegocnizer/CS/Keg.UWP/Assets/LargeTile.scale-200.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 14 KiB

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше