[RELEASE] Follow Me - Speaker control with priority messaging, volume controls, voices and sound files!

Updated and the same.

arrive



Follow me

Update suggestion....would there be a way to make the "sound files" global rather than local to each child instance? I have a lot of GHs and when I change a file I have to change it on all of them.

  • I also just moved my sound files into the new "local" storage and all is working well.
3 Likes

I could move them to the parent app, then they would be available in any child app.

Added to the list!

1 Like

Sweet, thanks! I don't want my request to override others....if maybe they are using different sound files for different speakers. I just happen to generally want the same file to play before certain announcements.

That's the beauty of writing my own code... I get to decide, lol This one I like! :wink:

3 Likes

Is it possible to change the colors that are used?

I have been playing with animated gif backgrounds on my dashboards and of course the one the misses likes does not play well with your red messages.

Food for thought - If future version could have color picker that would be sweet, and more of them. I like them as categories more then "priority". just thoughts thanks!

1 Like

New version on GitHub. Be sure to update all 3 parts.

Push upgrades, Added Priority Speaker features

Added to the list

2 Likes

New version on GitHub...

Parent and Child apps:
07/07/20 - Sounds Setup now in Parent App

Be sure to go into the parent app and setup your sounds!

3 Likes

New version on Github...

Driver:
2.2.3 - 07/10/20 - Added user selectable Priority colors

Be sure to go into the device and select your colors and then hit 'save'

@TechMedX

3 Likes

Has anybody with multiple hubs tried to use Hubconnect to create a virtual "What Did I Say" device? I'm trying, but haven't got it working quite yet.

Use-case: I've put the WDIS tile on my tablet dashboards around the house (very high WAF). But I'd like the tile to capture announcements from all 3 hubs in home that have the Sonos connect app is installed. My thinking is that if I put a custom Hubconnect driver on the 2 of the hubs that shadows the actual WDIS device on my main hub (and I include the Follow Me device in announcements on the other hubs), then the tile will "catch" all announcements, independent of the hub from which they originate.

Would love any input or ideas.....or better ways to solve it?

All you need to do is 'share' the Follow Me device. Then select this device like you normally would on the other hubs to capture speech.

Ah, didn’t realize a plain SpeechSynthesis driver would work. I was trying to over-complicate with a custom driver. Now it’s so easy — damn, Bryan, you ruined my fun. :wink:

1 Like

I did. Sorry, don't have github. BTW, no support. usage at your own risk.

Code

/*

  • Copyright 2019 Steve White & Alan Eisen
  • Licensed under the Apache License, Version 2.0 (the "License"); you may not
  • use this file except in compliance with the License. You may obtain a copy
  • of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  • WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  • License for the specific language governing permissions and limitations
  • under the License.

*/
metadata
{
definition(name: "HubConnect zFollow Me Driver", namespace: "shackrat", author: "Alan Eisen")
{
capability "Initialize"
capability "Actuator"
capability "Speech Synthesis"
capability "Music Player"
capability "Notification"
capability "Refresh"

    command "playAnnouncement", 	[[name:"Text*", type:"STRING", description:"Text to play"], 
									 [name:"Volume Level", type:"NUMBER", description: "Volume level (0-100)"], 
									 [name:"Restore Volume Level",type:"NUMBER", description: "Restore volume (0-100)"]]
    command "playAnnouncement", 	[[name:"Text*", type: "STRING", description:"Text to play"], 
									 [name:"Title*", type:"STRING", description: "Title to display on Echo Show devices"], 
									 [name:"Volume Level", type:"NUMBER", description: "Volume level (0-100)"], 
									 [name:"Restore Volume Level",type:"NUMBER", description: "Restore volume (0-100)"]]
    command "playAnnouncementAll",	[[name:"Text*", type:"STRING", description:"Text to play"], 
									 [name:"Title*", type:"STRING", description: "Title to display on Echo Show devices"]]
	command "playTextAndRestore", 	[[name:"Text*", type:"STRING", description:"Text to play"]]
    command "playTrackAndRestore", 	[[name:"Track URI*", type:"STRING", description:"URI/URL of track to play"]]
    command "setVolume", 			[[name:"Volume Level*", type:"NUMBER", description: "Volume level (0-100)"]]
	command "setVolumeSpeakAndRestore", 
									[[name:"Volume Level*", type:"NUMBER", description:"Volume level (0-100)"],
									 [name:"Text*", type:"STRING", description:"Text to speak"],
									 [name:"Restore Volume Level",type:"NUMBER", description: "Restore volume (0-100)"]]										 
    command "setVolumeAndSpeak", 	[[name:"Volume Level*", type:"NUMBER", description:"Volume level (0-100)"], 
									 [name:"Text*", type:"STRING", description:"Text to speak"]]
	command "sendFollowMeSpeaker", 	[[name:"Follow Me Request*", type:"JSON_OBJECT", description:"JSON-encoded command string (see source)"]]
    
    command "sendQueue", ["string", "string", "string"]
    command "updateVersion"
    //command "deviceNotification", ["string"]

    attribute "bpt-whatDidISay", "string"
    attribute "whatDidISayCount", "string"
    attribute "latestMessage", "string"
    attribute "latestMessageDateTime", "string"
    attribute "bpt-speakerStatus1", "string"
    attribute "bpt-speakerStatus2", "string"
    attribute "bpt-speakerStatus3", "string"

    attribute "bpt-queue1", "string"
    attribute "bpt-queue2", "string"
    attribute "bpt-queue3", "string"
    attribute "bpt-queue4", "string"
    attribute "bpt-queue5", "string"
}

}

