functions/other/Start-PSUTimer.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
function Start-PSUTimer
{
<#
    .SYNOPSIS
        Creates a timer that will alarm the user after it has expired.
     
    .DESCRIPTION
        Creates a timer that will alarm the user after it has expired.
        Provides both visual and sound warnings.
        Also provides a progress bar with a time remaining display.
     
    .PARAMETER Duration
        The time to wait.
     
    .PARAMETER Message
        What to wait for.
     
    .PARAMETER AlarmCount
        How often to give warning.
     
    .PARAMETER NoProgress
        Disables progress bar.
     
    .PARAMETER AlarmInterval
        In what time interval to write warnings and send sound.
     
    .PARAMETER MinFrequency
        The minimum frequency of the beeps.
        Must be at least one lower than MaxFrequency.
        Increase delta to play random frequency sounds on each beep.
     
    .PARAMETER MaxFrequency
        The maximum frequency of the beeps.
        Must be at least one higher than MaxFrequency.
        Increase delta to play random frequency sounds on each beep.
     
    .EXAMPLE
        PS C:\> timer 170 Tea
         
        After 170 Duration give warning that the tea is ready.
#>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseShouldProcessForStateChangingFunctions", "")]
    [CmdletBinding()]
    param (
        [Parameter(Position = 0, Mandatory = $true)]
        [Alias('Seconds')]
        [PSFDateTime]
        $Duration,
        
        [Parameter(Position = 1, Mandatory = $true)]
        $Message,
        
        [Parameter(Position = 2)]
        [int]
        $AlarmCount = 25,
        
        [switch]
        $NoProgress,
        
        [int]
        $AlarmInterval = 250,
        
        [int]
        $MinFrequency = 2999,
        
        [int]
        $MaxFrequency = 3000
    )
    
    begin
    {
        $start = Get-Date
        $end = $Duration.Value
        
        function Get-FriendlyTime
        {
            [CmdletBinding()]
            param (
                [int]
                $Seconds
            )
            
            $tempSeconds = $Seconds
            $strings = @()
            if ($tempSeconds -gt 3599)
            {
                [int]$count = [math]::Floor(($tempSeconds / 3600))
                $strings += "{0}h" -f $count
                $tempSeconds = $tempSeconds - ($count * 3600)
            }
            
            if ($tempSeconds -gt 59)
            {
                [int]$count = [math]::Floor(($tempSeconds / 60))
                $strings += "{0}m" -f $count
                $tempSeconds = $tempSeconds - ($count * 60)
            }
            
            $strings += "{0}s" -f $tempSeconds
            
            $strings -join " "
        }
    }
    process
    {
        if (-not $NoProgress)
        {
            Write-Progress -Activity "Waiting for $Message" -Status "Starting" -PercentComplete 0
        }
        
        while ($end -gt (Get-Date))
        {
            Start-Sleep -Milliseconds 500
            
            if (-not $NoProgress)
            {
                $friendlyTime = Get-FriendlyTime -Seconds ($end - (Get-Date)).TotalSeconds
                [int]$percent = ((Get-Date) - $start).TotalSeconds / ($end - $start).TotalSeconds * 100
                Write-Progress -Activity "Waiting for $Message" -Status "Time remaining: $($friendlyTime)" -PercentComplete ([System.Math]::Min($percent, 100))
            }
        }
        
        if (-not $NoProgress)
        {
            Write-Progress -Activity "Waiting for $Message" -Completed
        }
        
        $countAlarm = 0
        while ($countAlarm -lt $AlarmCount)
        {
            Write-PSFHostColor -String "(<c='sub'>$countAlarm</c>) ### <c='em'>$($Message)</c> ###"
            [System.Console]::Beep((Get-Random -Minimum $MinFrequency -Maximum $MaxFrequency), $AlarmInterval)
            Start-Sleep -Milliseconds $AlarmInterval
            $countAlarm++
        }
    }
}
Import-PSUAlias -Name "timer" -Command "Start-PSUTimer"