Files
scripts/python/utils/interval-timer-ding.ps1
2026-02-17 10:30:18 +02:00

78 lines
2.1 KiB
PowerShell

<#
.SYNOPSIS
Plays a ding/timer sound at regular intervals aligned to round period marks (e.g. every 15 min),
with an optional offset so the sound plays a few seconds before each mark.
.DESCRIPTION
Default: period 15 minutes, offset 15 seconds. Notification plays at :14:45, :29:45, :44:45, :59:45.
.PARAMETER PeriodMinutes
Interval in minutes between notifications (default 15). Defines the "round" marks (0, 15, 30, 45 past the hour).
.PARAMETER OffsetSeconds
Seconds before each round mark to play the sound (default 15). E.g. 15 means play at XX:14:45, XX:29:45, etc.
.EXAMPLE
.\interval-timer-ding.ps1
.\interval-timer-ding.ps1 -PeriodMinutes 30 -OffsetSeconds 10
#>
param(
[int] $PeriodMinutes = 15,
[int] $OffsetSeconds = 15
)
$ErrorActionPreference = 'Stop'
if ($PeriodMinutes -lt 1) { throw "PeriodMinutes must be >= 1" }
if ($OffsetSeconds -lt 0) { throw "OffsetSeconds must be >= 0" }
$periodSec = $PeriodMinutes * 60
function Get-SecondsSinceMidnight {
$now = Get-Date
return $now.Hour * 3600 + $now.Minute * 60 + $now.Second
}
function Get-NextRingSeconds {
$nowSec = Get-SecondsSinceMidnight
$nextBoundarySec = [Math]::Ceiling($nowSec / $periodSec) * $periodSec
$ringSec = $nextBoundarySec - $OffsetSeconds
if ($ringSec -le $nowSec) {
$ringSec += $periodSec
}
return $ringSec
}
function Get-WaitSeconds {
$nowSec = Get-SecondsSinceMidnight
$ringSec = Get-NextRingSeconds
$wait = $ringSec - $nowSec
if ($wait -le 0) { $wait = 1 }
return [int]$wait
}
function Play-Ding {
try {
[System.Media.SystemSounds]::Asterisk.Play()
} catch {
[Console]::Beep(800, 200)
}
}
$nextRing = Get-NextRingSeconds
$nextH = [Math]::Floor($nextRing / 3600)
$nextM = [Math]::Floor(($nextRing % 3600) / 60)
$nextS = $nextRing % 60
Write-Host "Period: $PeriodMinutes min, offset: $OffsetSeconds s. Next ding at $($nextH.ToString('00')):$($nextM.ToString('00')):$($nextS.ToString('00')) (then every $PeriodMinutes min). Press Ctrl+C to stop."
while ($true) {
$waitSec = Get-WaitSeconds
if ($waitSec -gt 0) {
Start-Sleep -Seconds $waitSec
}
Play-Ding
$ts = Get-Date -Format "HH:mm:ss"
Write-Host "[$ts] ding"
}