fix(ppsk): null schedule = always on; disabled global toggle restores all

Previously SyncPpskSchedules returned early when the global setting
was disabled, leaving any PPSK that had been held by a prior sync
stuck in 'held' state. It also only iterated whereNotNull(schedule),
so null-schedule PPSKs ("always on") were never drift-corrected back
to active either.

Now the command always runs and computes a per-PPSK target state:
  - global ppsk_scheduling disabled  → target = active (always)
  - global enabled  + null schedule  → target = active (always)
  - global enabled  + has schedule   → follow the schedule's slot

PPSKs that drift from the target get enabled/disabled accordingly.
Schedules in unifi_ppsks.schedule are preserved across global toggles
either way — disabling the setting doesn't touch them, so re-enabling
resumes the operator's per-PPSK schedules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 16:09:40 -04:00
parent e59f193ffc
commit fc4f5370ae

View File

@@ -14,16 +14,21 @@ class SyncPpskSchedules extends Command
public function handle(UnifiApiClient $unifi): int
{
if (! $this->option('force') && ! Setting::get('unifi.ppsk_scheduling.enabled')) {
return self::SUCCESS;
}
// Always run, even when global ppsk_scheduling is disabled — in
// that case the target state for every PPSK is "active" (always
// on). That way disabling the global setting actually restores
// any held PPSKs to active without operators having to do
// anything else, and null-schedule PPSKs always end up active.
// Schedules in the DB are preserved regardless of toggle state,
// so re-enabling resumes the per-PPSK schedule.
$globalEnabled = (bool) Setting::get('unifi.ppsk_scheduling.enabled');
$tz = \App\Support\Timezone::current();
$now = now($tz);
$day = $now->dayOfWeek; // 0=Sun … 6=Sat
$slot = $now->hour * 2 + ($now->minute >= 30 ? 1 : 0); // 047
$ppsks = UnifiPpsk::whereNotNull('schedule')->get();
$ppsks = UnifiPpsk::all();
if ($ppsks->isEmpty()) {
return self::SUCCESS;
@@ -42,7 +47,12 @@ class SyncPpskSchedules extends Command
}
foreach ($ppsks as $ppsk) {
// Default to "always on". Only consult the schedule if
// global scheduling is enabled AND this PPSK has one.
$shouldBeOn = true;
if ($globalEnabled && $ppsk->schedule) {
$shouldBeOn = (bool) ($ppsk->schedule[$day * 48 + $slot] ?? true);
}
if ($shouldBeOn && $ppsk->state === 'held') {
$this->enablePpsk($ppsk, $unifi, $networksByVlan);