Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 108 additions & 18 deletions ProfinetTools.Gui/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,53 @@
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Reactive.Threading.Tasks;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using ProfinetTools.Interfaces.Extensions;
using ProfinetTools.Interfaces.Models;
using ProfinetTools.Interfaces.Services;

using ReactiveUI;

namespace ProfinetTools.Gui.ViewModels
{
public class SettingsViewModel : ViewModelBase
{
public class SettingsViewModel : ViewModelBase
{
private readonly IDeviceService deviceService;
private readonly IAdaptersService adaptersService;
private readonly ISettingsService settingsService;
private Device device1;

public ReactiveUI.ReactiveCommand SaveCommand { get; set; }
private Device _selectedDevice;

private bool _signalActive = false;

private string _locateButtonText;
public string LocateButtonText
{
get { return _locateButtonText; }
set { this.RaiseAndSetIfChanged(ref _locateButtonText, value); }
}

private bool _isDeviceSelected;
public bool IsDeviceSelected
{
get { return _isDeviceSelected; }
set { this.RaiseAndSetIfChanged(ref _isDeviceSelected, value); }
}


public ReactiveUI.ReactiveCommand SaveCommand { get; set; }
public ReactiveUI.ReactiveCommand ResetCommand { get; set; }

public ReactiveUI.ReactiveCommand SavePermanentCommand { get; set; }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we really make two commands for saving settings?
An enum for "Permanent" and "Temporary" would be enough and would avoid code duplication.


public ReactiveUI.ReactiveCommand LocateDeviceCommand { get; set; }

public SettingsViewModel(IDeviceService deviceService, IAdaptersService adaptersService, ISettingsService settingsService)
public SettingsViewModel(IDeviceService deviceService, IAdaptersService adaptersService, ISettingsService settingsService)
{
this.deviceService = deviceService;
this.adaptersService = adaptersService;
this.settingsService = settingsService;
}
}

public override void Init()
{
Expand All @@ -40,9 +62,17 @@ public override void Init()
SaveCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SaveDeviceSettings)
.AddDisposableTo(Disposables);

ResetCommand = ReactiveUI.ReactiveCommand.CreateFromTask(ResetDevice)
SavePermanentCommand = ReactiveUI.ReactiveCommand.CreateFromTask(SavePermanentDeviceSettings)
.AddDisposableTo(Disposables);

ResetCommand = ReactiveUI.ReactiveCommand.CreateFromTask(ResetDevice)
.AddDisposableTo(Disposables);
}

LocateDeviceCommand = ReactiveUI.ReactiveCommand.CreateFromTask(LocateDevice)
.AddDisposableTo(Disposables);
LocateButtonText = "Start Blinking";
IsDeviceSelected = false;
}


private async Task<Unit> ResetDevice()
Expand All @@ -62,14 +92,57 @@ private async Task<Unit> ResetDevice()
return Unit.Default;
}

private async Task<Unit> SaveDeviceSettings()
// TODO put some code for flashing in here
private async Task<Unit> LocateDevice()
{
var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
if (_signalActive)
{
_signalActive = false;
LocateButtonText = "Start Blinking";
}
else
{
_signalActive = true;
var newThread = new Thread(new ThreadStart(LocationService));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Observable.Interval from System.Reactive here instead.

newThread.Start();
LocateButtonText = "Stop Blinking";
}
return Unit.Default;
}