def setVersion(){
appName = "FollowMeDriver"
version = "v2.1.1"
dwInfo = "${appName}:${version}"
sendEvent(name: "dwDriverInfo", value: dwInfo, displayed: true)
}

def updateVersion() {
log.info "In updateVersion"
setVersion()
}

def deviceNotification(value)
{
parent.sendDeviceEvent(device.deviceNetworkId, "deviceNotification", value)
}

def playAnnouncement(String message, String title, volume=null, restoreVolume=null) {
parent.sendDeviceEvent(device.deviceNetworkId, "playAnnouncement", message, title, volume, restoreVolume)
}

def playAnnouncement(String message, volume=null, restoreVolume=null) {
parent.sendDeviceEvent(device.deviceNetworkId, "playAnnouncement", message, volume, restoreVolume)
}

def playAnnouncementAll(String message, title=null) {
parent.sendDeviceEvent(device.deviceNetworkId, "playAnnouncementAll", message, title)
}

def playText(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "playText", message)
}

def playTextAndRestore(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "playTextAndRestore", message)
}

def playTrack(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "playTrack", message)
}

def playTrackAndRestore(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "playTrackAndRestore", message)
}

def restoreTrack(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "restoreTrack", message)
}

def resumeTrack(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "resumeTrack", message)
}

def setTrack(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "setTrack", message)
}

def setVolume(volume) {
parent.sendDeviceEvent(device.deviceNetworkId, "setVolume", volume)
}

def setVolumeAndSpeak(volume, message) {
parent.sendDeviceEvent(device.deviceNetworkId, "setVolumeAndSpeak", volume, message)
}

def speak(message) {
parent.sendDeviceEvent(device.deviceNetworkId, "speak", message)
}

def sendFollowMeSpeaker(status) {
parent.sendDeviceEvent(device.deviceNetworkId, "sendFollowMeSpeaker", status)
}

def sendQueue(ps, theMessage, duration) {
}

def installed()
{
initialize()
}

/*
updated
*/
def updated()
{
initialize()
}

/*
initialize
*/
def initialize()
{
refresh()
}

/*
refresh
*/
def refresh()
{
// The server will update status
parent.sendDeviceEvent(device.deviceNetworkId, "refresh")
}

/*
sync
*/
def sync()
{
// The server will respond with updated status and details
parent.syncDevice(device.deviceNetworkId, "omnipurpose")
sendEvent([name: "version", value: "v${driverVersion.major}.${driverVersion.minor}.${driverVersion.build}"])
}

1 Like

I am getting 10-15 second delay on all the devices selected in one child app, is that normal?
Side question if we want to use your other apps like the life360 tracker do we have to use follow me child devices or can we just use the devices directly?

No, everything should happen within a second or two.

All speech, from any of my apps, require Follow Me to work.

Thanks

Wonder if anybody can help me configure Follow Me for the following use case. Been playing with it but just can't seem to get it right.

I want to use it ONLY to populate the What Did I Say (WDIS) tile on my dashboard, but not to send send speak commands to any speech/TTS device. In my many apps and rules, when I want to send a Speak command, I send the text directly to my Sonos and/or other TTS devices. Then I always include the WDIS proxy device as well so that every notification gets onto the tile.

This has resulted in some doublespeak lol. So I removed my Sonos device from the Follow Me configuration, but I'm still not sure I have it right. My config is below is that helps any.

Screen Shot of App Configuration




P.S. I understand that FM is required for other BPTWorld apps that speak, but I planned to meet that need through a separate FM child app. Unless this is flawed logic for some reason I'm not appreciating.

Should just have to create a virtual device that uses the follow me driver. Then output to that device and there shouldn’t be any speech. The app isn’t necessary In your case.

2 Likes

Exactly.

Bryan, is there any way to delete the FM app without deleting the device?

Nope, they go hand and hand. If the app created it, then the app will delete it. This is so you don't end up with a bunch of orphaned devices