78 lines
2.1 KiB
PowerShell
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"
|
|
}
|