// Send Signal request endlessly, until the button is pressed again
private async void LocationService()
{
SaveResult result;
var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();

if (adapter == null) return;
if (Device == null) return;

while (_signalActive)
{
result = await settingsService.SendSignalRequest(adapter, Device.MAC);

if(!result.Success)
{
MessageBox.Show("Device refuse: " + result.ErrorMessage, "Device Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
_signalActive = false;
return;
}
Thread.Sleep(4000);
}

}

private async Task<Unit> SaveDeviceSettings()
{
var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
if (adapter == null) return Unit.Default;

if (Device == null || !settingsService.TryParseNetworkConfiguration(Device)) return Unit.Default;

var result = await settingsService.SendSettings(adapter, Device.MAC, Device);
var result = await settingsService.SendSettings(adapter, Device.MAC, Device, false);
if (!result.Success)
MessageBox.Show("Device refuse: " + result.ErrorMessage, "Device Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
else
Expand All @@ -78,16 +151,33 @@ private async Task<Unit> SaveDeviceSettings()
return Unit.Default;
}

private async Task<Unit> SavePermanentDeviceSettings()
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid code duplication here

{
// TODO permanent saveing setting
var adapter = await adaptersService.SelectedAdapter.FirstAsync().ToTask();
if (adapter == null) return Unit.Default;

if (Device == null || !settingsService.TryParseNetworkConfiguration(Device)) return Unit.Default;

var result = await settingsService.SendSettings(adapter, Device.MAC, Device, true);
if (!result.Success)
MessageBox.Show("Device refuse: " + result.ErrorMessage, "Device Error", MessageBoxButton.OK, MessageBoxImage.Exclamation);
else
MessageBox.Show("All done!", "Device Info", MessageBoxButton.OK, MessageBoxImage.Information);

public Device Device
return Unit.Default;
}

public Device Device
{
get { return device1; }
get { return _selectedDevice; }
set
{
if (Equals(value, device1)) return;
device1 = value;
if (Equals(value, _selectedDevice)) return;
_selectedDevice = value;
raisePropertyChanged();
}
}
IsDeviceSelected = _selectedDevice != null;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use Reactive Ui for that

}
}
}
}
26 changes: 18 additions & 8 deletions ProfinetTools.Gui/Views/SettingsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="24.277"/>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid fix height definition

<RowDefinition Height="27.723"/>
</Grid.RowDefinitions>
<GroupBox Header="Settings" Grid.Row="0" Margin="8,8" DataContext="{Binding Device}" HorizontalAlignment="Left">
<GroupBox Header="Settings" Grid.Row="0" Margin="8,8,0,8" DataContext="{Binding Device}" HorizontalAlignment="Left">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
Expand All @@ -34,14 +35,23 @@
<Label Grid.Row="3" Grid.Column="0" HorizontalAlignment="Right">Gateway:</Label>
<TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Gateway, UpdateSourceTrigger=PropertyChanged}" Margin="4" Width="250" HorizontalAlignment="Left"/>
</Grid>
</GroupBox>
<Grid Grid.Row="1" Margin="8" HorizontalAlignment="Left">
</GroupBox>
<Grid Grid.Row="1" Margin="0,4" Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="20*" />
<ColumnDefinition Width="120*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="120*" />
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="120*" />
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="120*" />
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Margin="0,0,8,0" Padding="8" Command="{Binding SaveCommand}">Save</Button>
<Button Grid.Column="1" Margin="8,0,0,0" Padding="8" Command="{Binding ResetCommand}">Factory Reset</Button>
<Button IsEnabled="{Binding IsDeviceSelected, UpdateSourceTrigger=PropertyChanged}" Grid.Column="1" Padding="8" Command="{Binding SaveCommand}" HorizontalAlignment="Left" Width="120" Content="Set" />
<Button IsEnabled="{Binding IsDeviceSelected, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Padding="8" Command="{Binding SavePermanentCommand}" HorizontalAlignment="Left" Width="120" Content="Set Permanent" />
<Button IsEnabled="{Binding IsDeviceSelected, UpdateSourceTrigger=PropertyChanged}" Grid.Column="5" Padding="8" Command="{Binding ResetCommand}" HorizontalAlignment="Left" Width="120" Content="Factory Reset"/>
<Button IsEnabled="{Binding IsDeviceSelected, UpdateSourceTrigger=PropertyChanged}" Grid.Column="7" Padding="8" Command="{Binding LocateDeviceCommand}" Width ="120" Content="{Binding LocateButtonText, UpdateSourceTrigger=PropertyChanged}" />
</Grid>
</Grid>
</UserControl>
6 changes: 4 additions & 2 deletions ProfinetTools.Interfaces/Services/ISettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace ProfinetTools.Interfaces.Services
public interface ISettingsService
{
Task<SaveResult> FactoryReset(ICaptureDevice adapter, string deviceName);
Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings);
bool TryParseNetworkConfiguration(Device device);
Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings, bool permanent);

Task<SaveResult> SendSignalRequest(ICaptureDevice adapter, string macAddress);
bool TryParseNetworkConfiguration(Device device);
}
}
62 changes: 57 additions & 5 deletions ProfinetTools.Logic/Services/SettingsService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,13 @@ public bool TryParseNetworkConfiguration(Device device)

return true;
}
catch (Exception e)
catch (Exception /*e*/)
{
return false;
}
}

public Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings)
public Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress, Device newSettings, bool permanent)
{
var disposables = new CompositeDisposable();
var transport = new ProfinetEthernetTransport(adapter);
Expand All @@ -43,13 +43,13 @@ public Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress,
{
System.Net.NetworkInformation.PhysicalAddress deviceAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(macAddress);

DCP.BlockErrors err = transport.SendSetNameRequest(deviceAddress, timeoutInMilliseconds, retries, newSettings.Name);
DCP.BlockErrors err = transport.SendSetNameRequest(deviceAddress, timeoutInMilliseconds, retries, newSettings.Name, permanent);
if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));

System.Net.IPAddress ip = System.Net.IPAddress.Parse(newSettings.IP);
System.Net.IPAddress subnet = System.Net.IPAddress.Parse(newSettings.SubnetMask);
System.Net.IPAddress gateway = System.Net.IPAddress.Parse(newSettings.Gateway);
err = transport.SendSetIpRequest(deviceAddress, timeoutInMilliseconds, retries, ip, subnet, gateway);
err = transport.SendSetIpRequest(deviceAddress, timeoutInMilliseconds, retries, ip, subnet, gateway, permanent);
if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));

return Task.FromResult(new SaveResult(true, err.ToString()));
Expand All @@ -64,7 +64,59 @@ public Task<SaveResult> SendSettings(ICaptureDevice adapter, string macAddress,
}
}

public Task<SaveResult> FactoryReset(ICaptureDevice adapter, string deviceName)
public Task<SaveResult> SendSignalRequest(ICaptureDevice adapter, string macAddress)
{
var disposables = new CompositeDisposable();
var transport = new ProfinetEthernetTransport(adapter);
transport.Open();
transport.AddDisposableTo(disposables);


try
{
System.Net.NetworkInformation.PhysicalAddress deviceAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(macAddress);
DCP.BlockErrors err = transport.SendSetSignalRequest(deviceAddress, timeoutInMilliseconds, retries);
if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));

return Task.FromResult(new SaveResult(true, err.ToString()));
}
catch (Exception e)
{
return Task.FromResult(new SaveResult(false, e.Message));
}
finally
{
disposables.Dispose();
}
}

public Task<SaveResult> SignalRequestStart(ICaptureDevice adapter, string macAddress, Device target)
{
var disposables = new CompositeDisposable();
var transport = new ProfinetEthernetTransport(adapter);

transport.Open();
transport.AddDisposableTo(disposables);

System.Net.NetworkInformation.PhysicalAddress deviceAddress = System.Net.NetworkInformation.PhysicalAddress.Parse(macAddress);
try
{
DCP.BlockErrors err = transport.SendSetSignalRequest(deviceAddress, timeoutInMilliseconds, retries);
if (err != DCP.BlockErrors.NoError) return Task.FromResult(new SaveResult(false, err.ToString()));

return Task.FromResult(new SaveResult(false, err.ToString()));
}
catch (Exception e)
{
return Task.FromResult(new SaveResult(false, e.Message));
}
finally
{
disposables.Dispose();
}
}

public Task<SaveResult> FactoryReset(ICaptureDevice adapter, string deviceName)
{
var disposables = new CompositeDisposable();
var transport = new ProfinetEthernetTransport(adapter);
Expand Down
Loading