1 Commits
Author SHA1 Message Date
fristy f28d26b585 feat: BE prefix filter, fail-loud error notifications
CI / build-and-test (push) Successful in 1m27s
CI / release (push) Successful in 2m30s
2026-09-05 18:20:54 +03:00
3 changed files with 37 additions and 6 deletions

No files matched your search

@@ -4,10 +4,10 @@
<TargetFramework>net8.0-windows10.0.19041.0</TargetFramework> <TargetFramework>net8.0-windows10.0.19041.0</TargetFramework>
<UseWPF>true</UseWPF> <UseWPF>true</UseWPF>
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<Version>0.3.1</Version> <Version>0.3.2</Version>
<AssemblyVersion>0.3.1.0</AssemblyVersion> <AssemblyVersion>0.3.2.0</AssemblyVersion>
<FileVersion>0.3.1.0</FileVersion> <FileVersion>0.3.2.0</FileVersion>
<InformationalVersion>0.3.1</InformationalVersion> <InformationalVersion>0.3.2</InformationalVersion>
<AssemblyProduct>Fristy.RgbLedStripController</AssemblyProduct> <AssemblyProduct>Fristy.RgbLedStripController</AssemblyProduct>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@@ -39,6 +39,7 @@ public sealed class BleDeviceService : IBleTransport
await MergeWindowsDeviceInventoryAsync(captures); await MergeWindowsDeviceInventoryAsync(captures);
return captures.Values return captures.Values
.Where(capture => IsSupportedAddress(capture.Address))
.Select(capture => new BleScanResult .Select(capture => new BleScanResult
{ {
DeviceId = FormatAddress(capture.Address), DeviceId = FormatAddress(capture.Address),
@@ -299,6 +300,9 @@ public sealed class BleDeviceService : IBleTransport
|| normalized.Contains("DUOCO"); || normalized.Contains("DUOCO");
} }
internal static bool IsSupportedAddress(ulong address)
=> FormatAddress(address).StartsWith("BE:", StringComparison.OrdinalIgnoreCase);
private static async Task RunScanPassAsync( private static async Task RunScanPassAsync(
ConcurrentDictionary<ulong, ScanCapture> captures, ConcurrentDictionary<ulong, ScanCapture> captures,
BluetoothLEScanningMode mode, BluetoothLEScanningMode mode,
@@ -360,7 +364,8 @@ public sealed class BleDeviceService : IBleTransport
if (!device.Properties.TryGetValue("System.Devices.Aep.DeviceAddress", out var addressValue) if (!device.Properties.TryGetValue("System.Devices.Aep.DeviceAddress", out var addressValue)
|| addressValue is not string addressText || addressValue is not string addressText
|| !TryParseBluetoothAddress(addressText, out var address)) || !TryParseBluetoothAddress(addressText, out var address)
|| !IsSupportedAddress(address))
{ {
continue; continue;
} }
@@ -99,6 +99,11 @@ public sealed class MultiDeviceController : IAsyncDisposable
public async Task<ConnectedDeviceViewModel> ConnectAsync(BleScanResult device, CancellationToken cancellationToken = default) public async Task<ConnectedDeviceViewModel> ConnectAsync(BleScanResult device, CancellationToken cancellationToken = default)
{ {
if (!BleDeviceService.IsSupportedAddress(device.AddressValue))
{
throw new ArgumentException($"Desteklenmeyen cihaz adresi: {device.BluetoothAddress}", nameof(device));
}
DeviceConnectionContext? existing; DeviceConnectionContext? existing;
lock (_stateLock) lock (_stateLock)
{ {
@@ -583,6 +588,11 @@ public sealed class MultiDeviceController : IAsyncDisposable
private void UpsertKnownDevice(BleScanResult device) private void UpsertKnownDevice(BleScanResult device)
{ {
if (!BleDeviceService.IsSupportedAddress(device.AddressValue))
{
return;
}
var alias = GetAlias(device.BluetoothAddress); var alias = GetAlias(device.BluetoothAddress);
var profile = new DeviceProfile( var profile = new DeviceProfile(
string.IsNullOrWhiteSpace(alias) ? device.NativeName : alias, string.IsNullOrWhiteSpace(alias) ? device.NativeName : alias,
@@ -675,6 +685,19 @@ public sealed class MultiDeviceController : IAsyncDisposable
: connections.Any(context => context.ViewModel.ConnectionStatus == DeviceConnectionStatus.Faulted) : connections.Any(context => context.ViewModel.ConnectionStatus == DeviceConnectionStatus.Faulted)
? DeviceConnectionStatus.Faulted ? DeviceConnectionStatus.Faulted
: DeviceConnectionStatus.Disconnected; : DeviceConnectionStatus.Disconnected;
if (State.ConnectionStatus == DeviceConnectionStatus.Faulted
&& !State.StatusText.Contains("Hata:", StringComparison.Ordinal))
{
var firstFault = connections
.Where(context => context.ViewModel.ConnectionStatus == DeviceConnectionStatus.Faulted)
.Select(context => context.ViewModel.StatusText)
.FirstOrDefault(text => !string.IsNullOrWhiteSpace(text));
if (!string.IsNullOrWhiteSpace(firstFault))
{
State.StatusText = firstFault;
}
}
} }
private void EnsureTargetsAvailable() private void EnsureTargetsAvailable()
@@ -708,7 +731,10 @@ public sealed class MultiDeviceController : IAsyncDisposable
: $"İşlem başarısız oldu: {firstFailureMessage}"; : $"İşlem başarısız oldu: {firstFailureMessage}";
} }
return $"{successMessage} {successCount}/{totalCount} hedef başarılı, {failureCount} hata."; var partialMessage = $"{successMessage} {successCount}/{totalCount} hedef başarılı, {failureCount} hata.";
return string.IsNullOrWhiteSpace(firstFailureMessage)
? partialMessage
: $"{partialMessage} Hata: {firstFailureMessage}";
} }
private sealed class DeviceConnectionContext private sealed class DeviceConnectionContext