Code by Scott שאול בן ישוע
Unverified Commit 20c62288 authored by Brian Lowrance's avatar Brian Lowrance Committed by GitHub
Browse files

P2.0.2

* Corrected major issues with time based events
* Each child event now calls sendTalk() instead of direct calling parent.Talk() for further analysis
* Added error detection to processPhraseTokens() to help detect invalid user input (logged in parent logs, error announced verbally)..  ie: if someone actually uses %weathercurrent(00000)% instead of using a proper zipcode in place of 00000.
* Corrected an issue when calling %description% from Talk Now.
* Corrected an issue with non-zip code locations in weather phrase tokens/variables.
** ie: %weathercurrent(France/Paris)% was saying this phrase instead of translating it. The issue was phrase casing.
parent 8b7b85cb
......@@ -5,9 +5,9 @@ definition(
description: "Let's talk about mode changes, switches, motions, and so on.",
category: "Fun & Social",
singleInstance: true,
iconUrl: "http://lowrance.cc/ST/icons/BigTalker-2.0.1.png",
iconX2Url: "http://lowrance.cc/ST/icons/BigTalker@2x-2.0.1.png",
iconX3Url: "http://lowrance.cc/ST/icons/BigTalker@2x-2.0.1.png")
iconUrl: "http://lowrance.cc/ST/icons/BigTalker-BetaVersion.png",
iconX2Url: "http://lowrance.cc/ST/icons/BigTalker@2x-BetaVersion.png",
iconX3Url: "http://lowrance.cc/ST/icons/BigTalker@2x-BetaVersion.png")
preferences {
page(name: "pageStart")
......@@ -1821,7 +1821,7 @@ def pageTalkNow(){
myTalkNowResume = (myTalkNowResume == "") ? settings.resumeAudio : true //use global setting if TalkNow is not set
if (settings?.talkNowResume == null) {mytalkNowResume = true} //default to true if not set.
}
def customevent = [displayName: 'BigTalker:TalkNow', name: 'TalkNow', value: 'TalkNow']
def customevent = [displayName: 'BigTalker:TalkNow', name: 'TalkNow', value: 'TalkNow', descriptionText: "Talk Now"]
def myVolume = getDesiredVolume(settings?.talkNowVolume)
def myVoice = getMyVoice(settings.talkNowVoice)
//def myVoice = (!(talkNowVoice == null || talkNowVoice == "")) ? talkNowVoice : (settings?.speechVoice ? settings.speechVoice : "Sallie(en-us)")
......@@ -2012,154 +2012,160 @@ def initialize() {
}
def processPhraseVariables(appname, phrase, evt){
def zipCode = location.zipCode
def mp3Url = ""
if (phrase.toLowerCase().contains("%mp3(")) {
if (phrase.toLowerCase().contains(".mp3)%")) {
def phraseMP3Start = (phrase.toLowerCase().indexOf("%mp3(") + 5)
def phraseMP3End = (phrase.toLowerCase().indexOf(".mp3)%"))
mp3Url = phrase.substring(phraseMP3Start, phraseMP3End)
LOGDEBUG("MP3 URL: ${mp3Url}")
phrase = phrase.replace("%mp3(","")
phrase = phrase.replace(".mp3)%", ".mp3")
phrase = phrase.replace (" ", "%20")
phrase = phrase.replace ("+", "%2B")
phrase = phrase.replace ("-", "%2D")
} else {
phrase = "Invalid M P 3 URL found in M P 3 token"
}
return phrase
}
if (phrase.toLowerCase().contains(" percent ")) { phrase = phrase.replace(" percent ","%") }
if (phrase.toLowerCase().contains("%groupname%")) {
phrase = phrase.toLowerCase().replace('%groupname%', appname)
}
if (phrase.toLowerCase().contains("%devicename%")) {
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.displayName) //User given name of the device triggering the event
}
catch (ex) {
LOGDEBUG("evt.displayName failed; trying evt.device.displayName")
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.device.displayName) //User given name of the device triggering the event
}
catch (ex2) {
LOGDEBUG("evt.device.displayName filed; trying evt.device.name")
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.device.name) //SmartThings name for the device triggering the event
}
catch (ex3) {
LOGDEBUG("evt.device.name filed; Giving up")
phrase = phrase.toLowerCase().replace('%devicename%', "Device Name Unknown")
}
}
}
}
if (phrase.toLowerCase().contains("%devicetype%")) {phrase = phrase.toLowerCase().replace('%devicetype%', evt.name)} //Device type: motion, switch, etc...
if (phrase.toLowerCase().contains("%devicechange%")) {phrase = phrase.toLowerCase().replace('%devicechange%', evt.value)} //State change that occurred: on/off, active/inactive, etc...
if (phrase.toLowerCase().contains("%description%")) {phrase = phrase.toLowerCase().replace('%description%', evt.descriptionText)} //Description of the event which occurred via device-specific text`
if (phrase.toLowerCase().contains("%locationname%")) {phrase = phrase.toLowerCase().replace('%locationname%', location.name)}
if (phrase.toLowerCase().contains("%lastmode%")) {phrase = phrase.toLowerCase().replace('%lastmode%', state.lastMode)}
if (phrase.toLowerCase().contains("%mode%")) {phrase = phrase.toLowerCase().replace('%mode%', location.mode)}
if (phrase.toLowerCase().contains("%time%")) {
phrase = phrase.toLowerCase().replace('%time%', getTimeFromCalendar(false,true))
if ((phrase.toLowerCase().contains("00:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('00:', "12:")}
if ((phrase.toLowerCase().contains("24:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('24:', "12:")}
if ((phrase.toLowerCase().contains("0:")) && (!phrase.toLowerCase().contains("10:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('0:', "12:")}
}
if (phrase.toLowerCase().contains("%weathercurrent%")) {phrase = phrase.toLowerCase().replace('%weathercurrent%', getWeather("current", zipCode)); phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertoday%")) {phrase = phrase.toLowerCase().replace('%weathertoday%', getWeather("today", zipCode)); phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertonight%")) {phrase = phrase.toLowerCase().replace('%weathertonight%', getWeather("tonight", zipCode));phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertomorrow%")) {phrase = phrase.toLowerCase().replace('%weathertomorrow%', getWeather("tomorrow", zipCode));phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathercurrent(")) {
if (phrase.toLowerCase().contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathercurrent(") + 16)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathercurrent(${zipCode})%", getWeather("current", zipCode))
phrase = adjustWeatherPhrase(phrase.toLowerCase())
} else {
phrase = "Custom Zip Code format error in request for current weather"
}
}
if (phrase.toLowerCase().contains("%weathertoday(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertoday(") + 14)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertoday(${zipCode})%", getWeather("today", zipCode))
phrase = adjustWeatherPhrase(phrase.toLowerCase())
} else {
phrase = "Custom Zip Code format error in request for today's weather"
}
}
if (phrase.toLowerCase().contains("%weathertonight(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertonight(") + 16)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertonight(${zipCode})%", getWeather("tonight", zipCode))
phrase = adjustWeatherPhrase(phrase)
} else {
phrase = "Custom Zip Code format error in request for tonight's weather"
}
}
if (phrase.toLowerCase().contains("%weathertomorrow(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertomorrow(") + 17)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertomorrow(${zipCode})%", getWeather("tomorrow", zipCode))
phrase = adjustWeatherPhrase(phrase)
} else {
phrase = "Custom ZipCode format error in request for tomorrow's weather"
}
}
if (state.speechDeviceType == "capability.speechSynthesis"){
//ST TTS Engine pronunces "Dash", so only convert for speechSynthesis devices (LANnouncer)
if (phrase.contains(",")) { phrase = phrase.replace(","," - ") }
//if (phrase.contains(".")) { phrase = phrase.replace("."," - ") }
}
if (phrase.toLowerCase().contains("%shmstatus%")) {
def shmstatus = location.currentState("alarmSystemStatus")?.value
LOGDEBUG("SHMSTATUS=${shmstatus}")
def shmmessage = [off : "Disarmed", away: "Armed, away", home: "Armed, home"][shmstatus] ?: shmstatus
LOGDEBUG("SHMMESSAGE=${shmmessage}")
phrase = phrase.replace("%shmstatus%", shmmessage)
}
if (phrase.contains('"')) { phrase = phrase.replace('"',"") }
if (phrase.contains("'")) { phrase = phrase.replace("'","") }
if (phrase.contains("10S")) { phrase = phrase.replace("10S","tens") }
if (phrase.contains("20S")) { phrase = phrase.replace("20S","twenties") }
if (phrase.contains("30S")) { phrase = phrase.replace("30S","thirties") }
if (phrase.contains("40S")) { phrase = phrase.replace("40S","fourties") }
if (phrase.contains("50S")) { phrase = phrase.replace("50S","fifties") }
if (phrase.contains("60S")) { phrase = phrase.replace("60S","sixties") }
if (phrase.contains("70S")) { phrase = phrase.replace("70S","seventies") }
if (phrase.contains("80S")) { phrase = phrase.replace("80S","eighties") }
if (phrase.contains("90S")) { phrase = phrase.replace("90S","nineties") }
if (phrase.contains("100S")) { phrase = phrase.replace("100S","one hundreds") }
if (phrase.contains("%askalexa%")) {
phrase=phrase.replace("%askalexa%","")
if (!(phrase == "") && (!(phrase == null))){
LOGTRACE("Sending to AskAlexa: ${phrase}.")
sendLocationEvent(name: "AskAlexaMsgQueue", value: "BigTalker", isStateChange: true, descriptionText: phrase)
}else{
LOGERROR("Phrase only contained %askalexa%. Nothing to say/send.")
}
}
if (phrase.contains("%date%")) {
phrase=phrase.replace("%date%",(new Date().format( 'MMMM dd' )))
}
if (phrase.contains("%day%")) {
phrase=phrase.replace("%day%",(new Date().format( 'EEEE' )))
}
if (phrase.contains("%")) { phrase = phrase.replace("%"," percent ") }
return phrase
try {
def zipCode = location.zipCode
def mp3Url = ""
if (phrase.toLowerCase().contains("%mp3(")) {
if (phrase.toLowerCase().contains(".mp3)%")) {
def phraseMP3Start = (phrase.toLowerCase().indexOf("%mp3(") + 5)
def phraseMP3End = (phrase.toLowerCase().indexOf(".mp3)%"))
mp3Url = phrase.substring(phraseMP3Start, phraseMP3End)
LOGDEBUG("MP3 URL: ${mp3Url}")
phrase = phrase.replace("%mp3(","")
phrase = phrase.replace(".mp3)%", ".mp3")
phrase = phrase.replace (" ", "%20")
phrase = phrase.replace ("+", "%2B")
phrase = phrase.replace ("-", "%2D")
} else {
phrase = "Invalid M P 3 URL found in M P 3 token"
}
return phrase
}
if (phrase.toLowerCase().contains(" percent ")) { phrase = phrase.replace(" percent ","%") }
if (phrase.toLowerCase().contains("%groupname%")) {
phrase = phrase.toLowerCase().replace('%groupname%', appname)
}
if (phrase.toLowerCase().contains("%devicename%")) {
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.displayName) //User given name of the device triggering the event
}
catch (ex) {
LOGDEBUG("evt.displayName failed; trying evt.device.displayName")
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.device.displayName) //User given name of the device triggering the event
}
catch (ex2) {
LOGDEBUG("evt.device.displayName filed; trying evt.device.name")
try {
phrase = phrase.toLowerCase().replace('%devicename%', evt.device.name) //SmartThings name for the device triggering the event
}
catch (ex3) {
LOGDEBUG("evt.device.name filed; Giving up")
phrase = phrase.toLowerCase().replace('%devicename%', "Device Name Unknown")
}
}
}
}
if (phrase.toLowerCase().contains("%devicetype%")) {phrase = phrase.toLowerCase().replace('%devicetype%', evt.name)} //Device type: motion, switch, etc...
if (phrase.toLowerCase().contains("%devicechange%")) {phrase = phrase.toLowerCase().replace('%devicechange%', evt.value)} //State change that occurred: on/off, active/inactive, etc...
if (phrase.toLowerCase().contains("%description%")) {phrase = phrase.toLowerCase().replace('%description%', evt.descriptionText)} //Description of the event which occurred via device-specific text`
if (phrase.toLowerCase().contains("%locationname%")) {phrase = phrase.toLowerCase().replace('%locationname%', location.name)}
if (phrase.toLowerCase().contains("%lastmode%")) {phrase = phrase.toLowerCase().replace('%lastmode%', state.lastMode)}
if (phrase.toLowerCase().contains("%mode%")) {phrase = phrase.toLowerCase().replace('%mode%', location.mode)}
if (phrase.toLowerCase().contains("%time%")) {
phrase = phrase.toLowerCase().replace('%time%', getTimeFromCalendar(false,true))
if ((phrase.toLowerCase().contains("00:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('00:', "12:")}
if ((phrase.toLowerCase().contains("24:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('24:', "12:")}
if ((phrase.toLowerCase().contains("0:")) && (!phrase.toLowerCase().contains("10:")) && (phrase.toLowerCase().contains("am"))) {phrase = phrase.toLowerCase().replace('0:', "12:")}
}
if (phrase.toLowerCase().contains("%weathercurrent%")) {phrase = phrase.toLowerCase().replace('%weathercurrent%', getWeather("current", zipCode)); phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertoday%")) {phrase = phrase.toLowerCase().replace('%weathertoday%', getWeather("today", zipCode)); phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertonight%")) {phrase = phrase.toLowerCase().replace('%weathertonight%', getWeather("tonight", zipCode));phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathertomorrow%")) {phrase = phrase.toLowerCase().replace('%weathertomorrow%', getWeather("tomorrow", zipCode));phrase = adjustWeatherPhrase(phrase)}
if (phrase.toLowerCase().contains("%weathercurrent(")) {
if (phrase.toLowerCase().contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathercurrent(") + 16)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathercurrent(${zipCode.toLowerCase()})%", getWeather("current", zipCode.toLowerCase()))
phrase = adjustWeatherPhrase(phrase.toLowerCase())
} else {
phrase = "Custom Zip Code format error in request for current weather"
}
}
if (phrase.toLowerCase().contains("%weathertoday(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertoday(") + 14)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertoday(${zipCode.toLowerCase()})%", getWeather("today", zipCode.toLowerCase()))
phrase = adjustWeatherPhrase(phrase.toLowerCase())
} else {
phrase = "Custom Zip Code format error in request for today's weather"
}
}
if (phrase.toLowerCase().contains("%weathertonight(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertonight(") + 16)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertonight(${zipCode.toLowerCase()})%", getWeather("tonight", zipCode.toLowerCase()))
phrase = adjustWeatherPhrase(phrase)
} else {
phrase = "Custom Zip Code format error in request for tonight's weather"
}
}
if (phrase.toLowerCase().contains("%weathertomorrow(")) {
if (phrase.contains(")%")) {
def phraseZipStart = (phrase.toLowerCase().indexOf("%weathertomorrow(") + 17)
def phraseZipEnd = (phrase.toLowerCase().indexOf(")%"))
zipCode = phrase.substring(phraseZipStart, phraseZipEnd)
LOGDEBUG("Custom zipCode: ${zipCode}")
phrase = phrase.toLowerCase().replace("%weathertomorrow(${zipCode.toLowerCase()})%", getWeather("tomorrow", zipCode.toLowerCase()))
phrase = adjustWeatherPhrase(phrase)
} else {
phrase = "Custom ZipCode format error in request for tomorrow's weather"
}
}
if (state.speechDeviceType == "capability.speechSynthesis"){
//ST TTS Engine pronunces "Dash", so only convert for speechSynthesis devices (LANnouncer)
if (phrase.contains(",")) { phrase = phrase.replace(","," - ") }
//if (phrase.contains(".")) { phrase = phrase.replace("."," - ") }
}
if (phrase.toLowerCase().contains("%shmstatus%")) {
def shmstatus = location.currentState("alarmSystemStatus")?.value
LOGDEBUG("SHMSTATUS=${shmstatus}")
def shmmessage = [off : "Disarmed", away: "Armed, away", home: "Armed, home"][shmstatus] ?: shmstatus
LOGDEBUG("SHMMESSAGE=${shmmessage}")
phrase = phrase.replace("%shmstatus%", shmmessage)
}
if (phrase.contains('"')) { phrase = phrase.replace('"',"") }
if (phrase.contains("'")) { phrase = phrase.replace("'","") }
if (phrase.contains("10S")) { phrase = phrase.replace("10S","tens") }
if (phrase.contains("20S")) { phrase = phrase.replace("20S","twenties") }
if (phrase.contains("30S")) { phrase = phrase.replace("30S","thirties") }
if (phrase.contains("40S")) { phrase = phrase.replace("40S","fourties") }
if (phrase.contains("50S")) { phrase = phrase.replace("50S","fifties") }
if (phrase.contains("60S")) { phrase = phrase.replace("60S","sixties") }
if (phrase.contains("70S")) { phrase = phrase.replace("70S","seventies") }
if (phrase.contains("80S")) { phrase = phrase.replace("80S","eighties") }
if (phrase.contains("90S")) { phrase = phrase.replace("90S","nineties") }
if (phrase.contains("100S")) { phrase = phrase.replace("100S","one hundreds") }
if (phrase.contains("%askalexa%")) {
phrase=phrase.replace("%askalexa%","")
if (!(phrase == "") && (!(phrase == null))){
LOGTRACE("Sending to AskAlexa: ${phrase}.")
sendLocationEvent(name: "AskAlexaMsgQueue", value: "BigTalker", isStateChange: true, descriptionText: phrase)
}else{
LOGERROR("Phrase only contained %askalexa%. Nothing to say/send.")
}
}
if (phrase.contains("%date%")) {
phrase=phrase.replace("%date%",(new Date().format( 'MMMM dd' )))
}
if (phrase.contains("%day%")) {
phrase=phrase.replace("%day%",(new Date().format('EEEE',location.timeZone)))
}
if (phrase.contains("%")) { phrase = phrase.replace("%"," percent ") }
return phrase
} catch(ex) {
LOGTRACE("There was a problem processing your desired phrase: ${phrase}. ${ex}")
phrase = "Sorry, there was a problem processing your desired BigTalker phrase token."
return phrase
}
}
def addPersonalityToPhrase(phrase, evt){
......@@ -2275,6 +2281,7 @@ def adjustWeatherPhrase(phraseIn){
phraseOut = phraseOut.replace(" WSW ", " West Southwest ")
phraseOut = phraseOut.replace(" MPH", " Miles Per Hour")
phraseOut = phraseOut.replace(" MM)", " Milimeters ")
LOGDEBUG ("Adjust Weather: In=${phraseIn} Out=${phraseOut}")
return phraseOut
}
......@@ -2295,7 +2302,7 @@ def Talk(appname, phrase, customSpeechDevice, volume, resume, personality, voice
def smartAppSpeechDevice = false
def playAudioFile = false
def spoke = false
LOGDEBUG ("TALK(app=${appname},customdevice=${customSpeechDevice},volume=${volume},resume=${resume},personality=${personality},myDelay=${myDelay}, voice=${myVoice},evt=${evt},phrase=${phrase})")
LOGDEBUG ("TALK(app=${appname},customdevice=${customSpeechDevice},volume=${volume},resume=${resume},personality=${personality},myDelay=${myDelay},voice=${myVoice},evt=${evt},phrase=${phrase})")
if ((phrase?.toLowerCase())?.contains("%askalexa%")) {smartAppSpeechDevice = true}
if (!(phrase == null) && !(phrase == "")) {
phrase = processPhraseVariables(appname, phrase, evt)
......@@ -2531,7 +2538,7 @@ def Talk(appname, phrase, customSpeechDevice, volume, resume, personality, voice
}// if (state.speechDeviceType=="capability.musicPlayer")
if ((state.speechDeviceType == "capability.speechSynthesis") && (!( phrase==null ) && !(phrase==""))){
//capability.speechSynthesis is in use
if (!(settings.speechDeviceDefault == null) || !(customSpeechDevice == null)) {
if (!(settings?.speechDeviceDefault == null) || !(customSpeechDevice == null)) {
LOGTRACE("TALK(${appname}.${evt.name}) |sS| >> ${phrase}")
if (!(customSpeechDevice == null)) {
currentSpeechDevices = customSpeechDevice
......@@ -2570,6 +2577,7 @@ def Talk(appname, phrase, customSpeechDevice, volume, resume, personality, voice
LOGTRACE("TALK(${appname}.${evt.name}) |sA| Sent to another smartApp.")
}
}
phrase = ""
}//Talk()
def timeAllowed(devicetype,index){
......@@ -3544,5 +3552,5 @@ def LOGERROR(txt){
}
def setAppVersion(){
state.appversion = "P2.0.1"
state.appversion = "P2.0.2"
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment