Skip to content

Commit

Permalink
[GeothermalResearchInstitute] Add DeviceMetricHistoryExportView.
Browse files Browse the repository at this point in the history
  • Loading branch information
hcoona committed Oct 13, 2019
1 parent 262fe83 commit 73845be
Show file tree
Hide file tree
Showing 11 changed files with 295 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -226,25 +226,31 @@ public override AsyncUnaryCall<RunningParameter> UpdateRunningParameterAsync(Upd

public override AsyncUnaryCall<ListMetricsResponse> ListMetricsAsync(ListMetricsRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default)
{
DateTime datetime;
DateTime? startDateTime = request.StartTime?.ToDateTime();
DateTime endDateTime;
if (string.IsNullOrEmpty(request.PageToken))
{
datetime = DateTime.Now;
endDateTime = request.EndTime?.ToDateTime() ?? DateTime.Now;
}
else
{
datetime = DateTime.Parse(request.PageToken, CultureInfo.InvariantCulture);
endDateTime = DateTime.Parse(request.PageToken, CultureInfo.InvariantCulture);
}

datetime = datetime.ToUniversalTime();
endDateTime = endDateTime.ToUniversalTime();

var metrics = new List<Metric>(request.PageSize);
for (var i = 0; i < request.PageSize; i++)
{
datetime = datetime.Subtract(TimeSpan.FromSeconds(5));
endDateTime = endDateTime.Subtract(TimeSpan.FromSeconds(5));
if (startDateTime.HasValue && startDateTime > endDateTime)
{
break;
}

metrics.Add(new Metric
{
CreateTime = Timestamp.FromDateTime(datetime),
CreateTime = Timestamp.FromDateTime(endDateTime),
InputWaterCelsiusDegree = RandomUtils.NextFloat(10, 20),
OutputWaterCelsiusDegree = RandomUtils.NextFloat(10, 20),
HeaterOutputWaterCelsiusDegree = RandomUtils.NextFloat(10, 20),
Expand All @@ -256,7 +262,7 @@ public override AsyncUnaryCall<ListMetricsResponse> ListMetricsAsync(ListMetrics

var response = new ListMetricsResponse
{
NextPageToken = datetime.ToString(CultureInfo.InvariantCulture),
NextPageToken = endDateTime.ToString(CultureInfo.InvariantCulture),
};
response.Metrics.AddRange(metrics);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<None Remove="Resources\logo.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Extended.Wpf.Toolkit" Version="3.6.0" />
<PackageReference Include="Grpc.Core.Testing" Version="2.24.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" Version="3.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="3.0.0" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public void RegisterTypes(IContainerRegistry containerRegistry)
containerRegistry.RegisterForNavigation<DeviceRunningParameterView>();
containerRegistry.RegisterForNavigation<DeviceMetricHistoryView>();
containerRegistry.RegisterForNavigation<DeviceMetricBoardView>();
containerRegistry.RegisterForNavigation<DeviceMetricHistoryExportView>();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// <copyright file="DeviceMetricHistoryExportViewModel.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using GeothermalResearchInstitute.v2;
using Google.Protobuf.WellKnownTypes;
using Prism.Commands;
using Prism.Mvvm;

namespace GeothermalResearchInstitute.Wpf.ViewModels
{
[System.Diagnostics.CodeAnalysis.SuppressMessage(
"Performance", "CA1822", Justification = "ViewModel.")]
public class DeviceMetricHistoryExportViewModel : BindableBase
{
private static readonly TimeSpan[] CandidateExportTimeSpans = new TimeSpan[]
{
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(5),
TimeSpan.FromSeconds(15),
};

private readonly DeviceService.DeviceServiceClient client;
private ViewModelContext viewModelContext;
private DateTime startDateTime = DateTime.Now;
private DateTime endDateTime = DateTime.Now;
private TimeSpan selectedTimeSpan = CandidateExportTimeSpans[0];

public DeviceMetricHistoryExportViewModel(DeviceService.DeviceServiceClient client)
{
this.client = client ?? throw new ArgumentNullException(nameof(client));
this.ExportCommand = new DelegateCommand(this.ExecuteExport, this.CanExport);
}

public ICollection<TimeSpan> ExportTimeSpans => CandidateExportTimeSpans;

public ViewModelContext ViewModelContext
{
get => this.viewModelContext;
set => this.SetProperty(ref this.viewModelContext, value);
}

public DateTime StartDateTime
{
get => this.startDateTime;
set => this.SetProperty(ref this.startDateTime, value);
}

public DateTime EndDateTime
{
get => this.endDateTime;
set => this.SetProperty(ref this.endDateTime, value);
}

public TimeSpan SelectedTimeSpan
{
get => this.selectedTimeSpan;
set => this.SetProperty(ref this.selectedTimeSpan, value);
}

public DelegateCommand ExportCommand { get; }

private bool CanExport() => this.StartDateTime < this.EndDateTime;

private async void ExecuteExport()
{
var metrics = new List<Metric>();
string nextPageToken = null;
while (true)
{
var request = new ListMetricsRequest
{
DeviceId = this.ViewModelContext.SelectedDevice.Id,
StartTime = this.StartDateTime.ToUniversalTime().ToTimestamp(),
EndTime = this.EndDateTime.ToUniversalTime().ToTimestamp(),
PageSize = 200,
};
if (nextPageToken != null)
{
request.PageToken = nextPageToken;
}

ListMetricsResponse response = await this.client.ListMetricsAsync(
request,
deadline: DateTime.Now.AddSeconds(5));
nextPageToken = response.NextPageToken;

if (response.Metrics.Count == 0)
{
break;
}

if (response.Metrics.Any(m => m.CreateTime.ToDateTimeOffset() < this.StartDateTime))
{
metrics.AddRange(response.Metrics.Where(
m => m.CreateTime.ToDateTimeOffset() >= this.StartDateTime));
break;
}
else
{
metrics.AddRange(response.Metrics);
}
}

using var saveFileDialog = new SaveFileDialog
{
Filter = "逗号分隔文件(*.csv)|*.csv",
AddExtension = true,
};

if (saveFileDialog.ShowDialog() == DialogResult.OK)
{
using var sw = new StreamWriter(
File.Open(saveFileDialog.FileName, FileMode.Create, FileAccess.Write, FileShare.Read),
Encoding.UTF8);

// TODO: Write it.
foreach (var m in metrics)
{
await sw.WriteLineAsync(m.ToString()).ConfigureAwait(true);
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using GeothermalResearchInstitute.v2;
using Google.Protobuf.WellKnownTypes;
using Prism.Mvvm;

namespace GeothermalResearchInstitute.Wpf.ViewModels
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ public NavigationViewModel(IRegionManager regionManager)
new DelegateCommand(this.ExecuteNavigateToDeviceMetricHistoryView);
this.NavigateToDeviceMetricBoardView =
new DelegateCommand(this.ExecuteNavigateToDeviceMetricBoardView, this.CanNavigateToDeviceMetricBoardView);
this.NavigateToDeviceMetricHistoryExportView = this.NavigateToDeviceMetricHistoryExportView =
new DelegateCommand(this.ExecuteNavigateToDeviceMetricHistoryExportView);
}

public ViewModelContext ViewModelContext
Expand Down Expand Up @@ -59,6 +61,8 @@ public ViewModelContext ViewModelContext

public DelegateCommand NavigateToDeviceMetricBoardView { get; }

public DelegateCommand NavigateToDeviceMetricHistoryExportView { get; }

private bool IsDeviceConnected =>
this.ViewModelContext?.SelectedDevice?.Status == v2.DeviceStatus.Healthy
|| this.ViewModelContext?.SelectedDevice?.Status == v2.DeviceStatus.Unhealthy;
Expand Down Expand Up @@ -108,5 +112,11 @@ private void ExecuteNavigateToDeviceMetricBoardView()
this.regionManager.RequestNavigate(Constants.ContentRegion, nameof(DeviceMetricBoardView));
this.ViewModelContext.NavigateBackTarget = nameof(NavigationView);
}

private void ExecuteNavigateToDeviceMetricHistoryExportView()
{
this.regionManager.RequestNavigate(Constants.ContentRegion, nameof(DeviceMetricHistoryExportView));
this.ViewModelContext.NavigateBackTarget = nameof(NavigationView);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ private void ExecuteNavigateToNavigationView()
private void ExecuteNavigateToContactView()
{
this.ViewModelContext.SelectedDevice = FakeClients.FakeDeviceServiceClient.Devices.Values.First();
this.regionManager.RequestNavigate(Constants.ContentRegion, nameof(DeviceMetricBoardView));
this.regionManager.RequestNavigate(Constants.ContentRegion, nameof(DeviceMetricHistoryExportView));
this.ViewModelContext.NavigateBackTarget = nameof(WelcomeView);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<UserControl
x:Class="GeothermalResearchInstitute.Wpf.Views.DeviceMetricHistoryExportView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:GeothermalResearchInstitute.Wpf.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prism="http://prismlibrary.com/"
xmlns:xwtk="clr-namespace:Xceed.Wpf.Toolkit;assembly=Xceed.Wpf.Toolkit"
d:DesignHeight="360"
d:DesignWidth="600"
prism:ViewModelLocator.AutoWireViewModel="True"
Loaded="DeviceMetricHistoryExportView_Loaded"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="3*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<DockPanel Grid.Row="1" Grid.Column="1">
<Button
HorizontalAlignment="Right"
Command="{Binding ExportCommand}"
Content="确定"
DockPanel.Dock="Bottom"
IsDefault="True"
Style="{StaticResource ButtonBaseStyle}" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label
Grid.Row="0"
Grid.Column="0"
VerticalAlignment="Center"
Content="起始时间:" />
<xwtk:DateTimePicker
Grid.Row="0"
Grid.Column="1"
VerticalAlignment="Center"
ShowButtonSpinner="False"
Value="{Binding StartDateTime}" />
<Label
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"
Content="结束时间:" />
<xwtk:DateTimePicker
Grid.Row="1"
Grid.Column="1"
VerticalAlignment="Center"
ShowButtonSpinner="False"
Value="{Binding EndDateTime}" />
<Label
Grid.Row="2"
Grid.Column="0"
VerticalAlignment="Center"
Content="时间间隔:" />
<ComboBox
Grid.Row="2"
Grid.Column="1"
VerticalAlignment="Center"
ItemsSource="{Binding ExportTimeSpans}"
SelectedItem="{Binding SelectedTimeSpan}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=TotalSeconds, StringFormat={}{0:# 秒}}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</DockPanel>
</Grid>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// <copyright file="DeviceMetricHistoryExportView.xaml.cs" company="Shuai Zhang">
// Copyright Shuai Zhang. All rights reserved.
// Licensed under the GPLv3 license. See LICENSE file in the project root for full license information.
// </copyright>

using System.Windows;
using System.Windows.Controls;
using GeothermalResearchInstitute.Wpf.ViewModels;
using Prism.Common;
using Prism.Regions;

namespace GeothermalResearchInstitute.Wpf.Views
{
public partial class DeviceMetricHistoryExportView : UserControl
{
public DeviceMetricHistoryExportView()
{
this.InitializeComponent();
RegionContext.GetObservableContext(this).PropertyChanged += this.RegionContext_PropertyChanged;
}

private DeviceMetricHistoryExportViewModel ViewModel => this.DataContext as DeviceMetricHistoryExportViewModel;

private void RegionContext_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
var context = (ObservableObject<object>)sender;
var viewModelContext = (ViewModelContext)context.Value;
this.ViewModel.ViewModelContext = viewModelContext;
}

private void DeviceMetricHistoryExportView_Loaded(object sender, RoutedEventArgs e)
{
ViewModelContext viewModelContext = this.ViewModel.ViewModelContext;
viewModelContext.UserBarVisibility = Visibility.Visible;
viewModelContext.BannerVisibility = Visibility.Visible;
viewModelContext.Title = "导出历史数据"; // TODO: From resource.
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@
Content="常规实时数据"
Style="{StaticResource NavigationButtonStyle}" />
<Button Content="故障记录" Style="{StaticResource NavigationButtonStyle}" />
<Button Content="导出历史数据" Style="{StaticResource NavigationButtonStyle}" />
<Button
Command="{Binding NavigateToDeviceMetricHistoryExportView}"
Content="导出历史数据"
Style="{StaticResource NavigationButtonStyle}" />
</UniformGrid>
</Border>
</UserControl>
Loading

0 comments on commit 73845be

Please sign in to comment.