-
Notifications
You must be signed in to change notification settings - Fork 47
Manage Google Nest speaker groups
Nate G edited this page Nov 3, 2020
·
9 revisions
This is an app that was created for managing Groups of Google Nest speakers.
Some of its features:
- When playing music on a group, change the volume to
musicVolume
unless the volume has been overridden--in which case, use that. - Switch between a "speaking" volume when not playing music and restore the volume to your prior music volume.
- Adjust the volume based on a day mode and night mode (e.g. once it's sunset, make Assistant talk quieter than during the day).
Hope this helps someone get more familiar with this awesome tool!
pyscript:
apps:
speaker_group_manager:
- group: media_player.downstairs_group
speakers: # the speakers in the group
media_player.living_room_speaker:
volumeOverride: None # this is here so we can write a little less code in the script ;)
musicVolume: 0.25 # default volume for media
speakingVolume: 0.50 # default volume for the Assistant
media_player.kitchen_speaker:
volumeOverride: None
musicVolume: 0.30
speakingVolume: 0.50
registered_triggers = []
def loadApp(app_name, factory):
if 'apps' not in pyscript.config:
return
if app_name not in pyscript.config['apps']:
return
for app in pyscript.config['apps'][app_name]:
factory(app)
@time_trigger('startup')
def speakerGroupStartup():
loadApp('speaker_group_manager', buildSpeakerGroup)
def buildSpeakerGroup(config):
global registered_triggers
### Day/Night mode variables ###
startNightMode = '22:30:00'
dayMode = f'range(sunrise, {startNightMode})'
nightMode = f'range({startNightMode}, sunrise)'
### config variables ###
group = config.get('group')
speakers = config.get('speakers')
### conditionals used in the @state_triggers ##
useMusicVol = f'{group} == "playing" and {group}.old != "playing"'
useSpeakingVol = f'{group} != "playing" and {group}.old == "playing"'
### Day mode versions ###
@time_active(dayMode)
@state_trigger(useMusicVol)
def restoreGroupMusicVolume():
setMusicVolume()
@time_active(dayMode)
@state_trigger(useSpeakingVol)
def restoreGroupSpeakingVolume():
# Spotify changes to 'paused' between songs; wait to alter volume
task.sleep(0.65)
setSpeakingVolume()
### Night mode versions ###
@time_active(nightMode)
@state_trigger(useMusicVol)
def restoreGroupNightMusicVolume():
setMusicVolume(nightMode=True)
@time_active(nightMode)
@state_trigger(useSpeakingVol)
def restoreGroupNightSpeakingVolume():
# Spotify changes to 'paused' between songs; wait to alter volume
task.sleep(0.65)
setSpeakingVolume(nightMode=True)
### Time triggers ###
# Reset group overrides to defaults at sunrise
@time_trigger('once(sunrise)')
def resetGroupOverrides():
global speakers
speakers = config.get('speakers')
# Change group speaker volumes to night mode
@state_active(f'{group} != "playing"')
@time_trigger(f'once({startNightMode})')
def setGroupNightSpeakingVolume():
setSpeakingVolume(nightMode=True)
### Pièce de résistance ###
# Sets volume overrides for group speakers
@task_unique(f'monitor_{group}_volume')
@state_active(f'{group} == "playing"')
@state_trigger(f'{group}.volume_level')
def monitorGroupVolume():
task.sleep(0.75) # just hold on
for speaker, volumes in speakers.items():
volume = state.get(f'{speaker}.volume_level')
volumes['volumeOverride'] = round(volume, 2)
### Helper functions ###
def setMusicVolume(nightMode=False):
for speaker, volumes in speakers.items():
volOverride = volumes['volumeOverride']
musicVol = volumes['musicVolume'] if (
volOverride == 'None' or volOverride is None) else volOverride
volume = musicVol if not nightMode else musicVol - 0.07
media_player.volume_set(entity_id=speaker, volume_level=volume)
def setSpeakingVolume(nightMode=False):
for speaker, volumes in speakers.items():
speakingVol = volumes['speakingVolume']
volume = speakingVol if not nightMode else speakingVol - 0.15 # -15 speaking volume when in night mode: arbitrary
media_player.volume_set(entity_id=speaker, volume_level=volume)
# register to global scope
registered_triggers.append([
monitorGroupVolume,
restoreGroupMusicVolume,
restoreGroupSpeakingVolume,
restoreGroupNightMusicVolume,
restoreGroupNightSpeakingVolume,
resetGroupOverrides,
setGroupNightSpeakingVolume
])