Skip to content

Instantly share code, notes, and snippets.

@gpduck
Last active December 25, 2015 20:29
Show Gist options
  • Save gpduck/7035635 to your computer and use it in GitHub Desktop.
Save gpduck/7035635 to your computer and use it in GitHub Desktop.
Sits in a loop listening for keyword actions (defined in the switch from line 72 to 108). You must have Windows Speech Recognition configured and running before you run this script.
[Reflection.Assembly]::LoadWithPartialName("System.Speech") > $null
function InitGrammar {
param(
$Attention,
$CommandArray
)
$choices = new-object System.Speech.Recognition.Choices($CommandArray)
$GrammarBuilder = new-object System.Speech.Recognition.GrammarBuilder($Attention)
$GrammarBuilder.Append($choices)
$Grammar = New-Object System.Speech.Recognition.Grammar($GrammarBuilder)
return $Grammar
}
function GetRE {
param(
$Grammar
)
$re = New-Object System.Speech.Recognition.SpeechRecognitionEngine
$re.SetInputToDefaultAudioDevice()
$re.LoadGrammar($Grammar)
return $re
}
function out-say {
param(
[Parameter(ValueFromPipeline=$true)]
$Text,
[switch]$async
)
begin {
if(!$global:ss) {
$global:ss = New-Object speech.Synthesis.SpeechSynthesizer
}
}
process {
if($async) {
$global:ss.speakasync($Text)
} else {
$global:ss.Speak($Text)
}
}
}
$Attention = "computer"
$Commands = @("stop", "help", "beep", "get jobs", "clean jobs", "get weather")
$g = InitGrammar -Attention $attention -CommandArray $Commands
$re = GetRE $g
out-say "Hello my name is $attention, what can I do for you?"
$keepGoing = $true
while($keepGoing) {
$result = $re.Recognize()
if($result -and $result.words.count -gt 0) {
$FirstWord = $result.Words[0]
Write-Debug "$($result.text) at $($result.confidence)"
Write-Debug "Heard $($FirstWord.text) at $($FirstWord.confidence)"
if($result.words.Count -gt 1 -and $FirstWord.text -eq $Attention) {
$AvgConfidence = 0
$result.Words | %{
$AvgConfidence += $_.Confidence
}
$AvgConfidence = $AvgConfidence / $result.Words.Count
$WordsTextArr = $result.Words | select -ExpandProperty text
$command = [string]::Join(" ", $WordsTextArr, 1, $WordsTextArr.Count - 1)
Write-Debug "Heard $($command) at $($avgConfidence)"
if($AvgConfidence -gt .75) {
switch ($command) {
"stop" {
out-say "goodbye"
Write-Host "Ending Recognition"
$keepGoing = $false
}
"help" {
out-say ("Try saying: " + [string]::Join(" ", $Commands))
Write-Host ("Try saying: " + [string]::Join(", ", $Commands))
}
"beep" {
[Console]::Beep()
}
"get jobs" {
$RunningJobs = @(Get-Job | ?{$_.state -eq "running"})
$CompletedJobs = @(Get-Job | ?{$_.state -ne "running"})
out-say "$($RunningJobs.count) running jobs."
out-say "$($CompletedJobs.count) completed jobs."
}
"clean jobs" {
$StaleJobs = @(Get-Job | ?{$_.state -ne "running"})
if($StaleJobs) {
out-say "$($stalejobs.count) completed jobs"
$StaleJobs | Remove-Job
if( !(Get-Job | ?{$_.state -ne "running"}) ) {
out-say "cleaned up"
}
}
}
"get weather" {
#$intro = out-say "Please wait while I access the current conditions" -async
$wc = New-Object net.WebClient
$Weather = ConvertFrom-Json $wc.downloadstring("http://api.openweathermap.org/data/2.5/weather?q=Dallas,%20TX")
$Condition = $Weather.Weather.Main
$Temp = [Math]::Round((($Weather.Main.Temp - 273.15) * 1.8 + 32), 0)
$Wind = [Math]::Round(($Weather.Wind.Speed * 2.23694), 0)
out-say "It is currently $condition skies and $temp degrees outside, with wend speed $wind miles per hour"
}
default {
Write-Warning "Unknown word $($command)"
}
}
} else {
out-say "Please say that again"
Write-Warning "I'm not sure what you said ($($command))"
}
} else {
Write-Debug "Ignoring attention command"
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment