Skip to content
Snippets Groups Projects
Commit 66a86d3e authored by Paul-Winpenny's avatar Paul-Winpenny
Browse files

At this point the sending and receiving messages is working

parent 526befba
No related branches found
No related tags found
1 merge request!1App now has a basic structure and BLE support
using Plugin.BLE.Abstractions.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Robobin.Interfaces
{
public interface IBluetoothLEService
{
IBluetoothLE Current { get; }
}
public interface IAdapterService
{
IAdapter Adapter { get; }
}
}
......@@ -18,6 +18,7 @@ using Windows.Devices.WiFi;
using System.Reflection.PortableExecutable;
using Plugin.BLE.Windows;
using System.Text;
using System.Windows.Documents;
namespace RobobinApp.ViewModels
{
......@@ -32,6 +33,9 @@ namespace RobobinApp.ViewModels
public ICommand ConnectCommand { get; }
public ICommand SendWifiInfoCommand { get; }
public ICommand DisconnectCommand { get; }
public ICommand TestReadOperation { get; }
public ICommand TestWriteOperation { get; }
private bool _isConnected;
private string ssid;
private string password;
......@@ -39,6 +43,7 @@ namespace RobobinApp.ViewModels
public const string SendReceiveServiceUUID = "00000001-710e-4a5b-8d75-3e5b444bc3cf";
public const string rxUUID = "00000002-710e-4a5b-8d75-3e5b444bc3cf";
public const string wxUUID = "00000003-710e-4a5b-8d75-3e5b444bc3cf";
public string tempUnit = "C";
public bool IsConnected
{
......@@ -50,17 +55,31 @@ namespace RobobinApp.ViewModels
OnPropertyChanged(nameof(ConnectButtonText)); // Update button text when connection state changes
}
}
private ICharacteristic _readCharacteristic;
private ICharacteristic _writeCharacteristic;
public ICharacteristic ReadCharacteristic
{
get => _readCharacteristic;
set
{
_readCharacteristic = value;
OnPropertyChanged();
}
}
public string SSID
public ICharacteristic WriteCharacteristic
{
get => ssid;
get => _writeCharacteristic;
set
{
ssid = value;
OnPropertyChanged(nameof(SSID));
_writeCharacteristic = value;
OnPropertyChanged();
}
}
public string Password
{
get => password;
......@@ -76,7 +95,7 @@ namespace RobobinApp.ViewModels
public string ConnectButtonText => IsConnected ? "Disconnect" : "Connect";
private bool _isWifiNetworkSelectionVisible;
private WifiNetwork _selectedWifiNetwork;
public bool IsWifiNetworkSelectionVisible
{
get => _isWifiNetworkSelectionVisible;
......@@ -94,9 +113,12 @@ namespace RobobinApp.ViewModels
WifiNetworks = new ObservableCollection<WifiNetwork>();
ConnectCommand = new Command(OnConnect);
DisconnectCommand = new Command(OnDisconnect);
SendWifiInfoCommand = new Command(OnSendWifiInfo);
GoHomeCommand = new Command(async () => await OnGoHome());
ConnectCommand = new Command(OnToggleConnection);
TestReadOperation = new Command(async () => await ReadOperationAsync());
SendWifiInfoCommand = new Command(OnSendWifiInfo);
TestWriteOperation = new Command(async() => await PingPiASync());
_bluetoothLE = CrossBluetoothLE.Current;
_adapter = _bluetoothLE.Adapter;
_adapter.DeviceDiscovered += OnDeviceDiscovered;
......@@ -104,36 +126,53 @@ namespace RobobinApp.ViewModels
Debug.WriteLine("Checking and requesting Bluetooth permissions.");
CheckAndRequestBluetoothPermissions();
//ScanForWifiNetworks();
}
private async void ScanForWifiNetworks()
private void OnSendWifiInfo(object obj)
{
WifiNetworks.Clear();
Debug.WriteLine("Scanning for Wi-Fi networks...");
var SSID = SelectedWifiNetwork.SSID;
var result = WriteOperationAsync("CONNECT", SSID + "," + password);
Debug.WriteLine($"Result: {result}");
}
var wifiAdapter = await GetWifiAdapterAsync();
if (wifiAdapter == null)
private async Task PingPiASync()
{
if (tempUnit.Equals("C"))
{
Debug.WriteLine("Wi-Fi adapter not found.");
return;
tempUnit = "F";
} else
{
tempUnit = "C";
}
WriteOperationAsync(tempUnit);
}
await wifiAdapter.ScanAsync();
Debug.Write("Scanning for networks");
var networks = wifiAdapter.NetworkReport.AvailableNetworks;
private async void ScanForWifiNetworks()
{
WifiNetworks.Clear();
Debug.WriteLine("Retrieving Wifi networks from readCharacteristic");
var addedSsids = new HashSet<string>(); // To keep track of added SSIDs
//Delay 5 seconds
await Task.Delay(5000);
foreach (var network in networks)
//var networks = await ReadOperationAsync();
var networks = "Network1\nNetwork2\nNetwork3"; // For testing
Debug.WriteLine(networks);
var delimiter = "\n";
var networkList = networks.Split(delimiter);
var addedSsids = new HashSet<string>();
foreach (var network in networkList)
{
Debug.Write("This network exists: " + network.Ssid);
Debug.Write("This network exists: " + network);
if (addedSsids.Add(network.Ssid))
if (addedSsids.Add(network))
{
var wifiNetwork = new WifiNetwork
{
SSID = network.Ssid,
SignalStrength = network.NetworkRssiInDecibelMilliwatts
SSID = network,
SignalStrength = 0.0
};
Microsoft.Maui.Controls.Device.BeginInvokeOnMainThread(() => WifiNetworks.Add(wifiNetwork));
......@@ -143,67 +182,6 @@ namespace RobobinApp.ViewModels
}
private async Task<WiFiAdapter> GetWifiAdapterAsync()
{
var result = await WiFiAdapter.FindAllAdaptersAsync();
return result.FirstOrDefault(); // Get the first available Wi-Fi adapter
}
private async void OnSendWifiInfo(object obj)
{
if (SelectedWifiNetwork != null)
{
Debug.WriteLine("Wifi been selected");
Debug.WriteLine($"Selected Network {SelectedWifiNetwork.SSID}");
}
if (!_isConnected || _connectedDevice == null)
{
Debug.WriteLine("Cannot send WiFi information: No device is connected.");
await Application.Current.MainPage.DisplayAlert("Error", "No device is connected.", "OK");
return;
}
try
{
Debug.WriteLine($"Sending WiFi information to {_connectedDevice.Name}...");
var services = await _connectedDevice.GetServicesAsync();
var uartService = services.FirstOrDefault(s => s.Id == Guid.Parse("6e400001-b5a3-f393-e0a9-e50e24dcca9e"));
if (uartService == null)
{
Debug.WriteLine("UART service not found.");
await Application.Current.MainPage.DisplayAlert("Error", "UART service not found on the device.", "OK");
return;
}
var characteristics = await uartService.GetCharacteristicsAsync();
var rxCharacteristic = characteristics.FirstOrDefault(c => c.Id == Guid.Parse(rxUUID));
if (rxCharacteristic == null)
{
Debug.WriteLine("RX characteristic not found.");
await Application.Current.MainPage.DisplayAlert("Error", "RX characteristic not found on the device.", "OK");
return;
}
string wifiInfo = $"{SSID},{Password}";
byte[] data = System.Text.Encoding.UTF8.GetBytes(wifiInfo);
await rxCharacteristic.WriteAsync(data);
Debug.WriteLine("WiFi information sent successfully.");
await Application.Current.MainPage.DisplayAlert("Success", "WiFi information sent successfully.", "OK");
}
catch (Exception ex)
{
Debug.WriteLine($"Error sending WiFi information: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Error", $"Failed to send WiFi information: {ex.Message}", "OK");
}
}
public BluetoothDevice SelectedDevice
{
get => _selectedDevice;
......@@ -351,29 +329,38 @@ namespace RobobinApp.ViewModels
if (_connectedDevice != null)
{
Debug.WriteLine($"Successfully connected to {SelectedDevice.Name}.");
//
var services = await _connectedDevice.GetServicesAsync();
Debug.WriteLine("Services gotten");
IsWifiNetworkSelectionVisible = true;
// Iterate through the discovered services
//var service = await _connectedDevice.GetServiceAsync(Guid.Parse("00000001-710e-4a5b-8d75-3e5b444bc3cf"));
foreach (var service in services)
{
Debug.WriteLine($"Service: ID={service.Id}, Name={service.Name}");
if (service.Id.Equals(Guid.Parse("00000001-710e-4a5b-8d75-3e5b444bc3cf")) )
{
Debug.WriteLine("Found RW service");
var characteristics = await service.GetCharacteristicsAsync();
foreach (var characteristic in characteristics)
{
Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name}");
var descriptor = await characteristic.GetDescriptorsAsync();
Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name} | {descriptor}");
if (characteristic.Uuid.Equals(rxUUID))
{
var result = await ReadOperationAsync(characteristic);
ReadCharacteristic = characteristic;
var result = await ReadOperationAsync();
}
else if (characteristic.Uuid.Equals(wxUUID))
{
const string data = "C";
await WriteOperationAsync(characteristic,data);
WriteCharacteristic = characteristic;
const string command = "SCAN";
await WriteOperationAsync(command);
ScanForWifiNetworks();
}
}
......@@ -382,7 +369,7 @@ namespace RobobinApp.ViewModels
var transmissionService = services.FirstOrDefault(s => s.Id == Guid.Parse(SendReceiveServiceUUID));
var readCharacteristic = await transmissionService.GetCharacteristicAsync(Guid.Parse(rxUUID));
var result2 = await ReadOperationAsync(readCharacteristic);
var result2 = await ReadOperationAsync();
}
else
......@@ -415,14 +402,20 @@ namespace RobobinApp.ViewModels
private async Task<string> ReadOperationAsync(ICharacteristic characteristic, int retryCount = 3)
private async Task<string> ReadOperationAsync(int retryCount = 3)
{
if (ReadCharacteristic == null)
{
Debug.WriteLine("Read characteristic is not set.");
return "Failure";
}
Debug.WriteLine($"READ COMMAND : {ReadCharacteristic.Uuid}");
for (int attempt = 1; attempt <= retryCount; attempt++)
{
try
{
Debug.WriteLine($"Attempt {attempt}: Reading from characteristic {characteristic.Uuid}");
var temperatureData = await characteristic.ReadAsync();
Debug.WriteLine($"Attempt {attempt}: Reading from characteristic {ReadCharacteristic.Uuid}");
var temperatureData = await ReadCharacteristic.ReadAsync();
var temperatureValue = System.Text.Encoding.UTF8.GetString(temperatureData.data);
Debug.WriteLine($"Temperature Value: {temperatureValue}");
return temperatureValue;
......@@ -440,21 +433,27 @@ namespace RobobinApp.ViewModels
}
}
}
return null;
return "Failure";
}
private async Task WriteOperationAsync(ICharacteristic characteristic,string sendData, int retryCount = 3)
private async Task<string> WriteOperationAsync(string command, string arguments="", int retryCount = 3)
{
byte[] data = System.Text.Encoding.UTF8.GetBytes(sendData);
if (WriteCharacteristic == null)
{
Debug.WriteLine("Write characteristic is not set.");
return "Failure";
}
string joinedData = command + ":" + arguments;
Debug.WriteLine($"WRITE COMMAND {joinedData}, UUID: {WriteCharacteristic}");
byte[] data = System.Text.Encoding.UTF8.GetBytes(joinedData);
for (int attempt = 1; attempt <= retryCount; attempt++)
{
try
{
Debug.WriteLine($"Attempt {attempt}: Writing to characteristic {characteristic.Uuid}");
await characteristic.WriteAsync(data);
{
await WriteCharacteristic.WriteAsync(data);
Debug.WriteLine("Write operation succeeded.");
return;
return "Success";
}
catch (Exception ex)
{
......@@ -469,6 +468,8 @@ namespace RobobinApp.ViewModels
}
}
}
return "Failure";
}
......@@ -505,50 +506,4 @@ namespace RobobinApp.ViewModels
}
/**
*
var transmitService = services.FirstOrDefault(s => s.Id == Guid.Parse(SendReceiveServiceUUID));
Debug.WriteLine("Transmit service was accessed");
Debug.WriteLine($"{transmitService.Name} : {transmitService.Id}");
if (transmitService == null)
{
Debug.WriteLine("Transmit service wasn't found");
}
var characteristics = await transmitService.GetCharacteristicsAsync();
foreach (var characteristic in characteristics)
{
Debug.WriteLine($"{characteristic.Uuid} | {characteristic.Name}");
if (characteristic.Uuid.Equals(rxUUID))
{
var result = await ReadOperationAsync(characteristic);
}
else if (characteristic.Uuid.Equals(wxUUID))
{
//await WriteOperationAsync(characteristic);
}
}
}
catch (DeviceConnectionException ex)
{
Debug.WriteLine($"Connection error: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Connection Error", $"Failed to connect: {ex.Message}", "OK");
}
catch (TaskCanceledException ex)
{
Debug.WriteLine($"TaskCanceledException: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Connection Error", "Connection timed out.", "OK");
_connectedDevice = null;
IsConnected = false;
}
catch (Exception ex)
{
Debug.WriteLine($"General connection error: {ex.Message}");
await Application.Current.MainPage.DisplayAlert("Connection Error", $"An error occurred: {ex.Message}", "OK");
}
} **/
}
......@@ -121,5 +121,22 @@
VerticalOptions="End" />
</StackLayout>
</StackLayout>
<StackLayout Padding="10"
BackgroundColor="Black"
HorizontalOptions="FillAndExpand"
VerticalOptions="Start">
<Label Text="Admin Panel:"
FontSize="Medium"
HorizontalOptions="Start" />
<Button Text= "Test Read Operation"
Command="{Binding TestReadOperation}"
HorizontalOptions="Center"
VerticalOptions="End" />
<Button Text="Test Write Operation"
Command="{Binding TestWriteOperation}"
HorizontalOptions="Center"
VerticalOptions="End" />
</StackLayout>
</StackLayout>
</ContentPage>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment