diff --git a/WpfDemo/App.xaml.cs b/WpfDemo/App.xaml.cs
index 44f8391..014c05b 100644
--- a/WpfDemo/App.xaml.cs
+++ b/WpfDemo/App.xaml.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
@@ -16,12 +16,14 @@ namespace WpfDemo
///
/// Interaction logic for App.xaml
///
- public partial class App : Application
+ public partial class App : Application, INotifyPropertyChanged
{
public SensorsPage mainWindow { get; private set; }
public AddSensorPage discoverSensorsWindow { get; private set; }
+ public bool ConfigModified { get => configStore.Modified; }
+
public ObservableCollection Sensors
{
get { return bleSensors; }
@@ -35,6 +37,8 @@ public ObservableCollection Sensors
private System.Windows.Forms.NotifyIcon notifyIcon;
private HomeWindow homeWindow;
+ public event PropertyChangedEventHandler PropertyChanged;
+
public App()
{
ShutdownMode = ShutdownMode.OnExplicitShutdown;
@@ -44,6 +48,7 @@ protected override void OnStartup(StartupEventArgs e)
base.OnStartup(e);
configStore = new SFConfigStore();
+ configStore.PropertyChanged += ConfigStorePropertyChanged;
// init sensors
bleSensorsDict = new Dictionary();
@@ -56,6 +61,8 @@ protected override void OnStartup(StartupEventArgs e)
Normal = sensorConfig.Normal,
MACAddress = sensorConfig.MACAddress,
};
+ sensor.AutoConnect = sensorConfig.AutoConnect;
+ sensor.Binding.MonitorDeviceName = sensorConfig.BindedMonitor;
sensor.PropertyChanged += (object s, PropertyChangedEventArgs ev) =>
{
SyncSensorProperty(sensor, sensorConfig, ev.PropertyName);
@@ -131,14 +138,23 @@ private void sensorCollectionChanged(object sender, NotifyCollectionChangedEvent
{
throw new NotImplementedException();
}
- //System.Diagnostics.Debugger.Break();
+ configStore.Modified = true;
}
private void SensorPropertyChangedEventHandler(object sender, PropertyChangedEventArgs e)
{
+
+ }
+ private void ConfigStorePropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ if (e.PropertyName == "Modified")
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("ConfigModified"));
+ }
}
private void SyncSensorProperty(IBLEAccelerationSensor sensor, BLEGravitySensorConfig sensorConfig, string propertyName)
{
+ bool isConfigProperty = true;
switch (propertyName)
{
case "DeviceName":
@@ -156,6 +172,26 @@ private void SyncSensorProperty(IBLEAccelerationSensor sensor, BLEGravitySensorC
sensorConfig.Normal = sensor.Normal;
break;
}
+ case "AutoConnect":
+ {
+ sensorConfig.AutoConnect = sensor.AutoConnect;
+ break;
+ }
+ case "BindMonitor":
+ {
+ sensorConfig.BindedMonitor = sensor.Binding.MonitorDeviceName;
+ break;
+ }
+ default:
+ {
+ isConfigProperty = false;
+ break;
+ }
+
+ }
+ if (isConfigProperty)
+ {
+ configStore.Modified = true;
}
}
public void SaveSettings()
diff --git a/WpfDemo/HomeWindow.xaml b/WpfDemo/HomeWindow.xaml
index bd2706b..40e0149 100644
--- a/WpfDemo/HomeWindow.xaml
+++ b/WpfDemo/HomeWindow.xaml
@@ -21,15 +21,10 @@
-
-
-
+
-
-
-
diff --git a/WpfDemo/HomeWindow.xaml.cs b/WpfDemo/HomeWindow.xaml.cs
index cc057a4..bedaa42 100644
--- a/WpfDemo/HomeWindow.xaml.cs
+++ b/WpfDemo/HomeWindow.xaml.cs
@@ -28,6 +28,7 @@ public HomeWindow(App app)
SensorsFrame.Content = new SensorsPage(app);
ManualFrame.Content = new ManualPage();
AddSensorFrame.Content = new AddSensorPage(app, this);
+ btnSave.DataContext = app;
}
private void BtnSave_Click(object sender, RoutedEventArgs e)
{
diff --git a/WpfDemo/Models/IBLEAccSensor.cs b/WpfDemo/Models/IBLEAccSensor.cs
index ae73a77..6e5ae2b 100644
--- a/WpfDemo/Models/IBLEAccSensor.cs
+++ b/WpfDemo/Models/IBLEAccSensor.cs
@@ -45,6 +45,7 @@ public interface IBLEAccelerationSensor : INotifyPropertyChanged
BLESensorConnectionStatus ConnectionStatus { get; }
+ string StatusMessage { get; }
void Disconnect();
//event AngleChangeHandler AngleChange;
diff --git a/WpfDemo/Models/SFSettings.cs b/WpfDemo/Models/SFSettings.cs
index 4fa48ba..509dc2c 100644
--- a/WpfDemo/Models/SFSettings.cs
+++ b/WpfDemo/Models/SFSettings.cs
@@ -35,6 +35,11 @@ public class BLEGravitySensorConfig
///
public Vector3? Normal;
+ ///
+ /// AutoConnect when ScreenFerris starts
+ ///
+ public bool AutoConnect;
+
///
/// Id of binding monitor
diff --git a/WpfDemo/SFConfigStore.cs b/WpfDemo/SFConfigStore.cs
index 87d4bee..0c38737 100644
--- a/WpfDemo/SFConfigStore.cs
+++ b/WpfDemo/SFConfigStore.cs
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
@@ -8,16 +9,33 @@
namespace WpfDemo
{
- public class SFConfigStore
+ public class SFConfigStore : INotifyPropertyChanged
{
public SFSettings settings;
+ public bool Modified
+ {
+ get => modified; set
+ {
+ if (value != modified)
+ {
+ modified = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Modified"));
+ }
+ }
+ }
+ private bool modified;
private readonly string configurFilePath;
+
+
private static readonly JsonSerializerSettings JsonSerializerSettings = new JsonSerializerSettings
{
ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor,
//ContractResolver = new SettingsReaderContractResolver(),
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
+
+ public event PropertyChangedEventHandler PropertyChanged;
+
public SFConfigStore(String configurFilePath = null)
{
if (configurFilePath == null)
@@ -26,6 +44,7 @@ public SFConfigStore(String configurFilePath = null)
}
this.configurFilePath = configurFilePath;
settings = Load(this.configurFilePath) as SFSettings;
+ Modified = false;
SettingsSanityCheck();
}
@@ -59,6 +78,7 @@ public string Serialize()
public void Save()
{
File.WriteAllText(configurFilePath, Serialize());
+ Modified = false;
}
}
diff --git a/WpfDemo/Sensors/TheSensor.cs b/WpfDemo/Sensors/TheSensor.cs
index 8a3ef70..33bcc2b 100644
--- a/WpfDemo/Sensors/TheSensor.cs
+++ b/WpfDemo/Sensors/TheSensor.cs
@@ -14,6 +14,7 @@
namespace WpfDemo.Sensors
{
+ using ControlzEx.Standard;
using System.Net.NetworkInformation;
using Orientations = WpfDemo.Display.Orientations;
public class TheSensor : IBLEAccelerationSensor
@@ -23,8 +24,9 @@ public class TheSensor : IBLEAccelerationSensor
protected bool autoConnect;
protected Task autoConnectTask;
protected Vector3? baseline, normal;
- protected DateTime lastReport;
+ protected DateTime lastReport, lastConnected;
protected MonitorBinding monitorBinding;
+ protected string statusMessage;
// BLE variable
protected BluetoothLEDevice bluetoothLEDevice;
@@ -58,6 +60,7 @@ public TheSensor(string deviceId, string deviceName)
shouldAutoConnectContinue = false;
monitorBinding = new MonitorBinding();
this.PropertyChanged += monitorBinding.SensorPropertyChangedEventHandler;
+ monitorBinding.PropertyChanged += MonitorBindingPropertyChanged;
connectionStatus = BLESensorConnectionStatus.NotConnected;
}
@@ -127,19 +130,22 @@ public bool Connected
get => connected;
private set
{
- bool changed = value != connected;
- connected = value;
- if (!connected)
+ if (value != connected)
{
- CleanUpSubscription();
- }
- if (changed) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Connected")); }
- if (connected)
- {
- ConnectionStatus = BLESensorConnectionStatus.Connected;
- } else
- {
- ConnectionStatus = BLESensorConnectionStatus.NotConnected;
+ connected = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Connected"));
+ if (!connected)
+ {
+ CleanUpSubscription();
+ }
+ if (connected)
+ {
+ ConnectionStatus = BLESensorConnectionStatus.Connected;
+ }
+ else
+ {
+ ConnectionStatus = BLESensorConnectionStatus.NotConnected;
+ }
}
}
}
@@ -175,6 +181,18 @@ private set
}
}
+ public string StatusMessage
+ {
+ get => statusMessage;
+ set {
+ if (value != statusMessage)
+ {
+ statusMessage = value;
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("StatusMessage"));
+ }
+ Debug.WriteLine(value);
+ }
+ }
public event PropertyChangedEventHandler PropertyChanged;
@@ -190,6 +208,7 @@ protected void bluetoothLeDeviceConnectionStatusChanged(BluetoothLEDevice sender
}
protected async Task ConnectToSensor()
{
+ StatusMessage = "Connecting" + DeviceId;
if (bluetoothLEDevice == null)
{
bluetoothLEDevice = await BluetoothLEDevice.FromIdAsync(deviceId);
@@ -199,13 +218,12 @@ protected async Task ConnectToSensor()
GattDeviceServicesResult servicesResult = await bluetoothLEDevice.GetGattServicesForUuidAsync(serviceUuid);
if (servicesResult.Status != GattCommunicationStatus.Success)
{
- Debug.WriteLine("GetGattServicesAsync Error");
- Debug.WriteLine(servicesResult.ProtocolError.ToString());
+ StatusMessage = "GetGattServicesAsync Error:" + servicesResult.ProtocolError.ToString();
return false;
}
if (servicesResult.Services.Count == 0)
{
- Debug.WriteLine("Can not get service.");
+ StatusMessage = "Can not get service.";
return false;
}
if (selectedService != null)
@@ -217,7 +235,7 @@ protected async Task ConnectToSensor()
IReadOnlyList characteristics = null;
- Debug.WriteLine(selectedService.Uuid);
+ StatusMessage = "Successfully conecte to service: " + selectedService.Uuid.ToString();
DeviceAccessStatus accessStatus = await selectedService.RequestAccessAsync();
if (accessStatus == DeviceAccessStatus.Allowed)
@@ -229,22 +247,20 @@ protected async Task ConnectToSensor()
}
else
{
- Debug.WriteLine("Error accessing service " + result.Status + ".");
+ StatusMessage = "Error accessing service " + result.Status + ".";
return false;
}
}
else
{
- Debug.WriteLine("ERROR RequestAccessAsync");
- Debug.WriteLine(accessStatus.ToString());
+ StatusMessage = "ERROR RequestAccessAsync: " + accessStatus.ToString();
return false;
}
- Debug.WriteLine("Successful get service");
if (characteristics.Count == 0)
{
- Debug.WriteLine("Characteristic not found.");
+ StatusMessage = "Characteristic not found.";
return false;
}
GattCharacteristic selectedCharacteristic = characteristics[0];
@@ -253,7 +269,7 @@ protected async Task ConnectToSensor()
await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.None);
if (disableNotificationstatus != GattCommunicationStatus.Success)
{
- Debug.WriteLine("Error clearing registering for value changes: " + disableNotificationstatus);
+ StatusMessage = "Error clearing registering for value changes: " + disableNotificationstatus;
return false;
}
// Enable notify
@@ -268,25 +284,29 @@ protected async Task ConnectToSensor()
}
else
{
- Debug.WriteLine("Characteristic doesn't support Indicate or Notify");
+ StatusMessage = "Characteristic doesn't support Indicate or Notify";
return false;
}
- Debug.WriteLine("Enable notify");
GattCommunicationStatus status = await selectedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(cccdValue);
if (status != GattCommunicationStatus.Success)
{
- Debug.WriteLine("Error registering for value changes: " + status);
+ StatusMessage = "Error registering for value changes: " + status;
return false;
}
+ StatusMessage = "Notify enabled";
subscribedCharacteristic = selectedCharacteristic;
subscribedCharacteristic.ValueChanged += Characteristic_ValueChanged;
return true;
}
+ private void MonitorBindingPropertyChanged(object sender, PropertyChangedEventArgs e)
+ {
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("BindMonitor"));
+ }
protected void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
- lastReport = DateTime.Now;
+ LastReport = DateTime.Now;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LastReport"));
byte[] data;
@@ -382,7 +402,8 @@ protected async void autoConnectWorkerAsync()
Debug.WriteLine(String.Format("Enabling atuoconnect on {0}", deviceId));
while (shouldAutoConnectContinue)
{
- if (DateTime.Now - LastReport > new TimeSpan(hours: 0, minutes: 0, seconds: 30))
+ var timeoutDeadline = DateTime.Now - new TimeSpan(hours: 0, minutes: 0, seconds: 30);
+ if (lastReport < timeoutDeadline && lastConnected < timeoutDeadline)
{
Connected = false;
}
@@ -395,18 +416,18 @@ protected async void autoConnectWorkerAsync()
if (await task)
{
Connected = true;
- }
+ lastConnected = DateTime.Now;
+ }
}
catch (Exception e)
{
- Debugger.Break();
+ StatusMessage = "Connection Error:" + e.Message;
}
if (!Connected)
{
ConnectionStatus = BLESensorConnectionStatus.NotConnected;
}
- lastReport = DateTime.Now; // W
}
Thread.Sleep(5000);
}
@@ -414,7 +435,7 @@ protected async void autoConnectWorkerAsync()
protected void EnableAutoConnect()
{
shouldAutoConnectContinue = true;
- autoConnectTask = Task.Run(autoConnectWorkerAsync);
+ autoConnectTask = Task.Run(() => autoConnectWorkerAsync());
}
protected void DisableAutoConnect()
{
@@ -428,9 +449,19 @@ protected void CleanUpSubscription()
{
if (subscribedCharacteristic != null)
{
+ _ = Task.Run(async () =>
+ {
+ GattCommunicationStatus disableNotificationstatus =
+ await subscribedCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.None);
+ if (disableNotificationstatus != GattCommunicationStatus.Success)
+ {
+ Debug.WriteLine("Error clearing registering for value changes: " + disableNotificationstatus);
+ }
+ });
+
subscribedCharacteristic.ValueChanged -= Characteristic_ValueChanged;
subscribedCharacteristic = null;
-
+
Debug.WriteLine("Cleanup Subscription");
}
if (selectedService != null)
diff --git a/WpfDemo/UserControls/SensorControl.xaml b/WpfDemo/UserControls/SensorControl.xaml
index e223a13..6b4f686 100644
--- a/WpfDemo/UserControls/SensorControl.xaml
+++ b/WpfDemo/UserControls/SensorControl.xaml
@@ -56,7 +56,10 @@
-
+
+
+
+
diff --git a/WpfDemo/ValueConverters.cs b/WpfDemo/ValueConverters.cs
index 0ebd54c..9d92e10 100644
--- a/WpfDemo/ValueConverters.cs
+++ b/WpfDemo/ValueConverters.cs
@@ -20,7 +20,7 @@ public object Convert(object value, Type targetType, object parameter, System.Gl
Vector3? v = value as Vector3?;
if (v.HasValue)
{
- return String.Format("x = {0}, y = {0}, z = {0}", v.Value.X, v.Value.Y, v.Value.Z);
+ return String.Format("x = {0:0.0000}, y = {1:0.0000}, z = {2:0.0000}", v.Value.X, v.Value.Y, v.Value.Z);
}
return "";
}