Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 87 additions & 4 deletions smartapps/bangali/rooms-child-app.src/rooms-child-app.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -1508,7 +1508,14 @@ private pageAsleepSettings() {
private pageLockedSettings() {
dynamicPage(name: "pageLockedSettings", title: "", install: false, uninstall: false) {
section("Switch configuration for LOCKED state:", hideable:false) {
input "lockedSwitch", "capability.switch", title: "Which switch turns ON?", required:false, multiple: false
input "lockedSwitch", "capability.switch", title: "This switch will Lock this room?", required:false, multiple: false, submitOnChange: true
if (lockedSwitch) {
input "lockedSwitchCmd", "enum", title: "...when it is turned...", options: [[on:"On"],[off:"Off"]], submitOnChange: true, required:false
}
input "lockedContact", "capability.contactSensor", title: "This contact will Lock this room?", required:false, multiple: false, submitOnChange: true
if (lockedContact) {
input "lockedContactCmd", "enum", title: "...when it is...", options: [[open:"Open"],[closed:"Closed"]], submitOnChange: true, required:false
}
input "lockedTurnOff", "bool", title: "Turn off switches when room changes to LOCKED?", required: false, multiple: false, defaultValue: false
input "unLocked", "number", title: "Timeout LOCKED state after how many hours?", required: false, multiple: false, defaultValue: null, range: "1..99"
}
Expand Down Expand Up @@ -1829,10 +1836,32 @@ def updateRoom(adjMotionSensors) {
state.nightSetCT = (nightSetCT ? nightSetCT as Integer : null)
state.noAsleep = ((noAsleep && noAsleep >= 1) ? (noAsleep * 60 * 60) : null)
ifDebug("updateRoom 4")
if (lockedSwitch) {

if (lockedContact) {
if (lockedContactCmd == "open") {
subscribe(lockedContact, "contact.open", lockedContactOpenEventHandler)
log.info "locked contact has opened with the command Open"
subscribe(lockedContact, "contact.closed", lockedContactClosedEventHandler)
log.info "locked contact has closed with the command Open"
}
if (lockedContactCmd == "closed") {
subscribe(lockedContact, "contact.open", lockedContactClosedEventHandler)
log.info "locked contact has opened with the command Closed"
subscribe(lockedContact, "contact.closed", lockedContactOpenEventHandler)
log.info "locked contact has closed with the command Closed"
}
}

if (lockedSwitch) {
if (lockedSwitchCmd == "on") {
subscribe(lockedSwitch, "switch.on", lockedSwitchOnEventHandler)
subscribe(lockedSwitch, "switch.off", lockedSwitchOffEventHandler)
}
subscribe(lockedSwitch, "switch.off", lockedSwitchOffEventHandler)
}
if (lockedSwitchCmd == "off") {
subscribe(lockedSwitch, "switch.off", lockedSwitchOnEventHandler)
subscribe(lockedSwitch, "switch.on", lockedSwitchOffEventHandler)
}
}
if (windowShades) subscribe(windowShades, "windowShade", windowShadeEventHandler);
if (roomFanSwitch) {
subscribe(roomFanSwitch, "switch", updateFanIndP)
Expand Down Expand Up @@ -1988,6 +2017,21 @@ private isAnyLSwitchOn() {
return (lockedSwitch ? (lockedSwitch.currentSwitch.contains('on') ? 1 : 0) : -1)
}

private isAnyLSwitchOff() {
ifDebug("isAnyLSwitchOff")
return (lockedSwitch ? (lockedSwitch.currentSwitch.contains('off') ? 1 : 0) : -1)
}

private isAnyLContactOpen() {
ifDebug("isAnyLContactOpen")
return (lockedSwitch ? (lockedSwitch.currentSwitch.contains('on') ? 1 : 0) : -1)
}

private isAnyLContactClosed() {
ifDebug("isAnyLContactClosed")
return (lockedSwitch ? (lockedSwitch.currentSwitch.contains('off') ? 1 : 0) : -1)
}

def updateRulesToState() {
ifDebug("updateRulesToState")
state.timeCheck = false
Expand Down Expand Up @@ -2670,21 +2714,60 @@ def asleepSwitchOffEventHandler(evt) {
}

def lockedSwitchOnEventHandler(evt) {
log.info "lockedSwitchOnEventHandler has been called = On"
ifDebug("lockedSwitchOnEventHandler")
def child = getChildDevice(getRoom())
if (lockedSwitchCmd == "on") {
child.updateLSwitchInd(isAnyLSwitchOn())
}
if (lockedSwitchCmd == "off") {
child.updateLSwitchInd(isAnyLSwitchOff())
}
if (!checkPauseModesAndDoW()) return;
child.generateEvent(locked)
}

def lockedSwitchOffEventHandler(evt) {
log.info "lockedSwtichOffEventHandler has been called = Off"
ifDebug("lockedSwitchOffEventHandler")
def child = getChildDevice(getRoom())
if (lockedSwitchCmd == "on") {
child.updateLSwitchInd(isAnyLSwitchOn())
}
if (lockedSwitchCmd == "off") {
child.updateLSwitchInd(isAnyLSwitchOff())
}
if (!checkPauseModesAndDoW()) return;
if (child?.currentValue(occupancy) == locked) child.generateEvent(checking);
}

def lockedContactOpenEventHandler(evt) {
log.info "lockedContactOpenEventHandler has been called = Open"
ifDebug("lockedContactOpenEventHandler")
def child = getChildDevice(getRoom())
if (lockedContactCmd == "open") {
child.updateLContactInd(isAnyLContactOpen())
}
if (lockedContactCmd == "closed") {
child.updateLContactInd(isAnyLContactClosed())
}
if (!checkPauseModesAndDoW()) return;
child.generateEvent(locked)
}

def lockedContactClosedEventHandler(evt) {
log.info "lockedContactClosedEventHandler has been called = Closed"
ifDebug("lockedContactClosedEventHandler")
def child = getChildDevice(getRoom())
if (lockedContactCmd == "open") {
child.updateLContactInd(isAnyLContactOpen())
}
if (lockedContactCmd == "closed") {
child.updateLContactInd(isAnyLContactClosed())
}
if (!checkPauseModesAndDoW()) return;
if (child?.currentValue(occupancy) == locked) child.generateEvent(checking);
}

/*
def processCoolHeat() {
Expand Down
65 changes: 45 additions & 20 deletions smartapps/bangali/rooms-manager.src/rooms-manager.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -466,36 +466,40 @@ def pageSpeakerSettings() {
if (i != j) sendNotification("Count of presense sensors and names do not match!", [method: "push"]);
dynamicPage(name: "pageSpeakerSettings", title: "Speaker Settings", install: true, uninstall: true) {
section("Speaker selection:") {
input "musicPlayers", "capability.musicPlayer", title: "Which Media Players?", required: false, multiple: true, submitOnChange: true
if (musicPlayers) {
input "volume", "number", title: "Temporarily change volume", description: "0-100% (default value = 30%)", required: false
}
input "speakerDevices", "capability.audioNotification", title: "Which speakers?", required: false, multiple: true, submitOnChange: true
input "speechDevices", "capability.speechSynthesis", title: "Which speech devices?\nlike lannounceer.", required: false, multiple: true, submitOnChange: true
if (speakerDevices || speechDevices)
if (speakerDevices || speechDevices || musicPlayers)
input "speakerVolume", "number", title: "Speaker volume?", required: false, multiple: false, defaultValue: 33, range: "1..100"
else
paragraph "Speaker volume?\nselect speaker(s) to set."
}
section("Annouce only between hours:") {
if ((speakerDevices || speechDevices)) {
input "startHH", "number", title: "Annouce from hour?", required: true, multiple: false, defaultValue: 7, range: "1..${endHH ? endHH : 23}", submitOnChange: true
section("Announce only between hours:") {
if ((speakerDevices || speechDevices || musicPlayers)) {
input "startHH", "number", title: "Announce from hour?", required: true, multiple: false, defaultValue: 7, range: "1..${endHH ? endHH : 23}", submitOnChange: true
input "endHH", "number", title: "Announce to hour?", required: true, multiple: false, defaultValue: 7, range: "${startHH ? startHH : 23}..23", submitOnChange: true
}
else {
paragraph "Announce from hour?\nselect either presence or time annoucement to set"
paragraph "Announce to hour?\nselect either presence or time annoucement to set"
paragraph "Announce from hour?\nselect either presence or time announcement to set"
paragraph "Announce to hour?\nselect either presence or time announcement to set"
}
}
section("Time announcement:") {
if (speakerDevices || speechDevices)
if (speakerDevices || speechDevices || musicPlayers)
input "timeAnnounce", "enum", title: "Announce time?", required: false, multiple: false, defaultValue: 4,
options: [[1:"Every 15 minutes"], [2:"Every 30 minutes"], [3:"Every hour"], [4:"No"]], submitOnChange: true
else
paragraph "Announce time?\nselect speaker devices to set."
}
section("Arrival and departure annoucement:") {
if (speakerDevices || speechDevices)
section("Arrival and departure announcement:") {
if (speakerDevices || speechDevices || musicPlayers)
input "speakerAnnounce", "bool", title: "Announce when presence sensors arrive or depart?", required: false, multiple: false, defaultValue: false, submitOnChange: true
else
paragraph "Announce when presence sensors arrive or depart?\nselect speaker(s) to set."
if ((speakerDevices || speechDevices) && speakerAnnounce) {
if ((speakerDevices || speechDevices || musicPlayers) && speakerAnnounce) {
input "presenceSensors", "capability.presenceSensor", title: "Which presence snesors?", required: true, multiple: true
input "presenceNames", "text", title: "Comma delmited names? (in sequence of presence sensors)", required: true, multiple: false, submitOnChange: true
input "contactSensors", "capability.contactSensor", title: "Which contact sensors? (welcome home greeting is played after this contact sensor closes.)",
Expand All @@ -522,7 +526,7 @@ def pageSpeakerSettings() {
}
}
section("Battery status:") {
if (speakerDevices || speechDevices)
if (speakerDevices || speechDevices || musicPlayers)
input "batteryTime", "time", title: "Annouce battery status when?", required: false, multiple: false, submitOnChange: true
else
paragraph "Annouce battery status when?\nselect either speakers or speech device to set"
Expand Down Expand Up @@ -589,7 +593,7 @@ private announceSetup() {
state.welcomeHome1 = [:]
state.welcomeHome2 = [:]
state.welcomeHomeCloser = [:]
str = welcomeHome.split(',')
str = welcomeHome.split('/')
i = 0
str.each {
def str2 = it.split('&')
Expand All @@ -598,7 +602,7 @@ private announceSetup() {
i = i + 1
}
if (welcomeHomeCloser) {
str = welcomeHomeCloser.split(',')
str = welcomeHomeCloser.split('/')
i = 0
str.each {
state.welcomeHomeCloser[i] = it
Expand All @@ -608,7 +612,7 @@ private announceSetup() {
state.leftHome1 = [:]
state.leftHome2 = [:]
state.leftHomeCloser = [:]
str = leftHome.split(',')
str = leftHome.split('/')
i = 0
str.each {
def str2 = it.split('&')
Expand All @@ -617,7 +621,7 @@ private announceSetup() {
i = i + 1
}
if (leftHomeCloser) {
str = leftHomeCloser.split(',')
str = leftHomeCloser.split('/')
i = 0
str.each {
state.leftHomeCloser[i] = it
Expand Down Expand Up @@ -672,26 +676,47 @@ def contactClosedEventHandler(evt = null) {
// ifDebug("k: $k ${state.welcomeHome1[(k)]} | l: $l ${state.leftHome1[(l)]}")
def persons = (evt ? state.welcomeHome1[(k)] : state.leftHome1[(l)]) + ' '
str.each {
persons = persons + (j != 1 ? (j == i ? ' and ' : ', ') : '') + it
persons = persons + (j != 1 ? (j == i ? ' and ' : '/ ') : '') + it
j = j + 1
}
persons = persons + ' ' + (evt ? state.welcomeHome2[(k)] : state.leftHome2[(l)]) +
' ' + (evt ? (welcomeHomeCloser ? state.welcomeHomeCloser[(k2)] : '') :
(leftHomeCloser ? state.leftHomeCloser[(l2)] : '')) + '.'
// ifDebug("k: $k ${state.welcomeHome2[(k)]} | l: $l ${state.leftHome2[(l)]}")
ifDebug("message: $persons")
speakIt(persons)
speakIt(str, persons)
if (evt) state.whoCameHome.personsIn = [];
else state.whoCameHome.personsOut = [];
}

private speakIt(string) {
private speakIt(str, persons) {
def nowDate = new Date(now())
def intCurrentHH = nowDate.format("HH", location.timeZone) as Integer
def intCurrentMM = nowDate.format("mm", location.timeZone) as Integer
if (intCurrentHH >= startHH && (intCurrentHH < endHH || (intCurrentHH == endHH && intCurrentMM == 0))) {
if (speakerDevices) speakerDevices.playTextAndResume(persons, speakerVolume);
if (speechDevices) speechDevices.speak(persons);
if (speakerDevices) speakerDevices.playTextAndResume(str, speakerVolume);
if (speechDevices) speechDevices.speak(str);
// if (musicPlayers) musicPlayers.speak(persons);
if (persons) {
state.sound = textToSpeech(persons instanceof List ? persons[9] : persons)
}
else {
state.sound = textToSpeech("You selected the custom message option but did not enter a message in the $app.label Smart App")
log.debug "You selected the custom message option but did not enter a message"
}
if (musicPlayers) {
def currVolLevel = musicPlayers.latestValue("level")
def currMuteOn = musicPlayers.latestValue("mute").contains("muted")
log.debug "currVolSwitchOff = ${currVolSwitchOff}, vol level = ${currVolLevel}, currMuteOn = ${currMuteOn} "
if (currMuteOn) {
log.warn "speaker is on mute, sending unmute command"
musicPlayers.unmute()
}
def sVolume = settings.volume ?: 30
musicPlayers?.playTrackAndResume(state.sound.uri, state.sound.duration, sVolume)
log.info "Playing message on the music player '${musicPlayers}' at volume '${volume}'"
};

}
}

Expand Down