diff --git a/CODEOWNERS b/CODEOWNERS index 6874fe61da4..cf9dd2008f0 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -358,7 +358,6 @@ source/_integrations/rpi_power.markdown @shenxn @swetoast source/_integrations/ruckus_unleashed.markdown @gabe565 source/_integrations/safe_mode.markdown @home-assistant/core source/_integrations/saj.markdown @fredericvl -source/_integrations/salt.markdown @bjornorri source/_integrations/samsungtv.markdown @escoand source/_integrations/scene.markdown @home-assistant/core source/_integrations/schluter.markdown @prairieapps @@ -453,7 +452,6 @@ source/_integrations/transmission.markdown @engrbm87 @JPHutchins source/_integrations/tts.markdown @pvizeli source/_integrations/tuya.markdown @ollo69 source/_integrations/twentemilieu.markdown @frenck -source/_integrations/ubee.markdown @mzdrale source/_integrations/unifi.markdown @Kane610 source/_integrations/unifiled.markdown @florisvdk source/_integrations/upb.markdown @gwww @@ -499,7 +497,6 @@ source/_integrations/yamaha_musiccast.markdown @jalmeroth source/_integrations/yandex_transport.markdown @rishatik92 @devbis source/_integrations/yeelight.markdown @rytilahti @zewelor @shenxn source/_integrations/yeelightsunflower.markdown @lindsaymarkward -source/_integrations/yessssms.markdown @flowolf source/_integrations/yi.markdown @bachya source/_integrations/zeroconf.markdown @bdraco source/_integrations/zerproc.markdown @emlove diff --git a/_config.yml b/_config.yml index 20ec588125d..552153bf3be 100644 --- a/_config.yml +++ b/_config.yml @@ -99,10 +99,10 @@ social: account: home_assistant # Home Assistant release details -current_major_version: 0 -current_minor_version: 118 -current_patch_version: 5 -date_released: 2020-12-05 +current_major_version: 2020 +current_minor_version: 12 +current_patch_version: 0 +date_released: 2020-12-13 # Either # or the anchor link to latest release notes in the blog post. # Must be prefixed with a # and have double quotes around it. diff --git a/plugins/configuration.rb b/plugins/configuration.rb index fc599102e64..e1e65355220 100644 --- a/plugins/configuration.rb +++ b/plugins/configuration.rb @@ -5,11 +5,13 @@ module Jekyll 'device_class' => '/docs/configuration/customizing-devices/#device-class', 'template' => '/docs/configuration/templating/', 'icon' => '/docs/configuration/customizing-devices/#icon', + 'selector' => '/docs/blueprint/selectors/', } TYPES = [ 'action', 'boolean', 'string', 'integer', 'float', 'time', 'template', - 'device_class', 'icon', 'map', 'list', 'date', 'datetime', 'any' + 'device_class', 'icon', 'map', 'list', 'date', 'datetime', 'any', + 'selector', ] MIN_DEFAULT_LENGTH = 30 diff --git a/plugins/details.rb b/plugins/details.rb new file mode 100644 index 00000000000..6ecfd1fe447 --- /dev/null +++ b/plugins/details.rb @@ -0,0 +1,45 @@ +module Jekyll + class DetailsBlock < Liquid::Block + + def render_details_block(vars:, converter:, classes: nil, parent_type: nil) + result = Array.new + result << vars.map do |entry| + markup = Array.new + markup << "
" + markup << "
#{entry['title']}" + markup << '' + markup << '' + markup << "
" + markup << "" + markup << "
" + end + result.join + end + + def render(context) + contents = super(context) + vars = SafeYAML.load(contents) + + site = context.registers[:site] + converter = site.find_converter_instance(::Jekyll::Converters::Markdown) + + <<~MARKUP + +
+ #{render_details_block(vars: vars, converter: converter)} +
+ MARKUP + end + end +end + +Liquid::Template.register_tag('details', Jekyll::DetailsBlock) \ No newline at end of file diff --git a/sass/custom/_blue.scss b/sass/custom/_blue.scss new file mode 100644 index 00000000000..8f433812173 --- /dev/null +++ b/sass/custom/_blue.scss @@ -0,0 +1,998 @@ +$blue__deep_color: #161d61; +$blue__light_color: #18abfd; +$ha__primary_color: #03a9f4; + +#blue { + $blue__hero_height: 670px; + font-family: Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif; + .site-header { + .grid-wrapper { + max-width: 1100px !important; + padding: 0 25px !important; + } + } + .grid-wrapper { + max-width: 1500px; + padding: 0; + width: 100%; + } + .page-content { + overflow-x: hidden; + } + .banner { + height: $blue__hero_height; + margin-bottom: 16px; + margin-top: -42px; + width: 100%; + text-align: center; + .title { + position: relative; + width: 550px; + height: 168px; + left: calc(50% - 550px / 2 - 0.5px); + font-weight: 900; + font-size: 68px; + line-height: 55px; + text-align: center; + color: #ffffff; + bottom: 226px; + svg { + stroke: $ha__primary_color; + } + } + img { + width: 100%; + object-fit: cover; + object-position: bottom; + border-radius: 0; + border: 0; + height: $blue__hero_height; + box-shadow: none; + } + } + .content { + max-width: 1000px; + margin: auto; + + .sub-title { + font-weight: bold; + font-size: 42px; + line-height: 49px; + margin: 32px; + text-align: center; + } + + .missing-piece { + z-index: 2; + position: relative; + display: flex; + width: 600px; + border-radius: 8px; + margin: -36px auto 0; + + .missing-piece-header { + font-weight: 900; + font-size: 24px; + line-height: 28px; + } + + .missing-piece-content { + font-size: 16px; + line-height: 19px; + margin-top: 16px; + width: 420px; + } + + .missing-piece-overlay { + width: 210px; + border-radius: 8px; + margin: -50px -50px 0 0; + padding: 22px; + display: flex; + flex-flow: wrap; + justify-content: space-between; + + .missing-piece-overlay-header { + font-weight: 500; + font-size: 12px; + line-height: 14px; + letter-spacing: 0.1em; + color: #0c0c0c; + opacity: 0.33; + width: 100%; + text-align: right; + } + .missing-piece-overlay-price { + width: calc(100% - 6px); + text-align: right; + font-weight: 900; + font-size: 24px; + line-height: 28px; + color: #0c0c0c; + display: inline-flex; + justify-content: flex-end; + + div { + width: 6px; + margin-top: 2px; + font-size: 12px; + line-height: 14px; + color: #0c0c0c; + opacity: 0.4; + } + } + + .missing-piece-overlay-images { + display: grid; + grid-template-columns: 47px 47px 47px; + grid-template-rows: 47px 47px; + grid-auto-flow: row; + gap: 2px; + + .img-container { + border: 1px solid #e9e9e9; + box-sizing: border-box; + border-radius: 4px; + height: 47px; + width: 47px; + display: flex; + + img { + margin: auto; + box-shadow: none; + border-radius: 0; + border: 0; + } + } + + .img-container:first-of-type { + grid-column: 1 / span 2; + grid-row: 1 / span 2; + height: 96px; + width: 96px; + } + } + .missing-piece-overlay-button { + background-color: $ha__primary_color; + margin-top: 12px; + border-radius: 4px; + width: 154px; + height: 46px; + display: flex; + cursor: pointer; + + div { + margin: auto; + font-weight: 900; + font-size: 18px; + color: #ffffff; + } + } + } + } + .missing-piece-disclaimer { + font-size: 12px; + line-height: 14px; + color: #0c0c0c; + opacity: 0.4; + text-align: center; + margin: 12px auto 50px; + } + + .bullet-points { + margin: 24px 136px; + display: grid; + gap: 32px; + grid-template-columns: repeat(2, 1fr); + .item { + display: grid; + text-align: center; + span:nth-of-type(1) { + color: rgba(0, 0, 0, 0.87); + font-size: 24px; + font-weight: 300; + letter-spacing: 0.1em; + line-height: 28px; + opacity: 0.66; + text-transform: uppercase; + } + span:nth-of-type(2) { + color: rgba(0, 0, 0, 0.87); + font-size: 48px; + letter-spacing: -2px; + line-height: 56px; + } + span:nth-of-type(3) { + color: rgba(0, 0, 0, 0.87); + font-size: 14px; + font-weight: 500; + letter-spacing: -1px; + line-height: 16px; + } + } + } + + .vision { + position: sticky; + text-align: center; + display: inline-block; + width: 100%; + margin-bottom: 160px; + + svg { + z-index: 0; + width: 100vw; + margin-left: calc(-100vw / 2); + position: absolute; + + path { + z-index: 0; + } + } + .vision-content { + z-index: 1; + position: relative; + + .vision-header { + margin-top: 172px; + font-weight: 900; + font-size: 68px; + line-height: 80px; + color: $blue__deep_color; + } + .vision-statement { + font-size: 18px; + line-height: 21px; + } + + .vision-blocks { + width: 100%; + display: flex; + flex-flow: wrap; + justify-content: space-between; + + .vision-block { + width: 335px; + margin: 62px; + + .vision-block-title { + text-transform: uppercase; + color: $blue__deep_color; + letter-spacing: -2px; + font-size: 48px; + line-height: 56px; + font-weight: bold; + } + .vision-block-content { + font-size: 18px; + line-height: 133%; + } + } + } + } + } + .mood { + text-align: center; + margin-bottom: 32px; + margin-bottom: 80px; + + .mood-cards { + display: inline-flex; + align-items: center; + justify-content: space-between; + margin: 0 150px; + width: calc(100% - 300px); + position: relative; + + .material-card { + display: block; + align-items: initial; + width: 300px; + z-index: 1; + + img { + box-shadow: none; + border: 0; + border-radius: 0; + } + + .mood-card-type { + width: 60px; + text-align: start; + font-weight: bold; + font-size: 32px; + line-height: 32px; + + .mode { + margin-top: -8px; + font-weight: normal; + font-size: 15px; + text-align: justify; + letter-spacing: 6px; + } + } + + .mood-card-footer { + display: flex; + + .specifications { + display: grid; + height: 60px; + margin-top: 16px; + grid-template-columns: repeat(2, 1fr); + justify-items: left; + align-items: self-end; + flex-wrap: wrap; + width: calc(100% - 75px); + + .spec-item { + height: 30px; + font-size: 11px; + display: inline-grid; + line-height: 15px; + justify-items: left; + + span:first-of-type { + font-weight: bold; + } + } + } + .outline { + display: flex; + place-self: flex-end; + color: #c4c4c4; + } + } + } + + .mood-separator { + z-index: 0; + display: grid; + height: 120px; + width: 120px; + align-content: center; + justify-content: center; + border-radius: 188px; + border: 1px dashed #c4c4c4; + margin: 0 -80px; + padding: 120px; + + span { + display: block; + width: inherit; + } + + span:first-of-type { + color: $ha__primary_color; + font-weight: bold; + font-size: 16px; + line-height: 15px; + } + + span:last-of-type { + font-size: 12px; + color: #0c0c0c; + opacity: 0.4; + } + + .mood-separator-arrow { + color: #c4c4c4; + } + + .mood-separator-arrow.right { + margin-top: -118px; + } + + .mood-separator-arrow.left { + margin-bottom: -118px; + align-self: end; + } + } + } + } + + .specifications { + display: grid; + grid-template-columns: repeat(5, 1fr); + + .specifications-components { + grid-column: 1 / span 3; + margin-right: 24px; + } + + .component-list { + display: grid; + row-gap: 8px; + grid-template-columns: repeat(5, 1fr); + font-size: 18px; + line-height: 21px; + + .spec-title { + grid-column: 1; + margin-right: 24px; + margin-top: 16px; + text-transform: uppercase; + opacity: 0.4; + } + .spec-content { + grid-column: 2 / span 4; + font-weight: bold; + margin-top: 16px; + + .spec-content-additional { + font-weight: normal; + + ul { + margin-bottom: 0; + margin-left: 16px; + + li { + margin-bottom: 0; + } + li::marker { + content: "- "; + } + } + } + } + } + .specifications-form-factor { + grid-column: 4 / span 2; + + .specifications-form-factor-grid { + display: grid; + margin-left: 42px; + + .sff-description { + display: grid; + + span:first-of-type { + font-size: 1.525em; + line-height: 24px; + grid-column: 1; + text-transform: uppercase; + opacity: 0.4; + align-self: self-end; + } + + span:last-of-type { + font-weight: bold; + font-size: 1.425em; + word-spacing: -4px; + } + } + + .sff-width { + grid-column: 1 / span 2; + } + svg#zen { + grid-column: 1; + height: 100px; + width: 200px; + margin-bottom: 32px; + } + + .sff-height { + grid-column: 2; + margin-left: 14px; + } + + svg#depth { + grid-column: 1; + height: 200px; + width: 200px; + margin-bottom: 32px; + } + + .sff-depth { + grid-column: 2; + margin-left: 14px; + } + + svg#weight { + grid-column: 1 / span 2; + height: 200px; + width: 100%; + } + + .sff-weight { + grid-column: 1 / span 2; + justify-content: center; + margin-top: -24px; + } + } + img { + box-shadow: none; + border: 0; + border-radius: 0; + } + } + } + .faq-list { + margin: 0 72px; + } + + .blue3d { + text-decoration: none; + + .blue3d-container { + align-items: flex-end; + background-image: url('/images/blue/blue_3d.jpg'); + background-position: bottom; + background-size: cover; + display: flex; + height: 390px; + margin: auto; + margin-top: 62px; + padding: 0; + width: 720px; + + .blue3d-description { + display: flex; + align-items: center; + justify-content: space-between; + background-color: #000000ab; + color: #FFFFFF; + height: 60px; + width: 100%; + + svg { + fill: white; + height: 32px; + width: 32px; + min-width: 32px; + } + } + } + } + } + + .blue-buy-fab { + background-color: $ha__primary_color; + border-radius: 62px; + bottom: 16px; + display: flex; + box-shadow: rgba(0, 0, 0, 0.2) 0px 7px 8px -4px, + rgba(0, 0, 0, 0.14) 0px 12px 17px 2px, + rgba(0, 0, 0, 0.12) 0px 5px 22px 4px; + box-sizing: border-box; + color: #ffffff; + cursor: pointer; + display: inline-flex; + float: right; + font-size: 12.25px; + font-weight: 400; + font-weight: bold; + line-height: 32px; + padding: 8px 16px 4px; + position: fixed; + right: 24px; + z-index: 1111; + + svg { + margin-top: 4px; + } + } + + #buy-dialog { + z-index: 1000; + display: none; + position: fixed; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + background-color: rgb(0, 0, 0); + background-color: rgba(0, 0, 0, 0.4); + + .dialog-content { + border-radius: 8px; + margin: auto; + width: 600px; + padding: 0; + overflow-y: auto; + display: flex; + flex-flow: column; + justify-content: space-between; + + .close-container { + position: fixed; + float: right; + width: 615px; + text-align: right; + margin-top: -17px; + + .dialog-close { + cursor: pointer; + font-size: 32px; + background-color: #ffffff; + border-radius: 100px; + height: 32px; + width: 32px; + display: inline-flex; + align-items: center; + justify-content: center; + } + } + + .dialog-header { + display: flex; + justify-content: space-between; + padding: 8px 16px; + font-weight: bold; + font-size: 24px; + + svg { + width: 32px; + height: 32px; + cursor: pointer; + } + } + + .distributors { + a { + text-decoration: none; + + .distributor { + width: 100%; + display: flex; + justify-content: space-between; + padding: 8px 16px; + color: #222222; + margin: auto; + + svg { + height: 100%; + align-self: center; + } + + div { + display: grid; + line-height: 20px; + + div:nth-of-type(1) { + align-content: center; + grid-column: 1; + grid-row: 1 / span 2; + margin-right: 8px; + } + div:nth-of-type(2) { + grid-column: 2; + } + div:nth-of-type(3) { + grid-column: 2; + color: darkslategrey; + font-size: small; + } + } + } + .distributor:hover { + border-color: $ha__primary_color; + } + } + } + + .box-contents { + margin: 0 16px 32px; + ul { + margin: 12px 0 12px 24px; + color: darkslategrey; + font-size: small; + + li { + margin-bottom: 4px; + } + } + .ul-sub { + margin: 0 0 0 16px; + } + } + + .tip { + color: darkslategrey; + font-size: small; + text-align: center; + padding: 12px 62px 12px; + margin-top: 16px; + border-top: 1px darkslategrey solid; + } + } + } +} + +@media only screen and (max-width: $palm-end) { + $blue__hero_height: 500px; + #blue { + .site-header { + background-color: #ffffff66; + transition: background 0.5s; + + ul { + margin: 0 4px; + width: calc(100% - 8px); + } + } + .page-content { + margin-top: 0; + height: 100%; + } + .grid-wrapper { + margin-left: 0; + width: 100%; + } + .banner { + margin-bottom: 8px; + height: $blue__hero_height; + img { + height: $blue__hero_height; + } + .title { + width: 100%; + left: unset; + font-size: 2em; + line-height: 0px; + + svg { + width: 152px; + height: 122px; + + text { + font-size: 65px; + } + } + } + } + .content { + margin: 0 8px; + + .sub-title { + font-size: 24px; + line-height: 28px; + } + + .missing-piece { + margin: -116px auto 0; + display: block; + width: 100%; + padding: 0; + + .missing-piece-header { + padding-left: 8px; + padding-top: 8px; + } + + .missing-piece-content { + padding-left: 8px; + } + + .missing-piece-content { + width: 100%; + } + .secondary { + display: none; + } + + .missing-piece-overlay { + margin: 0; + margin-top: 12px; + width: 100%; + + .missing-piece-overlay-images { + margin-top: -42px; + margin-left: -8px; + } + } + } + + .missing-piece-disclaimer { + margin: 12px auto 12px; + } + + .bullet-points { + margin: 24px 0; + .item { + span:nth-of-type(1) { + font-size: 16px; + line-height: 16px; + } + span:nth-of-type(2) { + font-size: 32px; + line-height: 32px; + } + span:nth-of-type(3) { + font-size: 12px; + line-height: 12px; + } + } + } + + .vision { + margin-bottom: 0; + svg { + display: none; + } + .vision-content { + margin-top: 28px; + .vision-header { + font-size: 34px; + line-height: 40px; + margin-top: 8px; + } + .vision-statement { + font-size: 12px; + line-height: 14px; + } + .vision-blocks { + .vision-block { + width: 100%; + margin: 9px; + .vision-block-title { + font-size: 24px; + line-height: 28px; + } + .vision-block-content { + display: none; + } + } + } + } + } + + .mood { + .mood-cards { + display: inline-grid; + margin: 0; + width: 100%; + + .material-card { + width: 100% !important; + display: block; + height: auto !important; + margin: 0 !important; + z-index: 4; + + img { + max-height: 180px; + } + + .mood-card-footer { + .specifications { + display: none; + } + } + } + .mood-separator { + margin: -80px calc((100% / 2) - 120px); + + .mood-separator-arrow { + display: none; + } + } + } + } + + .faq-list { + margin: 0; + } + + .specifications { + display: block; + + h3 { + text-align: center; + } + + .component-list { + grid-template-columns: repeat(1, 1fr); + + .spec-title, + .spec-content { + grid-column: 1; + } + + .spec-title { + margin-top: 8px; + } + + .spec-content { + margin-top: -4px; + } + } + .specifications-form-factor { + .specifications-form-factor-grid { + margin-left: 0; + + .sff-width { + margin-left: 50px; + } + .sff-description { + span:last-of-type { + font-size: 16px; + } + } + } + } + } + } + + .blue-buy-fab { + bottom: 12px; + right: 12px; + display: none; + } + + #buy-dialog { + padding-top: 0; + + .dialog-content { + border-radius: 0; + height: 100vh; + width: 100vw; + padding-bottom: 64px; + display: block; + + .tip { + margin: 32px 8px 8px 8px; + } + } + } + .blue3d { + .blue3d-container { + width: 100% !important; + + .blue3d-description { + height: auto !important; + + i { + align-self: center; + } + } + } + } + } +} + +@media only screen and (max-width: $lap-end) { + #blue { + .page-content { + .content { + .bullet-points { + margin: 24px 0; + } + .vision { + margin-top: -200px; + + .vision-content { + padding-top: 200px; + + .vision-blocks { + margin: 32px 0; + + .vision-block { + margin: 8px !important; + + .vision-block-content { + display: none; + } + } + } + } + } + .mood { + .mood-cards { + margin: 0; + width: inherit; + .material-card { + height: 300px; + width: 230px; + margin: 0 24px; + } + } + } + .specifications { + margin: 0 16px; + } + } + } + } +} diff --git a/sass/custom/_details.scss b/sass/custom/_details.scss new file mode 100644 index 00000000000..ec764e31a55 --- /dev/null +++ b/sass/custom/_details.scss @@ -0,0 +1,26 @@ +div.details-block { + width: 100%; + display: block; + + .details-block-item { + background-color: white; + padding: 4px 16px; + margin: 8px; + cursor: pointer; + box-shadow: 0px 4px 20px rgba(0, 0, 0, 0.1); + border-radius: 16px; + + .details-block-title { + font-weight: bold; + font-size: 18px; + line-height: 21px; + height: 54px; + justify-content: space-between; + display: flex; + align-items: center; + } + .details-block-content { + margin: 4px 32px 0 0; + } + } +} diff --git a/sass/custom/_features.scss b/sass/custom/_features.scss new file mode 100644 index 00000000000..2c7634ef8ea --- /dev/null +++ b/sass/custom/_features.scss @@ -0,0 +1,59 @@ +.feature-cards { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 32px; + margin: auto; + + .card { + border-radius: 8px; + display: inline-block; + width: calc(100% - 16px); + vertical-align: top; + + .card-header { + font-size: 1.4rem; + line-height: 1.6; + display: flex; + align-items: center; + padding-bottom: 8px; + height: 62px; + + i { + height: 62px; + min-width: 62px; + text-align: center; + font-size: 39px; + } + } + + .card-content { + padding-left: 24px; + + .button { + font-size: small; + font-weight: 600; + text-decoration: none; + } + + p:last-of-type, + ul { + margin-bottom: 12px; + } + } + } +} + +@media only screen and (max-width: $palm-end) { + .feature-cards { + width: 95%; + grid-template-columns: repeat(1, 1fr); + + .card { + width: 100%; + + .card-content { + padding-left: 0; + } + } + } +} diff --git a/sass/custom/_paulus.scss b/sass/custom/_paulus.scss index 4a528bcf30d..2175b84ad65 100644 --- a/sass/custom/_paulus.scss +++ b/sass/custom/_paulus.scss @@ -157,6 +157,9 @@ $primary-color: #049cdb; color: white; border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; + display: flex; + justify-content: space-between; + align-items: center; .title { font-size: 20px; @@ -167,6 +170,13 @@ $primary-color: #049cdb; font-size: 12px; font-weight: initial; } + + svg { + fill: white; + width: 32px; + height: 32px; + min-width: 32px; + } } } diff --git a/sass/screen.scss b/sass/screen.scss index 7470f86f37b..dda71c2daa4 100644 --- a/sass/screen.scss +++ b/sass/screen.scss @@ -1,6 +1,9 @@ @import 'oscailte/oscailte'; @import 'custom/paulus'; +@import 'custom/blue'; +@import 'custom/features'; @import 'custom/component_page'; @import 'custom/syntax'; +@import 'custom/details'; @import 'custom/print'; @import 'custom/layout'; \ No newline at end of file diff --git a/source/_docs/automation.markdown b/source/_docs/automation.markdown index 6294c48f783..85a9b72a15e 100644 --- a/source/_docs/automation.markdown +++ b/source/_docs/automation.markdown @@ -3,42 +3,14 @@ title: "Automating Home Assistant" description: "Steps to help you get automation setup in Home Assistant." --- -Home Assistant offers a wide range of automation configurations. In this section, we'll try to guide you through all the different possibilities and options. Besides this documentation, there are also a couple of people who have made their automations [publicly available](/cookbook/#example-configurationyaml). +Home Assistant contains information about all your devices and services. This information is not only available for the user in the dashboard, it can also be used to trigger automations. And that's fun! -Please see [Automation Integration](/integrations/automation/) for configuration options and services. +Automations in Home Assistant allow you to automatically respond to things that happen. You can turn the lights on at sunset or pause the music when you receive a call. -### Automation basics +If you are just starting out, we strongly suggest you start with blueprint automations. These are ready-made automations by the community that you only need to configure. -Before you can go ahead and create your own automations, it's important to learn the basics. To explore these, let's have a look at the following example home automation rule: +### [Learn about automation blueprints »](/docs/automation/using_blueprints/) -```text -(trigger) When Paulus arrives home -(condition) and it is after sunset: -(action) Turn the lights in the living room on -``` +If you got the hang of blueprints and need more, it's time for the next step. But before we can start creating automations, you will need to learn about the automation basics. -The example consists of three different parts: a [trigger](/docs/automation/trigger/), a [condition](/docs/automation/condition/) and an [action](/docs/automation/action/). - -The first line is the **trigger** of the automation rule. Triggers describe events that should trigger the automation rule. In this case, it is a person arriving home, which can be observed in Home Assistant by observing the state of Paulus changing from 'not_home' to 'home'. - -The second line is the **condition**. Conditions are optional tests that can limit an automation rule to only work in your specific use cases. A condition will test against the current state of the system. This includes the current time, devices, people and other things like the sun. In this case, we only want to act when the sun has set. - -The third part is the **action**, which will be performed when a rule is triggered and all conditions are met. For example, it can turn a light on, set the temperature on your thermostat or activate a scene. - -
-The difference between a condition and a trigger can be confusing as they are very similar. Triggers look at the actions, while conditions look at the results: turning a light on versus a light being on. -
- -### Exploring the internal state - -Automation rules interact directly with the internal state of Home Assistant, so you'll need to familiarize yourself with it. Home Assistant exposes its current state via the developer tools. These are available at the bottom of the sidebar in the frontend. **Developer Tools** -> **States** will show all currently available states. An entity can be anything. A light, a switch, a person and even the sun. A state consists of the following parts: - -| Name | Description | Example | -| ---- | ----- | ---- | -| Entity ID | Unique identifier for the entity. | `light.kitchen` -| State | The current state of the device. | `home` -| Attributes | Extra data related to the device and/or current state. | `brightness` - -State changes can be used as the source of triggers and the current state can be used in conditions. - -Actions are all about calling services. To explore the available services open the **Developer Tools** -> **Services**. Services allow to change anything. For example turn on a light, run a script or enable a scene. Each service has a domain and a name. For example the service `light.turn_on` is capable of turning on any light in your system. Services can be passed parameters to for example tell which device to turn on or what color to use. +### [Learn about automation basics »](/docs/automation/basics/) diff --git a/source/_docs/automation/basics.markdown b/source/_docs/automation/basics.markdown new file mode 100644 index 00000000000..fb46acb9a40 --- /dev/null +++ b/source/_docs/automation/basics.markdown @@ -0,0 +1,46 @@ +--- +title: "Understanding Automations" +description: "A breakdown of what an automation consists of." +--- + +All automations are made up of a trigger and an action. Optionally combined with a condition. Take for example the automation: + +> When Paulus arrives home and it is after sunset: Turn the lights on in the living room.". + +We can break up this automation into the following three parts: + +```text +(trigger) When Paulus arrives home +(condition) and it is after sunset: +(action) Turn the lights on in the living room +``` + +The first part is the [trigger](/docs/automation/trigger/) of the automation rule. Triggers describe events that should trigger the automation rule. In this case, it is a person arriving home, which can be observed in Home Assistant by observing the state of Paulus changing from 'not_home' to 'home'. + +The second part is the [condition](/docs/automation/condition/). Conditions are optional tests that can limit an automation rule to only work in your specific use cases. A condition will test against the current state of the system. This includes the current time, devices, people and other things like the sun. In this case, we only want to act when the sun has set. + +The third part is the [action](/docs/automation/action/), which will be performed when a rule is triggered and all conditions are met. For example, it can turn a light on, set the temperature on your thermostat or activate a scene. + +
+The difference between a condition and a trigger can be confusing as they are very similar. Triggers look at the actions, while conditions look at the results: turning a light on versus a light being on. +
+ +## Exploring the internal state + +Automation rules interact directly with the internal state of Home Assistant, so you'll need to familiarize yourself with it. Home Assistant exposes its current state via the developer tools. These are available at the bottom of the sidebar in the frontend. **Developer Tools** -> **States** will show all currently available states. An entity can be anything. A light, a switch, a person and even the sun. A state consists of the following parts: + +| Name | Description | Example | +| ---- | ----- | ---- | +| Entity ID | Unique identifier for the entity. | `light.kitchen` +| State | The current state of the device. | `home` +| Attributes | Extra data related to the device and/or current state. | `brightness` + +State changes can be used as the source of triggers and the current state can be used in conditions. + +Actions are all about calling services. To explore the available services open the **Developer Tools** -> **Services**. Services allow changing anything. For example turn on a light, run a script or enable a scene. Each service has a domain and a name. For example the service `light.turn_on` is capable of turning on any light in your system. Services can be passed parameters to for example tell which device to turn on or what color to use. + +## Creating automations + +Now that you've got a sneak peek of what is possible, it's time to get your feet wet and create your first automation. + +### [Using the automation editor »](/docs/automation/editor/) diff --git a/source/_docs/automation/editor.markdown b/source/_docs/automation/editor.markdown index a1ad5f128a3..6e3b2e3b0da 100644 --- a/source/_docs/automation/editor.markdown +++ b/source/_docs/automation/editor.markdown @@ -3,8 +3,6 @@ title: "Automation Editor" description: "Instructions on how to use the automation editor." --- -In Home Assistant 0.45 we introduced the first version of our automation editor. If you just created a new configuration with Home Assistant, then you're all set! Go to the UI and enjoy. - From the UI choose **Configuration** which is located in the sidebar, then click on **Automation** to go to the automation editor. Press the **+** sign in the lower right corner to get started. This example is based on the manual steps described in the [Getting started section](/getting-started/automation/) for a [`random` sensor](/integrations/random#sensor). Choose a meaningful name for your automation rules. @@ -27,75 +25,9 @@ Firing a [persistent notification](/integrations/persistent_notification/) is th As "Service Data" we want a simple text that is shown as part of the notification. -```json -{ - "message": "Sensor value greater than 10" -} +```yaml +message: Sensor value greater than 10 ``` Don't forget to save your new automation rule. For your saved automation rule to come into effect, you will need to go to the **Configuration** page and click on **Reload Automation**. -## Updating your configuration to use the editor - -First, check that you have activated the configuration editor. - -```yaml -# Activate the configuration editor -config: -``` - -The automation editor reads and writes to the file `automations.yaml` in the root of your [configuration](/docs/configuration/) folder. -Currently, both the name of this file and its location are fixed. -Make sure that you have set up the automation integration to read from it: - -```yaml -# Configuration.yaml example -automation: !include automations.yaml -``` - -If you still want to use your old automation section, add a label to the old entry: - -```yaml -automation old: -- trigger: - platform: ... -``` - -You can use the `automation:` and `automation old:` sections at the same time: - - `automation old:` to keep your manual designed automations - - `automation:` to save the automation created by the online editor - -```yaml -automation: !include automations.yaml -automation old: !include_dir_merge_list automations -``` - - -## Migrating your automations to `automations.yaml` - -If you want to migrate your old automations to use the editor, you'll have to copy them to `automations.yaml`. Make sure that `automations.yaml` remains a list! For each automation that you copy over, you'll have to add an `id`. This can be any string as long as it's unique. - -For example, the below automation will be triggered when the sun goes from below the horizon to above the horizon. Then, if the temperature is between 17 and 25 degrees, a light will be turned on. - -```yaml -# Example automations.yaml entry -- id: my_unique_id # <-- Required for editor to work, for automations created with the editor the id will be automatically generated. - alias: Hello world - trigger: - - platform: state - entity_id: sun.sun - from: below_horizon - to: above_horizon - condition: - - condition: numeric_state - entity_id: sensor.temperature - above: 17 - below: 25 - value_template: '{% raw %}{{ float(state.state) + 2 }}{% endraw %}' - action: - - service: light.turn_on -``` - -
-Any comments in the YAML file will be lost and templates will be reformatted when you update an automation via the editor. -
diff --git a/source/_docs/automation/examples.markdown b/source/_docs/automation/examples.markdown deleted file mode 100644 index 2a9e33309b2..00000000000 --- a/source/_docs/automation/examples.markdown +++ /dev/null @@ -1,77 +0,0 @@ ---- -title: "Automation Examples" -description: "Some automation examples to get you started." ---- - -Just some sample automation rules to get you started. - -{% raw %} -```yaml -# Example of entry in configuration.yaml -automation: -# Turns on lights 1 hour before sunset if people are home -# and if people get home between 16:00-23:00 - - alias: 'Rule 1 Light on in the evening' - trigger: - # Prefix the first line of each trigger configuration - # with a '-' to enter multiple - - platform: sun - event: sunset - offset: '-01:00:00' - - platform: state - entity_id: all - to: 'home' - condition: - # Prefix the first line of each condition configuration - # with a '-'' to enter multiple - - condition: state - entity_id: all - state: 'home' - - condition: time - after: '16:00:00' - before: '23:00:00' - action: - # With a single service call, we don't need a '-' before service - though you can if you want to - service: homeassistant.turn_on - entity_id: group.living_room - -# Turn off lights when everybody leaves the house - - alias: 'Rule 2 - Away Mode' - trigger: - platform: state - entity_id: all - to: 'not_home' - action: - service: light.turn_off - entity_id: all - -# Notify when Paulus leaves the house in the evening - - alias: 'Leave Home notification' - trigger: - platform: zone - event: leave - zone: zone.home - entity_id: device_tracker.paulus - condition: - condition: time - after: '20:00' - action: - service: notify.notify - data: - message: 'Paulus left the house' - -# Send a notification via Pushover with the event of a Xiaomi cube. Custom event from the Xiaomi component. - - alias: 'Xiaomi Cube Action' - initial_state: false - trigger: - platform: event - event_type: cube_action - event_data: - entity_id: binary_sensor.cube_158d000103a3de - action: - service: notify.pushover - data: - title: "Cube event detected" - message: "Cube has triggered this event: {{ trigger.event }}" -``` -{% endraw %} diff --git a/source/_docs/automation/modes.markdown b/source/_docs/automation/modes.markdown new file mode 100644 index 00000000000..70b083f3f07 --- /dev/null +++ b/source/_docs/automation/modes.markdown @@ -0,0 +1,53 @@ +--- +title: "Automation Modes" +description: "How to use and configure automation modes." +--- + +An automation can be triggered while it is already running. + +The automation's `mode` configuration option controls what happens when the automation is triggered while the actions are still running from a previous trigger. + +Mode | Description +-|- +`single` | (Default) Do not start a new run. Issue a warning. +`restart` | Start a new run after first stopping previous run. +`queued` | Start a new run after all previous runs complete. Runs are guaranteed to execute in the order they were queued. +`parallel` | Start a new, independent run in parallel with previous runs. + +

+ +

+ +For both `queued` and `parallel` modes, configuration option `max` controls the maximum +number of runs that can be executing and/or queued up at a time. The default is 10. + +When `max` is exceeded (which is effectively 1 for `single` mode) a log message will be emitted to indicate this has happened. Configuration option `max_exceeded` controls the severity level of that log message. Set it to `silent` to ignore warnings or set it to a [log level](/integrations/logger/#log-levels). The default is `warning`. + +## Example throttled automation + +Some automations you only want to run every 5 minutes. This can be achieved using the `single` mode and silencing the warnings when the automation is triggered while it's running. + +```yaml +automation: + - mode: single + max_exceeded: silent + trigger: + - ... + action: + - ... + - delay: 300 # seconds (=5 minutes) +``` + +## Example Queued + +Sometimes an automation is doing an action on a device that does not support multiple simultaneous actions. In such cases, a queue can be used. In that case, the automation will be executed once it's current invocation and queue are done. + +```yaml +automation: + - mode: queued + max: 25 + trigger: + - ... + action: + - ... +``` diff --git a/source/_docs/automation/services.markdown b/source/_docs/automation/services.markdown new file mode 100644 index 00000000000..57525889bde --- /dev/null +++ b/source/_docs/automation/services.markdown @@ -0,0 +1,46 @@ +--- +title: "Automation Services" +description: "How to use the various automation services." +--- + +The automation integration has services to control automations, like turning automations on and off. This can be useful if you want to disable an automation from another automation. + +## Service `automation.turn_on` + +This service enables the automation's triggers. + +Service data attribute | Optional | Description +-|-|- +`entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. + +## Service `automation.turn_off` + +This service disables the automation's triggers, and optionally stops any currently active actions. + +Service data attribute | Optional | Description +-|-|- +`entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. +`stop_actions` | yes | Stop any currently active actions (defaults to true). + +## Service `automation.toggle` + +This service enables the automation's triggers if they were disabled, or disables the automation's triggers, and stops any currently active actions, if the triggers were enabled. + +Service data attribute | Optional | Description +-|-|- +`entity_id` | no | Entity ID of automation to turn on. Can be a list. `none` or `all` are also accepted. + +## Service `automation.trigger` + +This service will trigger the action of an automation. By default it bypasses any conditions, though that can be changed via the `skip_condition` attribute. + +Service data attribute | Optional | Description +-|-|- +`entity_id` | no | Entity ID of automation to trigger. Can be a list. `none` or `all` are also accepted. +`skip_condition` | yes | Whether or not the condition will be skipped (defaults to true). + +## Service `automation.reload` + +_This service is only required if you create/edit automations in YAML. Automations via the UI do this automatically._ + +This service reloads all automations, stopping all currently active automation actions. diff --git a/source/_docs/automation/trigger.markdown b/source/_docs/automation/trigger.markdown index 4d7466069d8..443349800f6 100644 --- a/source/_docs/automation/trigger.markdown +++ b/source/_docs/automation/trigger.markdown @@ -32,6 +32,18 @@ automation: - ANOTHER_USER_ID ``` +It is also possible to listen for multiple events at once. This is useful for +event that contain no, or similar, data and contexts. + +```yaml +automation: + trigger: + platform: event + event_type: + - automation_reloaded + - scene_reloaded +``` + ### Home Assistant trigger Fires when Home Assistant starts up or shuts down. @@ -319,8 +331,6 @@ A very thorough explanation of this is available in the Wikipedia article about Fires when a [tag](/integrations/tag) is scanned. For example, a NFC tag is scanned using the Home Assistant Companion mobile application. -{% raw %} - ```yaml automation: trigger: @@ -328,13 +338,9 @@ automation: tag_id: A7-6B-90-5F ``` -{% endraw %} - Additionally, you can also only trigger if a card is scanned by a specific device/scanner by setting the `device_id`: -{% raw %} - ```yaml automation: trigger: @@ -343,7 +349,19 @@ automation: device_id: 0e19cd3cf2b311ea88f469a7512c307d ``` -{% endraw %} +Or trigger on multiple possible devices for multiple tags: + +```yaml +automation: + trigger: + platform: tag + tag_id: + - A7-6B-90-5F + - A7-6B-15-AC + device_id: + - 0e19cd3cf2b311ea88f469a7512c307d + - d0609cb25f4a13922bb27d8f86e4c821 +``` ### Template trigger diff --git a/source/_docs/automation/using_blueprints.markdown b/source/_docs/automation/using_blueprints.markdown new file mode 100644 index 00000000000..4eccd471673 --- /dev/null +++ b/source/_docs/automation/using_blueprints.markdown @@ -0,0 +1,45 @@ +--- +title: "Using Automation Blueprints" +description: "How to create automations based off blueprints." +--- + +Automation blueprints are pre-made automations that you can easily add to your Home Assistant instance. Each blueprint can be added as many times as you want. + +Quick links: + - [Blueprints in the Home Assistant forums][blueprint-forums] + +## Blueprint Automations + +Automations based on a blueprint only need to be configured to be used. What needs to be configured differs on each blueprint. + +To create your first automation based on a blueprint, go to **Configuration** and then **Blueprints**. Find the blueprint that you want to use and click on "Create Automation". + +This will open the automation editor with the blueprint selected. Give it a name and configure the blueprint and click on the blue button "Save Automation" in the bottom right. + +Done! If you want to revisit the configuration values, you can find it by going to **Configuration** and then **Automations**. + +## Importing blueprints + +Home Assistant can import blueprints from the Home Assistant forums, GitHub and GitHub gists. + +To do this, first [find a blueprint you want to import][blueprint-forums]. If you just want to practice importing, you can use this URL: + +```text +https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml +``` + +Go to **Configuration** and then **Blueprints**. Click on the blue "Import Blueprint" button in the bottom right. + +A new dialog will pop-up asking you for the URL. Enter the URL and click on "preview blueprint". + +This will load the blueprint and show a preview in the import dialog. You can change the name and finish the import. + +The blueprint can now be used for creating automations. + +## Finding new blueprints + +The Home Assistant Community forums have a specific tag for blueprints. This tag is used to collect all blueprints. + +[Visit the Home Assistant forums][blueprint-forums] + +[blueprint-forums]: /get-blueprints \ No newline at end of file diff --git a/source/_docs/automation/yaml.markdown b/source/_docs/automation/yaml.markdown new file mode 100644 index 00000000000..7ab5a71d95f --- /dev/null +++ b/source/_docs/automation/yaml.markdown @@ -0,0 +1,145 @@ +--- +title: "Automation YAML" +description: "How to use the automation integration with YAML." +--- + +Automations are created in Home Assistant via the UI, but are stored in a YAML format. If you want to edit the YAML of an automation, go to edit the automation, click on the menu button in the top right and turn on YAML mode. + +The UI will write your automations to `automations.yaml`. This file is managed by the UI and should not be edited manually. + +It is also possible to write your automations directly inside `configuration.yaml` or other YAML files. You can do this by adding a labeled `automation` block to your `configuration.yaml`: + +```yaml +# The configuration required for the UI to work +automation: !include automations.yaml + +# Labeled automation block +automation kitchen: +- trigger: + platform: ... +``` + +You can add as many labeled `automation` blocks as you want. + +## YAML Example + +Example of a YAML based automation that you can add to `configuration.yaml`. + +{% raw %} +```yaml +# Example of entry in configuration.yaml +automation my_lights: +# Turns on lights 1 hour before sunset if people are home +# and if people get home between 16:00-23:00 + - alias: 'Rule 1 Light on in the evening' + trigger: + # Prefix the first line of each trigger configuration + # with a '-' to enter multiple + - platform: sun + event: sunset + offset: '-01:00:00' + - platform: state + entity_id: all + to: 'home' + condition: + # Prefix the first line of each condition configuration + # with a '-'' to enter multiple + - condition: state + entity_id: all + state: 'home' + - condition: time + after: '16:00:00' + before: '23:00:00' + action: + # With a single service call, we don't need a '-' before service - though you can if you want to + service: homeassistant.turn_on + entity_id: group.living_room + +# Turn off lights when everybody leaves the house + - alias: 'Rule 2 - Away Mode' + trigger: + platform: state + entity_id: all + to: 'not_home' + action: + service: light.turn_off + entity_id: all + +# Notify when Paulus leaves the house in the evening + - alias: 'Leave Home notification' + trigger: + platform: zone + event: leave + zone: zone.home + entity_id: device_tracker.paulus + condition: + condition: time + after: '20:00' + action: + service: notify.notify + data: + message: 'Paulus left the house' + +# Send a notification via Pushover with the event of a Xiaomi cube. Custom event from the Xiaomi component. + - alias: 'Xiaomi Cube Action' + initial_state: false + trigger: + platform: event + event_type: cube_action + event_data: + entity_id: binary_sensor.cube_158d000103a3de + action: + service: notify.pushover + data: + title: "Cube event detected" + message: "Cube has triggered this event: {{ trigger.event }}" +``` +{% endraw %} + + +## Extra options + +When writing automations directly in YAML, you will have access to advanced options that are not available in the user interface. + +### Automation initial state + +At startup, automations by default restore their last state of when Home Assistant ran. This can be controlled with the `initial_state` option. Set it to `false` or `true` to force initial state to be off or on. + +```yaml +automation: +- alias: Automation Name + initial_state: false + trigger: + - platform: ... +``` + +## Migrating your YAML automations to `automations.yaml` + +If you want to migrate your manual automations to use the editor, you'll have to copy them to `automations.yaml`. Make sure that `automations.yaml` remains a list! For each automation that you copy over, you'll have to add an `id`. This can be any string as long as it's unique. + +```yaml +# Example automations.yaml entry. Note, automations.yaml is always a list! +- id: my_unique_id # <-- Required for editor to work, for automations created with the editor the id will be automatically generated. + alias: Hello world + trigger: + - platform: state + entity_id: sun.sun + from: below_horizon + to: above_horizon + condition: + - condition: numeric_state + entity_id: sensor.temperature + above: 17 + below: 25 + value_template: '{% raw %}{{ float(state.state) + 2 }}{% endraw %}' + action: + - service: light.turn_on +``` + +### Deleting Automations + +When automations remain visible in the Home Assistant Dashboard, even after having deleted in the YAML file, you have to delete them in the UI. + +To delete them completely, go to UI **Configuration** -> **Entities** and find the automation in the search field or by scrolling down. + +Check the square box aside of the automation you wish to delete and from the top-right of your screen, select 'REMOVE SELECTED'. diff --git a/source/_docs/blueprint.markdown b/source/_docs/blueprint.markdown new file mode 100644 index 00000000000..d97d4f95c24 --- /dev/null +++ b/source/_docs/blueprint.markdown @@ -0,0 +1,22 @@ +--- +title: "Creating blueprints" +description: "Documentation on how to get started creating blueprints." +--- + +
+ +If you're looking on how to use blueprints, see the [automation documentation](/docs/automation/using_blueprints/). + +
+ +An automation blueprint is an automation configuration with certain parts marked as configurable. This allows users to create multiple automations based on the same blueprint, with each having its own configuration. + +Imagine a blueprint that controls a light based on motion, that allows you to configure the motion sensor to trigger on, and the light to control. It is now possible to create two automations that each have their own configuration for this blueprint and that act completely independent, yet are based on the same automation configuration. + +
+ +This is an advanced feature and requires knowledge of writing [automations in YAML](/docs/automation/yaml/). + +
+ +### [Tutorial: Create a blueprint »](/docs/blueprint/tutorial/) diff --git a/source/_docs/blueprint/schema.markdown b/source/_docs/blueprint/schema.markdown new file mode 100644 index 00000000000..90f2c105fd1 --- /dev/null +++ b/source/_docs/blueprint/schema.markdown @@ -0,0 +1,183 @@ +--- +title: "Blueprint schema" +description: "The schema for a valid blueprint." +--- + +The configuration schema of a blueprint consists of 2 parts: + +- The blueprint high-level metadata, like its name and a description and + the input the blueprint needs from the user. +- The schema of the thing the blueprint describes. + +The first part is referred to as the blueprint schema and contains mainly the +blueprint's metadata. The second part depends on what the blueprint is for. + +For example, in the case of creating a blueprint for an automation, the full +schema for an [automation](/docs/automation/yaml/) applies. + +This page is mainly set up to describe the configuration schema of the +blueprint metadata. Try our [blueprint tutorial](/docs/blueprint/tutorial/) +in case you are interested in creating your first blueprint. + +## The blueprint schema + +The only requirement for a blueprint is a name. In its most basic form, +a blueprint would look like: + +```yaml +blueprint: + name: Example blueprint + domain: automation +``` + +And this is already a valid blueprint. But typically, one would need +more. For example, user inputs or a description to describe the blueprint's +functionality. + +This is the full blueprint schema: + +{% configuration %} +name: + description: The name of the blueprint. Keep this short and descriptive. + type: string + required: true +description: + description: > + The description of the blueprint. While optional, this field is highly + recommended. For example, to describe what the blueprint does, or tell more + about the options inputs of the blueprint provide. New lines in this + description are displayed in the UI, so paragraphs are allowed. + type: string + required: false +domain: + description: > + The domain name this blueprint provides a blueprint for. Currently, only + `automation` is supported. + type: string + required: true +input: + description: > + A dictionary of defined user inputs. These are the input fields that the + consumer of your blueprint can provide using YAML definition, or via + a configuration form in the UI. + type: map + required: false + keys: + name: + description: The name of the input field. + type: string + required: false + description: + description: > + A short description of the input field. Keep this short and descriptive. + type: string + required: false + selector: + description: > + The [selector](/docs/blueprint/selectors/) to use for this input. A + selector defines how the input is displayed in the frontend UI. + type: selector + required: false + default: + description: > + The default value of this input, in case the input is not provided + by the user of this blueprint. + type: any + required: false +{% endconfiguration %} + +## Blueprint inputs + +As written in the above schema, a blueprint can accept one (or multiple) +inputs from the blueprint consumer. + +These inputs can be of any type (string, boolean, list, dictionary), can have +a default value and also provide a [selector](/docs/blueprint/selectors/) that +ensures a matching input field in the user interface. + +Each input field can be referred to, outside of the blueprint metadata, using +the `!input` custom tag. + +The following example shows a minimal blueprint with a single input: + +```yaml +blueprint: + name: Example blueprint + description: Example showing an input + input: + my_input: + name: Example input +``` + +In the above example, `my_input` is the identifier of the input, that can be +referred to later on using the `!input my_input` custom tag. + +In this example, no `selector` was provided. In this case, if this blueprint +was used in the user interface, a text input field would be shown to the user. + +A blueprint can have as many inputs as you like. + +## Example blueprints + +The [built-in blueprints][blueprint-built-in] +are great examples to get a bit of a feeling of how blueprints work. + +Here is the built-in motion light automation blueprint: + +```yaml +blueprint: + name: Motion-activated Light + description: Turn on a light when motion is detected. + domain: automation + input: + motion_entity: + name: Motion Sensor + selector: + entity: + domain: binary_sensor + device_class: motion + light_target: + name: Light + selector: + target: + entity: + domain: light + no_motion_wait: + name: Wait time + description: Time to leave the light on after last motion is detected. + default: 120 + selector: + number: + min: 0 + max: 3600 + unit_of_measurement: seconds + +# If motion is detected within the delay, +# we restart the script. +mode: restart +max_exceeded: silent + +trigger: + platform: state + entity_id: !input motion_entity + from: "off" + to: "on" + +action: + - service: light.turn_on + target: !input light_target + - wait_for_trigger: + platform: state + entity_id: !input motion_entity + from: "on" + to: "off" + - delay: !input no_motion_wait + - service: light.turn_off + target: !input light_target +``` + +Additional examples, provided by the community, can be found on the +[community forum][blueprint-forums]. + +[blueprint-built-in]: https://github.com/home-assistant/core/tree/dev/homeassistant/components/automation/blueprints +[blueprint-forums]: /get-blueprints diff --git a/source/_docs/blueprint/selectors.markdown b/source/_docs/blueprint/selectors.markdown new file mode 100644 index 00000000000..a67a244039b --- /dev/null +++ b/source/_docs/blueprint/selectors.markdown @@ -0,0 +1,492 @@ +--- +title: "Selectors" +description: "Documentation on available selectors." +--- + +Selectors can be used to specify what values are accepted for a blueprint +input. The selector also defines how the input is shown in the user interface. + +Some selectors can, for example, show a toggle button to turn something +on or off, while another select can filter a list of devices to show +only devices that have motion-sensing capabilities. + +Having the good selectors set on your blueprint automations inputs makes a +blueprint easier to use from the UI. + +The following selectors are currently available: + +- [Action selector](#action-selector) +- [Area selector](#area-selector) +- [Boolean selector](#boolean-selector) +- [Device selector](#device-selector) +- [Entity selector](#entity-selector) +- [Number selector](#number-selector) +- [Target selector](#target-selector) +- [Time selector](#time-selector) + +If no selector is defined, a text input for a single line will be shown. + +## Action selector + +The action selector allows the user to input one or more sequences of actions. +On the user interface, the action part of the automation editor will be shown. +The value of the input will contain a list of actions to perform. + +![Screenshot of an action selector](/images/blueprints/selector-action.png) + +This selector does not have any other options; therefore, it only has its key. + +```yaml +action: +``` + +## Area selector + +The area selector shows an area finder that can pick a single area. The value +of the input will be the area ID of the user-selected area. + +An area selector can filter the list of areas, based on properties of the devices +and entities that are assigned to those areas. For example, the areas list could +be limited to areas with entities provided by the [ZHA](/integration/zha) +integration. + +In its most basic form, it doesn't require any options, which will show +all areas. + +```yaml +area: +``` + +{% configuration area %} +device: + description: > + When device options are provided, the list of areas is filtered by areas + that at least provide one device that matches the given conditions. + type: map + keys: + integration: + description: > + Can be set to an integration domain. Limits the list of areas that + provide devices by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false + manufacturer: + description: > + When set, it limits the list of areas that provide devices by the set + manufacturer name. + type: string + required: false + model: + description: > + When set, it limits the list of areas that provide devices that have + the set model. + type: string + required: false +entity: + description: > + When entity options are provided, the list of areas is filtered by areas + that at least provide one entity that matches the given conditions. + type: map + required: false + keys: + integration: + description: > + Can be set to an integration domain. Limits the list of areas that + provide entities by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false + domain: + description: > + Limits the list of areas that provide entities of a certain domain, + for example, [`light`](/integrations/light) or + [`binary_sensor`](/integrations/binary_sensor). + type: string + required: false + device_class: + description: > + Limits the list of areas to areas that have entities with a certain + device class, for example, `motion` or `window`. + type: device_class + required: false +{% endconfiguration %} + +### Example area selectors + +An example area selector only shows areas that provide one or more lights +provided by the [ZHA](/integrations/zha) integration. + +```yaml +area: + entity: + integration: zha + domain: light +``` + +Another example uses the area selector, which only shows areas that provide one +or more remote controls provided by the [deCONZ](/integrations/deconz) +integration. + +```yaml +area: + device: + integration: deconz + manufacturer: IKEA of Sweden + model: TRADFRI remote control +``` + +## Boolean selector + +The boolean selector shows a toggle that allows the user to turn on or off +the selected option. The input's value will contain the boolean value of that +toggle as a boolean value, being `true` or `false`. + +![Screenshot of a boolean selector](/images/blueprints/selector-boolean.png) + +The boolean selector can be incredibly useful for adding feature switches +to, for example, blueprints. + +This selector does not have any other options; therefore, it only has its key. + +```yaml +boolean: +``` + +## Device selector + +The device selector shows a device finder that can pick a single device. +The value of the input will contain the device ID of the user-selected device. + +A device selector can filter the list of devices, based on things like the +manufacturer or model of the device, the entities the device provides or based +on the domain that provided the device. + +![Screenshot of an device selector](/images/blueprints/selector-device.png) + +In its most basic form, it doesn't require any options, which will show +all devices. + +```yaml +device: +``` + +{% configuration device %} +integration: + description: > + Can be set to an integration domain. Limits the list of devices to devices + provided by the set integration domain. + type: string + required: false +manufacturer: + description: > + When set, it limits the list of devices to devices provided by the set + manufacturer name. + type: string + required: false +model: + description: > + When set, it limits the list of devices to devices that have the set model. + type: string + required: false +entity: + description: > + When entity options are provided, the list of devices is filtered by devices + that at least provide one entity that matches the given conditions. + type: map + required: false + keys: + integration: + description: > + Can be set to an integration domain. Limits the list of devices that + provide entities by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false + domain: + description: > + Limits the list of devices that provide entities of a certain domain, + for example, [`light`](/integrations/light) + or [`binary_sensor`](/integrations/binary_sensor). + type: string + required: false + device_class: + description: > + Limits the list of entities to entities that have a certain device + class, for example, `motion` or `window`. + type: device_class + required: false +{% endconfiguration %} + +### Example device selector + +An example entity selector that, will only show devices that are: + +- Provided by the [deCONZ](/integration/deconz) integration. +- Are a Philips Hue Remote of Model RWL021. +- Provide a battery [sensor](/integration/sensor). + +And this is what is looks like in YAML: + +```yaml +device: + integration: deconz + manufacturer: Philips + model: RWL021 + entity: + domain: sensor + device_class: battery +``` + +## Entity selector + +The entity selector shows an entity finder that can pick a single entity. +The value of the input will contain the entity ID of user-selected entity. + +An entity selector can filter the list of entities, based on things like the +class of the device, the domain of the entity or the domain that provided the +entity. + +![Screenshot of an entity selector](/images/blueprints/selector-entity.png) + +In its most basic form, it doesn't require any options, which will show +all entities. + +```yaml +entity: +``` + +{% configuration entity %} +integration: + description: > + Can be set to an integration domain. Limits the list of entities to entities + provided by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false +domain: + description: > + Limits the list of entities to entities of a certain domain, for example, + [`light`](/integrations/light) or + [`binary_sensor`](/integrations/binary_sensor). + type: string + required: false +device_class: + description: > + Limits the list of entities to entities that have a certain device class, + for example, `motion` or `window`. + type: device_class + required: false +{% endconfiguration %} + +### Example entity selector + +An example entity selector that, will only show entities that are: + +- Provided by the [ZHA](/integration/zha) integration. +- From the [Binary Sensor](/integration/binary_sensor) domain. +- Have presented themselves as devices of a motion device class. + +And this is what it looks like in YAML: + +```yaml +entity: + integration: zha + domain: binary_sensor + device_class: motion +``` + +## Number selector + +The number selector shows either a number input or a slider input, that allows +the user to specify a numeric value. The value of the input will contain +the select value. + +![Screenshot of a number selector](/images/blueprints/selector-number.png) + +On the user interface, the input can either be in a slider or number mode. +Both modes limit the user input by a minimal and maximum value, and can +have a unit of measurement to go with it. + +In its most basic form, it requires a minimal and maximum value: + +```yaml +number: + min: 0 + max: 100 +``` + +{% configuration number %} +min: + description: The minimal user-settable number value. + type: [integer, float] + required: true +max: + description: The maximum user-settable number value. + type: [integer, float] + required: true +step: + description: The step value of the number value. + type: [integer, float] + required: false + default: 1 +unit_of_measurement: + description: Unit of measurement in which the number value is expressed in. + type: string + required: false +mode: + description: This can be either `box` or `slider` mode. + type: string + required: false + default: box +{% endconfiguration %} + +### Example number selectors + +An example number selector that allows a user a percentage, directly in a +regular number input box. + +```yaml +number: + min: 0 + max: 100 + unit_of_measurement: "%" +``` + +A more visual variant of this example could be achieved using a slider. +This can be helpful for things like allowing the user to select a +brightness level of lights. Additionally, this example changes the brightness +in incremental steps of 10%. + +```yaml +number: + min: 0 + max: 100 + step: 10 + unit_of_measurement: "%" + mode: slider +``` + +## Target selector + +The target selector is a rather special selector, allowing the user to selector +targeted entities, devices or areas for service calls. The value of +the input will contain a special target format, that is accepted by +service calls. + +The selectable targets can be filtered, based on entity or device properties. +Areas are only selectable as a target, if some entities or devices match +those properties in those areas. + +![Screenshot of a target selector](/images/blueprints/selector-target.png) + +Its most basic form, doesn't require any options, which will allow the +user to target any entity, device or area available in the system. + +```yaml +target: +``` + +{% configuration target %} +device: + description: > + When device options are provided, the targets are limited by devices + that at least match the given conditions. + type: map + keys: + integration: + description: > + Can be set to an integration domain. Limits the device targets that + are provided devices by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false + manufacturer: + description: > + When set, it limits the targets to devices provided by the set + manufacturer name. + type: string + required: false + model: + description: When set, it limits the targets to devices by the set model. + type: string + required: false +entity: + description: > + When entity options are provided, the targets are limited by entities + that at least match the given conditions. + type: map + required: false + keys: + integration: + description: > + Can be set to an integration domain. Limits targets to entities + provided by the set integration domain, for example, + [`zha`](/integrations/zha). + type: string + required: false + domain: + description: > + Limits the targets to entities of a certain domain, + for example, [`light`](/integrations/light) or + [`binary_sensor`](/integrations/binary_sensor). + type: string + required: false + device_class: + description: > + Limits the targets to entities with a certain + device class, for example, `motion` or `window`. + type: device_class + required: false +{% endconfiguration %} + +
+ +Targets are meant to be used with the `target` property of a service call in +a script sequence. For example: + +```yaml +action: + - service: light.turn_on + target: !input lights +``` + +
+ +### Example target selectors + +An example target selector that only shows targets that at least provide one +or more lights, provided by the [ZHA](/integrations/zha) integration. + +```yaml +target: + entity: + integration: zha + domain: light +``` + +Another example using the target selector, which only shows targets that +provide one or more remote controls, provided by the +[deCONZ](/integrations/deconz) integration. + +```yaml +target: + device: + integration: deconz + manufacturer: IKEA of Sweden + model: TRADFRI remote control +``` + +## Time selector + +The time selector shows a time input that allows the user to specify a time +of the day. The value of the input will contain the time in 24-hour format, +for example, `23:59:59`. + +![Screenshot of a time selector](/images/blueprints/selector-time.png) + +This selector does not have any other options; therefore, it only has its key. + +```yaml +time: +``` diff --git a/source/_docs/blueprint/tutorial.markdown b/source/_docs/blueprint/tutorial.markdown new file mode 100644 index 00000000000..97011da201b --- /dev/null +++ b/source/_docs/blueprint/tutorial.markdown @@ -0,0 +1,229 @@ +--- +title: "Blueprint tutorial" +description: "Tutorial on creating a blueprint." +--- + +In this tutorial, we're going to create a blueprint that controls a light based on a motion sensor. We will do this by taking an existing automation and converting it to a blueprint. + +For this tutorial, we use a simple automation. The process for converting a complex automation is not any different. + +## Our automation + +To create a blueprint, we first need to have a working automation. The automation we're going to use in this tutorial, which controls a light based on a motion sensor, looks like this: + +{% raw %} + +```yaml +trigger: + platform: state + entity_id: binary_sensor.motion_kitchen + +action: + service: > + {% if trigger.to_state.state == "on" %} + light.turn_on + {% else %} + light.turn_off + {% endif %} + target: + entity_id: light.kitchen +``` + +{% endraw %} + +## Create the blueprint file + +Automation blueprints are YAML files (with the `.yaml` extension) and live in the `/blueprints/automation/` folder. You can create as many subdirectories in this folder as you want. + +To get started with our blueprint, we're going to copy the above automation YAML and save it in that directory with the name `motion_light_tutorial.yaml`. + +## Add basic blueprint metadata + +Home Assistant needs to know about the blueprint. This is achieved by adding a `blueprint:` section. It should contain the `domain` of the integration it is for (`automation`) and `name`, the name of your blueprint. Optionally, you can also include a `description` for your blueprint. + +Add this to the top of the file: + +```yaml +blueprint: + name: Motion Light Tutorial + description: Turn a light on based on detected motion + domain: automation +``` + +## Define the configurable parts as inputs + +Now we have to decide what steps we want to make configurable. We want to make it as re-usable as possible, without losing its original intent of turning on a light-based on a motion sensor. + +Configurable parts in blueprints are called inputs. To make the motion sensor entity configurable, we're replacing the entity ID with a custom YAML tag `!input`. This YAML tag has to be combined with the name of the input: + +```yaml +trigger: + platform: state + entity_id: !input motion_sensor +``` + +For the light, we can offer some more flexibility. We want to allow the user to be able to define any device or area as the target. The `target` property in the service action can contain references to areas, devices and/or entities, so that's what we will use. + +Inputs are not limited to strings. They can contain complex objects too. So in this case, we're going to mark the whole `target` as input: + +{% raw %} + +```yaml +action: + service: > + {% if trigger.to_state.state == "on" %} + light.turn_on + {% else %} + light.turn_off + {% endif %} + target: !input target_light +``` + +{% endraw %} + +## Add the inputs to the metadata + +All parts that are marked as inputs need to be added to the metadata. The minimum is that we add their names as used in the automation: + +```yaml +blueprint: + name: Motion Light Tutorial + description: Turn a light on based on detected motion + domain: automation + input: + motion_sensor: + target_light: +``` + +## Use it via `configuration.yaml` + +With the bare minimum metadata added, your blueprint is ready to use. + +Open your `configuration.yaml` and add the following: + +```yaml +automation tutorial: + use_blueprint: + path: motion_light_tutorial.yaml + input: + motion_sensor: binary_sensor.kitchen + target_light: + entity_id: light.kitchen +``` + +Reload automations and your new automation should popup. Because we configured the exact values as the original automation, they should work exactly the same. + +## Adding user friendly names to the inputs + +Blueprints are easier to use if it's easy to see what each field is used for. We can improve this experience by adding names and descriptions to our inputs: + +```yaml +blueprint: + name: Motion Light Tutorial + domain: automation + input: + motion_sensor: + name: Motion Sensor + description: This sensor will be synchronized with the light. + target_light: + name: Lights + description: The lights to keep in sync. +``` + +## Describing the inputs + +Our blueprint doesn't currently describe what the inputs should contain. Without this information, Home Assistant will offer the user an empty text box. + +To instead allow Home Assistant to offer more assistance, we will use [selectors](/docs/blueprint/selectors/). Selectors describe a type and can be used to help the user pick a matching value. + +The selector for the motion sensor entity should describe that we want entities from the binary sensor domain that have the device class `motion`. + +The selector for the target light should describe that we want to target light entities. + +```yaml +blueprint: + name: Motion Light Tutorial + domain: automation + input: + motion_sensor: + name: Motion Sensor + description: This sensor will be synchronized with the light. + selector: + entity: + domain: binary_sensor + device_class: motion + target_light: + name: Lights + description: The lights to keep in sync. + selector: + target: + entity: + domain: light +``` + +By limiting our blueprint to working with lights and motion sensors, we unlock a couple of benefits: the UI will be able to limit suggested values to lights and motion sensors instead of all devices. It will also allow the user to pick an area to control the lights in. + +## The final blueprint + +After we have added all the steps, our blueprint will look like this: + +{% raw %} + +```yaml +blueprint: + name: Motion Light Tutorial + description: Turn a light on based on detected motion + domain: automation + input: + motion_sensor: + name: Motion Sensor + description: This sensor will be synchronized with the light. + selector: + entity: + domain: binary_sensor + device_class: motion + target_light: + name: Lights + description: The lights to keep in sync. + selector: + target: + entity: + domain: light + +trigger: + platform: state + entity_id: !input motion_sensor + +action: + service: > + {% if trigger.to_state.state == "on" %} + light.turn_on + {% else %} + light.turn_off + {% endif %} + target: !input target_light +``` + +{% endraw %} + +## Use it via the UI + +To configure it via the UI, go to **Configuration** and then **Blueprints**. Find the "Motion Light Tutorial" blueprint and click on "Create Automation". + +
+Don't forget to reload automations after you make changes to your blueprint to have the UI and the automation integration pick up the latest blueprint changes. +
+ +![Screenshot of the blueprint UI](/images/blueprints/tutorial-ui.png) + +## Share the love + +The final step is to share this blueprint with others. For this tutorial we're going to share it on GitHub Gists. + +- Go to [GitHub Gists](https://gist.github.com/) +- Gist description: blueprint tutorial +- Filename including extension: `motion_light_tutorial.yaml` +- Content is the content of the blueprint file. +- Click the "Create Gist" button + +You can now copy the URL of your new Gist and share it with other people. They can import it by going to **Configuration**, **Blueprints** and clicking on the blue "Import Blueprint" button. diff --git a/source/_docs/scripts/service-calls.markdown b/source/_docs/scripts/service-calls.markdown index 9559af19c81..98f081eac56 100644 --- a/source/_docs/scripts/service-calls.markdown +++ b/source/_docs/scripts/service-calls.markdown @@ -22,6 +22,28 @@ service: homeassistant.turn_on entity_id: group.living_room ``` +### Targeting areas and devices + +Instead of targeting an entity, you can also target an area or device. Or a combination of these. +This is done with the `target` key. + +A `target` is a map thats contains atleast one of the following: `area_id`, `device_id`, `entity_id`. +Each of these can be a list. + +When the service is called, the area's and devices will be resolved to entities. + +```yaml +service: homeassistant.turn_on +target: + area_id: livingroom + device_id: + - ff22a1889a6149c5ab6327a8236ae704 + - 52c050ca1a744e238ad94d170651f96b + entity_id: + - light.hallway + - light.landing +``` + ### Passing data to the service call You can also specify other parameters beside the entity to target. For example, the light turn on service allows specifying the brightness. diff --git a/source/_includes/asides/docs_navigation.html b/source/_includes/asides/docs_navigation.html index 5ccf656b2e8..f70674aa17c 100644 --- a/source/_includes/asides/docs_navigation.html +++ b/source/_includes/asides/docs_navigation.html @@ -85,17 +85,29 @@
  • {% active_link /docs/automation/ Automation %}
  • +
  • + {% active_link /docs/blueprint/ Blueprints %} + +
  • {% active_link /docs/frontend/ Frontend %}