Package: home-assistant-streamdeck-yaml
Home Assistant on Stream DeckConfigured via YAML (with templates) and running on Linux, MacOS, and WindowsIntroducing: Home Assistant on Stream Deck!If you use Home Assistant and want a seamless way to control it, you've come to the right place.
With this Python script, you can control your Home Assistant instance via a Stream Deck, making it easier than ever to manage your smart home devices and scenes.Key Features:✅ Easy to use🛠️ Highly customizable🧩Home Assistant Add-on support🐧 Supports Linux, MacOS, and Windows📁 YAML configuration🏠 Runs from same machine as Home Assistant🚀 Template support for advanced customization💤 Automatically sync state ofentity_idto turn display on/off[ToC]Why choose our solution over others?You might have seen a similar project (cgiesche/streamdeck-homeassistant) on Github before [†].
However, our solution is more versatile and allows you to connect a Stream Deck to the same Linux machine where Home Assistant is running.
The native Stream Deck software doesn't support Linux, but we've got you covered with the help of thepython-elgato-streamdecklibrary.
If you are looking for some inspiration, check out the>20 Button Configurations ideassection below.Check out the video below to see it in action!https://user-images.githubusercontent.com/6897215/226788119-6c198ea6-2950-4f95-95dc-346c9e5b5cee.mp4:books: Table of Contents🌟 Share Your Success:rocket: Getting Started:house_with_garden: Installation as Home Assistant Add-on:whale: Installation with Docker:computer: Installation without Docker:penguin: Linux:apple: MacOS:desktop_computer: Windows:gear: Configuration:page_facing_up:configuration.yaml:link: Using!includefor Modular Configuration:clipboard: Config YAML configuration:bookmark_tabs: Page YAML configuration:white_square_button: Button YAML configuration:bulb: More than 30 Button Configurations ideas🌟 Share Your SuccessI love hearing from users!
If you're using Home Assistant StreamDeck YAML in your projects, please consider opening an issue on theGitHub repositoryto let me know.
Your feedback and success stories not only help to improve the library but also inspire others in the community.
By sharing your experience, you can contribute to the growth and development of Home Assistant StreamDeck YAML.
I truly appreciate your support!:rocket: Getting StartedFollow the steps below to get up and running with Home Assistant on Stream Deck.:house_with_garden: Installation as Home Assistant Add-onClick to expand.In your Home Assistant instance, navigate toSupervisor>Add-on Store.Click the menu icon (three vertical dots) in the top right corner and selectRepositories.Add the following repository URL:https://github.com/basnijholt/home-assistant-streamdeck-yaml-addon.The add-on should now appear in theAdd-on Store. Click on "Home Assistant Stream Deck YAML" and then click "Install".After the installation is complete, configure the add-on using either the.envfile or the individual configuration options (see theadd-on configuration documentationfor more information).Start the add-on and check the logs for any errors.:whale: Installation with DockerClick to expand.Edit the.env.examplefile and rename it to.env.Setup aconfiguration.yamlfile (see below).Install Docker, seethispage for instructionsUse thebasnijholt/home-assistant-streamdeck-yaml:latestDocker image with:dockerrun--rm-it--privileged--env-file=$(pwd)/.env-v$(pwd)/:/app/basnijholt/home-assistant-streamdeck-yaml:latestOr use the adocker-composefile, an example of which is here:docker-compose.yamlOptionally, you can build the Docker image yourself with:dockerbuild-tbasnijholt/home-assistant-streamdeck-yaml:latest.:computer: Installation without DockerClick to expand common steps for Linux :penguin:, :apple: MacOS, and :desktop_computer: Windows.Runpip install -e .in the repo folder to install the required dependencies.Edit the.env.examplefile and rename it to.env.Setup aconfiguration.yamlfile (see below).Follow the platform-specific steps forLinux,MacOS, orWindows.:penguin: LinuxClick to expand.OnLinuxyou need to install some extra dependencies:sudoapt-getupdate
sudoapt-getinstall-ylibudev-devlibusb-1.0-0-devlibhidapi-libusb0libffi-devand add a udev rule to allow access to the Stream Deck, runsudo nano /etc/udev/rules.d/99-streamdeck.rulesand add the following line:SUBSYSTEMS=="usb",ATTRS{idVendor}=="0fd9",GROUP="users",TAG+="uaccess":apple: MacOSClick to expand.OnMacOSyou need to install some extra dependencies:brewinstallhidapicairolibffi:desktop_computer: WindowsClick to expand.ForWindows, seethispage.:gear: ConfigurationCreate aconfiguration.yamlfile in the same directory.Choose one of the two usage options:Option 1: With environment variables. (See.env.examplefor details)Option 2: With command-line arguments. (Runhome-assistant-streamdeck-yaml -hto see the available options)You're all set! 🎉Now you can enjoy controlling your smart home devices with ease.
Check out theconfiguration.yamlfile for an example configuration or feel free to share your own with the community.Happy controlling! 🏠💡🎮:page_facing_up:configuration.yamlHere's an exampleconfiguration.yamlfile to helpbrightness:100# Default brightness of the Stream Deck (0-100)state_entity_id:binary_sensor.anyone_home# Entity to sync display state withauto_reload:true# Automatically reload the configuration file when it changespages:-name:Homebuttons:-entity_id:light.bedroom_lightsservice:light.toggletext:|Bedroomlights-icon:netflix.pngservice:script.start_spotify-icon:xbox.pngservice:script.start_xbox-icon_mdi:restartservice:homeassistant.restarttext:|RestartHA# Special light control page-entity_id:light.living_room_lightsspecial_type:light-controlspecial_type_data:colormap:hsvtext:|Living roomlights# Move pages-special_type:previous-page-special_type:next-page-name:Examplebuttons:# Empty button-special_type:empty# Change pages-special_type:go-to-pagespecial_type_data:Home-special_type:go-to-pagespecial_type_data:0-special_type:previous-page-special_type:next-page-name:Otherbuttons:# Spotify playlist-service_data:id:playlist:37i9dQZF1DXaRycgyh6kXPsource:KEF LS50icon:"spotify:playlist/37i9dQZF1DXaRycgyh6kXP"# Downloads the cover artservice:script.start_spotify# (Advanced) Use templates!-entity_id:media_player.kef_ls50service:media_player.volume_setservice_data:volume_level:'{{(state_attr("media_player.kef_ls50","volume_level")-0.05)|max(0)}}'entity_id:media_player.kef_ls50text:'{{(100*state_attr("media_player.kef_ls50","volume_level"))|int}}%'text_size:16icon_mdi:"volume-minus"-special_type:go-to-pagespecial_type_data:0:link: Using!includefor Modular ConfigurationWarning: This feature does not work in the add-on version of this library at the moment.To make your configuration more organized and maintainable, you can use the!includedirective to split your configuration into multiple files, just like you can do in Home Assistant.
This is especially useful for large setups or when you want to share certain configurations across multiple setups.For example, if you have a set of common buttons that you want to use across multiple pages, you can define them in a separate YAML file and then include them in your main configuration:# includes/home.yaml-entity_id:light.bedroom_lightsservice:light.toggletext:|Bedroomlights-icon:netflix.pngservice:script.start_spotifyIn your main configuration:# configuration.yamlpages:-name:Homebuttons:!includeincludes/home.yaml...By using!include, you can keep your configuration clean and easily reusable.Warning:Any other directives that Home Assistant supports, such as!secretor!include_dir_list, are not supported by this library.:clipboard: Config YAML configurationEach YAML config can take the following configurationVariable nameDescriptionDefaultTypepagesA list ofPages in the configuration.List[Page]anonymous_pagesA list of anonymous Pages in the configuration. These pages are hidden and not displayed when cycling through the pages. They can only be reached using thespecial_type: 'go-to-page'button. Designed for single use, these pages return to the previous page upon clicking a button.List[Page]state_entity_idThe entity ID to sync display state with. For exampleinput_boolean.streamdeckorbinary_sensor.anyone_home.NoneOptional[str]brightnessThe default brightness of the Stream Deck (0-100).100intauto_reloadIf True, the configuration YAML file will automatically be reloaded when it is modified.Falsebool:bookmark_tabs: Page YAML configurationEach button can take the following configurationVariable nameDescriptionDefaultTypenameThe name of the page.strbuttonsA list of buttons on the page.List[Button]:white_square_button: Button YAML configurationEach button can take the following configurationVariable nameAllow templateDescriptionDefaultTypeentity_id✅Theentity_idthat this button controls. This entitity will be passed to theservicewhen the button is pressed. The button is re-rendered whenever the state of this entity changes.Optional[str]service✅Theservicethat will be called when the button is pressed.Optional[str]service_data✅Theservice_datathat will be passed to theservicewhen the button is pressed. If empty, theentity_idwill be passed.Optional[Mapping[str, Any]]target✅Thetargetthat will be passed to theservicewhen the button is pressed.Optional[Mapping[str, Any]]text✅The text to display on the button. If empty, no text is displayed. You might want to add\ncharacters to spread the text over several lines, or use the|character in YAML to create a multi-line string.strtext_color✅Color of the text. If empty, the color iswhite, unless anentity_idis specified, in which case the color isamberwhen the state ison, andwhitewhen it isoff.Optional[str]text_size❌Integer size of the text.12inttext_offset❌The text's position can be moved up or down from the center of the button, and this movement is measured in pixels. The value can be positive (for upward movement) or negative (for downward movement).inticon✅The icon filename to display on the button. Make the path absolute (e.g.,/config/streamdeck/my_icon.png) or relative to theassetsdirectory (e.g.,my_icon.png). If empty, a icon withicon_background_colorandtextis displayed. The icon can be a URL to an image, like'url:https://www.nijho.lt/authors/admin/avatar.jpg', or aspotify:icon, like'spotify:album/6gnYcXVaffdG0vwVM34cr8'. If the icon is aspotify:icon, the icon will be downloaded and cached. The icon can also display a partially complete ring, like a progress bar, or sensor value, likering:25for a 25% complete ring.Optional[str]icon_mdi✅The Material Design Icon to display on the button. If empty, no icon is displayed. Seehttps://mdi.bessarabov.com/for a list of icons. The SVG icon will be downloaded and cached.Optional[str]icon_background_color✅A color (in hex format, e.g., '#FF0000') for the background of the icon (if noiconis specified).#000000stricon_mdi_color✅The color of the Material Design Icon (in hex format, e.g., '#FF0000'). If empty, the color is derived fromtext_colorbut is less saturated (gray is mixed in).Optional[str]icon_gray_when_off❌When specifyingiconandentity_id, if the state isoff, the icon will be converted to grayscale.booldelay✅The delay (in seconds) before theserviceis called. This is useful if you want to wait before calling theservice. Counts down from the time the button is pressed. If while counting the button is pressed again, the timer is cancelled. Should be a float or template string that evaluates to a float.Union[float, str]special_type❌Special type of button. If no specified, the button is a normal button. Ifnext-page, the button will go to the next page. Ifprevious-page, the button will go to the previous page. Ifturn-off, the button will turn off the SteamDeck until any button is pressed. Ifempty, the button will be empty. Ifgo-to-page, the button will go to the page specified byspecial_type_data(either anintorstr(name of the page)). Iflight-control, the button will control a light, and thespecial_type_datacan be a dictionary, see its description. Ifreload, the button will reload the configuration file when pressed.Optional[Literal['next-page', 'previous-page', 'empty', 'go-to-page', 'turn-off', 'light-control', 'reload']]special_type_data✅Data for the special type of button. Ifgo-to-page, the data should be anintorstr(name of the page). Iflight-control, the data should optionally be a dictionary. The dictionary can contain the following keys: Thecolorskey and a value a list of max (n_keys_on_streamdeck - 5) hex colors. Thecolor_temp_kelvinkey and a value a list of max (n_keys_on_streamdeck - 5) color temperatures in Kelvin. Thecolormapkey and a value a colormap (https://matplotlib.org/stable/tutorials/colors/colormaps.html) can be used. This requires thematplotlibpackage to be installed. If no list ofcolorsorcolormapis specified, 10 equally spaced colors are used.Optional[Any]:bulb: More than 30 Button Configurations ideasHere are >30 interesting uses for the Stream Deck with Home Assistant (click on text to expand):1. 🎭 Activate a scene:-service:scene.turn_onservice_data:entity_id:scene.movie_nighticon_mdi:movietext:Movie Night2. 🚪 Toggle a cover (e.g., blinds or garage door):-entity_id:cover.garage_doorservice:cover.toggleicon_mdi:"{{'garage-open'ifis_state('cover.garage_door','open')else'garage-lock'}}"text:"{{'Open'ifis_state('cover.garage_door','open')else'Close'}}"3. 🤖 Start or stop the vacuum robot:-entity_id:vacuum.cleaning_robotservice:>-{% if is_state('vacuum.cleaning_robot', 'docked') %}vacuum.start{% else %}vacuum.return_to_base{% endif %}icon_mdi:robot-vacuumtext:>-{% if is_state('vacuum.cleaning_robot', 'docked') %}Start{% else %}Stop{% endif %}4. 🔇 Mute/unmute a media player:-entity_id:media_player.living_room_speakerservice:media_player.volume_muteservice_data:entity_id:media_player.living_room_speakeris_volume_muted:>-{% if is_state_attr('media_player.living_room_speaker', 'is_volume_muted', true) %}false{% else %}true{% endif %}icon_mdi:>-{% if is_state_attr('media_player.living_room_speaker', 'is_volume_muted', true) %}volume-off{% else %}volume-high{% endif %}text:>-{% if is_state_attr('media_player.living_room_speaker', 'is_volume_muted', true) %}Unmute{% else %}Mute{% endif %}5. 🌟 Control the brightness of a light (+10% on press):-entity_id:light.living_room_lightsservice:light.turn_onservice_data:entity_id:light.living_room_lightsbrightness:>-{% set current_brightness = state_attr('light.living_room_lights', 'brightness') %}{% set next_brightness = (current_brightness + 25.5) % 255 %}{{ next_brightness | min(255) | int }}text:>-{% set current_brightness = state_attr('light.living_room_lights', 'brightness') %}{% set brightness_pct = (current_brightness / 255) * 100 %}{{ brightness_pct | round }}%6. 🌀 Toggle a fan:-entity_id:fan.bedroom_fanservice:fan.toggleicon_mdi:"{{'fan'ifis_state('fan.bedroom_fan','on')else'fan-off'}}"text:|Bedroom{{ 'On' if is_state('fan.bedroom_fan', 'on') else 'Off' }}7. 🔒 Lock/unlock a door after 30 seconds:-entity_id:lock.front_doorservice:lock.toggledelay:"{{30ifis_state('lock.front_door','unlocked')else0}}"icon_mdi:"{{'door-open'ifis_state('lock.front_door','unlocked')else'door-closed'}}"text:|Front Door{{ 'Unlocked' if is_state('lock.front_door', 'unlocked') else 'Locked' }}text_size:10text_color:"{{'green'ifis_state('lock.front_door','unlocked')else'red'}}"8. ⚠️ Arm/disarm an alarm system after 30 seconds:-entity_id:alarm_control_panel.home_alarmdelay:"{{0ifis_state('alarm_control_panel.home_alarm','armed_away')else30}}"service:"{{'alarm_control_panel.alarm_disarm'ifis_state('alarm_control_panel.home_alarm','armed_away')else'alarm_control_panel.alarm_arm_away'}}"icon_mdi:"{{'shield-check'ifis_state('alarm_control_panel.home_alarm','armed_away')else'shield-off'}}"text:|{{ 'Disarm' if is_state('alarm_control_panel.home_alarm', 'armed_away') else 'Arm' }}Alarmtext_color:"{{'red'ifis_state('alarm_control_panel.home_alarm','armed_away')else'green'}}"Arm the alarm system in 30 seconds if it's disarmed, disarm it immediately if it's armed.9. ⏰ Set an alarm time for the next day:-service:input_datetime.set_datetimeservice_data:entity_id:input_datetime.alarm_timetime:"{{'07:00:00'ifstates('input_datetime.alarm_time')!='07:00:00'else'08:00:00'}}"icon_mdi:"alarm"text:|Set Alarm{{ '7AM' if states('input_datetime.alarm_time') != '07:00:00' else '8AM' }}10. ⏯️ Control a media player (play/pause):-entity_id:media_player.living_room_speakerservice:media_player.media_play_pauseicon_mdi:"{{'pause'ifis_state('media_player.living_room_speaker','playing')else'play'}}"text:"{{'Pause'ifis_state('media_player.living_room_speaker','playing')else'Play'}}"11. 🎵 Control a media player (skip tracks):-entity_id:media_player.living_room_speakerservice:media_player.media_next_trackicon_mdi:skip-nexttext:Next Track12. 🌈 Set a specific color for a light:-entity_id:light.living_room_lightservice:light.toggleservice_data:color_name:blueicon_mdi:"{{'lightbulb-on'ifis_state('light.living_room_light','on')else'lightbulb-off'}}"text:Blue Light13. 🌡️ Adjust the thermostat between two specific temperatures:-entity_id:climate.living_roomservice:climate.set_temperatureservice_data:temperature:"{{17ifstate_attr('climate.living_room','temperature')>=22else22}}"icon_mdi:thermostattext:|Set{{ '17°C' if state_attr('climate.living_room', 'temperature') >= 22 else '22°C' }}({{ state_attr('climate.living_room', 'current_temperature') }}°C now)14. 📲 Trigger a script to send a notification to your mobile device:-service:script.send_mobile_notificationicon_mdi:belltext:Send NotificationWhich uses this script (which needs to be defined in Home Assistant):send_mobile_notification:alias:"SendMobileNotification"sequence:-service:notify.mobile_app_<your_device_name>data:message:"Yourcustomnotificationmessage."15. 🌆 Toggle a day/night mode (using an input_boolean):-entity_id:input_boolean.day_night_modeservice:input_boolean.toggleicon_mdi:"{{'weather-night'ifis_state('input_boolean.day_night_mode','on')else'weather-sunny'}}"text:|{{ 'Night' if is_state('input_boolean.day_night_mode', 'on') else 'Day' }}Mode16. 📺 Control a TV (e.g., turn on/off or change input source):-entity_id:media_player.living_room_tvservice:media_player.select_sourceservice_data:source:HDMI 1text:HDMI 117. 🔦 Control a group of lights (e.g., turn on/off or change color):-entity_id:group.living_room_lightsservice:light.turn_onservice_data:color_name:redicon_mdi:"{{'lightbulb-group'ifis_state('group.living_room_lights','on')else'lightbulb-group-off'}}"text:Red Group Lights18. 🔔 Trigger a script to announce the doorbell:-service:script.trigger_doorbell_announcementtext:Doorbell AnnouncementWhich uses this script (which needs to be defined in Home Assistant):trigger_doorbell_announcement:alias:"TriggerDoorbellAnnouncement"sequence:-service:tts.google_translate_saydata:entity_id:media_player.<your_media_player>message:"Someoneisatthedoor."19. ⏰ Enable/disable a sleep timer (using an input_boolean):-entity_id:input_boolean.sleep_timerservice:input_boolean.toggleicon_mdi:"{{'timer'ifis_state('input_boolean.sleep_timer','on')else'timer-off'}}"text:|{{ 'Cancel' if is_state('input_boolean.sleep_timer', 'on') else 'Set' }}Sleep Timer20. 🌡️ Display current temperature:-entity_id:sensor.weather_temperaturetext:'{{states("sensor.weather_temperature")}}°C'text_size:16icon_mdi:weather-cloudy21. 📶 Toggle Wi-Fi on/off (using a switch):-entity_id:switch.wifi_switchservice:switch.toggleicon_mdi:"{{'wifi'ifis_state('switch.wifi_switch','on')else'wifi-off'}}"text:|{{ 'Disable' if is_state('switch.wifi_switch', 'on') else 'Enable' }}Wi-Fi22. 🗣️ Activate voice assistant:-service:script.activate_voice_assistanticon_mdi:microphonetext:Voice AssistantWhich uses this script (which needs to be defined in Home Assistant):activate_voice_assistant:alias:"ActivateVoiceAssistant"sequence:-service:media_player.play_mediatarget:entity_id:media_player.<your_media_player>data:media_content_id:"http://<your_url>/<filename>.mp3"media_content_type:"music"23. 🌿 Start/Stop air purifier:-entity_id:switch.air_purifierservice:switch.toggleicon_mdi:"{{'air-purifier'ifis_state('switch.air_purifier','on')else'air-purifier-off'}}"text:|{{ 'Stop' if is_state('switch.air_purifier', 'on') else 'Start' }}Air Purifier24. 📼 Start/stop a security camera recording:-service:script.toggle_security_camera_recordingicon_mdi:cctvtext:Toggle Camera RecordingWhich uses this script (which needs to be defined in Home Assistant):toggle_security_camera_recording:alias:"ToggleSecurityCameraRecording"sequence:-service:camera.recordtarget:entity_id:camera.<your_camera>data:duration:10lookback:2filename:"/config/www/recordings/camera_{{now().strftime('%Y%m%d_%H%M%S')}}.mp4"25. 🌙 Enable/disable a nightlight after 30 min:-entity_id:light.nightlightservice:light.toggledelay:1800icon_mdi:"{{'lightbulb-on'ifis_state('light.nightlight','on')else'lightbulb-off'}}"text:"{{'Disable'ifis_state('light.nightlight','on')else'Enable'}}Nightlight"text_color:"{{'red'ifis_state('light.nightlight','on')else'green'}}"26. 🔥 Control a smart fireplace:-entity_id:switch.smart_fireplaceservice:switch.toggleicon_mdi:"{{'fire'ifis_state('switch.smart_fireplace','on')else'fire-off'}}"text:|{{ 'Turn Off' if is_state('switch.smart_fireplace', 'on') else 'Turn On' }}Fireplace27. 🔌 Toggle a smart plug:-entity_id:switch.smart_plugservice:switch.toggleicon_mdi:"{{'power-plug'ifis_state('switch.smart_plug','on')else'power-plug-off'}}"text:|{{ 'Turn Off' if is_state('switch.smart_plug', 'on') else 'Turn On' }}Smart Plug28. 💦 Toggle irrigation system:-entity_id:switch.irrigation_systemservice:switch.toggleicon_mdi:"{{'water'ifis_state('switch.irrigation_system','on')else'water-off'}}"text:|{{ 'Turn Off' if is_state('switch.irrigation_system', 'on') else 'Turn On' }}Irrigation29. 🌤️ Change the position of a cover (e.g., blinds or curtains):-entity_id:cover.living_room_blindsservice:cover.set_cover_positionservice_data:position:"{{0ifstate_attr('cover.living_room_blinds','position')>=50else100}}"icon_mdi:window-shuttertext:|{{ 'Close' if state_attr('cover.living_room_blinds', 'position') >= 50 else 'Open' }}Blinds30. 📺 Toggle a media player (e.g., TV) and show different images:-entity_id:media_player.tvservice:media_player.toggleicon:>{% if is_state('media_player.tv', 'on') %}url:https://raw.githubusercontent.com/basnijholt/home-assistant-streamdeck-yaml/main/assets/fireplace.png{% else %}url:https://raw.githubusercontent.com/basnijholt/home-assistant-streamdeck-yaml/main/assets/hogwarts.png{% endif %}text:>Turn {{ 'Off' if is_state('media_player.tv', 'on') else 'On' }}31. ⏰ Turn off all lights in 60s:-entity_id:light.all_lightsservice:light.turn_offtext:|Turn offin 60sdelay:6032. 🌡️ Display outside temperature with a ring indicator:-entity_id:sensor.temperature_sensor_outside_temperatureicon:>{%- set temp = states('sensor.temperature_sensor_outside_temperature') -%}{%- set min_temp = -10 -%}{%- set max_temp = 40 -%}{%- set pct = ((temp - min_temp) / (max_temp - min_temp)) * 100 -%}ring:{{ pct | round }}text:|{%- set temp = states('sensor.temperature_sensor_outside_temperature') -%}Outside{{ temp | round(1) }}°CThis sets 0% to -10°C and 100% to 40°C.33. 🔄 Reload the `configuration.yaml` file:-special_type:reloadWhen pressed, theconfiguration.yamlis reloaded.