LAN-Scanner: Rückgängig-Zustand nach Entfernen der festen Lease erklären
Build / build (push) Canceled after 0s
Build / build (push) Canceled after 0s
Nutzer-Feedback: Nach "Feste IP zuweisen" → "Rückgängig machen" wirkte die Zeile wie
kaputt (Button einfach ausgegraut, Status nur "Kein DHCP-Lease"). Technischer Hintergrund
bestätigt: RouterOS kennt kein "wieder dynamisch machen", UndoStaticAsync entfernt den
Lease-Eintrag komplett — das Gerät merkt das aber nicht sofort, sondern hält seine IP
client-seitig, bis es sich neu meldet (Renewal-Timer oder Trennen/Neuverbinden). Die Zeile
zeigt das jetzt explizit ("Feste IP entfernt" + erklärender Hinweistext/Tooltip statt
kommentarlosem Ausgrauen). Zusätzlich: immer sichtbarer "Aktualisieren"-Button, um nach
einem Trennen/Neuverbinden ohne Schritt-Wechsel neu zu scannen.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
84f5ab21db
commit
2c2fae73eb
4 files changed
+45
-7
No files matched your search
@@ -34,7 +34,9 @@ Bei einem bereits konfigurierten Bestandsgerät liest der dritte Schritt automat
|
||||
|
||||
### Geräte im Netzwerk (LAN-Scanner)
|
||||
|
||||
Der vierte Schritt führt DHCP-Leases (`/ip/dhcp-server/lease`), die ARP-Tabelle (`/ip/arp`) und die Bridge-Host-Tabelle (`/interface/bridge/host`) per MAC-Adresse zu einer Geräteliste zusammen, gruppiert nach dem physischen Anschluss, an dem ein Gerät tatsächlich hängt (aus der Bridge-Host-Tabelle — ARP/Lease zeigen bei gebrückten Setups sonst nur die Bridge selbst, nicht den echten Port). Rein informativ bis auf eine Aktion: Bei einem Gerät mit DHCP-Lease lässt sich diese per Klick fest zuweisen (RouterOS „Make Static") oder wieder entfernen, damit es beim nächsten DHCP-Kontakt wieder eine dynamische Adresse bekommt. Wie die IST-Zustand-Analyse verändert dieser Schritt nichts an der vom Assistenten geplanten Soll-Konfiguration.
|
||||
Der vierte Schritt führt DHCP-Leases (`/ip/dhcp-server/lease`), die ARP-Tabelle (`/ip/arp`) und die Bridge-Host-Tabelle (`/interface/bridge/host`) per MAC-Adresse zu einer Geräteliste zusammen, gruppiert nach dem physischen Anschluss, an dem ein Gerät tatsächlich hängt (aus der Bridge-Host-Tabelle — ARP/Lease zeigen bei gebrückten Setups sonst nur die Bridge selbst, nicht den echten Port). Rein informativ bis auf eine Aktion: Bei einem Gerät mit DHCP-Lease lässt sich diese per Klick fest zuweisen (RouterOS „Make Static") oder wieder entfernen. Ein „Aktualisieren"-Button lädt die Liste jederzeit neu.
|
||||
|
||||
RouterOS kennt keinen direkten „wieder dynamisch machen"-Befehl — das Rückgängig-Machen entfernt den Lease-Eintrag komplett. Das betroffene Gerät merkt das aber nicht sofort: Es hält seine bisherige IP-Adresse client-seitig weiter, bis es von sich aus eine neue DHCP-Anfrage stellt (Lease-Renewal-Timer) oder der Link neu aufgebaut wird (Kabel/WLAN trennen und neu verbinden, Neustart). Bis dahin zeigt die Zeile „Feste IP entfernt" mit deaktiviertem Button und einem erklärenden Hinweistext, statt kommentarlos auszugrauen. Wie die IST-Zustand-Analyse verändert dieser Schritt nichts an der vom Assistenten geplanten Soll-Konfiguration.
|
||||
|
||||
### Experten-Modus
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ public partial class LanScanDeviceRowViewModel : ObservableObject
|
||||
[NotifyPropertyChangedFor(nameof(StatusLabel))]
|
||||
[NotifyPropertyChangedFor(nameof(ActionLabel))]
|
||||
[NotifyPropertyChangedFor(nameof(CanToggleStatic))]
|
||||
[NotifyPropertyChangedFor(nameof(ActionHint))]
|
||||
private DiscoveredDevice _device;
|
||||
|
||||
[ObservableProperty]
|
||||
@@ -26,6 +27,18 @@ public partial class LanScanDeviceRowViewModel : ObservableObject
|
||||
[ObservableProperty]
|
||||
private string? _errorMessage;
|
||||
|
||||
/// <summary>
|
||||
/// Gesetzt, direkt nachdem für dieses Gerät eine feste Lease entfernt wurde. RouterOS kennt danach
|
||||
/// keinen Lease-Eintrag mehr für dieses Gerät — das Gerät selbst merkt das aber nicht sofort: Es hält
|
||||
/// seine bisherige IP-Adresse client-seitig weiter, bis es von sich aus eine neue DHCP-Anfrage stellt
|
||||
/// (Lease-Renewal-Timer) oder der Link neu aufgebaut wird (Kabel/WLAN trennen und neu verbinden,
|
||||
/// Neustart). Rein für die Anzeige — wird bei jedem Neuladen des Schritts wieder zurückgesetzt.
|
||||
/// </summary>
|
||||
[ObservableProperty]
|
||||
[NotifyPropertyChangedFor(nameof(StatusLabel))]
|
||||
[NotifyPropertyChangedFor(nameof(ActionHint))]
|
||||
private bool _isAwaitingNewLease;
|
||||
|
||||
public string MacAddress => Device.MacAddress;
|
||||
|
||||
public string IpAddressDisplay => Device.IpAddress ?? "Keine IP bekannt";
|
||||
@@ -36,6 +49,7 @@ public partial class LanScanDeviceRowViewModel : ObservableObject
|
||||
{
|
||||
{ IsStaticLease: true } => "Feste IP-Adresse",
|
||||
{ HasDhcpLease: true } => "Automatisch per DHCP",
|
||||
_ when IsAwaitingNewLease => "Feste IP entfernt",
|
||||
_ => "Kein DHCP-Lease",
|
||||
};
|
||||
|
||||
@@ -43,4 +57,9 @@ public partial class LanScanDeviceRowViewModel : ObservableObject
|
||||
|
||||
/// <summary>Ohne DHCP-Lease-Eintrag gibt es nichts, das umgestellt werden könnte.</summary>
|
||||
public bool CanToggleStatic => !IsBusy && Device.LeaseId is not null;
|
||||
|
||||
/// <summary>Erklärt, warum der Button gerade deaktiviert ist, nachdem eine feste Zuweisung entfernt wurde.</summary>
|
||||
public string? ActionHint => IsAwaitingNewLease && Device.LeaseId is null
|
||||
? "Erst wieder möglich, sobald sich das Gerät neu meldet — üblicherweise nach Trennen/Neuverbinden oder wenn seine bisherige Lease-Zeit abläuft, nicht sofort."
|
||||
: null;
|
||||
}
|
||||
@@ -47,6 +47,7 @@ public partial class LanScanStepViewModel : WizardStepViewModelBase
|
||||
|
||||
public override Task OnActivatedAsync() => LoadAsync();
|
||||
|
||||
/// <summary>Auch als manuelles "Aktualisieren" genutzt — z. B. um nach einem Trennen/Neuverbinden zu prüfen, ob ein Gerät wieder eine DHCP-Lease bekommen hat.</summary>
|
||||
[RelayCommand]
|
||||
private Task Retry() => LoadAsync();
|
||||
|
||||
@@ -99,9 +100,15 @@ public partial class LanScanStepViewModel : WizardStepViewModelBase
|
||||
|
||||
try
|
||||
{
|
||||
row.Device = row.Device.IsStaticLease
|
||||
? await LanScanService.UndoStaticAsync(_session.Client, row.Device)
|
||||
: await LanScanService.MakeStaticAsync(_session.Client, row.Device);
|
||||
if (row.Device.IsStaticLease)
|
||||
{
|
||||
row.Device = await LanScanService.UndoStaticAsync(_session.Client, row.Device);
|
||||
row.IsAwaitingNewLease = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
row.Device = await LanScanService.MakeStaticAsync(_session.Client, row.Device);
|
||||
}
|
||||
}
|
||||
catch (RouterOsException ex)
|
||||
{
|
||||
|
||||
@@ -8,7 +8,15 @@
|
||||
mc:Ignorable="d"
|
||||
d:DesignWidth="600">
|
||||
<StackPanel Margin="0,16,0,0">
|
||||
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" Margin="0,0,0,20" Opacity="0.8" />
|
||||
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" Margin="0,0,0,12" Opacity="0.8" />
|
||||
|
||||
<ui:Button Content="Aktualisieren" Appearance="Secondary" HorizontalAlignment="Left" Margin="0,0,0,16"
|
||||
IsEnabled="{Binding IsLoading, Converter={StaticResource InverseBooleanConverter}}"
|
||||
Command="{Binding RetryCommand}">
|
||||
<ui:Button.Icon>
|
||||
<ui:SymbolIcon Symbol="ArrowSync24" />
|
||||
</ui:Button.Icon>
|
||||
</ui:Button>
|
||||
|
||||
<StackPanel Orientation="Horizontal" Visibility="{Binding IsLoading, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<ui:ProgressRing IsIndeterminate="True" Width="20" Height="20" Margin="0,0,12,0" />
|
||||
@@ -17,8 +25,6 @@
|
||||
|
||||
<StackPanel Visibility="{Binding ErrorMessage, Converter={StaticResource StringToVisibilityConverter}}">
|
||||
<TextBlock Text="{Binding ErrorMessage}" TextWrapping="Wrap" Foreground="{StaticResource MikrotikRedBrush}" Margin="0,0,0,12" />
|
||||
<ui:Button Content="Erneut versuchen" Appearance="Secondary" HorizontalAlignment="Left"
|
||||
Command="{Binding RetryCommand}" />
|
||||
</StackPanel>
|
||||
|
||||
<TextBlock Text="Es wurden keine Geräte gefunden." Opacity="0.6"
|
||||
@@ -53,10 +59,14 @@
|
||||
<TextBlock Text="{Binding ErrorMessage}" Foreground="{StaticResource MikrotikRedBrush}"
|
||||
TextWrapping="Wrap" FontSize="12"
|
||||
Visibility="{Binding ErrorMessage, Converter={StaticResource StringToVisibilityConverter}}" />
|
||||
<TextBlock Text="{Binding ActionHint}" Opacity="0.6"
|
||||
TextWrapping="Wrap" FontSize="12" Margin="0,2,0,0"
|
||||
Visibility="{Binding ActionHint, Converter={StaticResource StringToVisibilityConverter}}" />
|
||||
</StackPanel>
|
||||
<TextBlock Grid.Column="1" Text="{Binding StatusLabel}" Opacity="0.6" VerticalAlignment="Center" Margin="12,0" />
|
||||
<ui:Button Grid.Column="2" Content="{Binding ActionLabel}" Appearance="Secondary"
|
||||
IsEnabled="{Binding CanToggleStatic}"
|
||||
ToolTip="{Binding ActionHint}"
|
||||
Command="{Binding DataContext.ToggleStaticCommand, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}, AncestorLevel=2}}"
|
||||
CommandParameter="{Binding}" />
|
||||
</Grid>
|
||||
|
||||
Reference in new issue
Block a user