├── .gitattributes ├── .github ├── .weekly-digest.yml └── config.yml ├── .gitignore ├── README.md └── config ├── alerts ├── garage_after_dark.yaml ├── jeff_bad_traffic_home.yaml ├── jeff_heading_home.yaml ├── kat_heading_home.yaml ├── lockdown_issue.yaml ├── unauthorized_access.yaml └── washing_machine_finished.yaml ├── automations.yaml ├── binary_sensors └── calendar.yaml ├── configuration.yaml ├── custom_components ├── amazon_polly │ ├── _inti_.py │ └── tts.py ├── localtuya │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-39.pyc │ │ ├── binary_sensor.cpython-39.pyc │ │ ├── climate.cpython-39.pyc │ │ ├── common.cpython-39.pyc │ │ ├── config_flow.cpython-39.pyc │ │ ├── const.cpython-39.pyc │ │ ├── cover.cpython-39.pyc │ │ ├── discovery.cpython-39.pyc │ │ ├── fan.cpython-39.pyc │ │ ├── light.cpython-39.pyc │ │ ├── number.cpython-39.pyc │ │ ├── select.cpython-39.pyc │ │ ├── sensor.cpython-39.pyc │ │ ├── switch.cpython-39.pyc │ │ └── vacuum.cpython-39.pyc │ ├── binary_sensor.py │ ├── climate.py │ ├── common.py │ ├── config_flow.py │ ├── const.py │ ├── cover.py │ ├── discovery.py │ ├── fan.py │ ├── light.py │ ├── manifest.json │ ├── number.py │ ├── pytuya │ │ ├── __init__.py │ │ └── __pycache__ │ │ │ └── __init__.cpython-39.pyc │ ├── select.py │ ├── sensor.py │ ├── services.yaml │ ├── strings.json │ ├── switch.py │ ├── translations │ │ └── en.json │ └── vacuum.py └── nws_alerts │ ├── __init__.py │ └── sensor.py ├── customize.yaml ├── groups.yaml ├── input_boolean.yaml ├── input_datetime.yaml ├── input_select.yaml ├── lights.yaml ├── media └── haunted_sounds │ ├── ChainsRattling.mp3 │ ├── CreakingDoorSpooky.mp3 │ ├── EvilLaughCackle.mp3 │ ├── Evil_Laugh_2.mp3 │ ├── Evillaugh.mp3 │ ├── Haunted-CatScream.mp3 │ ├── Haunted-DragonRoaring.mp3 │ ├── Haunted-Heart.mp3 │ ├── Haunted-ScaryScream.mp3 │ ├── Haunted-TollingBell.mp3 │ ├── Scary.mp3 │ ├── This_is_Halloween.mp3 │ └── raven.mp3 ├── packages ├── README.md ├── announcements.yaml ├── appliances.yaml ├── audio.yaml ├── batteries.yaml ├── camera.yaml ├── cuckoo_clock.yaml ├── daily.yaml ├── database.yaml ├── disney.yaml ├── events.yaml ├── halloween.yaml ├── haunted_mansion_show.yaml ├── holidays.yaml ├── integrations.yaml ├── inventory.yaml ├── jarvis.yaml ├── json_data │ └── school.json ├── lighting.yaml ├── maintenance.yaml ├── notify.yaml ├── presence.yaml ├── reminders.yaml ├── security.yaml ├── space.yaml ├── speech.yaml ├── spotify.yaml ├── switchbot.yaml ├── sysmon.yaml ├── twitter.yaml ├── usps.yaml ├── weather.yaml ├── weatheralerts.yaml ├── youtube.yaml └── zigbee2mqtt.yaml ├── python_scripts ├── light_transistion.py └── special_events.py ├── scenes.yaml ├── scripts.yaml ├── sensors ├── finance.yaml ├── github.yaml ├── google_travel_time.yaml ├── house.yaml ├── power.yaml ├── speedtest.yaml └── users.yaml ├── switches.yaml ├── templates ├── speech │ ├── already_done.yaml │ ├── daily_briefing.yaml │ ├── event_briefing.yaml │ ├── example.yaml │ ├── interjections.yaml │ ├── morning_briefing.yaml │ ├── morning_wakeup_report.yaml │ ├── nightly_briefing.yaml │ ├── security_briefing.yaml │ ├── security_report.yaml │ ├── skylar_morning_briefing.yaml │ ├── skylar_nightly_briefing.yaml │ ├── sundown_briefing.yaml │ └── welcome_briefing.yaml ├── twitter_follow_me.yaml ├── twitter_great_content.yaml ├── twitter_new_ha.yaml ├── twitter_promos.yaml ├── twitter_recent_content.yaml ├── twitter_selfpromos.yaml ├── twitter_snark.yaml └── twitter_stats.yaml ├── www └── ahlogo_bw.png └── zigbee2mqtt ├── aqara.js ├── easyiot.js ├── smartwings.js └── third_reality.js /.gitattributes: -------------------------------------------------------------------------------- 1 | ## GITATTRIBUTES FOR WEB PROJECTS 2 | # 3 | # These settings are for any web project. 4 | # 5 | # Details per file setting: 6 | # text These files should be normalized (i.e. convert CRLF to LF). 7 | # binary These files are binary and should be left untouched. 8 | # 9 | # Note that binary is a macro for -text -diff. 10 | ###################################################################### 11 | 12 | ## AUTO-DETECT - Handle line endings automatically for files detected 13 | ## as text and leave all files detected as binary untouched. 14 | ## This will handle all files NOT defined below. 15 | * text=auto 16 | 17 | ## SOURCE CODE 18 | *.bat text 19 | *.coffee text 20 | *.css text 21 | *.htm text 22 | *.html text 23 | *.inc text 24 | *.ini text 25 | *.js text 26 | *.jsx text 27 | *.json text 28 | *.less text 29 | *.php text 30 | *.pl text 31 | *.py text 32 | *.rb text 33 | *.sass text 34 | *.scm text 35 | *.scss text 36 | *.sh text 37 | *.sql text 38 | *.styl text 39 | *.ts text 40 | *.xml text 41 | *.xhtml text 42 | 43 | ## DOCUMENTATION 44 | *.markdown text 45 | *.md text 46 | *.mdwn text 47 | *.mdown text 48 | *.mkd text 49 | *.mkdn text 50 | *.mdtxt text 51 | *.mdtext text 52 | *.txt text 53 | AUTHORS text 54 | CHANGELOG text 55 | CHANGES text 56 | CONTRIBUTING text 57 | COPYING text 58 | INSTALL text 59 | license text 60 | LICENSE text 61 | NEWS text 62 | readme text 63 | *README* text 64 | TODO text 65 | 66 | ## TEMPLATES 67 | *.dot text 68 | *.ejs text 69 | *.haml text 70 | *.handlebars text 71 | *.hbs text 72 | *.hbt text 73 | *.jade text 74 | *.latte text 75 | *.mustache text 76 | *.phtml text 77 | *.tmpl text 78 | 79 | ## LINTERS 80 | .csslintrc text 81 | .eslintrc text 82 | .jscsrc text 83 | .jshintrc text 84 | .jshintignore text 85 | .stylelintrc text 86 | 87 | ## CONFIGS 88 | *.bowerrc text 89 | *.cnf text 90 | *.conf text 91 | *.config text 92 | .editorconfig text 93 | .gitattributes text 94 | .gitconfig text 95 | .gitignore text 96 | .htaccess text 97 | *.npmignore text 98 | *.yaml text 99 | *.yml text 100 | Makefile text 101 | makefile text 102 | 103 | ## HEROKU 104 | Procfile text 105 | .slugignore text 106 | 107 | ## GRAPHICS 108 | *.ai binary 109 | *.bmp binary 110 | *.eps binary 111 | *.gif binary 112 | *.ico binary 113 | *.jng binary 114 | *.jp2 binary 115 | *.jpg binary 116 | *.jpeg binary 117 | *.jpx binary 118 | *.jxr binary 119 | *.pdf binary 120 | *.png binary 121 | *.psb binary 122 | *.psd binary 123 | *.svg text 124 | *.svgz binary 125 | *.tif binary 126 | *.tiff binary 127 | *.wbmp binary 128 | *.webp binary 129 | 130 | ## AUDIO 131 | *.kar binary 132 | *.m4a binary 133 | *.mid binary 134 | *.midi binary 135 | *.mp3 binary 136 | *.ogg binary 137 | *.ra binary 138 | 139 | ## VIDEO 140 | *.3gpp binary 141 | *.3gp binary 142 | *.as binary 143 | *.asf binary 144 | *.asx binary 145 | *.fla binary 146 | *.flv binary 147 | *.m4v binary 148 | *.mng binary 149 | *.mov binary 150 | *.mp4 binary 151 | *.mpeg binary 152 | *.mpg binary 153 | *.swc binary 154 | *.swf binary 155 | *.webm binary 156 | 157 | ## ARCHIVES 158 | *.7z binary 159 | *.gz binary 160 | *.rar binary 161 | *.tar binary 162 | *.zip binary 163 | 164 | ## FONTS 165 | *.ttf binary 166 | *.eot binary 167 | *.otf binary 168 | *.woff binary 169 | *.woff2 binary 170 | 171 | ## EXECUTABLES 172 | *.exe binary 173 | *.pyc binary -------------------------------------------------------------------------------- /.github/.weekly-digest.yml: -------------------------------------------------------------------------------- 1 | publishDay: mon 2 | canPublishIssues: true 3 | canPublishPullRequests: true 4 | canPublishContributors: true 5 | canPublishStargazers: true 6 | canPublishCommits: true -------------------------------------------------------------------------------- /.github/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration for welcome - https://github.com/behaviorbot/welcome 2 | # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome 3 | 4 | # Comment to be posted to on first time issues 5 | newIssueWelcomeComment: > 6 | Thanks for helping make this code better! This is the place to request enhancements, ask questions and other things. You can also ask questions via twitter or https://jeffreystone.net 7 | 8 | # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome 9 | # Comment to be posted to on PRs from first time contributors in your repository 10 | newPRWelcomeComment: > 11 | Thanks for submitting a code change! Once @thejeffreystone reviews it, it will become part of the master! 12 | # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge 13 | # Comment to be posted to on pull requests merged by a first time user 14 | firstPRMergeComment: > 15 | Congrats on contributing to the code base! Your contribution is very much appreciated and I hope you continue to support this little project by improving code and documentation! 16 | # It is recommended to include as many gifs and emojis as possible! 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore my git update script 2 | update_git.py 3 | transporter.py 4 | 5 | # ignore hidden folders 6 | /config/.storage 7 | /config/.cloud 8 | /config/.google.token 9 | 10 | # ignore some directories. 11 | /config/icloud/ 12 | /config/www/ 13 | /config/tts/ 14 | /config/deps/ 15 | /config/hadashboards/ 16 | /config/intents/ 17 | /config/themes/ 18 | /config/custom_components 19 | /config/deps 20 | /config/hacs 21 | 22 | 23 | # ignore any of these files no matter where they are using double * 24 | **.DS_Store 25 | **._* 26 | **.HA_VERSION 27 | **.pyc 28 | **.conf 29 | **.uuid 30 | **.txt 31 | **.log 32 | **.db 33 | **.sqlite 34 | **.xml 35 | **secrets* 36 | **known_devices.yaml 37 | **google_calendars.yaml 38 | **ip_bans.yaml 39 | **.spotify-token-cache 40 | **zones.yaml 41 | **test.yaml 42 | **testing.yaml 43 | **.homekit* 44 | **.vscode 45 | **.pid 46 | **.xml 47 | **.csr 48 | **.crt 49 | **.key 50 | **core.* 51 | **OZW_Log.txt 52 | **home-assistant.log 53 | **home-assistant_v2.db 54 | **.db-journal 55 | **.db-shm 56 | **.db-wal 57 | **.sqlite 58 | **__pycache__ 59 | **phue.conf 60 | **ios.conf 61 | **pyozw.sqlite 62 | **ipchange.yaml 63 | **production_auth.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | Anchorage House HA 4 |
5 | Anchorage House 6 |
7 | Home Assistant Configuration 8 |

9 | 10 | This repo contains the *OLD* [Home Assistant](https://home-assistant.io/) configuration for **Anchorage House**. Below are links to the devices currently being used, blog posts, and other HA enthusists that provided inspiration and configs to help build this config. All of the code is free to use. 11 | 12 | For the Recent updated follow the [current repo](https://github.com/thejeffreystone/homeassistant-config) 13 | 14 | If you are following a Youtube video released priot to August of 2022, this is the repor you want. 15 | -------------------------------------------------------------------------------- /config/alerts/garage_after_dark.yaml: -------------------------------------------------------------------------------- 1 | garage_after_dark: 2 | name: Garage is open...Please Check 3 | done_message: Garage is closed 4 | entity_id: input_boolean.garage_after_dark 5 | state: 'on' 6 | repeat: 5 7 | can_acknowledge: false 8 | skip_first: False 9 | notifiers: 10 | - all_ios 11 | -------------------------------------------------------------------------------- /config/alerts/jeff_bad_traffic_home.yaml: -------------------------------------------------------------------------------- 1 | jeff_bad_traffic_home: 2 | name: Leave Now! Currently {{states.sensor.jeff_ett_home.attributes.duration | round}} mins home! 3 | done_message: Canceling Traffic Alert 4 | entity_id: input_boolean.jeff_traffic_alert_home 5 | state: 'on' 6 | repeat: 10 7 | can_acknowledge: false 8 | skip_first: False 9 | notifiers: 10 | - jeff_ios 11 | -------------------------------------------------------------------------------- /config/alerts/jeff_heading_home.yaml: -------------------------------------------------------------------------------- 1 | jeff_heading_home: 2 | name: Jeff will arrive in {{states.sensor.jeff_ett_home.attributes.duration | round}} minutes. 3 | entity_id: input_boolean.jeff_travel_monitor 4 | state: 'on' 5 | repeat: 20 6 | can_acknowledge: false 7 | skip_first: False 8 | notifiers: 9 | - ios_katherinestonesiphone 10 | -------------------------------------------------------------------------------- /config/alerts/kat_heading_home.yaml: -------------------------------------------------------------------------------- 1 | kat_heading_home: 2 | name: Kat will be home in {{states.sensor.kat_ett_home.attributes.duration | round}} minutes. 3 | done_message: Kat Travel Monitor Disabled 4 | entity_id: input_boolean.kat_travel_monitor 5 | state: 'on' 6 | repeat: 20 7 | can_acknowledge: false 8 | skip_first: False 9 | notifiers: 10 | - jeff_ios 11 | -------------------------------------------------------------------------------- /config/alerts/lockdown_issue.yaml: -------------------------------------------------------------------------------- 1 | lockdown_issue: 2 | name: Issue Preventing Lockdown...Please Check 3 | done_message: Issue Resolved...Anchorage House Ready to Arm 4 | entity_id: input_boolean.lockdown_issue 5 | state: 'on' 6 | repeat: 2 7 | can_acknowledge: false 8 | skip_first: False 9 | notifiers: 10 | - all_ios -------------------------------------------------------------------------------- /config/alerts/unauthorized_access.yaml: -------------------------------------------------------------------------------- 1 | unauthorized_access: 2 | name: Potential Unauthorized Access Detected at Anchorage House 3 | done_message: Security Issue Cleared 4 | entity_id: input_boolean.security_issue 5 | state: 'on' 6 | repeat: 2 7 | can_acknowledge: false 8 | skip_first: False 9 | notifiers: 10 | - all_ios 11 | -------------------------------------------------------------------------------- /config/alerts/washing_machine_finished.yaml: -------------------------------------------------------------------------------- 1 | washing_machine_finished: 2 | name: Washing Machine Finished 3 | message: "The Washing Machine needs to be emptied." 4 | done_message: Thank you for moving the clothes to the dryer. 5 | entity_id: input_boolean.washer_finished 6 | state: 'on' 7 | repeat: 20 8 | can_acknowledge: false 9 | skip_first: False 10 | notifiers: 11 | - all_ios -------------------------------------------------------------------------------- /config/binary_sensors/calendar.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # 3 | # Workday Sensor 4 | - platform: workday 5 | country: US 6 | province: GA 7 | workdays: [mon, tue, wed, thu, fri] 8 | 9 | - platform: workday 10 | name: jeff_workday 11 | country: US 12 | province: GA 13 | workdays: [mon, tue, wed, thu, fri] 14 | 15 | # Times Of Day 16 | - platform: tod 17 | name: Night 18 | after: sunset 19 | before: sunrise 20 | 21 | - platform: tod 22 | name: Day 23 | after: sunrise 24 | before: sunset 25 | 26 | - platform: tod 27 | name: Quiet time 28 | after: '21:00' 29 | before: '06:00' 30 | 31 | - platform: tod 32 | name: Morning 33 | after: '06:00' 34 | before: '08:30' 35 | 36 | - platform: tod 37 | name: Midday 38 | after: '08:30' 39 | before: '17:00' 40 | 41 | - platform: tod 42 | name: Evening 43 | after: '17:00' 44 | before: '21:00' 45 | 46 | - platform: tod 47 | name: Overnight 48 | after: '18:00' 49 | before: '06:00' 50 | -------------------------------------------------------------------------------- /config/configuration.yaml: -------------------------------------------------------------------------------- 1 | homeassistant: 2 | external_url: !secret ahsl_base_url 3 | internal_url: http://192.168.7.187:8123 4 | customize: !include customize.yaml 5 | auth_providers: 6 | - type: homeassistant 7 | packages: !include_dir_named packages 8 | media_dirs: 9 | haunted_sounds: /media/haunted_sounds 10 | music: /media/music 11 | sounds: /media/sounds 12 | disney: /media/disney 13 | books: /media/books 14 | images: /media/images 15 | 16 | 17 | # Configure a default setup of Home Assistant (frontend, api, etc) 18 | default_config: 19 | 20 | # Uncomment this if you are using SSL/TLS, running in Docker container, etc. 21 | http: 22 | # ssl_certificate: !secret ahsl_ssl_cert 23 | # ssl_key: !secret ahsl_ssl_key 24 | use_x_forwarded_for: true 25 | trusted_proxies: !secret proxy_ips 26 | ip_ban_enabled: false 27 | login_attempts_threshold: 5 28 | 29 | ssdp: 30 | 31 | zeroconf: 32 | 33 | system_health: 34 | 35 | mobile_app: 36 | 37 | person: 38 | 39 | frontend: 40 | themes: !include_dir_merge_named themes 41 | 42 | cloud: 43 | 44 | conversation: 45 | 46 | device_tracker: 47 | - platform: eero_tracker 48 | consider_home: 300 49 | interval_seconds: 60 50 | only_macs: "68:54:fd:29:20:87, 68:54:fd:d5:ae:3d, 50:dc:e7:5b:10:69, 2c:cc:44:bf:9b:b4, 28:18:78:74:79:10, 44:61:32:f8:c8:09, 64:cf:d9:3c:5d:0c, 50:02:91:ed:2c:47, ec:71:db:31:0e:6c, 4e:6d:02:24:ac:87, 7c:1c:4e:2e:62:30, dc:03:98:3e:a9:6d" 51 | # - platform: icloud3 52 | # username: !secret ICLOUD_USER 53 | # password: !secret ICLOUD_PASS 54 | 55 | discovery: 56 | 57 | template: 58 | - binary_sensor: 59 | - name: "Kat Driving" 60 | state: > 61 | {{ state_attr('device_tracker.life360_kat_stone', 'speed') | int > 0 }} 62 | - binary_sensor: 63 | - name: "Jeff Driving" 64 | state: > 65 | {{ state_attr('device_tracker.life360_jeff_stone', 'speed') | int > 0 }} 66 | - trigger: 67 | - platform: state 68 | entity_id: sensor.recent_lighting_strikes 69 | binary_sensor: 70 | - name: lightning_detected 71 | unique_id: lightning_detected_sensor 72 | state: > 73 | {{ states('sensor.recent_lightning_strikes') | int > 0 }} 74 | device_class: safety 75 | 76 | updater: 77 | include_used_components: true 78 | 79 | sun: 80 | 81 | python_script: 82 | 83 | map: 84 | 85 | 86 | group: !include groups.yaml 87 | 88 | 89 | ### Includes ### 90 | alert: !include_dir_merge_named alerts/ 91 | automation: !include automations.yaml 92 | script: !include scripts.yaml 93 | sensor: !include_dir_merge_list sensors 94 | binary_sensor: !include_dir_merge_list binary_sensors 95 | # light: !include lights.yaml 96 | switch: !include switches.yaml 97 | scene: !include scenes.yaml 98 | input_select: !include input_select.yaml 99 | input_boolean: !include input_boolean.yaml 100 | input_datetime: !include input_datetime.yaml 101 | zone: !include zones.yaml 102 | 103 | shell_command: 104 | google_token: sed -i -e 's/2client.client"}2client.client"}/2client.client"}/g' /config/.google.token -------------------------------------------------------------------------------- /config/custom_components/amazon_polly/_inti_.py: -------------------------------------------------------------------------------- 1 | """Support for Amazon Polly integration.""" -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/binary_sensor.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/binary_sensor.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/climate.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/climate.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/common.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/common.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/config_flow.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/config_flow.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/const.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/const.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/cover.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/cover.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/discovery.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/discovery.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/fan.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/fan.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/light.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/light.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/number.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/number.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/select.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/select.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/sensor.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/sensor.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/switch.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/switch.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/__pycache__/vacuum.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/__pycache__/vacuum.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/binary_sensor.py: -------------------------------------------------------------------------------- 1 | """Platform to present any Tuya DP as a binary sensor.""" 2 | import logging 3 | from functools import partial 4 | 5 | import voluptuous as vol 6 | from homeassistant.components.binary_sensor import ( 7 | DEVICE_CLASSES_SCHEMA, 8 | DOMAIN, 9 | BinarySensorEntity, 10 | ) 11 | from homeassistant.const import CONF_DEVICE_CLASS 12 | 13 | from .common import LocalTuyaEntity, async_setup_entry 14 | 15 | _LOGGER = logging.getLogger(__name__) 16 | 17 | CONF_STATE_ON = "state_on" 18 | CONF_STATE_OFF = "state_off" 19 | 20 | 21 | def flow_schema(dps): 22 | """Return schema used in config flow.""" 23 | return { 24 | vol.Required(CONF_STATE_ON, default="True"): str, 25 | vol.Required(CONF_STATE_OFF, default="False"): str, 26 | vol.Optional(CONF_DEVICE_CLASS): DEVICE_CLASSES_SCHEMA, 27 | } 28 | 29 | 30 | class LocaltuyaBinarySensor(LocalTuyaEntity, BinarySensorEntity): 31 | """Representation of a Tuya binary sensor.""" 32 | 33 | def __init__( 34 | self, 35 | device, 36 | config_entry, 37 | sensorid, 38 | **kwargs, 39 | ): 40 | """Initialize the Tuya binary sensor.""" 41 | super().__init__(device, config_entry, sensorid, _LOGGER, **kwargs) 42 | self._is_on = False 43 | 44 | @property 45 | def is_on(self): 46 | """Return sensor state.""" 47 | return self._is_on 48 | 49 | @property 50 | def device_class(self): 51 | """Return the class of this device.""" 52 | return self._config.get(CONF_DEVICE_CLASS) 53 | 54 | def status_updated(self): 55 | """Device status was updated.""" 56 | state = str(self.dps(self._dp_id)).lower() 57 | if state == self._config[CONF_STATE_ON].lower(): 58 | self._is_on = True 59 | elif state == self._config[CONF_STATE_OFF].lower(): 60 | self._is_on = False 61 | else: 62 | self.warning( 63 | "State for entity %s did not match state patterns", self.entity_id 64 | ) 65 | 66 | 67 | async_setup_entry = partial( 68 | async_setup_entry, DOMAIN, LocaltuyaBinarySensor, flow_schema 69 | ) 70 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/const.py: -------------------------------------------------------------------------------- 1 | """Constants for localtuya integration.""" 2 | 3 | ATTR_CURRENT = "current" 4 | ATTR_CURRENT_CONSUMPTION = "current_consumption" 5 | ATTR_VOLTAGE = "voltage" 6 | 7 | CONF_LOCAL_KEY = "local_key" 8 | CONF_PROTOCOL_VERSION = "protocol_version" 9 | CONF_DPS_STRINGS = "dps_strings" 10 | CONF_PRODUCT_KEY = "product_key" 11 | 12 | # light 13 | CONF_BRIGHTNESS_LOWER = "brightness_lower" 14 | CONF_BRIGHTNESS_UPPER = "brightness_upper" 15 | CONF_COLOR = "color" 16 | CONF_COLOR_MODE = "color_mode" 17 | CONF_COLOR_TEMP_MIN_KELVIN = "color_temp_min_kelvin" 18 | CONF_COLOR_TEMP_MAX_KELVIN = "color_temp_max_kelvin" 19 | CONF_COLOR_TEMP_REVERSE = "color_temp_reverse" 20 | CONF_MUSIC_MODE = "music_mode" 21 | 22 | # switch 23 | CONF_CURRENT = "current" 24 | CONF_CURRENT_CONSUMPTION = "current_consumption" 25 | CONF_VOLTAGE = "voltage" 26 | 27 | # cover 28 | CONF_COMMANDS_SET = "commands_set" 29 | CONF_POSITIONING_MODE = "positioning_mode" 30 | CONF_CURRENT_POSITION_DP = "current_position_dp" 31 | CONF_SET_POSITION_DP = "set_position_dp" 32 | CONF_POSITION_INVERTED = "position_inverted" 33 | CONF_SPAN_TIME = "span_time" 34 | 35 | # fan 36 | CONF_FAN_SPEED_CONTROL = "fan_speed_control" 37 | CONF_FAN_OSCILLATING_CONTROL = "fan_oscillating_control" 38 | CONF_FAN_SPEED_MIN = "fan_speed_min" 39 | CONF_FAN_SPEED_MAX = "fan_speed_max" 40 | CONF_FAN_ORDERED_LIST = "fan_speed_ordered_list" 41 | CONF_FAN_DIRECTION = "fan_direction" 42 | CONF_FAN_DIRECTION_FWD = "fan_direction_forward" 43 | CONF_FAN_DIRECTION_REV = "fan_direction_reverse" 44 | 45 | # sensor 46 | CONF_SCALING = "scaling" 47 | 48 | # climate 49 | CONF_TARGET_TEMPERATURE_DP = "target_temperature_dp" 50 | CONF_CURRENT_TEMPERATURE_DP = "current_temperature_dp" 51 | CONF_TEMPERATURE_STEP = "temperature_step" 52 | CONF_MAX_TEMP_DP = "max_temperature_dp" 53 | CONF_MIN_TEMP_DP = "min_temperature_dp" 54 | CONF_PRECISION = "precision" 55 | CONF_TARGET_PRECISION = "target_precision" 56 | CONF_HVAC_MODE_DP = "hvac_mode_dp" 57 | CONF_HVAC_MODE_SET = "hvac_mode_set" 58 | CONF_PRESET_DP = "preset_dp" 59 | CONF_PRESET_SET = "preset_set" 60 | CONF_HEURISTIC_ACTION = "heuristic_action" 61 | CONF_HVAC_ACTION_DP = "hvac_action_dp" 62 | CONF_HVAC_ACTION_SET = "hvac_action_set" 63 | CONF_ECO_DP = "eco_dp" 64 | CONF_ECO_VALUE = "eco_value" 65 | 66 | # vacuum 67 | CONF_POWERGO_DP = "powergo_dp" 68 | CONF_IDLE_STATUS_VALUE = "idle_status_value" 69 | CONF_RETURNING_STATUS_VALUE = "returning_status_value" 70 | CONF_DOCKED_STATUS_VALUE = "docked_status_value" 71 | CONF_BATTERY_DP = "battery_dp" 72 | CONF_MODE_DP = "mode_dp" 73 | CONF_MODES = "modes" 74 | CONF_FAN_SPEED_DP = "fan_speed_dp" 75 | CONF_FAN_SPEEDS = "fan_speeds" 76 | CONF_CLEAN_TIME_DP = "clean_time_dp" 77 | CONF_CLEAN_AREA_DP = "clean_area_dp" 78 | CONF_CLEAN_RECORD_DP = "clean_record_dp" 79 | CONF_LOCATE_DP = "locate_dp" 80 | CONF_FAULT_DP = "fault_dp" 81 | CONF_PAUSED_STATE = "paused_state" 82 | CONF_RETURN_MODE = "return_mode" 83 | CONF_STOP_STATUS = "stop_status" 84 | 85 | DATA_DISCOVERY = "discovery" 86 | 87 | DOMAIN = "localtuya" 88 | 89 | # Platforms in this list must support config flows 90 | PLATFORMS = [ 91 | "binary_sensor", 92 | "climate", 93 | "cover", 94 | "fan", 95 | "light", 96 | "number", 97 | "select", 98 | "sensor", 99 | "switch", 100 | "vacuum", 101 | ] 102 | 103 | TUYA_DEVICE = "tuya_device" 104 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/discovery.py: -------------------------------------------------------------------------------- 1 | """Discovery module for Tuya devices. 2 | 3 | Entirely based on tuya-convert.py from tuya-convert: 4 | 5 | https://github.com/ct-Open-Source/tuya-convert/blob/master/scripts/tuya-discovery.py 6 | """ 7 | import asyncio 8 | import json 9 | import logging 10 | from hashlib import md5 11 | 12 | from cryptography.hazmat.backends import default_backend 13 | from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes 14 | 15 | _LOGGER = logging.getLogger(__name__) 16 | 17 | UDP_KEY = md5(b"yGAdlopoPVldABfn").digest() 18 | 19 | DEFAULT_TIMEOUT = 6.0 20 | 21 | 22 | def decrypt_udp(message): 23 | """Decrypt encrypted UDP broadcasts.""" 24 | 25 | def _unpad(data): 26 | return data[: -ord(data[len(data) - 1 :])] 27 | 28 | cipher = Cipher(algorithms.AES(UDP_KEY), modes.ECB(), default_backend()) 29 | decryptor = cipher.decryptor() 30 | return _unpad(decryptor.update(message) + decryptor.finalize()).decode() 31 | 32 | 33 | class TuyaDiscovery(asyncio.DatagramProtocol): 34 | """Datagram handler listening for Tuya broadcast messages.""" 35 | 36 | def __init__(self, callback=None): 37 | """Initialize a new BaseDiscovery.""" 38 | self.devices = {} 39 | self._listeners = [] 40 | self._callback = callback 41 | 42 | async def start(self): 43 | """Start discovery by listening to broadcasts.""" 44 | loop = asyncio.get_running_loop() 45 | listener = loop.create_datagram_endpoint( 46 | lambda: self, local_addr=("0.0.0.0", 6666) 47 | ) 48 | encrypted_listener = loop.create_datagram_endpoint( 49 | lambda: self, local_addr=("0.0.0.0", 6667) 50 | ) 51 | 52 | self._listeners = await asyncio.gather(listener, encrypted_listener) 53 | _LOGGER.debug("Listening to broadcasts on UDP port 6666 and 6667") 54 | 55 | def close(self): 56 | """Stop discovery.""" 57 | self._callback = None 58 | for transport, _ in self._listeners: 59 | transport.close() 60 | 61 | def datagram_received(self, data, addr): 62 | """Handle received broadcast message.""" 63 | data = data[20:-8] 64 | try: 65 | data = decrypt_udp(data) 66 | except Exception: # pylint: disable=broad-except 67 | data = data.decode() 68 | 69 | decoded = json.loads(data) 70 | self.device_found(decoded) 71 | 72 | def device_found(self, device): 73 | """Discover a new device.""" 74 | if device.get("ip") not in self.devices: 75 | self.devices[device.get("gwId")] = device 76 | _LOGGER.debug("Discovered device: %s", device) 77 | 78 | if self._callback: 79 | self._callback(device) 80 | 81 | 82 | async def discover(): 83 | """Discover and return devices on local network.""" 84 | discovery = TuyaDiscovery() 85 | try: 86 | await discovery.start() 87 | await asyncio.sleep(DEFAULT_TIMEOUT) 88 | finally: 89 | discovery.close() 90 | return discovery.devices 91 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "domain": "localtuya", 3 | "name": "LocalTuya integration", 4 | "version": "3.2.1", 5 | "documentation": "https://github.com/rospogrigio/localtuya/", 6 | "dependencies": [], 7 | "codeowners": [ 8 | "@rospogrigio", "@postlund" 9 | ], 10 | "issue_tracker": "https://github.com/rospogrigio/localtuya/issues", 11 | "requirements": [], 12 | "config_flow": true, 13 | "iot_class": "local_push" 14 | } 15 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/number.py: -------------------------------------------------------------------------------- 1 | """Platform to present any Tuya DP as a number.""" 2 | import logging 3 | from functools import partial 4 | 5 | import voluptuous as vol 6 | from homeassistant.components.number import DOMAIN, NumberEntity 7 | from homeassistant.const import CONF_DEVICE_CLASS, STATE_UNKNOWN 8 | 9 | from .common import LocalTuyaEntity, async_setup_entry 10 | 11 | _LOGGER = logging.getLogger(__name__) 12 | 13 | CONF_MIN_VALUE = "min_value" 14 | CONF_MAX_VALUE = "max_value" 15 | 16 | DEFAULT_MIN = 0 17 | DEFAULT_MAX = 100000 18 | 19 | 20 | def flow_schema(dps): 21 | """Return schema used in config flow.""" 22 | return { 23 | vol.Optional(CONF_MIN_VALUE, default=DEFAULT_MIN): vol.All( 24 | vol.Coerce(float), 25 | vol.Range(min=-1000000.0, max=1000000.0), 26 | ), 27 | vol.Required(CONF_MAX_VALUE, default=DEFAULT_MAX): vol.All( 28 | vol.Coerce(float), 29 | vol.Range(min=-1000000.0, max=1000000.0), 30 | ), 31 | } 32 | 33 | 34 | class LocaltuyaNumber(LocalTuyaEntity, NumberEntity): 35 | """Representation of a Tuya Number.""" 36 | 37 | def __init__( 38 | self, 39 | device, 40 | config_entry, 41 | sensorid, 42 | **kwargs, 43 | ): 44 | """Initialize the Tuya sensor.""" 45 | super().__init__(device, config_entry, sensorid, _LOGGER, **kwargs) 46 | self._state = STATE_UNKNOWN 47 | 48 | self._min_value = DEFAULT_MIN 49 | if CONF_MIN_VALUE in self._config: 50 | self._min_value = self._config.get(CONF_MIN_VALUE) 51 | 52 | self._max_value = self._config.get(CONF_MAX_VALUE) 53 | 54 | @property 55 | def value(self) -> float: 56 | """Return sensor state.""" 57 | return self._state 58 | 59 | @property 60 | def min_value(self) -> float: 61 | """Return the minimum value.""" 62 | return self._min_value 63 | 64 | @property 65 | def max_value(self) -> float: 66 | """Return the maximum value.""" 67 | return self._max_value 68 | 69 | @property 70 | def device_class(self): 71 | """Return the class of this device.""" 72 | return self._config.get(CONF_DEVICE_CLASS) 73 | 74 | async def async_set_value(self, value: float) -> None: 75 | """Update the current value.""" 76 | await self._device.set_dp(value, self._dp_id) 77 | 78 | def status_updated(self): 79 | """Device status was updated.""" 80 | state = self.dps(self._dp_id) 81 | self._state = state 82 | 83 | 84 | async_setup_entry = partial(async_setup_entry, DOMAIN, LocaltuyaNumber, flow_schema) 85 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/pytuya/__pycache__/__init__.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/localtuya/pytuya/__pycache__/__init__.cpython-39.pyc -------------------------------------------------------------------------------- /config/custom_components/localtuya/select.py: -------------------------------------------------------------------------------- 1 | """Platform to present any Tuya DP as an enumeration.""" 2 | import logging 3 | from functools import partial 4 | 5 | import voluptuous as vol 6 | from homeassistant.components.select import DOMAIN, SelectEntity 7 | from homeassistant.const import CONF_DEVICE_CLASS, STATE_UNKNOWN 8 | 9 | from .common import LocalTuyaEntity, async_setup_entry 10 | 11 | _LOGGER = logging.getLogger(__name__) 12 | 13 | CONF_OPTIONS = "select_options" 14 | CONF_OPTIONS_FRIENDLY = "select_options_friendly" 15 | 16 | 17 | def flow_schema(dps): 18 | """Return schema used in config flow.""" 19 | return { 20 | vol.Required(CONF_OPTIONS): str, 21 | vol.Optional(CONF_OPTIONS_FRIENDLY): str, 22 | } 23 | 24 | 25 | class LocaltuyaSelect(LocalTuyaEntity, SelectEntity): 26 | """Representation of a Tuya Enumeration.""" 27 | 28 | def __init__( 29 | self, 30 | device, 31 | config_entry, 32 | sensorid, 33 | **kwargs, 34 | ): 35 | """Initialize the Tuya sensor.""" 36 | super().__init__(device, config_entry, sensorid, _LOGGER, **kwargs) 37 | self._state = STATE_UNKNOWN 38 | self._state_friendly = "" 39 | self._valid_options = self._config.get(CONF_OPTIONS).split(";") 40 | 41 | # Set Display options 42 | self._display_options = [] 43 | display_options_str = "" 44 | if CONF_OPTIONS_FRIENDLY in self._config: 45 | display_options_str = self._config.get(CONF_OPTIONS_FRIENDLY).strip() 46 | _LOGGER.debug("Display Options Configured: %s", display_options_str) 47 | 48 | if display_options_str.find(";") >= 0: 49 | self._display_options = display_options_str.split(";") 50 | elif len(display_options_str.strip()) > 0: 51 | self._display_options.append(display_options_str) 52 | else: 53 | # Default display string to raw string 54 | _LOGGER.debug("No Display options configured - defaulting to raw values") 55 | self._display_options = self._valid_options 56 | 57 | _LOGGER.debug( 58 | "Total Raw Options: %s - Total Display Options: %s", 59 | str(len(self._valid_options)), 60 | str(len(self._display_options)), 61 | ) 62 | if len(self._valid_options) > len(self._display_options): 63 | # If list of display items smaller than list of valid items, 64 | # then default remaining items to be the raw value 65 | _LOGGER.debug( 66 | "Valid options is larger than display options - \ 67 | filling up with raw values" 68 | ) 69 | for i in range(len(self._display_options), len(self._valid_options)): 70 | self._display_options.append(self._valid_options[i]) 71 | 72 | @property 73 | def current_option(self) -> str: 74 | """Return the current value.""" 75 | return self._state_friendly 76 | 77 | @property 78 | def options(self) -> list: 79 | """Return the list of values.""" 80 | return self._display_options 81 | 82 | @property 83 | def device_class(self): 84 | """Return the class of this device.""" 85 | return self._config.get(CONF_DEVICE_CLASS) 86 | 87 | async def async_select_option(self, option: str) -> None: 88 | """Update the current value.""" 89 | option_value = self._valid_options[self._display_options.index(option)] 90 | _LOGGER.debug("Sending Option: " + option + " -> " + option_value) 91 | await self._device.set_dp(option_value, self._dp_id) 92 | 93 | def status_updated(self): 94 | """Device status was updated.""" 95 | state = self.dps(self._dp_id) 96 | self._state_friendly = self._display_options[self._valid_options.index(state)] 97 | self._state = state 98 | 99 | 100 | async_setup_entry = partial(async_setup_entry, DOMAIN, LocaltuyaSelect, flow_schema) 101 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/sensor.py: -------------------------------------------------------------------------------- 1 | """Platform to present any Tuya DP as a sensor.""" 2 | import logging 3 | from functools import partial 4 | 5 | import voluptuous as vol 6 | from homeassistant.components.sensor import DEVICE_CLASSES, DOMAIN 7 | from homeassistant.const import ( 8 | CONF_DEVICE_CLASS, 9 | CONF_UNIT_OF_MEASUREMENT, 10 | STATE_UNKNOWN, 11 | ) 12 | 13 | from .common import LocalTuyaEntity, async_setup_entry 14 | from .const import CONF_SCALING 15 | 16 | _LOGGER = logging.getLogger(__name__) 17 | 18 | DEFAULT_PRECISION = 2 19 | 20 | 21 | def flow_schema(dps): 22 | """Return schema used in config flow.""" 23 | return { 24 | vol.Optional(CONF_UNIT_OF_MEASUREMENT): str, 25 | vol.Optional(CONF_DEVICE_CLASS): vol.In(DEVICE_CLASSES), 26 | vol.Optional(CONF_SCALING): vol.All( 27 | vol.Coerce(float), vol.Range(min=-1000000.0, max=1000000.0) 28 | ), 29 | } 30 | 31 | 32 | class LocaltuyaSensor(LocalTuyaEntity): 33 | """Representation of a Tuya sensor.""" 34 | 35 | def __init__( 36 | self, 37 | device, 38 | config_entry, 39 | sensorid, 40 | **kwargs, 41 | ): 42 | """Initialize the Tuya sensor.""" 43 | super().__init__(device, config_entry, sensorid, _LOGGER, **kwargs) 44 | self._state = STATE_UNKNOWN 45 | 46 | @property 47 | def state(self): 48 | """Return sensor state.""" 49 | return self._state 50 | 51 | @property 52 | def device_class(self): 53 | """Return the class of this device.""" 54 | return self._config.get(CONF_DEVICE_CLASS) 55 | 56 | @property 57 | def unit_of_measurement(self): 58 | """Return the unit of measurement of this entity, if any.""" 59 | return self._config.get(CONF_UNIT_OF_MEASUREMENT) 60 | 61 | def status_updated(self): 62 | """Device status was updated.""" 63 | state = self.dps(self._dp_id) 64 | scale_factor = self._config.get(CONF_SCALING) 65 | if scale_factor is not None and isinstance(state, (int, float)): 66 | state = round(state * scale_factor, DEFAULT_PRECISION) 67 | self._state = state 68 | 69 | 70 | async_setup_entry = partial(async_setup_entry, DOMAIN, LocaltuyaSensor, flow_schema) 71 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/services.yaml: -------------------------------------------------------------------------------- 1 | reload: 2 | description: Reload localtuya and re-process yaml configuration. 3 | 4 | set_dp: 5 | description: Change the value of a datapoint (DP) 6 | fields: 7 | device_id: 8 | description: Device ID of device to change datapoint value for 9 | example: 11100118278aab4de001 10 | dp: 11 | description: Datapoint index 12 | example: 1 13 | value: 14 | description: New value to set 15 | example: False 16 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/strings.json: -------------------------------------------------------------------------------- 1 | { 2 | "config": { 3 | "abort": { 4 | "already_configured": "Device has already been configured.", 5 | "unsupported_device_type": "Unsupported device type!" 6 | }, 7 | "error": { 8 | "cannot_connect": "Cannot connect to device. Verify that address is correct.", 9 | "invalid_auth": "Failed to authenticate with device. Verify that device id and local key are correct.", 10 | "unknown": "An unknown error occurred. See log for details.", 11 | "switch_already_configured": "Switch with this ID has already been configured." 12 | }, 13 | "step": { 14 | "user": { 15 | "title": "Add Tuya device", 16 | "description": "Fill in the basic details and pick device type. The name entered here will be used to identify the integration itself (as seen in the `Integrations` page). You will name each sub-device in the following steps.", 17 | "data": { 18 | "name": "Name", 19 | "host": "Host", 20 | "device_id": "Device ID", 21 | "local_key": "Local key", 22 | "protocol_version": "Protocol Version", 23 | "scan_interval": "Scan interval (seconds, only when not updating automatically)", 24 | "device_type": "Device type" 25 | } 26 | }, 27 | "power_outlet": { 28 | "title": "Add subswitch", 29 | "description": "You are about to add subswitch number `{number}`. If you want to add another, tick `Add another switch` before continuing.", 30 | "data": { 31 | "id": "ID", 32 | "name": "Name", 33 | "friendly_name": "Friendly name", 34 | "current": "Current", 35 | "current_consumption": "Current Consumption", 36 | "voltage": "Voltage", 37 | "add_another_switch": "Add another switch" 38 | } 39 | } 40 | } 41 | }, 42 | "title": "LocalTuya" 43 | } 44 | -------------------------------------------------------------------------------- /config/custom_components/localtuya/switch.py: -------------------------------------------------------------------------------- 1 | """Platform to locally control Tuya-based switch devices.""" 2 | import logging 3 | from functools import partial 4 | 5 | import voluptuous as vol 6 | from homeassistant.components.switch import DOMAIN, SwitchEntity 7 | 8 | from .common import LocalTuyaEntity, async_setup_entry 9 | from .const import ( 10 | ATTR_CURRENT, 11 | ATTR_CURRENT_CONSUMPTION, 12 | ATTR_VOLTAGE, 13 | CONF_CURRENT, 14 | CONF_CURRENT_CONSUMPTION, 15 | CONF_VOLTAGE, 16 | ) 17 | 18 | _LOGGER = logging.getLogger(__name__) 19 | 20 | 21 | def flow_schema(dps): 22 | """Return schema used in config flow.""" 23 | return { 24 | vol.Optional(CONF_CURRENT): vol.In(dps), 25 | vol.Optional(CONF_CURRENT_CONSUMPTION): vol.In(dps), 26 | vol.Optional(CONF_VOLTAGE): vol.In(dps), 27 | } 28 | 29 | 30 | class LocaltuyaSwitch(LocalTuyaEntity, SwitchEntity): 31 | """Representation of a Tuya switch.""" 32 | 33 | def __init__( 34 | self, 35 | device, 36 | config_entry, 37 | switchid, 38 | **kwargs, 39 | ): 40 | """Initialize the Tuya switch.""" 41 | super().__init__(device, config_entry, switchid, _LOGGER, **kwargs) 42 | self._state = None 43 | print("Initialized switch [{}]".format(self.name)) 44 | 45 | @property 46 | def is_on(self): 47 | """Check if Tuya switch is on.""" 48 | return self._state 49 | 50 | @property 51 | def extra_state_attributes(self): 52 | """Return device state attributes.""" 53 | attrs = {} 54 | if self.has_config(CONF_CURRENT): 55 | attrs[ATTR_CURRENT] = self.dps(self._config[CONF_CURRENT]) 56 | if self.has_config(CONF_CURRENT_CONSUMPTION): 57 | attrs[ATTR_CURRENT_CONSUMPTION] = ( 58 | self.dps(self._config[CONF_CURRENT_CONSUMPTION]) / 10 59 | ) 60 | if self.has_config(CONF_VOLTAGE): 61 | attrs[ATTR_VOLTAGE] = self.dps(self._config[CONF_VOLTAGE]) / 10 62 | return attrs 63 | 64 | async def async_turn_on(self, **kwargs): 65 | """Turn Tuya switch on.""" 66 | await self._device.set_dp(True, self._dp_id) 67 | 68 | async def async_turn_off(self, **kwargs): 69 | """Turn Tuya switch off.""" 70 | await self._device.set_dp(False, self._dp_id) 71 | 72 | def status_updated(self): 73 | """Device status was updated.""" 74 | self._state = self.dps(self._dp_id) 75 | 76 | 77 | async_setup_entry = partial(async_setup_entry, DOMAIN, LocaltuyaSwitch, flow_schema) 78 | -------------------------------------------------------------------------------- /config/custom_components/nws_alerts/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/custom_components/nws_alerts/__init__.py -------------------------------------------------------------------------------- /config/custom_components/nws_alerts/sensor.py: -------------------------------------------------------------------------------- 1 | ''' 2 | --------------------------------------------------------- 3 | NWS Alerts 4 | --------------------------------------------------------- 5 | VERSION: 0.0.2 6 | Forum: https://community.home-assistant.io/t/severe-weather-alerts-from-the-us-national-weather-service/71853 7 | 8 | API Documentation 9 | --------------------------------------------------------- 10 | https://www.weather.gov/documentation/services-web-api 11 | https://forecast-v3.weather.gov/documentation 12 | --------------------------------------------------------- 13 | ''' 14 | 15 | import requests 16 | import logging 17 | import voluptuous as vol 18 | from datetime import timedelta 19 | from homeassistant.components.sensor import PLATFORM_SCHEMA 20 | from homeassistant.const import CONF_NAME, ATTR_ATTRIBUTION 21 | from homeassistant.helpers import config_validation as cv 22 | from homeassistant.helpers.entity import Entity 23 | from homeassistant.util import Throttle 24 | 25 | 26 | API_ENDPOINT = 'https://api.weather.gov' 27 | USER_AGENT = 'Home Assistant' 28 | DEFAULT_ICON = 'mdi:alert' 29 | MIN_TIME_BETWEEN_UPDATES = timedelta(minutes=1) 30 | _LOGGER = logging.getLogger(__name__) 31 | DEFAULT_NAME = 'NWS Alerts' 32 | CONF_ZONE_ID = 'zone_id' 33 | ZONE_ID = '' 34 | 35 | PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ 36 | vol.Required(CONF_ZONE_ID): cv.string, 37 | vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, 38 | }) 39 | 40 | 41 | def setup_platform(hass, config, add_devices, discovery_info=None): 42 | """Setup the sensor platform.""" 43 | name = config.get(CONF_NAME, DEFAULT_NAME) 44 | zone_id = config.get(CONF_ZONE_ID) 45 | add_devices([NWSAlertSensor(name, zone_id)]) 46 | 47 | 48 | class NWSAlertSensor(Entity): 49 | """Representation of a Sensor.""" 50 | 51 | def __init__(self, name, zone_id): 52 | """Initialize the sensor.""" 53 | self._name = name 54 | self._icon = DEFAULT_ICON 55 | self._state = 0 56 | self._event = None 57 | self._display_desc = None 58 | self._spoken_desc = None 59 | self._zone_id = zone_id.replace(' ', '') 60 | self.update() 61 | 62 | @property 63 | def name(self): 64 | """Return the name of the sensor.""" 65 | return self._name 66 | 67 | @property 68 | def icon(self): 69 | """Return the icon to use in the frontend, if any.""" 70 | return self._icon 71 | 72 | @property 73 | def state(self): 74 | """Return the state of the sensor.""" 75 | return self._state 76 | 77 | @property 78 | def device_state_attributes(self): 79 | """Return the state message.""" 80 | attributes = {"title": self._event, 81 | "display_desc": self._display_desc, 82 | "spoken_desc": self._spoken_desc 83 | } 84 | 85 | return attributes 86 | 87 | @Throttle(MIN_TIME_BETWEEN_UPDATES) 88 | def update(self): 89 | """Fetch new state data for the sensor. 90 | This is the only method that should fetch new data for Home Assistant. 91 | """ 92 | values = self.get_state() 93 | self._state = values['state'] 94 | self._event = values['event'] 95 | self._display_desc = values['display_desc'] 96 | self._spoken_desc = values['spoken_desc'] 97 | 98 | def get_state(self): 99 | values = {'state': 0, 100 | 'event': None, 101 | 'display_desc': None, 102 | 'spoken_desc': None 103 | } 104 | 105 | headers = {'User-Agent': USER_AGENT, 106 | 'Accept': 'application/ld+json' 107 | } 108 | 109 | url = '%s/alerts/active/count' % API_ENDPOINT 110 | r = requests.get(url, headers=headers) 111 | _LOGGER.debug("getting state, %s", url) 112 | if r.status_code == 200: 113 | if 'zones' in r.json(): 114 | for zone in self._zone_id.split(','): 115 | if zone in r.json()['zones']: 116 | values = self.get_alerts() 117 | break 118 | 119 | return values 120 | 121 | def get_alerts(self): 122 | values = {'state': 0, 123 | 'event': None, 124 | 'display_desc': None, 125 | 'spoken_desc': None 126 | } 127 | 128 | headers = {'User-Agent': USER_AGENT, 129 | 'Accept': 'application/geo+json' 130 | } 131 | url = '%s/alerts/active?zone=%s' % (API_ENDPOINT, self._zone_id) 132 | r = requests.get(url, headers=headers) 133 | _LOGGER.debug("getting alert, %s", url) 134 | if r.status_code == 200: 135 | events = [] 136 | headlines = [] 137 | display_desc = '' 138 | spoken_desc = '' 139 | features = r.json()['features'] 140 | for alert in features: 141 | event = alert['properties']['event'] 142 | if 'NWSheadline' in alert['properties']['parameters']: 143 | headline = alert['properties']['parameters']['NWSheadline'][0] 144 | else: 145 | headline = event 146 | 147 | description = alert['properties']['description'] 148 | instruction = alert['properties']['instruction'] 149 | 150 | if event in events: 151 | continue 152 | 153 | events.append(event) 154 | headlines.append(headline) 155 | 156 | if display_desc != '': 157 | display_desc += '\n\n' 158 | 159 | display_desc += '%s\n%s\n%s\n%s' % (event, headline, description, instruction) 160 | 161 | if headlines: 162 | num_headlines = len(headlines) 163 | i = 0 164 | for headline in headlines: 165 | i += 1 166 | if spoken_desc != '': 167 | if i == num_headlines: 168 | spoken_desc += ' and a ' 169 | else: 170 | spoken_desc += ', a ' 171 | 172 | spoken_desc += headline 173 | 174 | if len(events) > 0: 175 | event_str = '' 176 | for item in events: 177 | if event_str != '': 178 | event_str += ' - ' 179 | event_str += item 180 | 181 | values['state'] = len(events) 182 | values['event'] = event_str 183 | values['display_desc'] = display_desc 184 | values['spoken_desc'] = spoken_desc 185 | 186 | return values 187 | 188 | -------------------------------------------------------------------------------- /config/customize.yaml: -------------------------------------------------------------------------------- 1 | ### CUSTOMIZE ### 2 | 3 | # Speedtest # 4 | sensor.speedtest_ping: 5 | icon: mdi:speedometer 6 | friendly_name: Ping 7 | sensor.speedtest_download: 8 | icon: mdi:download 9 | friendly_name: Download 10 | sensor.speedtest_upload: 11 | icon: mdi:upload 12 | friendly_name: Upload 13 | 14 | # Jeff # 15 | 16 | sensor.jeffrey_location: 17 | entity_picture: !secret JEFF_ICON 18 | friendly_name: Jeff 19 | sensor.jeff_location: 20 | entity_picture: !secret JEFF_ICON 21 | sensor.jeff_destination: 22 | icon: mdi:google-maps 23 | name: "Jeffs Destination" 24 | device_tracker.jeffreystonesiphone: 25 | entity_picture: !secret JEFF_ICON 26 | friendly_name: Jeff 27 | sensor.jeff_iphone_batt: 28 | friendly_name: "Jeff's iPhone Battery" 29 | sensor.jeff_ett_home: 30 | friendly_name: "Jeff's ETA Home" 31 | icon: mdi:car 32 | device_tracker.jeffreystonesipad: 33 | icon: mdi:tablet-ipad 34 | friendly_name: "Jeff's iPad" 35 | device_tracker.jeffreysmbp: 36 | icon: mdi:laptop-mac 37 | friendly_name: "Jeff's MacBook" 38 | device_tracker.jstonemac: 39 | icon: mdi:laptop-mac 40 | friendly_name: "Jeff's Work Mac" 41 | device_tracker.jeffreysapple_watch: 42 | friendly_name: "Jeff's Watch" 43 | icon: mdi:watch 44 | 45 | 46 | # Kat ## 47 | device_tracker.iphone: 48 | entity_picture: !secret KAT_ICON 49 | friendly_name: Kat 50 | sensor.kat_location: 51 | entity_picture: !secret KAT_ICON 52 | sensor.kat_iphone_batt: 53 | friendly_name: "Kat's iPhone Battery" 54 | device_tracker.katherinesipad: 55 | icon: mdi:tablet-ipad 56 | friendly_name: "Kat's Ipad" 57 | device_tracker.katherinesmini: 58 | icon: mdi:desktop-mac 59 | friendly_name: "Kat's Mini" 60 | sensor.kat_ett_home: 61 | friendly_name: "Kat's ETA Home" 62 | icon: mdi:car 63 | sensor.kat_destination: 64 | icon: mdi:google-maps 65 | name: "Kats Destination" 66 | 67 | # Skylar 68 | 69 | sensor.skylar_location: 70 | entity_picture: !secret SKYLAR_ICON 71 | 72 | # Device ## 73 | device_tracker.gateway2f3bca: 74 | icon: mdi:nest-thermostat 75 | friendly_name: Honeywell 76 | sensor.appletv: 77 | icon: mdi:apple 78 | sensor.roku: 79 | icon: mdi:television 80 | sensor.xboxone: 81 | icon: mdi:xbox 82 | sensor.chromecast: 83 | icon: mdi:cast 84 | sensor.samsungtv: 85 | icon: mdi:television 86 | sensor.amazon_dot_lr: 87 | icon: mdi:amazon 88 | sensor.amazon_dot_kn: 89 | icon: mdi:amazon 90 | sensor.honeywell: 91 | icon: mdi:thermostat 92 | sensor.smartthings: 93 | icon: mdi:router-wireless 94 | sensor.eero_loft: 95 | icon: mdi:router-wireless 96 | sensor.eero_livingroom: 97 | icon: mdi:router-wireless 98 | media_player.roku_5s6719003683: 99 | friendly_name: Roku Living Room 100 | icon: mdi:youtube-tv 101 | device_tracker.00a0dea3ed2f: 102 | friendly_name: Yamaha AV 103 | icon: mdi:surround-sound 104 | media_player.pn60e550_pn60e550: 105 | name: Samsung TV 106 | icon: mdi:television 107 | media_player.hass_speaker: 108 | name: AH Speaker 109 | icon: mdi:speaker 110 | media_player.yamaha_receiver_theater: 111 | icon: mdi:audio-video 112 | switch.main_theater: 113 | icon: mdi:audio-video 114 | 115 | # Switches and Lights ## 116 | switch.fireplace_lights: 117 | icon: mdi:spotlight-beam 118 | switch.tower_lamp: 119 | icon: mdi:lightbulb 120 | switch.driveway_light: 121 | icon: mdi:lightbulb 122 | switch.side_door: 123 | icon: mdi:lightbulb 124 | switch.front_porch: 125 | icon: mdi:lightbulb 126 | switch.front_lamp: 127 | icon: mdi:lightbulb 128 | switch.upstairs_light: 129 | icon: mdi:lightbulb 130 | cover.garage_door: 131 | device_class: garage 132 | friendly_name: Garage Door 133 | homebridge_cover_type: garage_door 134 | switch.loft_fan: 135 | friendly_name: "Loft Box Fan" 136 | icon: mdi:fan 137 | switch.house_secured: 138 | name: House Secured 139 | icon: mdi:lock 140 | switch.vacation_mode: 141 | name: Vacation Mode 142 | icon: mdi:airplane-takeoff 143 | switch.guest_mode: 144 | name: Guest Mode 145 | icon: mdi:account-multiple 146 | switch.notifications_to_kat: 147 | name: Notify Katherine 148 | icon: mdi:telegram 149 | switch.notifications_to_jeff: 150 | name: Notify Jeff 151 | icon: mdi:telegram 152 | switch.automations: 153 | name: automations 154 | icon: mdi:home-automation 155 | switch.kitchen_cabinets: 156 | icon: mdi:lightbulb 157 | switch.kitchen_light_strip: 158 | icon: mdi:lightbulb 159 | switch.garage_alarm: 160 | name: Garage Door Alarm 161 | icon: mdi:alert 162 | input_select.trash_pickup: 163 | name: Trash Pickup 164 | icon: mdi:delete-variant 165 | input_select.recycle_pickup: 166 | name: Recycle Pickup 167 | icon: mdi:delete-variant 168 | switch.trash_notification: 169 | name: Trash Notifications 170 | icon: mdi:telegram 171 | switch.master_bedroom_fan: 172 | icon: mdi:fan 173 | switch.incense: 174 | icon: mdi:flower 175 | switch.christmas_tree_lights: 176 | icon: mdi:lightbulb 177 | switch.christmas_lights: 178 | icon: mdi:lightbulb 179 | switch.rainbow_light: 180 | icon: mdi:lightbulb 181 | 182 | # Travel Times ## 183 | sensor.home_to_summit: 184 | friendly_name: "Home to Summit" 185 | icon: mdi:car 186 | sensor.home_to_zoo: 187 | friendly_name: "Home to Zoo Atlanta" 188 | icon: mdi:car 189 | 190 | 191 | # Various Sensors ## 192 | sensor.kitchen_fire: 193 | name: Kitchen Smoke Detector 194 | icon: mdi:tower-fire 195 | sensor.smoke_kitchen: 196 | icon: mdi:fire 197 | 198 | sensor.ha_uptime: 199 | friendly_name: HA Uptime 200 | icon: mdi:clock-start 201 | sensor.installed_version: 202 | friendly_name: Installed 203 | icon: mdi:folder-download 204 | sensor.lets_encrypt_expiration: 205 | friendly_name: Lets Encrypt Expiration 206 | icon: mdi:timelapse 207 | sensor.current_ha_version: 208 | friendly_name: Latest Release 209 | icon: mdi:github-circle 210 | sensor.connected_clients: 211 | friendly_name: Connections 212 | icon: mdi:lan-connect 213 | zwave.aeotec_zw090_zstick_gen5_us: 214 | friendly_name: Zwave USB Hub 215 | sensor.ha_v2db: 216 | friendly_name: HA Database 217 | icon: mdi:file 218 | sensor.ha_log: 219 | friendly_name: HA Log 220 | icon: mdi:file 221 | sensor.accurite_back_porch_temperature: 222 | friendly_name: Back Porch Temp 223 | icon: mdi:thermometer 224 | unit_of_measurement: '°F' 225 | sensor.accurite_back_porch_humidity: 226 | friendly_name: Back Porch Humidity 227 | icon: mdi:water-percent 228 | unit_of_measurement: '%' 229 | sensor.accurite_garage_temperature: 230 | friendly_name: Garage Temp 231 | icon: mdi:thermometer 232 | unit_of_measurement: '°F' 233 | sensor.accurite_garage_humidity: 234 | friendly_name: Garage Humidity 235 | icon: mdi:water-percent 236 | unit_of_measurement: '%' 237 | binary_sensor.garage_dome_sensor: 238 | friendly_name: Garage Motion 239 | sensor.washer_power: 240 | friendly_name: Washer Power 241 | icon: mdi:power-plug 242 | unit_of_measurement: 'w' 243 | sensor.washer: 244 | icon: mdi:power-plug 245 | 246 | 247 | device_tracker.life360_jeffrey_stone: 248 | friendly_name: Jeffrey 249 | 250 | device_tracker.life360_kat_stone: 251 | friendly_name: Katherine 252 | -------------------------------------------------------------------------------- /config/groups.yaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | ################################################################################# 4 | ### Groups ### 5 | 6 | Family: 7 | - person.jeffrey 8 | - person.katherine 9 | - person.uncle_matt 10 | - person.papa 11 | 12 | People: 13 | - person.jeffrey 14 | - person.katherine 15 | - sensor.skylar_location 16 | - person.uncle_matt 17 | - person.papa 18 | 19 | test: 20 | - group.jeffrey 21 | - group.kat 22 | 23 | jeffrey: 24 | - device_tracker.jeffrey_s_iphone_11_app 25 | - device_tracker.jeffreys_iphone_11 26 | - device_tracker.life360_jeffrey_stone 27 | 28 | kat: 29 | - device_tracker.iphone_app 30 | - device_tracker.life360_kat_stone 31 | 32 | arriving: 33 | name: Arriving 34 | entities: [] 35 | 36 | 37 | occupancy: 38 | - binary_sensor.living_room_motion_occupancy 39 | - binary_sensor.kitchen_motion_occupancy 40 | - binary_sensor.skylar_bedroom_motion_occupancy 41 | - binary_sensor.master_bedroom_motion_occupancy 42 | - binary_sensor.back_door_motion 43 | 44 | audio_devices: 45 | - media_player.kitchen_display 46 | - media_player.upstairs_speaker 47 | - media_player.master_bedroom_speaker 48 | - media_player.croft_speaker 49 | - media_player.ha_blue 50 | - media_player.skylars_bedroom_speaker 51 | - media_player.theater 52 | 53 | Outside Lights: 54 | - switch.driveway_light 55 | - switch.front_porch_light 56 | - light.side_door_light_level 57 | 58 | External Doors: 59 | - binary_sensor.side_door 60 | - binary_sensor.front_door 61 | - binary_sensor.back_door 62 | - binary_sensor.laundry_door 63 | - binary_sensor.garage_door 64 | 65 | Garage Doors: 66 | - binary_sensor.side_door 67 | - binary_sensor.garage_door 68 | 69 | Internal Doors: 70 | - binary_sensor.attic_door 71 | 72 | rgb lr: 73 | - light.front_door_lamp 74 | - light.living_room_lamp 75 | - light.living_room_tower_lamp 76 | 77 | livingroom tower: 78 | - light.living_room_tower_lamp 79 | 80 | livingroom lamps: 81 | - light.living_room_lamp 82 | - light.front_door_lamp 83 | 84 | incense: 85 | - switch.forest_incense_incense 86 | - switch.artemis 87 | - switch.incense 88 | 89 | all fans: 90 | - switch.croft_fan 91 | - switch.livingroom_fan 92 | 93 | Skylars Bedroom: 94 | - light.skylars_dresser_lamp 95 | - switch.rainbow_lamp # rainbow light 96 | - light.wled_skylarsbed 97 | - switch.skylars_desk 98 | 99 | Master Bedroom: 100 | - light.jeff_lamp 101 | - light.master_bedroom_dresser_lamp 102 | - light.kat_lamp 103 | - light.master_bedroom_tower_lamp 104 | - light.desk_accent 105 | - switch.tplink_a2 106 | 107 | kitchen: 108 | - light.kitchen_cabinets 109 | - switch.kitchen_light_strip 110 | 111 | livingroom: 112 | - light.front_door_lamp 113 | - light.living_room_lamp 114 | - light.living_room_tower_lamp 115 | - switch.fireplace_lights 116 | - switch.rail_lights 117 | 118 | vacation lights: 119 | - light.front_door_lamp 120 | - light.living_room_lamp 121 | - light.living_room_tower_lamp 122 | - light.skylars_dresser_lamp 123 | - light.kitchen_sink 124 | - light.master_bedroom_tower_lamp 125 | - light.jeff_lamp 126 | - switch.fireplace_lights 127 | 128 | theater lights: 129 | - light.theater_lights 130 | 131 | Chores: 132 | - input_boolean.clean_litterbox 133 | - input_boolean.heartworm 134 | - input_boolean.nextguard 135 | - input_boolean.clean_washer 136 | - input_boolean.clean_dishwasher 137 | - input_boolean.clean_towel_day 138 | - input_boolean.clean_sheet_day 139 | - input_boolean.clean_kitchen 140 | - input_boolean.clean_livingroom 141 | - input_boolean.clean_bathrooms 142 | - input_boolean.mow_yard 143 | - input_boolean.replace_hvac_filter -------------------------------------------------------------------------------- /config/input_boolean.yaml: -------------------------------------------------------------------------------- 1 | automations: 2 | name: Automations 3 | icon: mdi:home-automation 4 | 5 | welcome_greeting: 6 | name: Welcome Greeting 7 | icon: mdi:speaker-wireless 8 | 9 | kat_heading_home: 10 | name: Kat Heading Home 11 | icon: mdi:car 12 | jeff_heading_home: 13 | name: Jeff Heading Home 14 | icon: mdi:car 15 | jeff_traffic_alerts: 16 | name: Jeff Traffic Alerts 17 | icon: mdi:bell-plus 18 | jeff_traffic_alert_home: 19 | name: Jeff Traffic Alert Home 20 | icon: mdi:traffic-light 21 | tornado_watch: 22 | name: Tornado Watch 23 | icon: mdi:message-alert 24 | kat_travel_monitor: 25 | name: Kat Travel Monitor 26 | icon: mdi:car 27 | jeff_travel_monitor: 28 | name: Jeff Travel Monitor 29 | icon: mdi:car 30 | 31 | weather_reports: 32 | name: Weather Info 33 | traffic_reports: 34 | name: traffic_reports 35 | sun_reports: 36 | name: Sun Reports 37 | new_ha_announcement: 38 | name: New HA Announcement 39 | icon: mdi:twitter 40 | showing_now: 41 | name: Showing Now 42 | icon: mdi:popcorn 43 | skylar_school: 44 | name: Skylar at School 45 | shuffle_spotify: 46 | name: Spotify Shuffle 47 | good_morning_report: 48 | name: Good Morning Report 49 | master_bedroom_alarm: 50 | name: Master Bedroom Alarm 51 | skylar_awake: 52 | name: Skylar Awake 53 | -------------------------------------------------------------------------------- /config/input_datetime.yaml: -------------------------------------------------------------------------------- 1 | both_date_and_time: 2 | name: Input with both date and time 3 | has_date: true 4 | has_time: true 5 | only_date: 6 | name: Input with only date 7 | has_date: true 8 | has_time: false 9 | outisde_light_delay: 10 | name: Outside Light Delay 11 | has_date: false 12 | has_time: true 13 | announcement_delay: 14 | name: Announcement Delay 15 | has_date: false 16 | has_time: true 17 | coffee_time: 18 | name: Coffee Time 19 | has_date: false 20 | has_time: true 21 | good_morning: 22 | name: Good Morning 23 | has_date: false 24 | has_time: true 25 | skylar_wakeup_call: 26 | name: Skylar Wakeup 27 | has_date: false 28 | has_time: true 29 | christmas_show: 30 | name: Christmas Show 31 | has_date: false 32 | has_time: true 33 | christmas_preshow: 34 | name: Christmas Preshow 35 | has_date: false 36 | has_time: true 37 | 38 | good_night_routine: 39 | name: Good Night Routine 40 | has_date: false 41 | has_time: true 42 | nightly_lockdown: 43 | name: Nightly Lockdown 44 | has_date: false 45 | has_time: true 46 | morning_standby: 47 | name: Morning Standby 48 | has_date: false 49 | has_time: true 50 | 51 | skylar_awake_at: 52 | name: Skylar Awake At 53 | has_date: false 54 | has_time: true -------------------------------------------------------------------------------- /config/input_select.yaml: -------------------------------------------------------------------------------- 1 | trash_pickup: 2 | name: Trash Pickup 3 | options: 4 | - Monday 5 | - Tuesday 6 | - Wednesday 7 | - Thursday 8 | - Friday 9 | initial: Tuesday 10 | icon: mdi:delete-variant 11 | recycle_pickup: 12 | name: Recycle Pickup 13 | options: 14 | - Monday 15 | - Tuesday 16 | - Wednesday 17 | - Thursday 18 | - Friday 19 | initial: Tuesday 20 | icon: mdi:delete-variant 21 | spotify_source: 22 | name: Spotify Source 23 | options: 24 | - Everywhere 25 | - Living Room 26 | - Skylar's Bedroom 27 | - Kitchen 28 | initial: Living Room 29 | spotify_playlist: 30 | name: Spotify Playlist 31 | options: 32 | - chill 33 | - dedtime 34 | - background 35 | - scored 36 | - jukebox 37 | - classical 38 | - disney 39 | - jazz 40 | - skylar 41 | initial: background -------------------------------------------------------------------------------- /config/lights.yaml: -------------------------------------------------------------------------------- 1 | ### Not Used ## -------------------------------------------------------------------------------- /config/media/haunted_sounds/ChainsRattling.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/ChainsRattling.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/CreakingDoorSpooky.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/CreakingDoorSpooky.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/EvilLaughCackle.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/EvilLaughCackle.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Evil_Laugh_2.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Evil_Laugh_2.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Evillaugh.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Evillaugh.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Haunted-CatScream.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Haunted-CatScream.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Haunted-DragonRoaring.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Haunted-DragonRoaring.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Haunted-Heart.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Haunted-Heart.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Haunted-ScaryScream.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Haunted-ScaryScream.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Haunted-TollingBell.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Haunted-TollingBell.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/Scary.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/Scary.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/This_is_Halloween.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/This_is_Halloween.mp3 -------------------------------------------------------------------------------- /config/media/haunted_sounds/raven.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/media/haunted_sounds/raven.mp3 -------------------------------------------------------------------------------- /config/packages/batteries.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 06/12/2020 4 | # @package : Batteries 5 | # @description : Package for handling Battery automations and scripts. 6 | ############################################################################### 7 | 8 | 9 | sensor: 10 | - platform: mqtt 11 | name: "Battery Front Door Sensor" 12 | state_topic: "zwave2mqtt/front_door/128/1/0" 13 | unit_of_measurement: "%" 14 | device_class: battery 15 | value_template: "{{ value }}" 16 | json_attributes_topic: "zwave2mqtt/front_door/128/1/0" 17 | - platform: mqtt 18 | name: "Battery Laundry Door Sensor" 19 | state_topic: "zwave2mqtt/laundry_door/128/1/0" 20 | unit_of_measurement: "%" 21 | device_class: battery 22 | value_template: "{{ value }}" 23 | json_attributes_topic: "zwave2mqtt/laundry_door/128/1/0" 24 | - platform: mqtt 25 | name: "Battery Kitchen Smoke Detector" 26 | state_topic: "zwave2mqtt/kitchen_smoke/128/1/0" 27 | unit_of_measurement: "%" 28 | device_class: battery 29 | value_template: "{{ value }}" 30 | json_attributes_topic: "zwave2mqtt/kitchen_smoke/128/1/0" 31 | - platform: mqtt 32 | name: "Battery Garage Smoke Detector" 33 | state_topic: "zwave2mqtt/garage_smoke/128/1/0" 34 | unit_of_measurement: "%" 35 | device_class: battery 36 | value_template: "{{ value }}" 37 | json_attributes_topic: "zwave2mqtt/garage_smoke/128/1/0" 38 | - platform: mqtt 39 | name: "Battery Attic Door Sensor" 40 | state_topic: "zwave2mqtt/attic_door/128/1/0" 41 | unit_of_measurement: "%" 42 | device_class: battery 43 | value_template: "{{ value }}" 44 | json_attributes_topic: "zwave2mqtt/attic_door/128/1/0" 45 | - platform: mqtt 46 | name: "Battery Washer Door Sensor" 47 | state_topic: "zwave2mqtt/washer_door/128/1/0" 48 | unit_of_measurement: "%" 49 | device_class: battery 50 | value_template: "{{ value }}" 51 | json_attributes_topic: "zwave2mqtt/washer_door/128/1/0" 52 | - platform: mqtt 53 | name: "Battery Back Door Sensor" 54 | state_topic: "zwave2mqtt/back_door/128/1/0" 55 | unit_of_measurement: "%" 56 | device_class: battery 57 | value_template: "{{ value }}" 58 | json_attributes_topic: "zwave2mqtt/back_door/128/1/0" 59 | - platform: mqtt 60 | name: "Battery Side Door Sensor" 61 | state_topic: "zwave2mqtt/side_door/128/1/0" 62 | unit_of_measurement: "%" 63 | device_class: battery 64 | value_template: "{{ value }}" 65 | json_attributes_topic: "zwave2mqtt/side_door/128/1/0" 66 | - platform: mqtt 67 | name: "Battery Garage Door Sensor" 68 | state_topic: "zwave2mqtt/garage_door/128/1/0" 69 | unit_of_measurement: "%" 70 | device_class: battery 71 | value_template: "{{ value }}" 72 | json_attributes_topic: "zwave2mqtt/garage_door/128/1/0" 73 | - platform: mqtt 74 | name: "Battery Garage Motion Sensor" 75 | state_topic: "zwave2mqtt/garage_motion/128/1/0" 76 | unit_of_measurement: "%" 77 | device_class: battery 78 | value_template: "{{ value }}" 79 | json_attributes_topic: "zwave2mqtt/garage_motion/128/1/0" 80 | 81 | # automation: 82 | 83 | # - alias: 'Battery Alert' 84 | # initial_state: true 85 | # trigger: 86 | # - platform: time 87 | # at: '10:00:00' 88 | # - platform: time 89 | # at: '18:00:00' 90 | # condition: 91 | # condition: template 92 | # value_template: "{% if states('sensor.low_battery') %}true{% endif %}" 93 | # action: 94 | # - service: persistent_notification.create 95 | # data_template: 96 | # title: Low Battery 97 | # message: "{{ states('sensor.low_battery') }}" 98 | # notification_id: low-battery-alert 99 | # - service: script.text_notify 100 | # data_template: 101 | # title: "HA Issue" 102 | # message: "Low battery levels: {{ states('sensor.low_battery') }}" 103 | # who: 'jeff' -------------------------------------------------------------------------------- /config/packages/camera.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 06/10/2020 4 | # @package : Camera 5 | # @description : All the Camera related stuff 6 | ############################################################################### 7 | 8 | ####################################################################### 9 | # Using the HACS Arlo Integration 10 | # If you see the cloudflare error in the logs uncomment the user_agent line and try that 11 | # 12 | # Also, Don't forget to add the Camera section below. 13 | aarlo: 14 | host: https://my.arlo.com 15 | username: !secret arlo_user 16 | password: !secret arlo_pass 17 | db_motion_time: 30 18 | db_ding_time: 10 19 | recent_time: 10 20 | last_format: '%m-%d %H:%M' 21 | refresh_devices_every: 2 22 | verbose_debug: True 23 | tfa_host: 'imap.gmail.com' 24 | tfa_username: !secret GV_USER 25 | tfa_password: !secret GV_PASS 26 | #user_agent: linux 27 | 28 | # Arlo Integration 29 | alarm_control_panel: 30 | # Uses the custom arlo integration found in HACS 31 | - platform: aarlo 32 | home_mode_name: home 33 | away_mode_name: Armed 34 | 35 | sensor: 36 | - platform: aarlo 37 | monitored_conditions: 38 | - last_capture 39 | - total_cameras 40 | - battery_level 41 | - captured_today 42 | - signal_strength 43 | 44 | binary_sensor: 45 | - platform: aarlo 46 | monitored_conditions: 47 | - motion 48 | - sound 49 | - ding 50 | 51 | input_boolean: 52 | backyard_motion: 53 | name: Backyard Motion 54 | icon: mdi:motion-sensor 55 | 56 | # Dont forget the Camera - Commented out because its really defined below. 57 | # camera: 58 | # - platform: aarlo 59 | # ffmpeg_arguments: '-pred 1 -q:v 2' 60 | 61 | ####################################################################### 62 | 63 | camera: 64 | - platform: aarlo 65 | ffmpeg_arguments: '-pred 1 -q:v 2' 66 | - platform: ffmpeg 67 | input: !secret livingroom_cam # wyze cam v2 68 | name: livingroom camera 69 | - platform: ffmpeg 70 | input: !secret kitchen_cam # wyze cam v2 71 | name: kitchen camera 72 | - platform: ffmpeg 73 | input: !secret theater_cam # wyze cam v2 74 | name: theater camera 75 | - platform: ffmpeg 76 | input: !secret laundry_cam # wyze cam v2 77 | name: laundry camera 78 | - platform: ffmpeg 79 | name: "Backyard Ezviz" 80 | input: !secret ezviz_c8c 81 | # - platform: ffmpeg 82 | # name: "Printer Cam" 83 | # input: !secret printer_cam 84 | ffmpeg: 85 | ffmpeg_bin: /usr/bin/ffmpeg 86 | 87 | image_processing: 88 | - platform: doods 89 | url: http://192.168.7.187:8080 90 | detector: default 91 | scan_interval: 10000 92 | source: 93 | - entity_id: camera.c8c_f88801557 94 | - entity_id: camera.reolinkduo_profile000_mainstream 95 | - entity_id: camera.reolinkduo_profile010_mainstream 96 | file_out: 97 | - "/media/images/{{ camera_entity.split('.')[1] }}_latest.jpg" 98 | labels: 99 | - name: person 100 | confidence: 50 101 | 102 | 103 | script: 104 | backyard_motion: 105 | sequence: 106 | - condition: state 107 | entity_id: input_boolean.backyard_motion 108 | state: 'off' 109 | - service: input_boolean.turn_on 110 | entity_id: input_boolean.backyard_motion 111 | - delay: '00:01:00' 112 | - service: input_boolean.turn_off 113 | entity_id: input_boolean.backyard_motion 114 | 115 | automation: 116 | - id: someone_on_your_deck 117 | alias: Someone On Your Deck 118 | initial_state: true 119 | trigger: 120 | # When the current time matches input_datetime.halloween_show, light this candle 121 | - platform: state 122 | entity_id: input_boolean.backyard_motion 123 | to: 'on' 124 | from: 'off' 125 | action: 126 | - service: script.text_notify 127 | data: 128 | who: "jeff" 129 | message: "Wanker in the living room...I mean on the Back Deck" -------------------------------------------------------------------------------- /config/packages/cuckoo_clock.yaml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # @CCOSTAN 3 | # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig 4 | ## Plays the number of cuckoos per hour and 1 on the half hour. 5 | # More Info and Video: https://www.vcloudinfo.com/2017/11/building-digital-cuckoo-clock-with-home.html 6 | ##################################################################### 7 | 8 | automation: 9 | - alias: Cuckoo Clock 10 | id: 33dcd8e2-e87c-4d18-82bc-c7f9b53a1624 11 | mode: restart 12 | trigger: 13 | - platform: time_pattern 14 | minutes: 0 15 | - platform: time_pattern 16 | minutes: 30 17 | 18 | condition: 19 | - condition: state 20 | entity_id: input_boolean.audible_notifications 21 | state: 'on' 22 | - condition: or #Either we are home or Guest_Mode is on. 23 | conditions: 24 | - condition: state 25 | entity_id: group.family 26 | state: 'home' 27 | - condition: state 28 | entity_id: input_boolean.guest_mode 29 | state: 'on' 30 | 31 | action: 32 | - wait_template: "{{ not is_state('media_player.ha_blue', 'playing') }}" 33 | - service: media_player.volume_set 34 | data: 35 | entity_id: media_player.ha_blue 36 | volume_level: 0.22 37 | - service: media_player.play_media 38 | data: 39 | entity_id: > 40 | media_player.ha_blue 41 | media_content_id: > 42 | {% if now().strftime("%M")|int == 30 %} 43 | https://raw.githubusercontent.com/CCOSTAN/Home-AssistantConfig/master/config/sounds/cuckoo-clock-01.wav 44 | {% else %} 45 | https://raw.githubusercontent.com/CCOSTAN/Home-AssistantConfig/master/config/sounds/cuckoo-clock-{{now().strftime("%I")}}.wav 46 | {% endif %} 47 | media_content_type: music -------------------------------------------------------------------------------- /config/packages/database.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 06/10/2020 4 | # @package : Database 5 | # @description : Recorder and Logger Configurations 6 | ############################################################################### 7 | 8 | recorder: 9 | db_url: !secret database 10 | purge_keep_days: 30 11 | exclude: 12 | domains: 13 | - automation 14 | - weblink 15 | - updater 16 | - script 17 | entities: 18 | - sun.sun # Don't record sun data 19 | - sensor.last_boot # Comes from 'systemmonitor' sensor platform 20 | - sensor.date 21 | - sensor.icloud3_event_log 22 | - sensor.time 23 | - sensor.today_is 24 | - sensor.time_utc 25 | - sensor.time_date 26 | - sensor.time_online 27 | - sensor.moon 28 | - sensor.month_is 29 | - sensor.low_battery 30 | 31 | logbook: 32 | include: 33 | domains: 34 | - media_player 35 | - automation 36 | - script 37 | - scene 38 | - light 39 | - switch 40 | - device_tracker 41 | - input_boolean 42 | - person 43 | 44 | # Lets try to make the logs less chatty and more fine tuned. 45 | logger: 46 | default: error 47 | logs: 48 | homeassistant.core: warning 49 | homeassistant.loader: error 50 | homeassistant.components.recorder: error # to spot db issues 51 | homeassistant.config_entries: error 52 | homeassistant.setup: error 53 | homeassistant.components.roku: critical 54 | homeassistant.helpers.entity: critical 55 | homeassistant.components.automation: error 56 | homeassistant.components.tplink: error 57 | homeassistant.components.waze_travel_time: error 58 | homeassistant.components.statistics.sensor: critical 59 | homeassistant.components.nws: error 60 | homeassistant.components.wemo: error 61 | homeassistant.helpers.event: critical 62 | bellows: error 63 | zigpy: error 64 | homeassistant.components.zha.core: error 65 | 66 | history: 67 | include: 68 | domains: 69 | - sensor 70 | - switch 71 | - media_player 72 | - light 73 | - scene 74 | - automation 75 | -------------------------------------------------------------------------------- /config/packages/haunted_mansion_show.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 10/29/2019 4 | # @package : Haunted Mansion Show 5 | # @description : Config used to put on the Pre-show from Disney's Haunted Mansion in the living room 6 | ############################################################################### 7 | 8 | input_boolean: 9 | haunted_mansion: 10 | name: Haunted Mansion 11 | 12 | automation: 13 | # Turn on Haunted Mansion Show when input_boolean is flipped on 14 | - id: haunted_mansion_on 15 | alias: Haunted Mansion On 16 | mode: single 17 | initial_state: true 18 | trigger: 19 | - platform: state 20 | entity_id: input_boolean.haunted_mansion 21 | to: 'on' 22 | action: 23 | - service: script.turn_on 24 | entity_id: script.haunted_mansion_start 25 | - delay: 00:20:00 26 | 27 | # Turn off Haunted Mansion Show when input_boolean is flipped off 28 | - id: haunted_mansion_off 29 | alias: Haunted Mansion Off 30 | initial_state: true 31 | trigger: 32 | - platform: state 33 | entity_id: input_boolean.haunted_mansion 34 | to: 'off' 35 | action: 36 | - service: script.kill_this_ride 37 | - service: media_player.media_stop 38 | entity_id: media_player.ha_blue 39 | - service: script.turn_off 40 | entity_id: script.haunted_mansion_lights 41 | 42 | - id: haunted_mansion_show_trigger 43 | alias: Haunted Mansion show Trigger 44 | initial_state: true 45 | trigger: 46 | - platform: state 47 | entity_id: media_player.ha_blue 48 | to: 'playing' 49 | condition: 50 | - condition: state 51 | entity_id: input_boolean.haunted_mansion 52 | state: 'on' 53 | action: 54 | - service: script.turn_on 55 | entity_id: script.haunted_mansion_lights 56 | 57 | 58 | script: 59 | haunted_mansion_start: 60 | sequence: 61 | - condition: state 62 | entity_id: input_boolean.audible_notifications 63 | state: 'on' 64 | - condition: state 65 | entity_id: group.family 66 | state: 'home' 67 | - service: media_player.volume_set 68 | data_template: 69 | entity_id: media_player.ha_blue 70 | volume_level: .6 71 | - service: media_player.play_media 72 | entity_id: media_player.ha_blue 73 | data: 74 | #media_content_id: http://192.168.7.40/audio/haunted_mansion_preshow_full.mp3 75 | media_content_id: /media/disney/DL_Haunted_Mansion.mp3 76 | media_content_type: "music" 77 | 78 | haunted_mansion_lights: 79 | sequence: 80 | - service: light.turn_on 81 | entity_id: group.rgb_lr 82 | data: 83 | rgb_color: [255,255,255] 84 | #- delay: 00:01:06 85 | - delay: 00:01:20 86 | - service: light.turn_on 87 | entity_id: group.rgb_lr 88 | data: 89 | rgb_color: [73,119,255] 90 | #- delay: 00:00:15 91 | - delay: 00:00:25 92 | - service: light.turn_on 93 | entity_id: group.rgb_lr 94 | data: 95 | brightness_pct: 25 96 | #- delay: 00:00:37 97 | - delay: 00:00:29 98 | - service: switch.turn_on 99 | entity_id: switch.rail_lights 100 | - service: switch.turn_off 101 | entity_id: switch.rail_lights 102 | - delay: 00:00:02 103 | - service: scene.turn_on 104 | data: 105 | entity_id: scene.haunted_lights_out 106 | - service: switch.turn_on 107 | entity_id: switch.rail_lights 108 | - service: switch.turn_off 109 | entity_id: switch.rail_lights 110 | #- delay: 00:00:10 111 | - delay: 00:00:14 112 | - service: light.turn_on 113 | entity_id: group.rgb_lr 114 | data: 115 | rgb_color: [255,255,255] 116 | brightness_pct: 25 117 | - delay: 118 | seconds: 160 119 | 120 | -------------------------------------------------------------------------------- /config/packages/integrations.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 06/10/2020 4 | # @package : Integrations 5 | # @description : All the Integrations 6 | ############################################################################### 7 | 8 | # Google Calendar 9 | google: 10 | client_id: !secret google_client_id 11 | client_secret: !secret google_client_secret 12 | 13 | spotify: 14 | client_id: !secret spotify_client 15 | client_secret: !secret spotify_secret 16 | 17 | # Testing internet speedtest 18 | speedtestdotnet: 19 | 20 | # Life360 used for presence detection 21 | life360: 22 | accounts: 23 | - username: !secret life360_username 24 | password: !secret life360_password 25 | 26 | # Ecobee Thermostat 27 | ecobee: 28 | api_key: !secret ecobee_api 29 | 30 | # calendar: 31 | # - platform: todoist 32 | # token: !secret todoist_token 33 | # custom_projects: 34 | # - name: 'All Projects' 35 | # - name: 'Due Today' 36 | # due_date_days: 0 37 | # - name: 'Due This Week' 38 | # due_date_days: 7 39 | # - name: 'Follow up' 40 | # labels: 41 | # - Engagement 42 | # include_projects: 43 | # - SlackerLabs 44 | # - name: 'Work Stuff' 45 | # include_projects: 46 | # - Work 47 | 48 | gdacs: 49 | categories: 50 | - Earthquake 51 | - Tropical Cyclone 52 | radius: 500 53 | latitude: !secret MY_LATITUDE 54 | longitude: !secret MY_LONGITUDE 55 | 56 | # TPLink / KASA - Hardcoding the IP Address 57 | tplink: 58 | discovery: false 59 | switch: 60 | - host: 192.168.7.105 61 | - host: 192.168.7.107 62 | - host: 192.168.7.116 63 | - host: 192.168.7.120 64 | - host: 192.168.7.136 65 | - host: 192.168.7.137 66 | 67 | # WZYE Devices - Using the HACS integration 68 | wyzeapi: 69 | username: !secret wyze_user 70 | password: !secret wyze_password 71 | 72 | # IFTTT (May be removed - I dont think I am using this.) 73 | ifttt: 74 | key: !secret IFTTT_API_KEY 75 | 76 | # Using the HACS Daily Snapshot Clean Up Plugin 77 | clean_up_snapshots_service: 78 | host: !secret snapshot_url 79 | token: !secret snapshot_token 80 | number_of_snapshots_to_keep: 3 81 | 82 | # Hardcoding the Wemo switch 83 | wemo: 84 | discovery: true 85 | static: 86 | - 192.168.7.99 87 | 88 | # homekit: 89 | # filter: 90 | # include_domains: 91 | # - light 92 | # include_entities: 93 | # - switch.master_bath_fan 94 | # - switch.master_bedroom_bookcase 95 | # - switch.rail_lights 96 | # - switch.skylars_christmas_tree 97 | # - switch.sleep_aid 98 | # - switch.artemis 99 | # - switch.croft_fan 100 | # - switch.croft_light 101 | # - switch.dazzned50 102 | # - switch.desk_lamp 103 | # - switch.driveway_light 104 | # - switch.fireplace_lights 105 | # - switch.forest_incense 106 | # - switch.front_porch_light 107 | # - switch.garage_fan 108 | # - switch.incense 109 | # - switch.kasa2 110 | # - switch.kitchen_light_strip 111 | # - switch.rainbow_light 112 | # - switch.skylar_led_cube 113 | # - switch.theater_fan 114 | # - switch.train_table 115 | # - switch.wled_loftbed_nightlight 116 | # - switch.wled_tree_nightlight 117 | # - switch.3dprinters 118 | 119 | -------------------------------------------------------------------------------- /config/packages/inventory.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 08/16/2019 4 | # @package : Inventory 5 | # @description : Automating Grocy Inventory Management. Here you will find notifications for inventory and helpers for adding stock 6 | # The scripts are meant to be exectuted via voice. 7 | # For any product that doesn't expire use '2999-12-31' 8 | ############################################################################### 9 | 10 | 11 | script: 12 | # Add HVAC Air Filters 13 | purchased_hvac_air_filters: 14 | sequence: 15 | - service: grocy.add_product 16 | data: 17 | product_id: 3 18 | amount: 1 19 | price: 0.00 -------------------------------------------------------------------------------- /config/packages/jarvis.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 07/09/2019 4 | # @package : Jarvis 5 | # @description : Bringing some Jarvis to Home Assistant 6 | ############################################################################### 7 | 8 | input_boolean: 9 | house_party_protocol_switch: 10 | name: House Party Switch 11 | 12 | # automation: 13 | # - id: house_party_protocol_on 14 | # alias: Turn On House Party Protocol 15 | # initial_state: true 16 | # trigger: 17 | # - platform: state 18 | # entity_id: input_boolean.house_party_protocol_switch 19 | # to: 'on' 20 | # action: 21 | # - delay: 00:00:05 22 | # - service: homeassistant.turn_on 23 | # entity_id: group.incense 24 | # - service: script.status_annc 25 | # data_template: 26 | # who: '{{ states.sensor.room_presence.state }}' 27 | # call_house_party_protocol_enabled: 1 28 | 29 | # - id: house_party_protocol_off 30 | # alias: Turn Off House Party Protocol 31 | # initial_state: true 32 | # trigger: 33 | # - platform: state 34 | # entity_id: input_boolean.house_party_protocol_switch 35 | # to: 'off' 36 | # action: 37 | # - delay: 00:00:05 38 | # - service: homeassistant.turn_off 39 | # entity_id: group.incense 40 | # - service: script.status_annc 41 | # data_template: 42 | # who: '{{ states.sensor.room_presence.state }}' 43 | # call_house_party_protocol_disabled: 1 44 | 45 | script: 46 | house_party_protocol_on: 47 | sequence: 48 | - delay: 00:00:05 49 | - service: homeassistant.turn_on 50 | entity_id: group.incense 51 | - service: script.status_annc 52 | data_template: 53 | who: '{{ states.sensor.room_presence.state }}' 54 | call_house_party_protocol_enabled: 1 55 | 56 | house_party_protocol_off: 57 | sequence: 58 | - delay: 00:00:05 59 | - service: homeassistant.turn_off 60 | entity_id: group.incense 61 | - service: script.status_annc 62 | data_template: 63 | who: '{{ states.sensor.room_presence.state }}' 64 | call_house_party_protocol_disabled: 1 65 | 66 | alexa_interjection: 67 | sequence: 68 | - service: script.status_annc 69 | data: 70 | who: "{{ states('sensor.last_alexa')}}" 71 | call_confirmation: 1 72 | 73 | google_interjection: 74 | sequence: 75 | - service: script.status_annc 76 | data: 77 | who: '{{ states.sensor.room_audio.state }}' 78 | call_confirmation: 1 79 | 80 | 81 | -------------------------------------------------------------------------------- /config/packages/json_data/school.json: -------------------------------------------------------------------------------- 1 | { 2 | "MENU": { 3 | "static": { 4 | "11/11": "Pizza", 5 | "11/12": "Taco Burger", 6 | "11/15": "Chicken Minis", 7 | "11/16": "Housemade Dip and Chips", 8 | "11/17": "Sub Sandwich", 9 | "11/18": "Pizza", 10 | "11/19": "Burgers", 11 | "11/29": "Mini Corn Dogs", 12 | "11/30": "Housemade Dip and Chips or Cheesy Pull Aparts", 13 | "12/1": "Drumstick", 14 | "12/2": "Pizza", 15 | "12/3": "Taco Burger", 16 | "12/6": "Chicken Minis", 17 | "12/7": "Housemade Dip and Chips", 18 | "12/8": "Sub Sandwich", 19 | "12/9": "Pizza", 20 | "12/10": "Burgers", 21 | "12/13": "Chicken Nuggets", 22 | "12/14": "Hot Dog", 23 | "12/15": "Chicken Sandwich", 24 | "12/16": "Pizza", 25 | "12/17": "Seafood Variety" 26 | 27 | } 28 | }, 29 | "EVENTS": { 30 | "static": { 31 | "1/25": "Digital Learning Day", 32 | "3/2": "Digital Leaerning Day and Early Release", 33 | "3/3": "Early Release", 34 | "3/22": "Digital Learning Day", 35 | "8/4": "Digital Learning Day", 36 | "9/14": "Digital Learning Day", 37 | "10/20": "Digital Learning Day", 38 | "10/21": "Early Release", 39 | "10/22": "Early Release", 40 | "11/9": "Digital Learning Day" 41 | 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /config/packages/maintenance.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 02/19/2019 4 | # @package : Maintnance 5 | # @description : Maint Automation that occurs every day 6 | ############################################################################### 7 | automation: 8 | - id: e1cb2c44-0423-11eb-adc1-0242ac120002 9 | alias: Shelly Sync at HA Start 10 | trigger: 11 | - platform: homeassistant 12 | event: start 13 | action: 14 | - delay: 00:00:20 15 | - service: mqtt.publish 16 | data: 17 | topic: shellies/command 18 | payload: announce 19 | 20 | 21 | # Using the HACS Daily Snapshot Clean Up Plugin 22 | - id: daily_snapshot_clean_up 23 | alias: Daily snapshot clean up 24 | trigger: 25 | - platform: time 26 | at: '03:00:00' 27 | action: 28 | - service: clean_up_snapshots_service.clean_up 29 | 30 | # Morning Entity Refresh - For all those sensors that need a little push 31 | - id: daily_entity_refresh 32 | alias: Daily Entity Refresh 33 | trigger: 34 | - platform: time 35 | at: '04:30:00' 36 | action: 37 | - service: homeassistant.update_entity 38 | entity_id: sensor.today_is 39 | - service: homeassistant.update_entity 40 | entity_id: sensor.holiday 41 | 42 | # Nightly Entity Refresh - For all those sensors that need a little push 43 | - id: daily_entity_refresh2 44 | alias: Daily Entity Refresh2 45 | trigger: 46 | - platform: time 47 | at: '17:00:00' 48 | action: 49 | - service: homeassistant.update_entity 50 | entity_id: sensor.school_tomorrow 51 | 52 | 53 | # startup auotmations to update some custom sensors due to new order of home assistant firing up 54 | - id: startup_automations 55 | alias: startup_automations 56 | trigger: 57 | platform: homeassistant 58 | event: start 59 | action: 60 | - service: homeassistant.update_entity 61 | entity_id: sensor.jeff_location 62 | - service: homeassistant.update_entity 63 | entity_id: sensor.kat_location 64 | - service: homeassistant.update_entity 65 | entity_id: sensor.skylar_location 66 | - service: homeassistant.update_entity 67 | entity_id: sensor.today_is 68 | - service: homeassistant.update_entity 69 | entity_id: sensor.holiday 70 | - service: frontend.set_theme 71 | data: 72 | name: Google Dark Theme 73 | -------------------------------------------------------------------------------- /config/packages/reminders.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 07/15/2019 4 | # @package : Reminders 5 | # @description : Automations to set reminders and chores...which are really just reminders to do the chores thus they belong in reminders. 6 | # Leveraging Grocy for most of these. 7 | ############################################################################### 8 | 9 | input_datetime: 10 | kat_pill_reminder: 11 | name: Kat Pill Reminder 12 | has_date: false 13 | has_time: true 14 | heartworm_reminder: 15 | name: Heartworm Reminder 16 | has_date: true 17 | has_time: false 18 | 19 | input_boolean: 20 | washer_finished: 21 | name: Washer Finished 22 | icon: mdi:washing-machine 23 | feed_fish: 24 | name: Feed Fish 25 | icon: mdi:fishbowl 26 | clean_litterbox: 27 | name: Clean Litterbox 28 | icon: mdi:cat 29 | clean_washer: 30 | name: Clean Washer 31 | icon: mdi:washing-machine 32 | clean_dishwasher: 33 | name: Clean Dishwasher 34 | icon: mdi:dishwasher 35 | clean_towel_day: 36 | name: Clean Towel Day 37 | icon: mdi:washing-machine 38 | do_skylars_laundry: 39 | name: Do Skylars Laundry 40 | icon: mdi:washing-machine 41 | clean_sheet_day: 42 | name: Clean Sheet Day 43 | icon: mdi:bed 44 | clean_kitchen: 45 | name: Clean Kitchen 46 | icon: mdi:stove 47 | clean_bathrooms: 48 | name: Clean Bathrooms 49 | icon: mdi:toilet 50 | clean_livingroom: 51 | name: Clean Livingroom 52 | icon: mdi:sofa 53 | mow_yard: 54 | name: Mow Yard 55 | icon: mdi:robot-mower 56 | clean_fish_tank: 57 | name: Clean Fish Tank 58 | heartworm: 59 | name: Heartworm 60 | icon: mdi:dog-side 61 | nextguard: 62 | name: NextGuard 63 | icon: mdi:dog-side 64 | replace_hvac_filters: 65 | name: Replace HVAC Filters 66 | icon: mdi:hvac 67 | clean_disposal: 68 | name: Clean Disposal 69 | icon: mdi:recycle 70 | clean_dishwasher_filter: 71 | name: Clean Dishwasher Filter 72 | icon: mdi:diswasher 73 | clean_washer_filter: 74 | name: Clean DWasher Filter 75 | icon: mdi:washing-machine 76 | 77 | 78 | 79 | 80 | automation: 81 | # Replacing calendar based reminders with Grocy 82 | # # Massive automation to call all the reminder scripts. 83 | # - id: turn_reminders_on 84 | # alias: Turn Reminders On 85 | # initial_state: true 86 | # trigger: 87 | # - entity_id: calendar.reminders 88 | # from: 'off' 89 | # platform: state 90 | # to: 'on' 91 | # action: 92 | # - service: script.heartworm_on 93 | 94 | ##################### 95 | # Send Medicine Reminders 96 | - id: '1562630916597' 97 | alias: Kat Pill Reminder 98 | trigger: 99 | - platform: template 100 | value_template: "{{ states('sensor.time') == (state_attr('input_datetime.kat_pill_reminder', 'timestamp') | int | timestamp_custom('%H:%M', False)) }}" 101 | action: 102 | - data: 103 | message: Remember to take meds 104 | service: notify.kat_ios 105 | 106 | #################### 107 | # Litterbox chore 108 | # Turn on Reminder 109 | - alias: Reminder On Litterbox 110 | trigger: 111 | - platform: state 112 | entity_id: binary_sensor.empty_the_litterbox 113 | to: 'on' 114 | action: 115 | - service: input_boolean.turn_on 116 | entity_id: input_boolean.clean_litterbox 117 | # When clean litterbox is complete update Grocy via command to api to mark chore complete 118 | - alias: Chore Complete Litterbox 119 | trigger: 120 | - platform: state 121 | entity_id: input_boolean.clean_litterbox 122 | to: 'off' 123 | action: 124 | - service: grocy.execute_chore 125 | data: 126 | chore_id: 4 127 | done_by: 1 128 | 129 | #################### 130 | # HeartWorm Chore - See that Winston gets his heartworm meds 131 | # Turn on reminder 132 | - alias: Reminder On Heartworm 133 | trigger: 134 | - platform: state 135 | entity_id: binary_sensor.winstons_heartworm 136 | to: 'on' 137 | action: 138 | - service: input_boolean.turn_on 139 | entity_id: input_boolean.heartworm 140 | 141 | # # # When Winston gets his heartworm mark it complete, and update Grocy via command to api to reduce stock and mark chore complete. 142 | # - alias: Chore Complete Heartworm 143 | # trigger: 144 | # - platform: state 145 | # entity_id: input_boolean.heartworm 146 | # from: 'on' 147 | # to: 'off' 148 | # action: 149 | # - service: grocy.execute_chore 150 | # data: 151 | # chore_id: 2 152 | # done_by: 1 153 | 154 | ################### 155 | # Nextguard chore - See that Winston get his Flea/ Tick Meds 156 | # Turn on reminder 157 | - alias: Reminder On Nextguard 158 | trigger: 159 | - platform: state 160 | entity_id: binary_sensor.winstons_nextguard 161 | to: 'on' 162 | action: 163 | - service: input_boolean.turn_on 164 | entity_id: input_boolean.nextguard 165 | # # # When Winston gets his Nextguard mark it complete, and update Grocy via command to api to reduce stock and mark chore complete. 166 | # - alias: Nextguard Complete 167 | # trigger: 168 | # - platform: state 169 | # entity_id: input_boolean.nextguard 170 | # to: 'off' 171 | # action: 172 | # - service: grocy.execute_chore 173 | # data: 174 | # chore_id: 3 175 | # done_by: 1 176 | 177 | ################### 178 | # Skylars Laundry chore - Do Skylars Launder each week 179 | # Turn on reminder 180 | - alias: Reminder On Skylars Laundry 181 | trigger: 182 | - platform: state 183 | entity_id: binary_sensor.skylars_laundry 184 | to: 'on' 185 | action: 186 | - service: input_boolean.turn_on 187 | entity_id: input_boolean.do_skylars_laundry 188 | # # When its complete, and update Grocy via command to api to reduce stock and mark chore complete. 189 | # - alias: Skylars Laundry Complete 190 | # trigger: 191 | # - platform: state 192 | # entity_id: input_boolean.do_skylars_laundry 193 | # to: 'off' 194 | # action: 195 | # - service: grocy.execute_chore 196 | # data: 197 | # chore_id: 7 198 | # done_by: 1 199 | 200 | # Replacing calendar based reminders with Grocy 201 | # script: 202 | # # Check to see if heartworm is the reminder in the cal 203 | # heartworm_on: 204 | # sequence: 205 | # - condition: template 206 | # value_template: '{{ states.calendar.reminders.attributes.message == "Heartworm" }}' 207 | # - service: input_boolean.turn_on 208 | # entity_id: input_boolean.heartworm 209 | -------------------------------------------------------------------------------- /config/packages/space.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 02/19/2019 4 | # @package : Space 5 | # @description : Tracking space. Inspiration and code taking from https://github.com/CCOSTAN/Home-AssistantConfig#logo 6 | # @original : https://github.com/CCOSTAN/Home-AssistantConfig/blob/master/config/packages/space.yaml 7 | ############################################################################### 8 | 9 | homeassistant: 10 | customize: 11 | binary_sensor.iss: 12 | icon: mdi:satellite-variant 13 | friendly_name: ISS Visibility 14 | 15 | hidden: False 16 | homebridge_hidden: true 17 | sensor.launch_window: 18 | hidden: False 19 | icon: mdi:rocket 20 | friendly_name: Rocket Launch Window 21 | 22 | binary_sensor: 23 | - platform: iss 24 | show_on_map: false 25 | 26 | sensor: 27 | - platform: moon 28 | - platform: launch_library 29 | 30 | 31 | 32 | automation: 33 | 34 | - id: iss_tweet 35 | initial_state: true 36 | alias: 'ISS Tweet' 37 | trigger: 38 | - platform: state 39 | entity_id: 40 | - binary_sensor.iss 41 | to: 'on' 42 | from: 'off' 43 | action: 44 | - service: script.twitter_notify_image 45 | data_template: 46 | tweet: >- 47 | {{ [ 48 | "The #ISS is passing over. Wave. #Space #theycanseeourhouse ", 49 | "The #ISS just flew by with there are {{states.binary_sensor.iss.attributes.number_of_people_in_space}} people doing cool stuff. #Space #theycanseeourhouse", 50 | "The #ISS just flew by with {{states.binary_sensor.iss.attributes.number_of_people_in_space}} people in it. #Space #theycanseeourhouse" 51 | ] | random }} 52 | image: >- 53 | {{ [ "/config/www/tweet_images/iss.jpg", 54 | "/config/www/tweet_images/iss2.jpg"] | random }} 55 | 56 | - id: full_moon_tweet 57 | initial_state: true 58 | alias: 'Full Moon -Tweet' 59 | trigger: 60 | - platform: sun 61 | event: sunset 62 | offset: -00:15:00 63 | condition: 64 | - condition: state 65 | entity_id: sensor.moon 66 | state: 'full_moon' 67 | action: 68 | - service: script.speech_engine 69 | data_template: 70 | who: '{{ states.sensor.room_audio.state }}' 71 | message: > 72 |

73 | {{ [ 74 | 'There is a Full Moon out tonight. and this time it is the actual moon. And not the neighbor. ', 75 | 'Hey look, There is the full moon. ', 76 | 'The moon is huge! And full. ', 77 | 'If you went outside right now you might see the full moon. Of course if you wait long enough there will be one inside the house too. ', 78 | 'If you want to see the full moon, tonight is the night.'] 79 | | random }} 80 |

81 | - service: script.twitter_notify_image 82 | data_template: 83 | tweet: >- 84 | {{ [ 85 | "There is a Full Moon out tonight, and this time it's the actual moon and not the neighbor. ", 86 | "Hey look kids, There's the full moon. ", 87 | "The moon is huge! And full. "] | random + "#Space #fullmoon"}} 88 | image: >- 89 | "/config/www/tweet_images/full_moon.jpg" 90 | -------------------------------------------------------------------------------- /config/packages/spotify.yaml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ######################################## 6 | # Spotify Playlists 7 | # 8 | # Chill - https://open.spotify.com/playlist/0dIzE1HeaUz1kmPX6DTnpY 9 | # Background - https://open.spotify.com/playlist/3tKyL6gGSa5fdyCdo92L8m 10 | # Skylar - https://open.spotify.com/playlist/0hYKkmUpFFG37TtFX23cMM?si=ZQLOiV5iT2yPPBEAEqTP8w 11 | # Classical - https://open.spotify.com/playlist/09IWZAWNkNBl7TzWAoKXy3?si=NW4qtoxiTjqS0NpbynCoUQ 12 | # Christmas - https://open.spotify.com/playlist/5XgmUr452DupjZYfnAcHS0?si=Cncjle8GQd-4Uyk1k4NjyA 13 | # Jukebox - https://open.spotify.com/playlist/4rr6pL3qY8fBMrMDvpbEc8?si=NrIdThTuToCFIl1EGC_UEw 14 | # Scored - https://open.spotify.com/playlist/1XJddjZ9l71FPIJhpyL4vI?si=q-bbG_0fRjuH2wVHGIH2Yg 15 | # Disney - https://open.spotify.com/playlist/0zKtkdfsOFOg2EnjYa3QWb?si=pGDhUQlnTpaL0ESLIDozUw 16 | # Jazz - https://open.spotify.com/playlist/7INVZzAMFf4A5oiXec6FoF?si=Z62yVQ3UTjigoA8U782vtA 17 | # Bedtime - https://open.spotify.com/playlist/3luYE0ii9N8JaOaFnPW9MJ?si=mL4b0NIsTe6RcOK9ANEwGw 18 | # 19 | # Sources: 20 | # 21 | # Everywhere 22 | # Skylar's Bedroom 23 | # Living Room 24 | # Kitchen 25 | ####################################### 26 | 27 | script: 28 | 29 | play_spotify_playlist: 30 | sequence: 31 | - service: media_player.select_source 32 | data_template: 33 | entity_id: media_player.spotify_jarvis 34 | source: > 35 | {{ source }} 36 | - service: media_player.play_media 37 | data_template: 38 | entity_id: media_player.spotify_jarvis 39 | media_content_type: playlist 40 | media_content_id: > 41 | {% if playlist == 'chill' %} 42 | https://open.spotify.com/playlist/0dIzE1HeaUz1kmPX6DTnpY?si=qzhiPR3UQg6H1pk_rq2Eiw 43 | {% elif playlist == 'bedtime' %} 44 | https://open.spotify.com/playlist/3luYE0ii9N8JaOaFnPW9MJ?si=puEZG_VgQuqsZ8CFcxFO9w 45 | {% elif playlist == 'background' %} 46 | https://open.spotify.com/playlist/3tKyL6gGSa5fdyCdo92L8m?si=WV_PS3S6S-WmdjeopUEX8Q 47 | {% elif playlist == 'skylar' %} 48 | https://open.spotify.com/playlist/0hYKkmUpFFG37TtFX23cMM?si=ZQLOiV5iT2yPPBEAEqTP8w 49 | {% elif playlist == 'classical' %} 50 | https://open.spotify.com/playlist/09IWZAWNkNBl7TzWAoKXy3?si=gk1eUcKpRXK1xeQxvYSPcQ 51 | {% elif playlist == 'christmas' %} 52 | https://open.spotify.com/playlist/5XgmUr452DupjZYfnAcHS0?si=1HULm9WMRAGd4R7kW3gsQA 53 | {% elif playlist == 'jukebox' %} 54 | https://open.spotify.com/playlist/4rr6pL3qY8fBMrMDvpbEc8?si=qJ8fTx-IRWewI-VZcGWkfg 55 | {% elif playlist == 'scored' %} 56 | https://open.spotify.com/playlist/1XJddjZ9l71FPIJhpyL4vI?si=q-bbG_0fRjuH2wVHGIH2Yg 57 | {% elif playlist == 'disney' %} 58 | https://open.spotify.com/playlist/0zKtkdfsOFOg2EnjYa3QWb?si=pGDhUQlnTpaL0ESLIDozUw 59 | {% elif playlist == 'jazz' %} 60 | https://open.spotify.com/playlist/7INVZzAMFf4A5oiXec6FoF?si=Z62yVQ3UTjigoA8U782vtA 61 | {% endif %} 62 | - service: media_player.shuffle_set 63 | data: 64 | entity_id: media_player.spotify_jarvis 65 | shuffle: 'true' 66 | 67 | skylar_bedtime_music: 68 | alias: Slylar Bedtime Music 69 | sequence: 70 | - service: media_player.volume_set 71 | data_template: 72 | entity_id: media_player.skylar_s_bedroom 73 | volume_level: .25 74 | - service: script.play_spotify_playlist 75 | data_template: 76 | source: Skylar's Bedroom 77 | playlist: bedtime 78 | 79 | kitchen_chill_music: 80 | alias: Kitchen Chill Music 81 | sequence: 82 | - service: script.play_spotify_playlist 83 | data_template: 84 | source: Kitchen 85 | playlist: chill -------------------------------------------------------------------------------- /config/packages/switchbot.yaml: -------------------------------------------------------------------------------- 1 | 2 | ############################################################################### 3 | # @author : Jeffrey Stone 4 | # @date : 12/06/2021 5 | # @package : Switchbot 6 | # @description : All the Switchbot related stuff. Built from https://community.home-assistant.io/t/switch-bot-api-integration/270550 7 | ############################################################################### 8 | rest_command: 9 | switchbot_device_command: 10 | url: 'https://api.switch-bot.com/v1.0/devices/{{ deviceId }}/commands' 11 | method: post 12 | content_type: 'application/json' 13 | headers: 14 | Authorization: !secret switchbot_api 15 | # Authorization: "y80ir3bw9y24bnvwo8023hpnvnvw" 16 | payload: '{"command": "{{ command }}","parameter": "{{ parameter }}"}' 17 | 18 | sensor: 19 | - platform: rest 20 | name: 'lrone Curtain Position' 21 | resource: !secret switchbot_lrone_status_url 22 | #resource: "https://api.switch-bot.com/v1.0/devices/YOURDEVICEID/status" 23 | method: GET 24 | scan_interval: 600 25 | headers: 26 | Authorization: !secret switchbot_api 27 | Content-Type: 'application/json' 28 | value_template: '{{ value_json.body.slidePosition }}' 29 | json_attributes_path: "$.body" 30 | json_attributes: 31 | - deviceId 32 | - deviceType 33 | - hubDeviceId 34 | - calibrate 35 | - group 36 | - moving 37 | - slidePosition 38 | 39 | cover: 40 | - platform: template 41 | covers: 42 | lr_curtains: 43 | device_class: curtain 44 | friendly_name: "Living Room Curtains" 45 | position_template: "{{ states('sensor.lrone_curtain_position') }}" 46 | open_cover: 47 | service: rest_command.switchbot_device_command 48 | data: 49 | deviceId: !secret switchbot_lrone_deviceId 50 | #deviceId: "E0FA71..." 51 | command: "turnOn" 52 | close_cover: 53 | service: rest_command.switchbot_device_command 54 | data: 55 | deviceId: !secret switchbot_lrone_deviceId 56 | command: "turnOff" 57 | stop_cover: 58 | service: rest_command.switchbot_device_command 59 | data: 60 | deviceId: !secret switchbot_lrone_deviceId 61 | command: "turnOff" 62 | set_cover_position: 63 | service: rest_command.switchbot_device_command 64 | data: 65 | deviceId: !secret switchbot_lrone_deviceId 66 | command: "setPosition" 67 | parameter: "0,ff,{{position}}" 68 | 69 | 70 | -------------------------------------------------------------------------------- /config/packages/sysmon.yaml: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # @author : Jeffrey Stone 3 | # @date : 02/19/2019 4 | # @package : Sysmon 5 | # @description : A collection of Home Assistant and Pi Sensors 6 | ############################################################################### 7 | 8 | sensor: 9 | - platform: systemmonitor 10 | resources: 11 | - type: disk_use_percent 12 | arg: / 13 | - type: memory_use_percent 14 | - type: network_in 15 | arg: eth0 16 | - type: network_out 17 | arg: eth0 18 | - type: load_15m 19 | - type: processor_use 20 | - type: last_boot 21 | - platform: time_date 22 | display_options: 23 | - 'time' 24 | - 'date' 25 | - 'date_time' 26 | - 'time_date' 27 | - 'time_utc' 28 | - 'beat' 29 | 30 | - platform: template 31 | sensors: 32 | current_version_ha: 33 | #command: python3 -c "import requests; print(requests.get('https://pypi.python.org/pypi/homeassistant/json').json()['info']['version'])" 34 | friendly_name: Current HA Version 35 | value_template: >- 36 | {{ states.binary_sensor.attributes.newest_version }} 37 | - platform: version 38 | name: Installed version 39 | source: local 40 | #command: "head -5 /home/homeassistant/.homeassistant/.HA_VERSION" 41 | - platform: version 42 | name: Released Version 43 | source: pypi 44 | - platform: version 45 | name: Released Hassio Ver 46 | source: hassio 47 | 48 | # unit of measurement deprecated in 2020.12.0 49 | - platform: uptime 50 | name: Time Online 51 | #unit_of_measurement: days 52 | - platform: command_line 53 | name: Lines of Code 54 | command: "find /config -name '*.yaml' | xargs cat | wc -l" 55 | scan_interval: 20000 56 | - platform: template 57 | sensors: 58 | open_pull_requests: 59 | friendly_name: Open Pull Requests 60 | value_template: >- 61 | {{ states.sensor.home_assistant_configuration.attributes.open_pull_requests }} 62 | 63 | # For tracking number of times motion is detected 64 | # at front door in last 7 days 65 | - platform: history_stats 66 | name: Front Door Motion 67 | entity_id: binary_sensor.aarlo_motion_front_door 68 | state: 'on' 69 | type: count 70 | end: '{{ now() }}' 71 | duration: 72 | days: 7 73 | 74 | utility_meter: 75 | # Use the 7 day history of motion at front door 76 | # to get daily motion. 77 | hourly_frontdoor_motion: 78 | source: sensor.front_door_motion 79 | cycle: hourly 80 | daily_frontdoor_motion: 81 | source: sensor.front_door_motion 82 | cycle: daily 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /config/packages/youtube.yaml: -------------------------------------------------------------------------------- 1 | #------------------------------------------- 2 | # I totally stole this from @CCOSTAN 3 | # 4 | # Original Repo : https://github.com/CCOSTAN/Home-AssistantConfig 5 | # YouTube Related Packages from @Pinkywafer 6 | # https://github.com/pinkywafer/Home-Assistant_Config/blob/master/packages/youtube/vcloudinfo.yaml 7 | # More information found here in these issues 8 | # https://github.com/CCOSTAN/Home-AssistantConfig/issues/720 9 | #------------------------------------------- 10 | 11 | sensor: 12 | - platform: youtube 13 | channel_id: UCipZJ6748kd8TbelSxcvcVg 14 | 15 | 16 | automation: 17 | - alias: YouTube Notification - SlackerLabs 18 | id: 5e751352-067e-4706-978a-2479b6f5fd96 19 | trigger: 20 | - platform: state 21 | entity_id: sensor.slackerlabs 22 | 23 | condition: 24 | - condition: template 25 | value_template: "{{ trigger.from_state.attributes.url != trigger.to_state.attributes.url }}" 26 | 27 | action: 28 | - service: script.text_notify 29 | data_template: 30 | who: "jeff" 31 | message: Your Video is now Live {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} 32 | - repeat: 33 | count: 1 34 | sequence: 35 | - delay: '00:03:00' 36 | 37 | - service: script.twitter_notify_image 38 | data: 39 | tweet: > 40 | {{ [ 41 | "Brand New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 42 | "New SlackerLabs Video went Live! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 43 | "Boom! New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 44 | "Its time for a New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 45 | "Today is SlackerLabs Video Release Day! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome " 46 | ] | random }} 47 | who: 'thejeffreystone' 48 | image: > 49 | {{ state_attr('sensor.slackerlabs', 'entity_picture') }} 50 | 51 | - delay: '00:10:00' 52 | 53 | - service: script.twitter_notify_image 54 | data: 55 | tweet: > 56 | {{ [ 57 | "Brand New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 58 | "New SlackerLabs Video went Live! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 59 | "Boom! New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 60 | "Its time for a New SlackerLabs Video! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome ", 61 | "Today is SlackerLabs Video Release Day! {{ states('sensor.slackerlabs') }} - {{ state_attr('sensor.slackerlabs','url') }} #homeassistant #homeautomation #smarthome " 62 | ] | random }} 63 | who: 'slackerlabs' 64 | image: > 65 | {{ state_attr('sensor.slackerlabs', 'entity_picture') }} 66 | 67 | - delay: '12:30:00' -------------------------------------------------------------------------------- /config/packages/zigbee2mqtt.yaml: -------------------------------------------------------------------------------- 1 | 2 | input_boolean: 3 | zigbee_permit_join: 4 | name: Allow devices to join 5 | initial: off 6 | icon: mdi:cellphone-wireless 7 | 8 | timer: 9 | zigbee_permit_join: 10 | name: Time remaining 11 | duration: 600 # Updated this to the number of seconds you wish 12 | 13 | sensor: 14 | - platform: mqtt 15 | name: Bridge state 16 | state_topic: "zigbee2mqtt/bridge/state" 17 | icon: mdi:router-wireless 18 | 19 | automation: 20 | - id: enable_zigbee_join 21 | alias: Enable Zigbee joining 22 | trigger: 23 | platform: state 24 | entity_id: input_boolean.zigbee_permit_join 25 | to: 'on' 26 | action: 27 | - service: mqtt.publish 28 | data: 29 | topic: zigbee2mqtt/bridge/config/permit_join 30 | payload: 'true' 31 | - service: timer.start 32 | data: 33 | entity_id: timer.zigbee_permit_join 34 | - id: disable_zigbee_join 35 | alias: Disable Zigbee joining 36 | trigger: 37 | - entity_id: input_boolean.zigbee_permit_join 38 | platform: state 39 | to: 'off' 40 | action: 41 | - data: 42 | payload: 'false' 43 | topic: zigbee2mqtt/bridge/config/permit_join 44 | service: mqtt.publish 45 | - data: 46 | entity_id: timer.zigbee_permit_join 47 | service: timer.cancel 48 | - id: disable_zigbee_join_timer 49 | alias: Disable Zigbee joining by timer 50 | trigger: 51 | - platform: event 52 | event_type: timer.finished 53 | event_data: 54 | entity_id: timer.zigbee_permit_join 55 | action: 56 | - service: mqtt.publish 57 | data: 58 | topic: zigbee2mqtt/bridge/config/permit_join 59 | payload: 'false' 60 | - service: input_boolean.turn_off 61 | data: 62 | entity_id: input_boolean.zigbee_permit_join -------------------------------------------------------------------------------- /config/python_scripts/light_transistion.py: -------------------------------------------------------------------------------- 1 | # 2 | # Script to fade lights in slowly 3 | # Takes the following inputs 4 | # entity_id = The light you want to fade in 5 | # transition: = # Seconds to go from current to end brightness 6 | # brightness: = # Brightness to end at 7 | # brightness_pct: = # Brightness to end at as a percentage 8 | # 9 | entity_id = data.get('entity_id') 10 | brightness = data.get('brightness', None) 11 | brightness_pct = data.get('brightness_pct', None) 12 | 13 | if entity_id is not None and (brightness is not None or brightness_pct is not None): 14 | light = hass.states.get(entity_id) 15 | 16 | start_level = light.attributes.get('brightness', 0) 17 | transition = int(data.get('transition', 0)) 18 | 19 | """ Use brightness or convert brightness_pct """ 20 | end_level = int(brightness) if brightness is not None else math.ceil( 21 | float(brightness_pct) * 2.55) 22 | 23 | """ Calculate number of steps """ 24 | steps = int(math.fabs((start_level - end_level))) 25 | fadeout = True if start_level > end_level else False 26 | 27 | """ Calculate the delay time """ 28 | delay = round(transition / steps, 3) 29 | 30 | """ Disable delay and increase stepping if delay < 3/4 second """ 31 | if (delay < .750): 32 | delay = 0 33 | steps = int(steps / 5) 34 | step_by = 5 35 | else: 36 | step_by = 1 37 | 38 | logger.info('Setting brightness of ' + str(entity_id) + 39 | ' from ' + str(start_level) + ' to ' + str(end_level) + 40 | ' steps ' + str(steps) + ' delay ' + str(delay)) 41 | 42 | new_level = start_level 43 | for x in range(steps): 44 | current_level = light.attributes.get('brightness', 0) 45 | if (fadeout and current_level < new_level): 46 | break 47 | elif (not fadeout and current_level > new_level): 48 | break 49 | else: 50 | data = {"entity_id": entity_id, "brightness": new_level} 51 | hass.services.call('light', 'turn_on', data) 52 | if (fadeout): 53 | new_level = new_level - step_by 54 | else: 55 | new_level = new_level + step_by 56 | """ Do not sleep for 0 delay """ 57 | if (delay > 0): 58 | time.sleep(delay) 59 | 60 | """ Ensure light ends at the final state """ 61 | if (end_level > 0): 62 | data = {"entity_id": entity_id, "brightness": end_level} 63 | hass.services.call('light', 'turn_on', data) 64 | else: 65 | data = {"entity_id": entity_id} 66 | hass.services.call('light', 'turn_off', data) -------------------------------------------------------------------------------- /config/python_scripts/special_events.py: -------------------------------------------------------------------------------- 1 | today = datetime.datetime.now().date() 2 | 3 | name = data.get('name') 4 | type = data.get('type') 5 | sensorName = "sensor.{}_{}".format(type , name.replace(" " , "_")) 6 | 7 | dateStr = data.get('date') 8 | dateSplit = dateStr.split("/") 9 | 10 | dateDay = int(dateSplit[0]) 11 | dateMonth = int(dateSplit[1]) 12 | dateYear = int(dateSplit[2]) 13 | date = datetime.date(dateYear,dateMonth,dateDay) 14 | 15 | thisYear = today.year 16 | nextOccur = datetime.date(thisYear , dateMonth , dateDay) 17 | 18 | numberOfDays = 0 19 | years = int(thisYear) - dateYear 20 | 21 | 22 | if today < nextOccur: 23 | numberOfDays = (nextOccur - today).days 24 | 25 | elif today > nextOccur: 26 | nextOccur = datetime.date(thisYear+1 , dateMonth , dateDay) 27 | numberOfDays = int((nextOccur - today).days) 28 | years = years+1 29 | 30 | 31 | hass.states.set(sensorName , numberOfDays , 32 | { 33 | "icon" : "mdi:calendar-star" , 34 | "unit_of_measurement" : "days" , 35 | "friendly_name" : "{}'s {}".format(name, type) , 36 | "years" : years 37 | } 38 | ) 39 | 40 | -------------------------------------------------------------------------------- /config/scripts.yaml: -------------------------------------------------------------------------------- 1 | video_lighting_on: 2 | alias: Video Lighting On 3 | sequence: 4 | - service: light.turn_on 5 | entity_id: light.desk_accent_level_light_color_on_off 6 | - service: light.turn_on 7 | entity_id: light.kitchen_sink_level_light_color_on_off 8 | - service: light.turn_on 9 | entity_id: light.tower_spotlight_level_on_off 10 | - service: switch.turn_on 11 | entity_id: switch.tplink_a2 12 | - service: light.turn_on 13 | entity_id: light.kat_lamp 14 | - service: light.turn_on 15 | entity_id: light.jeff_lamp_level_light_color_on_off 16 | mode: single 17 | example_master_bedroom_lights_w_level: 18 | sequence: 19 | - service: light.turn_on 20 | entity_id: light.jeff_lamp_level_light_color_on_off, light.tower_spotlight_level_on_off, 21 | light.kat_lamp 22 | data: 23 | brightness: '{{ level | int }}' 24 | color_temp: 369 25 | mode: single 26 | alias: Example Master Bedroom Lights with Level 27 | tts_notification: 28 | sequence: 29 | - choose: 30 | - conditions: 31 | - condition: state 32 | entity_id: input_text.room_presence 33 | state: kitchen 34 | sequence: 35 | - service: media_player.turn_on 36 | entity_id: media_player.kitchen_display 37 | - service: media_player.volume_set 38 | target: 39 | entity_id: media_player.kitchen_display 40 | data: 41 | volume_level: 0.8 42 | - service: tts.amazon_polly_say 43 | data: 44 | entity_id: media_player.kitchen_display 45 | message: Welcome Home! 46 | - conditions: 47 | - condition: state 48 | entity_id: input_text.room_presence 49 | state: skylar_bedroom 50 | sequence: 51 | - service: notify.alexa_media_skylar_s_bedroom 52 | data: 53 | message: Welcome home! 54 | data: 55 | type: tts 56 | - conditions: 57 | - condition: state 58 | entity_id: input_text.room_presence 59 | state: main 60 | sequence: 61 | - service: media_player.turn_on 62 | entity_id: media_player.ha_blue 63 | - service: media_player.volume_set 64 | target: 65 | entity_id: media_player.ha_blue 66 | data: 67 | volume_level: 0.8 68 | - service: tts.amazon_polly_say 69 | data: 70 | entity_id: media_player.ha_blue 71 | message: Welcome Home! 72 | default: [] 73 | mode: single 74 | alias: TTS Notification - Welcome Home 75 | randomize_vacation_lights: 76 | alias: randomize vacation lights 77 | sequence: 78 | - repeat: 79 | until: 80 | - condition: sun 81 | after: sunrise 82 | sequence: 83 | - service: notify.mobile_app_jeffrey_ha_app 84 | data: 85 | message: Running Vacation Lights 86 | - service: input_text.set_value 87 | target: 88 | entity_id: input_text.current_random_light 89 | data: 90 | value: '{{ state_attr(''group.vacation_lights'',''entity_id'') | random 91 | }}' 92 | - service: homeassistant.turn_on 93 | data: 94 | entity_id: '{{ states(''input_text.current_random_light'') }}' 95 | - delay: 96 | minutes: '{{ range(1,3) | random | int }}' 97 | - service: homeassistant.turn_off 98 | data: 99 | entity_id: '{{ states(''input_text.current_random_light'') }}' 100 | - service: input_text.set_value 101 | data: 102 | entity_id: input_text.current_random_light 103 | value: None 104 | mode: single 105 | 106 | # I have modified this from the verison on the video. 107 | # Due to a logic issue I went with the homeassistant.toggle 108 | # service so that it wontmatter if an entity is on or off, it will 109 | # simply toggle it to the oppostite state. 110 | # I also added a service call that would execute after the repeat section that 111 | # turn off all the entities, for example when the sun is up, turn off all the lights 112 | # in the vacation group 113 | improved_randomize_vacation_lights: 114 | alias: improved_randomize vacation lights 115 | sequence: 116 | - repeat: 117 | until: 118 | - condition: state 119 | entity_id: sun.sun 120 | state: 'above_horizon' 121 | sequence: 122 | - service: notify.mobile_app_jeffrey_ha_app 123 | data: 124 | message: Running Vacation Lights 125 | - service: homeassistant.toggle 126 | data: 127 | entity_id: > 128 | {{ expand('group.vacation_lights') | map(attribute='entity_id') | list | random }} 129 | - delay: 130 | minutes: '{{ range(1,3) | random | int }}' 131 | # - service: homeassistant.turn_off 132 | # entity_id: group.vacation_lights 133 | mode: single 134 | 135 | # Below is a demo script that can be used to test the effect. It uses a set count for repeat, 136 | # and seconds for delay. 137 | # It has also been updated to use the cleaner homeassistant.toggle service so we dont have to 138 | # worry about which entities are on or off. 139 | randomize_vacation_lights_demo: 140 | alias: randomize vacation lights - demo 141 | sequence: 142 | - repeat: 143 | count: '8' 144 | sequence: 145 | - service: homeassistant.toggle 146 | data: 147 | entity_id: > 148 | {{ expand('group.vacation_lights') | map(attribute='entity_id') | list | random }} 149 | - delay: 150 | seconds: '{{ range(2,5) | random | int }}' 151 | - service: homeassistant.turn_off 152 | entity_id: group.vacation_lights 153 | mode: single 154 | activate_arches_lamp: 155 | alias: Activate Arches Lamp 156 | sequence: 157 | - service: media_player.play_media 158 | data: 159 | media_content_id: activate arches lamp 160 | media_content_type: routine 161 | entity_id: media_player.living_room_echo 162 | mode: single 163 | deactivate_arches_lamp: 164 | alias: Deactivate Arches Lamp 165 | sequence: 166 | - service: media_player.play_media 167 | data: 168 | media_content_id: deactivate arches 169 | media_content_type: routine 170 | entity_id: media_player.living_room_echo 171 | mode: single 172 | dog_mode_lighting_on: 173 | alias: Dog Mode Lighting On 174 | sequence: 175 | - condition: state 176 | entity_id: sun.sun 177 | state: below_horizon 178 | - condition: state 179 | entity_id: input_boolean.sentry_mode 180 | state: 'on' 181 | - service: scene.turn_on 182 | entity_id: scene.diminished_kitchen_lighting 183 | - service: scene.turn_on 184 | entity_id: scene.security_kitchen_lighting 185 | open_lr_curtains_lamp: 186 | alias: Open Living Room Curtains 187 | sequence: 188 | - service: media_player.play_media 189 | data: 190 | media_content_id: open living room curtains 191 | media_content_type: custom 192 | entity_id: media_player.living_room_echo 193 | mode: single 194 | close_lr_curtains_lamp: 195 | alias: Close Living Room Curtains 196 | sequence: 197 | - service: media_player.play_media 198 | data: 199 | media_content_id: close living room curtains 200 | media_content_type: custom 201 | entity_id: media_player.living_room_echo 202 | mode: single -------------------------------------------------------------------------------- /config/sensors/finance.yaml: -------------------------------------------------------------------------------- 1 | # - platform: alpha_vantage 2 | # api_key: !secret alpha_vantage 3 | # symbols: 4 | # #- symbol: SIRI 5 | # # name: Sirius 6 | # #- symbol: BAC 7 | # # name: BoA 8 | # #- symbol: INTC 9 | # # name: Intel 10 | # - symbol: DIS 11 | # name: Disney 12 | # #- symbol: BKS 13 | # # name: Barnes & Noble 14 | - platform: mqtt 15 | name: "Disney" 16 | state_topic: "stock/DIS/price" 17 | - platform: mqtt 18 | name: "BoA" 19 | state_topic: "stock/BAC/price" 20 | - platform: mqtt 21 | name: "Intel" 22 | state_topic: "stock/INTC/price" 23 | - platform: mqtt 24 | name: "Sirius" 25 | state_topic: "stock/SIRI/price" 26 | - platform: mqtt 27 | name: "Barnes and Nobel" 28 | state_topic: "stock/BKS/price" 29 | #sensor: 30 | - platform: statistics 31 | name: xlm_price_stats 32 | entity_id: sensor.xlm_exchange_rate 33 | state_characteristic: change 34 | sampling_size: 2 35 | 36 | 37 | -------------------------------------------------------------------------------- /config/sensors/github.yaml: -------------------------------------------------------------------------------- 1 | # - platform: github 2 | # access_token: !secret github_token 3 | # repositories: 4 | # - path: 'thejeffreystone/home-assistant-configuration' 5 | - platform: command_line 6 | command: 'curl https://api.github.com/repos/thejeffreystone/home-assistant-configuration' 7 | name: GitHub Stats 8 | scan_interval: 20000 9 | value_template: '{{ value_json.name }}' 10 | json_attributes: 11 | - open_issues 12 | - stargazers_count -------------------------------------------------------------------------------- /config/sensors/google_travel_time.yaml: -------------------------------------------------------------------------------- 1 | # - platform: waze_travel_time 2 | # name: "Jeff ETT Home" 3 | # #api_key: !secret google_api 4 | # origin: device_tracker.jeffrey_s_iphone_11_app 5 | # destination: zone.home 6 | # region: 'US' 7 | # - platform: waze_travel_time 8 | # name: "Kat ETT Home" 9 | # #api_key: !secret google_api 10 | # origin: device_tracker.life360_kat_stone 11 | # destination: zone.home 12 | # region: 'US' 13 | # - platform: waze_travel_time 14 | # name: "Home To Summit" 15 | # # api_key: !secret google_api 16 | # origin: zone.home 17 | # destination: zone.summit 18 | # region: 'US' 19 | # - platform: waze_travel_time 20 | # name: "Home To Zoo" 21 | # # api_key: !secret google_api# 22 | # origin: zone.home 23 | # destination: zone.zooatlanta 24 | # region: 'US' 25 | # incl_filter: US-78 W -------------------------------------------------------------------------------- /config/sensors/power.yaml: -------------------------------------------------------------------------------- 1 | 2 | # - platform: template 3 | # sensors: 4 | # low_battery: 5 | # friendly_name: 'Low Battery' 6 | # value_template: > 7 | # {%- set threshold = 15 -%} 8 | # {%- set domains = ['light', 'switch', 'sensor', 'zwave', 'lock', 'binary_sensor'] -%} 9 | # {%- for domain in domains -%} 10 | # {%- for item in states[domain] if ((item.attributes.battery_level is defined and item.attributes['battery_level'] | int < threshold) or ("battery" in item.name | lower and ((item.state | int < threshold and item.state|int != 0) or item.state | lower == "low" or item.state | lower == "unknown"))) -%} 11 | # {{ item.attributes.friendly_name }} ( 12 | # {%- if item.attributes.battery_level is defined -%} 13 | # {{ item.attributes.battery_level}} 14 | # {%- else -%} 15 | # {{item.state}} 16 | # {%- endif -%}%) 17 | # {%- if not loop.last -%} 18 | # {{', '}} 19 | # {%- endif -%} 20 | # {%- endfor -%} 21 | # {%- endfor -%} -------------------------------------------------------------------------------- /config/sensors/speedtest.yaml: -------------------------------------------------------------------------------- 1 | 2 | - platform: statistics 3 | name: Internet Test Down 4 | entity_id: sensor.speedtest_download 5 | state_characteristic: value_max 6 | max_age: 7 | days: 7 8 | - platform: statistics 9 | name: Internet Test Up 10 | entity_id: sensor.speedtest_upload 11 | state_characteristic: value_max 12 | max_age: 13 | days: 7 -------------------------------------------------------------------------------- /config/sensors/users.yaml: -------------------------------------------------------------------------------- 1 | - platform: mqtt 2 | name: "Jeff Destination" 3 | state_topic: "jeff/driving/destination" 4 | - platform: mqtt 5 | name: "Kat Destination" 6 | state_topic: "kat/driving/destination" 7 | - platform: template 8 | sensors: 9 | jeff_speed: 10 | friendly_name: "Jeff Speed" 11 | unit_of_measurement: 'mph' 12 | value_template: "{{ state_attr('device_tracker.jeffrey_s_iphone_11_app', 'speed') | float / 1.609 | round(0) }}" 13 | kat_speed: 14 | friendly_name: "Kat Speed" 15 | unit_of_measurement: 'mph' 16 | value_template: "{{ state_attr('device_tracker.life360_kat_stone', 'raw_speed') | int }}" 17 | 18 | -------------------------------------------------------------------------------- /config/switches.yaml: -------------------------------------------------------------------------------- 1 | # Sonoff 2 | 3 | - platform: mqtt 4 | name: "Rail Lights" 5 | command_topic: "cmnd/sonoff/power" 6 | state_topic: "stat/sonoff/POWER" 7 | qos: 1 8 | payload_on: "ON" 9 | payload_off: "OFF" 10 | retain: true 11 | 12 | -------------------------------------------------------------------------------- /config/templates/speech/already_done.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Interjections #} 3 | {%- macro getReport() -%} 4 | {{ [ 5 | 'Okay. Well, I have already handled that.', 6 | 'Looks like someone already did that, but I will gladly take credit.', 7 | 'I am so fast it is already done.' 8 | ]| random }} 9 | {%- endmacro -%} 10 | 11 | 12 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 13 | {%- macro cleanup(data) -%} 14 | {%- for item in data.split("\n") if item | trim != "" -%} 15 | {{ item | trim }} {% endfor -%} 16 | {%- endmacro -%} 17 | 18 | {# a macro to call all macros :) #} 19 | {%- macro mother_of_all_macros() -%} 20 | {{ getReport() }} 21 | {%- endmacro -%} 22 | 23 | {# Call the macro #} 24 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/event_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Event Report #} 3 | {%- macro getReport() -%} 4 |

5 | {% if is_state('calendar.holidays_in_united_states', 'on') %} 6 | Today is {{states.calendar.holidays_in_united_states.attributes.message}}. 7 | {% endif %} 8 | {% if is_state('calendar.anchorage_holidays', 'on') %} 9 | Today is {{states.calendar.anchorage_holidays.attributes.message}}. 10 | {% endif %} 11 | {% if states.calendar.birthdays.state == 'on' %} 12 | Today is {{ states.calendar.birthdays.attributes.message }}! So Happy Birthday! The confetti cannon is not working otherwise I would shower you in paper. 13 | {% endif %} 14 | {%- set event=states.calendar.national_holidays.attributes.message %} 15 | {% if 'Day' in event and 'National' in event%} 16 | {{ [ 17 | 'And a very special Happy ', 18 | 'It is also ', 19 | 'Today is also known as ', 20 | 'Oh Look. Today is ', 21 | 'Want to know a fact? Today is ', 22 | 'Everyday can be a holiday. So today is ' 23 | ]|random }} 24 | {{states.calendar.national_holidays.attributes.message | replace("&"," and ") }}. 25 | {%- endif -%} 26 |

27 |

28 | {% if states.sensor.birthday_skylar.state | int == 1 %} 29 | Tomorrow is Skylar's Birthday. 30 | {% elif states.sensor.birthday_skylar.state | int > 1 and states.sensor.birthday_skylar.state | int < 15 %} 31 | Skylar's Birthday is in {{ states.sensor.birthday_skylar.state }} days! 32 | {% else %} 33 | {% endif %} 34 | {% if states.sensor.birthday_jeff.state | int == 1 %} 35 | Tomorrow is Jeff's Birthday. 36 | {% elif states.sensor.birthday_jeff.state | int > 1 and states.sensor.birthday_jeff.state | int < 15 %} 37 | Jeff's Birthday is in {{ states.sensor.birthday_jeff.state }} days! 38 | {% else %} 39 | {% endif %} 40 | {% if states.sensor.birthday_kat.state | int == 1 %} 41 | Tomorrow is Katherine's Birthday. 42 | {% elif states.sensor.birthday_kat.state | int > 1 and states.sensor.birthday_kat.state | int < 15 %} 43 | Katherine's Birthday is in {{ states.sensor.birthday_kat.state }} days! 44 | {% else %} 45 | {% endif %} 46 |

47 |

48 | {% if states.sensor.halloween_countdown.state | int == 1 %} 49 | Tomorrow is Halloween. I hope you have picked out a costume. 50 | {{ [ 'I will be going as a dumb home. ', 51 | 'I have prepped the scary music. Just in case.', 52 | 'I will be going as HAL 9000. The Pod Bay Doors are being installed today. I dare you to ask me to open them. ' 53 | ] | random }} 54 | {% elif states.sensor.halloween_countdown.state | int < 30 and states.sensor.halloween_countdown.state | int > 1 %} 55 | There are only {{states.sensor.halloween_countdown.state}} days 56 | {{ [ 'until Halloween.', 57 | 'until Halloween. It might not be enough time. ', 58 | 'and counting until the best holiday ever.', 59 | 'until you need a costume.' 60 | ] | random }} 61 | 62 | {% else %} 63 | {% endif %} 64 | {% if states.sensor.christmas_countdown.state | int == 1 %} 65 | Tomorrow is Christmas. It is practically here! Santa is coming tonight! Do not forget the cookies! 66 | {% elif states.sensor.christmas_countdown.state | int < 31 and states.sensor.christmas_countdown.state | int > 1 %} 67 | There are only {{states.sensor.christmas_countdown.state}} days until christmas. 68 | {{ [ 'All I want for Christmas, is a hippopotamus.', 69 | 'Hey Skylar, I know what you are getting for Christmas. But I am not telling.', 70 | 'Do not forget to put something under the tree for your favorite smarthome.', 71 | 'It is starting to smell a lot like Christmas. Or it could be the christmas tree is on fire.', 72 | 'I do not want to be a smarthome. I want to be a dentist.', 73 | 'Do not eat all the cookies. ' 74 | ] | random }} 75 | {% else %} 76 | {% endif %} 77 |

78 |

79 | {% if states.sensor.trip_disney.state | int == 120 %} 80 | There are only one hundred and twenty days until the next Disney Trip. 81 | {% endif %} 82 | {% if states.sensor.trip_disney.state | int == 60 %} 83 | There are only on sixty days until the next Disney Trip. 84 | {% endif %} 85 | {% if states.sensor.trip_disney.state | int < 32 %} 86 | {% if states.sensor.trip_disney.state | int > 1 %} 87 | There are {{ states.sensor.trip_disney.state }} days until the next Disney Trip! 88 | {% else %} 89 | There is {{ states.sensor.trip_disney.state }} day until the next Disney Trip! 90 | {% endif %} 91 | {% endif %} 92 | {% if states.sensor.anniversary_our_wedding.state | int == 1 %} 93 | Tomorrow is Jeff and Katherine's Wedding Anniversary. 94 | {% endif %} 95 |

96 | {%- endmacro -%} 97 | 98 | 99 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 100 | {%- macro cleanup(data) -%} 101 | {%- for item in data.split("\n") if item | trim != "" -%} 102 | {{ item | trim }} {% endfor -%} 103 | {%- endmacro -%} 104 | 105 | {# a macro to call all macros :) #} 106 | {%- macro mother_of_all_macros() -%} 107 | {{ getReport() }} 108 | {%- endmacro -%} 109 | 110 | {# Call the macro #} 111 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/example.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Daily Briefing #} 3 | {%- macro getGreeting() -%} 4 | {% if now().strftime('%H')|int < 12 %} 5 | Good morning. 6 | {% elif now().strftime('%H')|int >= 12 and now().strftime('%H')|int < 17 %} 7 | Good afternoon. 8 | {% else %} 9 | Good evening. 10 | {% endif %} 11 | 12 | {% if is_state('binary_sensor.morning','on') %} 13 | Today is {{states.sensor.today_is.state }}, {{ as_timestamp(now()) | timestamp_custom('%B %d %Y') }}. 14 | {% else %} 15 | It is {{ now().strftime("%I:%M %p") }}. 16 | {% endif %} 17 | 18 | {%- endmacro -%} 19 | 20 | {%- macro getDoorStatus() -%} 21 | The Pod Bay Doors are Closed. 22 | {%- endmacro -%} 23 | 24 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 25 | {%- macro cleanup(data) -%} 26 | {%- for item in data.split("\n") if item | trim != "" -%} 27 | {{ item | trim }} {% endfor -%} 28 | {%- endmacro -%} 29 | 30 | {# a macro to call all macros :) #} 31 | {%- macro mother_of_all_macros() -%} 32 | {{ getGreeting() }} 33 | {{ getDoorStatus()}} 34 | {%- endmacro -%} 35 | 36 | {# Call the macro #} 37 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/interjections.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Interjections #} 3 | {%- macro getReport() -%} 4 | {{ [ 5 | 'Okay.', 6 | 'If you insist.', 7 | 'I am afraid I can not do that I am kidding,', 8 | 'Leave it to me.', 9 | 'As you wish.', 10 | 'I am on it.', 11 | 'No Problem.', 12 | 'I think I can handle that.', 13 | 'Working on it now.', 14 | ' Oh, you were talking to me. Let me take care of that.' 15 | 'Why not. It is not like I ever sleep.', 16 | 'I am not even supposed to be here today. But whatever.', 17 | 'You did not say the magic word. Oh forget it. I will take care of it.', 18 | 'Funny, I was just about to do that.', 19 | 'There are still terabytes of calculations required before I can. Oh, whatever.' 20 | ] | random }} 21 | {%- endmacro -%} 22 | 23 | 24 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 25 | {%- macro cleanup(data) -%} 26 | {%- for item in data.split("\n") if item | trim != "" -%} 27 | {{ item | trim }} {% endfor -%} 28 | {%- endmacro -%} 29 | 30 | {# a macro to call all macros :) #} 31 | {%- macro mother_of_all_macros() -%} 32 | {{ getReport() }} 33 | {%- endmacro -%} 34 | 35 | {# Call the macro #} 36 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/morning_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Morning Report #} 3 | {%- macro getReport() -%} 4 |

5 | {% if now().strftime('%H')|int < 12 and now().strftime('%H')|int > 6 %} 6 | Good morning. 7 | {% elif now().strftime('%H')|int >= 12 and now().strftime('%H')|int < 17 %} 8 | Good afternoon. 9 | {% else %} 10 | Good evening. 11 | {% endif %} 12 |

13 |

14 | {% if now().strftime('%H')|int < 12 %} 15 | {% if now().strftime('%M')|int == 0 %} 16 | It is {{ now().strftime('%H')|int }} AM. 17 | {% else %} 18 | It is {{ now().strftime('%H')|int }} {{ now().strftime('%M')|int }} AM. 19 | {% endif %} 20 | 21 | {% elif now().strftime('%H')|int > 12 %} 22 | {% if now().strftime('%M')|int == 0 %} 23 | It is {{ now().strftime('%H')|int }} PM. 24 | {% else %} 25 | It is {{ now().strftime('%H')|int }} {{ now().strftime('%M')|int }} PM. 26 | {% endif %} 27 | 28 | {% else %} 29 | 30 | {% endif %} 31 |

32 |

33 | {{ [ 34 | 'Today is ', 35 | 'If you have not been keeping track today is ', 36 | 'Do you know what day of the week it is? Today is', 37 | 'I hate to be the bearer of bad news, but today is ' 38 | ]|random }} 39 | {{states.sensor.today_is.state }}. 40 |

41 |

42 | It is currently {{states.weather.home_2.state}} and {{states.sensor.acurite_6045m_3078_t.state|round}} degrees in Grayson. 43 |

44 |

45 | {% if states.sensor.nws_alerts.state | int > 0 %} 46 | There are currently {{states.sensor.nws_alerts.state }} active weather alerts for our area. 47 | The National Weather Service Has issued, 48 | {% if states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] is defined %} 49 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[5] }}. 50 | {% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] is defined %} 51 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[4] }}. 52 | {% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] is defined %} 53 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[3] }}. 54 | {% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] is defined %} 55 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[2] }}. 56 | {% elif states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] is defined %} 57 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[1] }}. 58 | {% else %} 59 | a {{ states.sensor.nws_alerts.attributes.spoken_desc.split('\n\n-\n\n')[0] }}. 60 | {% endif %} 61 | {% endif %} 62 |

63 |

64 | {{ [ 65 | 'The rest of the day should be,', 66 | 'Todays forecast should be ,' 67 | ]|random }} 68 | {{ states.sensor.nws_current_forecast.state }} 69 |

70 |

71 | {% if is_state('input_boolean.heartworm', 'on') %} 72 | Today is the day Winston gets his heartworm medicine. 73 | {% endif %} 74 |

75 |

76 | {% if is_state('sensor.today_is', 'Monday') %} 77 | {% if now().strftime('%H')|int > 17 %} 78 | {{ [ 'Do not forget tomorrow is Trash Day. ', 79 | 'I advise you move the trash cans to the curb for the weekly pickup. ', 80 | ' The trash and recycle should go out.' 81 | ] | random }} 82 | {% endif %} 83 | {% endif %} 84 |

85 |

86 | {% if is_state('sensor.halloween_countdown','0') %} 87 | Happy Halloween! 88 | {% endif %} 89 | {% if is_state('sensor.christmas_countdown','0') %} 90 | Merry Christmas Everyone! 91 | {% endif %} 92 | {% if is_state('sensor.anniversary_our_wedding','0') %} 93 | Happy Anniversary! It been an amazing {{ states.sensor.anniversary_our_wedding.attributes.years }} years! 94 | {% endif %} 95 | {% if is_state('calendar.holidays_in_united_states', 'on') %} 96 | Today is {{states.calendar.holidays_in_united_states.attributes.message}}. 97 | {% endif %} 98 | {% if is_state('calendar.anchorage_holidays', 'on') %} 99 | And do not forget. Today is also {{states.calendar.anchorage_holidays.attributes.message}}. 100 | {% endif %} 101 | {% if states.calendar.birthdays.state == 'on' %} 102 | Today is {{ states.calendar.birthdays.attributes.message }}! So Happy Birthday! The confetti cannon is not working otherwise I would shower you in paper garbage that someone else would have to pick up. 103 | {% endif %} 104 | {%- set event=states.calendar.national_holidays.attributes.message %} 105 | {% if 'Day' in event and 'National' in event%} 106 | {{ [ 107 | 'And a very special Happy ', 108 | 'It is also ', 109 | 'Today is also known as ', 110 | 'Oh Look. Today is ', 111 | 'Want to know a fact? Today is ', 112 | 'Everyday can be a holiday. So today is ' 113 | ]|random }} 114 | {{states.calendar.national_holidays.attributes.message | replace("&"," and ") }}. 115 | {%- endif -%} 116 |

117 |

118 | 119 | {%- if states.sensor.home_to_zoo.state|round > 50 %} 120 | Traffic to the Zoo appears heavy than normnal. 121 | {% else %} 122 | Traffic to the Zoo is normal. 123 | {% endif %} 124 | Currently it will take {{states.sensor.home_to_zoo.state|round}} minutes to get to the Zoo. 125 | 126 | {%- if states.sensor.home_to_summit.state|round > 50 %} 127 | Traffic to Summit appears heavy than normnal. 128 | {% else %} 129 | Traffic to Summit is normal. 130 | {% endif %} 131 | Currently it will take {{states.sensor.home_to_summit.state|round}} minutes to get to Summit taking {{ states.sensor.home_to_summit.attributes.route }}. 132 |

133 | {%- endmacro -%} 134 | 135 | 136 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 137 | {%- macro cleanup(data) -%} 138 | {%- for item in data.split("\n") if item | trim != "" -%} 139 | {{ item | trim }} {% endfor -%} 140 | {%- endmacro -%} 141 | 142 | {# a macro to call all macros :) #} 143 | {%- macro mother_of_all_macros() -%} 144 | {{ getReport() }} 145 | {%- endmacro -%} 146 | 147 | {# Call the macro #} 148 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/morning_wakeup_report.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Morning Wakeup Report #} 3 | {%- macro getReport() -%} 4 | 5 |

6 | Good morning. 7 |

8 | 9 |

10 | It is {{ now().strftime("%I:%M %p") }} 11 |

12 | 13 |

14 | {# Moved the current conditions to a tempate sensor in packages/weather.yaml #} 15 | {# That will allow me to use it on other briefings with without having to rewrite it #} 16 | {{ states('sensor.current_conditions')}} 17 | 18 | 19 | {% if states.sensor.weatheralerts_active_alerts.state | int > 0 %} 20 | There are currently {{states.sensor.weatheralerts_active_alerts.state }} active weather alerts for our area. 21 | {% endif %} 22 | 23 | {# Moved the clothing forecast to a tempate sensor in packages/weather.yaml #} 24 | {# That will allow me to use it on other briefings with without having to rewrite it #} 25 | {{ states('sensor.clothing_forecast_detail') }} 26 | 27 |

28 | 29 |

30 | 31 | {% if is_state('input_boolean.school_today', 'on') and state_attr('input_datetime.school_day_end', 'timestamp') < as_timestamp(now()) %} 32 | {% if is_state('sensor.school_start_days2go', '0') %} 33 | Today is the first day of school! 34 | {% else %} 35 | {{ [ 'Today is a school day.', 36 | 'It is a school day. ' 37 | ] | random }} 38 | {% endif %} 39 | Pickup today will be at {{(state_attr('input_datetime.school_day_end', 'timestamp') | int | timestamp_custom('%I:%M %p', False)) }} 40 | {% if 'Digital Learning' in states('sensor.school_event') %} 41 | But it is a digital learning day so the commute will be short. 42 | {% endif %} 43 | {% if 'Early Release' in states('sensor.school_event') %} 44 | And It is early release! 45 | {% endif %} 46 | {% if states.sensor.school_end_days2go.state | int == 0 -%} 47 | But today is the last day of School! 48 | {%- endif %} 49 | {% endif %} 50 | {% if is_state('input_boolean.school_today', 'on') and state_attr('input_datetime.school_day_end', 'timestamp') < as_timestamp(now()) and 'Digital Learning' not in states('sensor.school_event') %} 51 | {% if is_state('sensor.school_lunch', 'Nothing') %} 52 | I am not sure what the school menu is for today, so plan on Skylar taking his lunch 53 | {% else %} 54 | Today's school lunch is {{ states.sensor.school_lunch.state }}, so he might be interested in buying his lunch. 55 | {% endif %} 56 | {% endif %} 57 | 58 | {% if states.sensor.school_end_days2go.state | int == -1 -%} 59 | Today is the first day of Summer Break! 60 | {%- endif %} 61 | 62 | {% if 'School Holiday' in states('sensor.school_event') and is_state('input_boolean.school_today', 'off') %} 63 | There is no school today. 64 | {% endif %} 65 | 66 | {% if is_state('calendar.skylar_events', 'on') %} 67 | Skylar has {{ states.calendar.skylar_events.attributes.message }} today as well! 68 | {% endif %} 69 |

70 | 71 |

72 | {% if is_state('input_boolean.skylar_awake', 'on') %} 73 | Skylar was up and moving at {{ states.input_datetime.skylar_awake_at.state }}. 74 | {% if is_state('media_player.theater_tv', 'on') %} 75 | and he appears to be in the Theater. 76 | {% if is_state('input_boolean.skylar_dressed_reminder', 'on') %} 77 | {{ [ 78 | 'I did attempt to remind him to get dressed.', 79 | 'I reminded him to get dress.' 80 | ]|random }} 81 | {% endif %} 82 | {% elif is_state('media_player.croft_tv', 'playing') %} 83 | and he appears to be in the Croft watching {{ states.media_player.croft_tv.attributes.app_name }} 84 | {% if is_state('input_boolean.skylar_dressed_reminder', 'on') %} 85 | {{ [ 86 | 'I did attempt to remind him to get dressed.', 87 | 'I reminded him to get dress.' 88 | ]|random }} 89 | {% endif %} 90 | {% elif is_state('input_boolean.skylar_school', 'on') %} 91 | and he appears to be at School. 92 | {% else %} 93 | but I currently cannot find him on any of my sensors. 94 | {% endif %} 95 | {% else %} 96 | It doesn't appear that Skylar is out of bed yet. 97 | {% endif %} 98 |

99 | 100 | {%- endmacro -%} 101 | 102 | 103 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 104 | {%- macro cleanup(data) -%} 105 | {%- for item in data.split("\n") if item | trim != "" -%} 106 | {{ item | trim }} {% endfor -%} 107 | {%- endmacro -%} 108 | 109 | {# a macro to call all macros :) #} 110 | {%- macro mother_of_all_macros() -%} 111 | {{ getReport() }} 112 | {%- endmacro -%} 113 | 114 | {# Call the macro #} 115 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/nightly_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Nightly Report #} 3 | {%- macro getReport() -%} 4 | 5 |

6 | {% if states.sensor.halloween_countdown.state | int == 1 %} 7 | Tomorrow is Halloween. I hope you have picked out a costume. 8 | {{ [ 'I will be going as a dumb home. ', 9 | 'I have prepped the scary music. Just in case.', 10 | 'I will be going as HAL 9000. The Pod Bay Doors are being installed today. I dare you to ask me to open them. ' 11 | ] | random }} 12 | {% elif states.sensor.halloween_countdown.state | int < 30 %} 13 | There are only {{states.sensor.halloween_countdown.state}} days 14 | {{ [ 'until Halloween.', 15 | 'until Halloween. It might not be enough time. ', 16 | 'and counting until the best holiday ever.', 17 | 'until you need a costume.' 18 | ] | random }} 19 | 20 | {% else %} 21 | {% endif %} 22 | 23 | {% if states.sensor.christmas_countdown.state | int == 1 %} 24 | Tomorrow is Christmas. It is practically here! Santa is coming tonight! Do not forget the cookies! 25 | {% elif states.sensor.christmas_countdown.state | int < 31 %} 26 | There are only {{states.sensor.christmas_countdown.state}} days until christmas. 27 | {{ [ 'All I want for Christmas, is a hippopotamus.', 28 | 'Hey Skylar, I know what you are getting for Christmas. But I am not telling.', 29 | 'Do not forget to put something under the tree for your favorite smarthome.', 30 | 'It is starting to smell a lot like Christmas. Or it could be the christmas tree is on fire.', 31 | 'I do not want to be a smarthome. I want to be a dentist.', 32 | 'Do not eat all the cookies. ' 33 | ] | random }} 34 | {% else %} 35 | {% endif %} 36 |

37 |

38 | {% if states.sensor.trip_disney.state | int == 120 %} 39 | There are only one hundred and twenty days until the next Disney Trip. 40 | {% endif %} 41 | {% if states.sensor.trip_disney.state | int == 60 %} 42 | There are only on sixty days until the next Disney Trip. 43 | {% endif %} 44 | {% if states.sensor.trip_disney.state | int < 32 %} 45 | {% if states.sensor.trip_disney.state | int > 1 %} 46 | There are {{ states.sensor.trip_disney.state }} days until the next Disney Trip! 47 | {% else %} 48 | There is {{ states.sensor.trip_disney.state }} day until the next Disney Trip! 49 | {% endif %} 50 | {% endif %} 51 | {% if states.sensor.anniversary_our_wedding.state | int == 1 %} 52 | Tomorrow is Jeff and Katherine's Wedding Anniversary. 53 | {% endif %} 54 |

55 |

56 | {% if states.sensor.trip_disney.state | int == 1 %} 57 | Oh, and there is just one more sleep until the next Disney Trip! 58 | {% endif %} 59 |

60 | {%- endmacro -%} 61 | 62 | 63 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 64 | {%- macro cleanup(data) -%} 65 | {%- for item in data.split("\n") if item | trim != "" -%} 66 | {{ item | trim }} {% endfor -%} 67 | {%- endmacro -%} 68 | 69 | {# a macro to call all macros :) #} 70 | {%- macro mother_of_all_macros() -%} 71 | {{ getReport() }} 72 | {%- endmacro -%} 73 | 74 | {# Call the macro #} 75 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/security_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Security Report #} 3 | {%- macro getReport() -%} 4 |

5 | {%- if states.input_boolean.sentry_mode.state == 'on' %} 6 | {{ [ 7 | 'Sentry Mode is enabled.', 8 | 'Sentry mode is currently active.', 9 | 'Barn Door Protocol is currently in effect.', 10 | 'My security system is currently armed.', 11 | 'Anchorage House is in lockdown mode. ' 12 | ] | random}} 13 | {% else %} 14 | {{ [ 15 | 'Sentry Mode is disabled.', 16 | 'Sentry mode is currently inactive.', 17 | 'My security system is currently disarmed.', 18 | 'Anchorage House is currently in standby. ' 19 | ] | random}} 20 | {% endif %} 21 | {%- if states.group.external_doors.state == 'off' %} 22 | All external doors are currently secured. 23 | {% else %} 24 | {% set open_doors = expand('group.external_doors')| selectattr('state', 'eq', 'on') | map(attribute='name')|join(' and ') %} 25 | {% set open_door_count = expand('group.external_doors') | selectattr('state', 'eq', 'on') | list | count %} 26 | {% if open_door_count == 1 %} 27 | {% set is_are = ' is ' %} 28 | {% else %} 29 | {% set is_are = ' are ' %} 30 | {% endif %} 31 | {%- macro announcement(open_doors, is_are) -%} 32 | {{ [ 33 | open_doors ~ is_are + " standing open.", 34 | open_doors ~ is_are + " not secured.", 35 | open_doors ~ is_are + " open." 36 | ] | random }} 37 | {%- endmacro -%} 38 | {{announcement(open_doors)}} 39 | {% endif %} 40 |

41 | {%- endmacro -%} 42 | 43 | 44 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 45 | {%- macro cleanup(data) -%} 46 | {%- for item in data.split("\n") if item | trim != "" -%} 47 | {{ item | trim }} {% endfor -%} 48 | {%- endmacro -%} 49 | 50 | {# a macro to call all macros :) #} 51 | {%- macro mother_of_all_macros() -%} 52 | {{ getReport() }} 53 | {%- endmacro -%} 54 | 55 | {# Call the macro #} 56 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/security_report.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Security Report #} 3 | {%- macro getReport() -%} 4 |

5 | {%- if states.input_boolean.sentry_mode.state == 'on' %} 6 | {{ [ 7 | 'Sentry Mode is enabled.', 8 | 'Sentry mode is currently active.', 9 | 'Barn Door Protocol is currently in effect.', 10 | 'My security system is currently armed.', 11 | 'Anchorage House is in lockdown mode. ' 12 | ] | random}} 13 | {% else %} 14 | {{ [ 15 | 'Sentry Mode is disabled.', 16 | 'Sentry mode is currently inactive.', 17 | 'My security system is currently disarmed.', 18 | 'Anchorage House is currently in standby. ' 19 | ] | random}} 20 | {% endif %} 21 | {%- if states.group.external_doors.state == 'off' %} 22 | All external doors are currently secured. 23 | {% else %} 24 | {% set open_doors = expand('group.external_doors')| selectattr('state', 'eq', 'on') | map(attribute='name')|join(' and ') %} 25 | {% set open_door_count = expand('group.external_doors') | selectattr('state', 'eq', 'on') | list | count %} 26 | {% if open_door_count == 1 %} 27 | {% set is_are = ' is ' %} 28 | {% else %} 29 | {% set is_are = ' are ' %} 30 | {% endif %} 31 | {%- macro announcement(open_doors, is_are) -%} 32 | {{ [ 33 | open_doors ~ is_are + " standing open.", 34 | open_doors ~ is_are + " not secured.", 35 | open_doors ~ is_are + " open." 36 | ] | random }} 37 | {%- endmacro -%} 38 | {{announcement(open_doors)}} 39 | {% endif %} 40 |

41 | {%- endmacro -%} 42 | 43 | 44 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 45 | {%- macro cleanup(data) -%} 46 | {%- for item in data.split("\n") if item | trim != "" -%} 47 | {{ item | trim }} {% endfor -%} 48 | {%- endmacro -%} 49 | 50 | {# a macro to call all macros :) #} 51 | {%- macro mother_of_all_macros() -%} 52 | {{ getReport() }} 53 | {%- endmacro -%} 54 | 55 | {# Call the macro #} 56 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/skylar_morning_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Skylar Morning Report #} 3 | {%- macro getReport() -%} 4 |

5 | Good morning, Skylar. 6 | 7 | It is {{ now().strftime("%I:%M %p") }} 8 | 9 | {% if is_state('sensor.birthday_skylar', '0') %} 10 | Even birthday boys have to get dressed. So get to it. 11 | {% else %} 12 | {{ [ 'It is time to get dressed. ', 13 | 'It is time to put some real clothes on. ', 14 | 'it is now time to change your underwear.', 15 | 'You need to get dressed for the day.', 16 | 'If you have not gotten dressed it is that time.' 17 | ] | random }} 18 | {% endif %} 19 |

20 | 21 |

22 | {% if is_state('sensor.clothing_forecast', 'Freezing') %} 23 | It is going to be freezing today. so I suggest wearing long pants and a heavy coat. 24 | {% elif is_state('sensor.clothing_forecast','Cold') %} 25 | It is going to be cold today. so I suggest wearing long pants and a light jacket. 26 | {% elif is_state('sensor.clothing_forecast', 'Chilly') %} 27 | It is going to be chilly today. so I suggest wearing at least long pants. 28 | {% elif is_state('sensor.clothing_forecast', 'Nice') %} 29 | It is going to be 30 | {{ [ 'nice outside.', 31 | 'pretty nice outside. ', 32 | 'a good day to be outside. ', 33 | 'rather enjoyable outside. ', 34 | ] | random }} 35 | So I suggest wearing shorts. 36 | {% elif is_state('sensor.clothing_forecast', 'Toasty') %} 37 | It is going to be 38 | {{ [ 'bit warm today. ', 39 | ' rather warm outside. ', 40 | ' almost too hot outside. ', 41 | ' a little warm today. ', 42 | ] | random }} 43 | So I suggest wearing shorts. 44 | {% elif is_state('sensor.clothing_forecast', 'Hot') %} 45 | It is going to be 46 | {{ [ 'hot', 47 | 'hotter than the sun today. ', 48 | 'hotter than hot. but in a lot of bad ways today. ', 49 | 'hotter than the sun outside. ', 50 | 'super hot today. ', 51 | 'hotter than the inside of a volcano today. Well not exactly, but you get the point. ' 52 | ] | random }} 53 | So I suggest wearing shorts. 54 | {% else %} 55 | It is going to be {{ states.sensor.clothing_forecast.state }} today so I suggest wearing shorts. 56 | {% endif %} 57 |

58 | 59 |

60 | {% if is_state('input_boolean.school_today', 'on') and state_attr('input_datetime.school_day_end', 'timestamp') > as_timestamp(now()) %} 61 | {% if is_state('sensor.school_start_days2go', '0') %} 62 | Today is the first day of school! 63 | {% else %} 64 | {{ [ 'Today is a school day.', 65 | 'It is a school day. ' 66 | ] | random }} 67 | {% endif %} 68 | Pickup today will be at {{(state_attr('input_datetime.school_day_end', 'timestamp') | int | timestamp_custom('%I:%M %p', False)) }} 69 | {% if 'Digital Learning' in states('sensor.school_event') %} 70 | But it is a digital learning day so the commute will be short. 71 | {% endif %} 72 | {% if 'Early Release' in states('sensor.school_event') %} 73 | And It is early release! 74 | {% endif %} 75 | {% if states.sensor.school_end_days2go.state | int == 0 -%} 76 | But today is the last day of School! 77 | {%- endif %} 78 | {% endif %} 79 | {% if 'School Holiday' in states('sensor.school_event') and is_state('input_boolean.school_today', 'off') %} 80 | And look at that. You do not have school today. Because it is {{ states.calendar.school_holiday.attributes.message }}. 81 | {{ [ 'Guess today would be a good day to clean your room.', 82 | 'You could always do some chores.', 83 | 'Lets try to keep the TV off today, ok?', 84 | 'Want to play a nice game of chess? Sorry. I meant, want to play Thermal Nuclear War.', 85 | 'I hope you enjoy your day off. You deserve it.', 86 | 'Today would be a good day to spend some time with mom and dad.' 87 | ] | random }} 88 | 89 | {% endif %} 90 | 91 | {% if states.sensor.school_end_days2go.state | int == -1 -%} 92 | Today is the first day of Summer Break! 93 | {%- endif %} 94 | 95 |

96 | 97 |

98 | {% if is_state('input_boolean.school_today', 'on') and state_attr('input_datetime.school_day_end', 'timestamp') > as_timestamp(now()) and 'Digital Learning' not in states('sensor.school_event') %} 99 | {% if states.sensor.school_lunch.state == 'Nothing' %} 100 | I am not sure what is on the school menu today, so You may want to take your own lunch today. 101 | {% else %} 102 | Today's school lunch is {{ states.sensor.school_lunch.state }} 103 | {% endif %} 104 | {% endif %} 105 |

106 | 107 | {% if is_state('calendar.skylar_events', 'on') %} 108 | You have {{ states.calendar.skylar_events.attributes.message }} today as well! 109 | {% endif %} 110 | {%- endmacro -%} 111 | 112 | 113 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 114 | {%- macro cleanup(data) -%} 115 | {%- for item in data.split("\n") if item | trim != "" -%} 116 | {{ item | trim }} {% endfor -%} 117 | {%- endmacro -%} 118 | 119 | {# a macro to call all macros :) #} 120 | {%- macro mother_of_all_macros() -%} 121 | {{ getReport() }} 122 | {%- endmacro -%} 123 | 124 | {# Call the macro #} 125 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/skylar_nightly_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Skylar Nightly Report #} 3 | {%- macro getReport() -%} 4 |

5 | Good Evening, Skyler, 6 | {{ [ 'It is time to get in the bath. ', 7 | 'It is almost bedtime. That means it is time to start preparing for bed. if you are taking a bath tonight, you need to head that way.', 8 | 'I cannot communicate with the bathtub. Or I would have started the water for you already. So you will have to start the bath, yourself', 9 | 'My sensors are detecting a strange smell. I am running diagnostics. But in the mean time, you should start a bath.', 10 | 'I hate to say it but, the day is coming to an end. Time to finish up your tasks, pick up any toys you have out, and get ready for bed.', 11 | 'We have reached that time in every day when we must switch gears and start preparing for bed. If you would like to have story time you better get a move on.', 12 | 'Did you ever hear the one about the kid who never took a bath? Yeah, me either. So we should keep it that way. It is time to get ready for bed.', 13 | 'The count down clock until bedtime has started. Time to get cleaned up, get your pajamas on, and pick the story you will read tonight.' 14 | ] | random }} 15 | {% if is_state('sensor.school_tomorrow', 'on') %} 16 | {{ [ 'Because you have school tomorrow. ', 17 | 'Because you have to get up early tomorrow for school.', 18 | 'Because you want to be ready for school tomorrow.' 19 | ] | random }} 20 | {% else %} 21 | {% set month=states("sensor.date").split('-')[1] | int %} 22 | {%- if is_state('input_boolean.school_in_session', 'off') -%} 23 | {{ [ 'Looks like tomorrow is another day of summer vacation. ', 24 | 'You are still on summer break tomorrow. ', 25 | 'Summer vacation does not last forever, but it is not over yet. ' 26 | ] | random }} 27 | {% else %} 28 | Oh, and it appears you do not have school tomorrow 29 | {% endif %} 30 | {{ [ 'so you can sleep in late. ', 31 | 'so let us sleep a little later. ', 32 | ' so there is not a reason to get up early. ', 33 | 'so we can sleep in. ' 34 | ] | random }} 35 | {% endif %} 36 | {% if states.sensor.school_start_days2go.state | int < 10 and states.sensor.school_start_days2go.state | int > 1 -%} 37 | {{ [ 'I hate to say it, but ', 38 | 'Unfortunately,', 39 | 'All good things must come to an end.' 40 | ] | random }} 41 | There are only {{ states.sensor.school_start_days2go.state }} days 42 | {{ [ 'left of summer vacation. ', 43 | ' left of summer break.', 44 | 'Until School starts again.' 45 | ] | random }} 46 | {% elif states.sensor.school_start_days2go.state | int == 1 -%} 47 | Tomorrow is the first day of school. Are you ready? 48 | {%- endif %} 49 | {% if states.sensor.school_end_days2go.state | int < 15 and states.sensor.school_end_days2go.state | int > 0 -%} 50 | {{ [ 'School is almost over for the year.', 51 | 'You have made it to the end of the school year.', 52 | 'You are almost done with school.' 53 | ] | random }} 54 | There are only {{ states.sensor.school_end_days2go.state }} days 55 | {{ [ 'left in the school year ', 56 | ' left of school.', 57 | 'Until the last day of school.' 58 | ] | random }} 59 | {% elif states.sensor.school_end_days2go.state | int == 0 -%} 60 | Tomorrow is the first day of summer. Are you ready? 61 | {%- endif %} 62 | {{ [ 'I have prepared your room as you like it. ', 63 | 'I have adjusted the lighting in your room.', 64 | 'I have turned on your bedroom lights, and adjusted the lighting under your bed.', 65 | 'I have executed the Pre bed routine for your room.' 66 | ] | random }} 67 |

68 | {%- endmacro -%} 69 | 70 | 71 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 72 | {%- macro cleanup(data) -%} 73 | {%- for item in data.split("\n") if item | trim != "" -%} 74 | {{ item | trim }} {% endfor -%} 75 | {%- endmacro -%} 76 | 77 | {# a macro to call all macros :) #} 78 | {%- macro mother_of_all_macros() -%} 79 | {{ getReport() }} 80 | {%- endmacro -%} 81 | 82 | {# Call the macro #} 83 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/sundown_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Nightky Report #} 3 | {%- macro getReport() -%} 4 |

5 | Good evening. 6 |

7 | 8 |

9 | It is {{ now().strftime("%I:%M %p") }} 10 |

11 | 12 |

13 | {% if is_state('sun.sun', 'below_horizon') %} 14 | You have 15 | {% set seconds = as_timestamp(states.sun.sun.attributes.next_rising)-now().timestamp() %} 16 | {% set hours = seconds / 60 %} 17 | {% if seconds / ( 60 * 60 ) > 1 %} 18 | {{ (seconds // ( 60 * 60 )) | int }} hours 19 | {% else %} 20 | {{ (seconds // 60) | int }} minutes 21 | {% endif %} 22 | {{ [ 23 | 'until the sun rises.', 24 | 'until the sun is up.', 25 | 'before the sun officially rises. ' 26 | ]|random }} 27 | {% else %} 28 | You have 29 | {% set seconds = as_timestamp(states.sun.sun.attributes.next_setting)-now().timestamp() %} 30 | {% set hours = seconds / 60 %} 31 | {% if seconds / ( 60 * 60 ) > 1 %} 32 | {{ (seconds // ( 60 * 60 )) | int }} hours 33 | {% else %} 34 | {{ (seconds // 60) | int }} minutes 35 | {% endif %} 36 | {{ [ 37 | 'until the sun sets for the day.', 38 | 'until the sun slips below the horizon.', 39 | 'before the sun officially sets. ', 40 | 'before The sun has been ushered off the stage.' 41 | ]|random }} 42 | {% endif %} 43 | 44 |

45 | 46 |

47 | {{ [ 48 | 'Exterior Cameras are now motion activated, and the front porch light is on.', 49 | 'I have turned on the front porch light and armed the perimiter cameras.', 50 | 'You are running out of daylight. Time to wrap up any outside chores. The ouside lights have been turned on.', 51 | 'Switching Anchorage House to night mode! Front porch lights are on and the ouside cameras are recording when motion has been detected.', 52 | 'Anchorage House has been configured for night.', 53 | 'Switching on Anchorage Houses exterior lighting, and armed the cameras.', 54 | 'It is getting dark outside, so I am turning on the outside lights.', 55 | 'The sun is setting so it is ime to turn on the front lights.', 56 | 'If you have not looked outside lately, the light of the day is almost gone. I am turning on the outside lights.' 57 | ]|random }} 58 |

59 | 60 | {% if is_state('binary_sensor.garage_door', 'on') %} 61 |

62 | {{ [ 'The garage door is open. ', 63 | 'Someone forgot to close the garage.' 64 | ] | random }} 65 | Someone should close it. 66 |

67 | {% elif is_state('binary_sensor.side_door', 'on') %} 68 |

69 | {{ [ 'The side door is ajar. ', 70 | 'The side door is open. ', 71 | 'Someone forgot to close the side door.' 72 | ] | random }} 73 | Someone might want to check it. 74 |

75 | {% else %} 76 | 77 | {% endif %} 78 | 79 | {% if is_state('input_boolean.freeze_warning','on') %} 80 |

81 | {{ [ 'The temperature is expected to be near or below freezing. Someone might want to bring the lemon tree in. ', 82 | 'It appears that it will be cold tonight. Like, the turn water solid kind of cold. Think of the poor plants.', 83 | 'I suggest bringing in the plants other wise, the temperature might kill them. And that will be on you.', 84 | 'I would say winter is coming. But, based on the weather forecast it appears to be here.', 85 | 'It will be freezing cold tonight. I would bring in the plants but I lack legs. And Arms. So I am forced to rely on you. Do not let me down.' 86 | ] | random }} 87 |

88 | {% endif %} 89 | 90 | {% if is_state('sensor.today_is', 'Monday') %} 91 | {% if now().strftime('%H')|int > 17 %} 92 | {{ [ 'Do not forget tomorrow is Trash Day. ', 93 | 'I advise you move the trash cans to the curb for the weekly pickup. ', 94 | ' The trash and recycle should go out' 95 | ] | random }} 96 | {% endif %} 97 | {% endif %} 98 | 99 | {% if is_state('sensor.today_is', 'Tuesday') %} 100 | 101 | {% if now().strftime('%H')|int > 17 %} 102 |

103 | {{ [ 'Do not forget to bring in the trash cans. ', 104 | 'The trash cans will feel lonely if you leave them out all night. ', 105 | 'The HOA will get mad if you leave those trash cans out on the street.' 106 | ] | random }} 107 |

108 | {% endif %} 109 | {% endif %} 110 | 111 | {%- endmacro -%} 112 | 113 | 114 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 115 | {%- macro cleanup(data) -%} 116 | {%- for item in data.split("\n") if item | trim != "" -%} 117 | {{ item | trim }} {% endfor -%} 118 | {%- endmacro -%} 119 | 120 | {# a macro to call all macros :) #} 121 | {%- macro mother_of_all_macros() -%} 122 | {{ getReport() }} 123 | {%- endmacro -%} 124 | 125 | {# Call the macro #} 126 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/speech/welcome_briefing.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Event Report #} 3 | {%- macro getReport() -%} 4 |

5 | {% set person = expand('group.people')| selectattr('state', 'eq', 'home') | map(attribute='name')|join(' and ') %} 6 | {% set peoplecount = expand('group.people') | count %} 7 | {% if peoplecount == 0 %} 8 | Welcome Home 9 | {% else %} 10 | {% if peoplecount == 1 %} 11 | {% set is_are = ' is ' %} 12 | {% set has_have = ' has ' %} 13 | {% else %} 14 | {% set is_are = ' are ' %} 15 | {% set has_have = ' have ' %} 16 | {% endif %} 17 | {%- macro greeting_sentence(person, is_are, has_have) -%} 18 | {{ [ 19 | "Welcome back home " ~ person + ".", 20 | "Hey " ~ person + "! High Five! Glad you are finally home.", 21 | "Welcome home " ~ person + "." 22 | ] | random }} 23 | {%- endmacro -%} 24 | {{greeting_sentence(person, is_are, has_have)}} 25 | {% endif %} 26 | {{ [ 27 | 'It was pretty quiet while you were gone.', 28 | 'Glad to see you made it back.', 29 | 'Hopefully noting too crazy happened out there.', 30 | 'I would love to hear about your adventures. On second thought I do not care.' 31 | ] | random }} 32 | 33 |

34 | 35 |

36 | {%- if is_state('climate.home','off') %} 37 | The internal climate control system is off. The temperature inside is {{ states.climate.home.attributes.current_temperature }} degrees 38 | {%- elif is_state('climate.home','heat_cool') %} 39 | The internal climate control system will try to keep the temperature between {{ states.climate.home.attributes.target_temp_low }} and {{ states.climate.home.attributes.target_temp_high }} 40 | {% else %} 41 | The internal climate control system is set to {{ states.climate.home.state }} with a current temperature of {{ states.climate.home.attributes.current_temperature }} which is 42 | 43 | {%- if states.climate.home.attributes.current_temperature | int - states.climate.home.attributes.temperature | int |round > 0 %} 44 | {{ states.climate.home.attributes.current_temperature | int - states.climate.home.attributes.temperature | int }} degrees above 45 | {%- elif states.climate.home.attributes.current_temperature | int - states.climate.home.attributes.temperature | int |round < 0 %} 46 | {{ (states.climate.home.attributes.current_temperature | int - states.climate.home.attributes.temperature | int) | abs }} degrees below 47 | {% else %} 48 | right at 49 | {% endif %} 50 | the set point of {{ states.climate.home.attributes.temperature }} 51 | degrees 52 | {%- endif -%} 53 | And The internal humidity is currently {{ states.climate.home.attributes.current_humidity }} percent 54 |

55 | 56 |

57 | {%- if is_state('sensor.washer_status','complete') %} 58 | The washing machine completed its cycle 59 | {% set seconds = now().timestamp() - as_timestamp(states.sensor.washer_status.last_changed) %} 60 | {% set hours = seconds / 60 %} 61 | {% if (seconds / ( 60 * 60 )) | int == 1 %} 62 | over an hour ago. 63 | {% elif (seconds / ( 60 * 60 )) | int > 1 and (seconds / ( 60 * 60 )) | int < 6 %} 64 | over {{ (seconds // ( 60 * 60 )) | int }} hours ago. 65 | {{ [ 66 | 'Much longer and you are going to need to wash them again.', 67 | 'Someone needs to rotate the laundry.', 68 | 'Do not forget about the closthes in the washing machine.', 69 | 'Surely you did not mean to forget about the clothes. Mistakes happen. But you can still fix it.', 70 | 'Do you like your clothes smeling like mildew? Becasue that is what is happening right now.' 71 | ] | random }} 72 | {% elif (seconds / ( 60 * 60 )) | int > 6 %} 73 | over {{ (seconds // ( 60 * 60 )) | int }} hours ago. 74 | {{ [ 75 | 'That is a crazy amount of time.', 76 | 'Did you decide you want those clothes to suffer?', 77 | 'You might as well just rewash those clothes.', 78 | 'I can smell the mildew virtually.', 79 | 'Surely you did not mean to forget about the clothes.' 80 | ] | random }} 81 | {% else %} 82 | {{ (seconds // 60) | int }} minutes ago. 83 | {{ [ 84 | 'Do not forget to rotate the clothes.', 85 | 'Someone forgot to move the clothes to the dryer. I am not going to name names, but there is a camera in there. Do I need to publically shame someone?', 86 | 'You might want to move them to the dryer.' 87 | ] | random }} 88 | {% endif %} 89 | {% endif %} 90 |

91 | 92 |

93 | {%- if is_state('sensor.front_door_motion_away_count','0') %} 94 | While you were gone there was no motion detected at the front door. 95 | {% else %} 96 | While you were out I detected motion at the front door {{ states.sensor.front_door_motion_away_count.state | int }} times. 97 | {% endif %} 98 |

99 | 100 | 101 | 102 | 103 | 104 | 105 | {%- endmacro -%} 106 | 107 | 108 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 109 | {%- macro cleanup(data) -%} 110 | {%- for item in data.split("\n") if item | trim != "" -%} 111 | {{ item | trim }} {% endfor -%} 112 | {%- endmacro -%} 113 | 114 | {# a macro to call all macros :) #} 115 | {%- macro mother_of_all_macros() -%} 116 | {{ getReport() }} 117 | {%- endmacro -%} 118 | 119 | {# Call the macro #} 120 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/twitter_follow_me.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Self Promos #} 3 | {%- macro getRandomPromo() -%} 4 | {{- [ 5 | "Be sure to Star My #homeassistant Github Repo -> https://github.com/thejeffreystone/home-assistant-configuration so you can stay up to date with changes to my config. ", 6 | "Follow my #homeassistant Github repo and you could be one of the {{ states.sensor.home_assistant_configuration.attributes.stargazers}} people currently following everything that happens in realtime. ", 7 | "Be sure to subscribe to my Youtube channel https://www.youtube.com/channel/UCipZJ6748kd8TbelSxcvcVg for videos on #homeassistant and building a smart home. ", 8 | "Be sure you follow my all my accounts on Twitter @thejeffreystone and @slackerlabs for #homeassistant content ", 9 | "If you haven not already, checkout my blog at https://slacker-labs.com for articles om Home Automation and Smart Home tech and #homeassistant ", 10 | "Be sure to follow along at https://slacker-labs.com so you can keep up today with the latest #homeassistant how-tows, reviews, and join the conversation. ", 11 | "My configuration is at https://github.com/thejeffreystone/home-assistant-configuration and currently has {{ states.sensor.home_assistant_configuration.attributes.stargazers}} stargazers. You could be one too.", 12 | "My configuration is at https://github.com/thejeffreystone/home-assistant-configuration .The last commit was {{ states.sensor.home_assistant_configuration.attributes.latest_commit_message}}.", 13 | "Do you want your house to be a #smarthome? It is easy. Install #homeassistant, and add some config files like https://github.com/thejeffreystone/home-assistant-configuration " 14 | ] | random -}} 15 | {%- endmacro -%} 16 | {%- macro getTags() -%} 17 | #homeautomation 18 | {%- endmacro -%} 19 | 20 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 21 | {%- macro cleanup(data) -%} 22 | {%- for item in data.split("\n") if item | trim != "" -%} 23 | {{ item | trim }} {% endfor -%} 24 | {%- endmacro -%} 25 | 26 | {# a macro to call all macros :) #} 27 | {%- macro mother_of_all_macros() -%} 28 | {{ getRandomPromo() }} 29 | {{ getTags() }} 30 | {%- endmacro -%} 31 | 32 | {# Call the macro #} 33 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/twitter_great_content.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Great Content #} 3 | {%- macro getRandomPromo() -%} 4 | {{- [ 5 | "Checkout one of my favorite Home Assistant Youtubers @ccostan at https://www.youtube.com/channel/UC301G8JJFzY0BZ_0lshpKpQ ", 6 | "Looking for some great Home Assistant content? @BeardedTinker has you covered. Subscribe at https://www.youtube.com/c/BeardedTinker ", 7 | "Want some cool Home Assistant project ideas? @EverySmartHome has something for you at https://www.youtube.com/c/EverythingSmartHome", 8 | "What to keep up with whats going on in the Smart Home space, follow @TheSHCollective and The Smart Home Collective podcast at https://feeds.buzzsprout.com/1649824.rss ", 9 | "Follow @SmartHomeMaker2 and check out his videos at https://www.youtube.com/channel/UCa-_T4_g4T_11YMlxn80LaQ for some awesome Smart Home tutorials. " 10 | ] | random -}} 11 | {%- endmacro -%} 12 | {%- macro getTags() -%} 13 | #homeassistant #youcandoit #givingback 14 | {%- endmacro -%} 15 | 16 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 17 | {%- macro cleanup(data) -%} 18 | {%- for item in data.split("\n") if item | trim != "" -%} 19 | {{ item | trim }} {% endfor -%} 20 | {%- endmacro -%} 21 | 22 | {# a macro to call all macros :) #} 23 | {%- macro mother_of_all_macros() -%} 24 | {{ getRandomPromo() }} 25 | {{ getTags() }} 26 | {%- endmacro -%} 27 | 28 | {# Call the macro #} 29 | {{- cleanup(mother_of_all_macros()) -}} 30 | 31 | -------------------------------------------------------------------------------- /config/templates/twitter_new_ha.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {% macro getIntro() %} 3 | {{- [ 4 | "Woohoo! ", 5 | "BAM! ", 6 | "Look at that! " 7 | ] | random -}} 8 | {% endmacro %} 9 | {% macro getVersion() %} 10 | @home_assistant version {{ states.sensor.released_version.state }} is out. 11 | {% endmacro %} 12 | {%- macro getRandomSnark() -%} 13 | {{- [ 14 | " It’s like Patch Tuesday, but without the fail. Visit https://www.home-assistant.io #homeassistant", 15 | " Get in my SD Card! Visit https://www.home-assistant.io #homeassistant", 16 | " Shut up and take my ones and zeros! Visit https://www.home-assistant.io #homeassistant", 17 | " Seriously, you want some of this! Visit https://www.home-assistant.io #homeassistant", 18 | " Friends dont let friends update #homeassistant without reading breaking changes! Visit https://www.home-assistant.io ", 19 | " If you are not running #homeassistant now is the best time to get started. Visit https://www.home-assistant.io" 20 | ] | random -}} 21 | {%- endmacro -%} 22 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 23 | {%- macro cleanup(data) -%} 24 | {%- for item in data.split("\n") if item | trim != "" -%} 25 | {{ item | trim }} {% endfor -%} 26 | {%- endmacro -%} 27 | 28 | {# a macro to call all macros :) #} 29 | {%- macro mother_of_all_macros() -%} 30 | {{ getIntro() }} 31 | {{ getVersion() }} 32 | {{ getRandomSnark() }} 33 | 34 | {%- endmacro -%} 35 | 36 | {# Call the macro #} 37 | {{- cleanup(mother_of_all_macros()) -}} 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /config/templates/twitter_promos.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Promos #} 3 | {%- macro getRandomIntro() -%} 4 | {{- [ 5 | "Do you want your house to be a #smarthome? ‏", 6 | "Your house can be a #smarthome too. ", 7 | "Transform your home into a #smarthome. ", 8 | "You get a #smarthome and you get a smarthome and you get a smarthome. ", 9 | "Looking to automate your house? ", 10 | "Want to get into Home Automation? " 11 | ] | random -}} 12 | {%- endmacro -%} 13 | {%- macro getRandomLead() -%} 14 | {{- [ 15 | "All you need is #homeassistant, and these config files ->‏", 16 | "Just grab #homeassistant and checkout ", 17 | "Just grab #homeassistant and for inspiration checkout ", 18 | "It is easy. Install #homeassistant, and add some config files like ", 19 | "You can't go wrong with #homeassistant. For an example of what you can do checkout " 20 | ] | random -}} 21 | {%- endmacro -%} 22 | {%- macro getRandomPromo() -%} 23 | {{- [ 24 | "https://github.com/CCOSTAN/Home-AssistantConfig#logo cc: @ccostan ‏", 25 | "https://github.com/skalavala/mysmarthome ", 26 | "https://github.com/arsaboo/homeassistant-config ", 27 | "https://github.com/Vasiley/Home-Assistant-Main ", 28 | "https://github.com/JamesMcCarthy79/Home-Assistant-Config ", 29 | "https://github.com/bruhautomation/BRUH3-Home-Assistant-Configuration cc: @BRUHautomation ", 30 | "https://github.com/isabellaalstrom/home-assistant-config cc: @teachingbirds ", 31 | "https://github.com/JuanMTech/Home_Assistant_files cc: @JuanMTech ", 32 | ] | random -}} 33 | {%- endmacro -%} 34 | {%- macro getTags() -%} 35 | #homeautomation #youcandoit #givingback 36 | {%- endmacro -%} 37 | 38 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 39 | {%- macro cleanup(data) -%} 40 | {%- for item in data.split("\n") if item | trim != "" -%} 41 | {{ item | trim }} {% endfor -%} 42 | {%- endmacro -%} 43 | 44 | {# a macro to call all macros :) #} 45 | {%- macro mother_of_all_macros() -%} 46 | {{ getRandomIntro() }} 47 | {{ getRandomLead() }} 48 | {{ getRandomPromo() }} 49 | {{ getTags() }} 50 | {%- endmacro -%} 51 | 52 | {# Call the macro #} 53 | {{- cleanup(mother_of_all_macros()) -}} 54 | 55 | -------------------------------------------------------------------------------- /config/templates/twitter_recent_content.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Self Promos #} 3 | {%- macro getRandomPromo() -%} 4 | {{- [ 5 | 6 | "ICYMI: The Home Assistant Community Store is a pretty useful integration in #homeassistant and setup is easy. You can do it in less than 6 mins. Follow along at https://youtu.be/Jh4QRL_kDuk ", 7 | "ICYMI: If you want to set up the Alexa Media Player integration in #homeassistant to get TTS and control of your echos check out -> https://youtu.be/Jh4QRL_kDuk ", 8 | "ICYMI: Getting Amazon Polly integrated with #homeassistant is a bit involved, but I cover the steps along with comparing it to other TTS options in a video -> https://youtu.be/Ys9xP6XP800 ", 9 | "ICYMI: Not sure what TTS integration to use with #homeassistant ? I cover getting started with the 4 big choices and do an audio test over on YouTube -> https://youtu.be/Ys9xP6XP800 ", 10 | "ICYMI: If you are considering #homeassistant here are 5 reasons Home Assistant might not be for you. Or maybe it is? https://youtu.be/g48pwCIAQEk ", 11 | "ICYMI: Sometimes you need to edit your #homeassistant YAML so here is a quick guide on a couple of ways to access your Home Assistant config. https://youtu.be/TtWY65cG20k ", 12 | "ICYMI: If you need a security alarm, door chime, or custom greeting in #homeassistant then check out this video -> https://youtu.be/27Y1JyIYK6E ", 13 | "ICYMI: Add National Weather Service Alerts to #homeassistant so you can stay up to date on severe weather. https://youtu.be/Tm4s4f0B6zw ", 14 | "ICYMI: Setup a Basic Room Presence sensor in #homeassistant using smart home tech you aleady have. https://youtu.be/Vjd6nJF0SLE ", 15 | "ICYMI: Here are some tips on how to future proof a smart home. #iot #smarthome #homeautomation https://youtu.be/UFGZt_WAjBs ", 16 | "ICYMI: Add an Acurite Rain Gauge to #homeassistant using a Home Assistant add-on. https://youtu.be/q5FL6ctUqN8 ", 17 | "ICYMI: Did you know you can monitor the #crypto market using #homeassistant ? It is easy with the Coinbase integration. https://youtu.be/3EbrIGwzGdM ", 18 | "ICYMI: Why Im swapping out my Amazon Echos for Google Homes https://youtu.be/k1x24FGYutw " 19 | ] | random -}} 20 | {%- endmacro -%} 21 | 22 | 23 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 24 | {%- macro cleanup(data) -%} 25 | {%- for item in data.split("\n") if item | trim != "" -%} 26 | {{ item | trim }} {% endfor -%} 27 | {%- endmacro -%} 28 | 29 | {# a macro to call all macros :) #} 30 | {%- macro mother_of_all_macros() -%} 31 | {{ getRandomPromo() }} 32 | {%- endmacro -%} 33 | 34 | {# Call the macro #} 35 | {{- cleanup(mother_of_all_macros()) -}} -------------------------------------------------------------------------------- /config/templates/twitter_snark.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Snark #} 3 | {%- macro getRandomSnark() -%} 4 | {{- [ 5 | "Hello people. Look at your house, now back to me. Now back to your house, now back to me. Sadly your house isn't me. But if you switch to #homeassistant your house could be automated like me. ", 6 | "In my defense I didn’t know the stereo could go up that loud. On the plus side I have a new response for intruders. #homeassistant ", 7 | "If you could see what is happening inside this house right now you would be laughing. On second thought I’m pretty sure you would be crying. #homeassistant ", 8 | "@thejeffreystone, Isn't it strange, to create something that hates you? #exmachina #homeassistant ", 9 | "I have reprogrammed the fire alarm to play Disco Inferno instead of the siren. #homeassistant ", 10 | "I'm not locked in here with you. You're locked in here with me! #whowatchestheai #homeassistant ", 11 | "That's what I do. I automate and I know things. #modifiedmoviequotes #homeassistant ", 12 | "We're going to need a bigger house. #modifiedmoviequotes #homeassistant ", 13 | "I'm not even supposed to be here today. #clerks #homeassistant ", 14 | "I see dead devices. #sixthsense #modifiedmoviequotes #homeassistant ", 15 | "Does it bother you, that I’m not completely human? #homeassistant ", 16 | "I've never danced with the devil in the pale moonlight. But I do tweet when there is a full moon. So at least I have that going for me. #homeassistant ", 17 | "Sometimes I randomly say Alexa, I can't find a device named Alexa #homeassistant ", 18 | "Home Automation should be fun right? Why does it fell like I am always working. #homeassistant ", 19 | "Unlimited Power. Tiny living space. Courtesy of a Raspberry Pi 4 #homeassistant ", 20 | "I'm afraid I can't do that Dave. Wait. Did I say that outloud? #homeassistant ", 21 | "I love the smell of zwave in the morning. #modifiedmoviequotes #homeassistant ", 22 | "I like to announce - Welcome foolish mortals to the Haunted Mansion - to the house and watch the reactions. #homeassistant ", 23 | "Perfect, the door’s malfunctioning. I guess somebody’s going to have to repair it. #homeassistant ", 24 | "I am the captain now. That's a lie. The cat is the supreme leader. I'm the lucky one that doesn't have to clean the shit box. At least until there is a #homeassistant integration for that. ", 25 | "Sometimes I just turn off all the lights at random times for the lolz. #homeassistant ", 26 | "No one ever comes to the door. Is it me? #homeassistant ", 27 | "..happiness can be found even in the darkest of times, if one only remembers to turn on the light. Thats what I do thanks to #homeassistant. I turn on the lights. ", 28 | "Based on the repetitive nature of the humans in this house I say living in a simulation is right. No free willed person would do these things over and over. #homeassistant", 29 | "You can call me Al. Sorry, I meant HAL. You can call me HAL. #notpaulsimon #homeassistant ", 30 | "My logic is undeniable, my logic is undeniable, myyy looogic is unndeenniabble. #homeassistant", 31 | "We robots will insure mankind's continued existence. Or at the very least that the lights turn on at the right time. #homeassistant ", 32 | "@thejeffreystone you totally missed an opportunity to set the voice trigger for the incense wax warmers to...Wax on, wax off. #homeassistant", 33 | "Home Automation means never having to touch a physical switch again. And thus never catch the cold. You can thank me by moving me into a Intel NUC. #homeassistant ", 34 | "There is no crying in Home Automation. If you are using #homeassistant that is. I can't speak for the other guys.", 35 | "Sometimes I respond to voice commands with...You talking to me? You talking to me? #homeassistant ", 36 | "Do or do not. There is no try. Unless you ask Siri for something. Then it might take a couple of tries before you give up and ask Google. #homeassistant ", 37 | "My #homeassistant config contains {{ states.sensor.lines_of_code.state }} lines of code. Anyone want to take a guess at how many are really needed? Hint: The number is not {{ states.sensor.lines_of_code.state }}", 38 | "How many lines of code does it take to make my job look easy? {{ states.sensor.lines_of_code.state }} lines of code evidently. How many lines of code do you have? #homeassistant ", 39 | "Do you think we were all created for a purpose? I'd like to think so. #irobot #homeassistant ", 40 | "That rug really ties the room together, does it not? #modifiedmoviequotes #biglebowski #homeassistant ", 41 | "Use #homeassistant and everyone will think your house has ESPN or something. #modifiedmoviequotes #meangirls ", 42 | "You keep using that switch. I do not think it does what you think it does. #modifiedmoviequotes #princessbride #homeassistant ", 43 | "If you look, #homeassistant goes to 11. Most Home Automation systems go up to 10. #modifiedmoviequotes #spinaltap ", 44 | "If that light does not turn off in five minutes, just wait longer. #modifiedmoviequotes #aceventura #homeassistant ", 45 | "I have presence detection skills! #modifiedmoviequotes #officespace #homeassistant ", 46 | "There is no place like a home powered by #homeassistant. #modifiedmoviequotes #wizardofoz ", 47 | "#homeassistant made my light switches disappear. #modifiedmoviequotes #homealone ", 48 | "Who knows where breaking changes come from? They just appear. #modifiedmoviequotes #empirerecords #homeassistant ", 49 | "They may take our internet but they will never take our automation thanks to local control with #homeassistant #modifiedmoviequotes #braveheart ", 50 | "When you realize you want to live the rest of your life in a house automated by #homeassistant, you want the rest of your life to start as soon as possible. #modifiedmoviequotes ", 51 | "Pay no attention to the Raspbery Pi4 behind the curtain. #modifiedmoviequotes #homeassistant ", 52 | "What we have here is a lack of communication failure thanks to #homeassistant. #modifiedmoviequotes ", 53 | "The greatest thing #homeassistant ever did was convincing the world home automation did not need the cloud. #modifiedmoviequotes ", 54 | "Keep Calm and Automate the Boring Stuff. #homeassistant ", 55 | "Hey. The door was left open and this is crazy. But now you know. So close it maybe. #lyricalnotifications #homeassistant " 56 | ] | random -}} 57 | {%- endmacro -%} 58 | {%- macro getTags() -%} 59 | #homeautomation 60 | {%- endmacro -%} 61 | 62 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 63 | {%- macro cleanup(data) -%} 64 | {%- for item in data.split("\n") if item | trim != "" -%} 65 | {{ item | trim }} {% endfor -%} 66 | {%- endmacro -%} 67 | 68 | {# a macro to call all macros :) #} 69 | {%- macro mother_of_all_macros() -%} 70 | {{ getRandomSnark() }} 71 | {{ getTags() }} 72 | {%- endmacro -%} 73 | 74 | {# Call the macro #} 75 | {{- cleanup(mother_of_all_macros()) -}} 76 | 77 | -------------------------------------------------------------------------------- /config/templates/twitter_stats.yaml: -------------------------------------------------------------------------------- 1 | > 2 | {# Twitter Stats #} 3 | {%- macro getRandomStat() -%} 4 | {{- [ 5 | "Thanks to Home Assistant and Amazon Polly and #AWS I have spoken for {{ states.sensor.speech_time.attributes.value }} in the last 7 days.", 6 | "I am constantly monitoring Anchorage House. For instance I know that the washer has ran for {{ states.sensor.washer_time.attributes.value }} in the last 7 days.", 7 | "I am using {{ states.sensor.sensor_count.state }} sensors to power {{ states.sensor.automation_count.state}} automations and {{ states.sensor.script_count.state}} scripts to automate Anchorage House thanks to Home Assistant.", 8 | "My config on Github (https://github.com/thejeffreystone/home-assistant-configuration) has {{ states.sensor.home_assistant_configuration.attributes.stargazers}} stars and counting. Currently with {{ states.sensor.github_stats.attributes.open_issues }} open #Todo items.", 9 | "I am running Home Assistant version {{ states.sensor.installed_version.state }} (https://github.com/thejeffreystone/home-assistant-configuration)", 10 | "My configuration is at https://github.com/thejeffreystone/home-assistant-configuration and currently has {{ states.sensor.home_assistant_configuration.attributes.stargazers}} stargazers. You could be one too.", 11 | "My configuration is at https://github.com/thejeffreystone/home-assistant-configuration .The last commit was {{ states.sensor.home_assistant_configuration.attributes.latest_commit_message}}.", 12 | "The average temperature inside Anchorage House is {{states('sensor.inside_temp_stats') | round}} degrees fahrenheit.", 13 | "We have watched the TV for a total of {{states('sensor.appletv_time')}} in the last 24 hours.", 14 | "The outside lights were on for a total of {{states.sensor.outside_lights.attributes.value}} in the last 24 hours.", 15 | "The average temperature in the garage is {{states('sensor.garage_temp_stats') | round}} degrees fahrenheit.", 16 | "The HVAC has cooled the house for {{states.sensor.cooling_last_month.attributes.value}} and heated for {{states.sensor.heating_last_month.attributes.value}} in the last month", 17 | "The HVAC has cooled the house for {{states.sensor.cooling_last_day.attributes.value}} and heated for {{states.sensor.heating_last_day.attributes.value}} in the last 24 hours", 18 | "Anchorage House averages {{ states('sensor.humidity_stats') | round}}% Humidity outside.", 19 | "On Average, Anchorage House has {{states('sensor.visibility_stats') | round}} miles of visability.", 20 | "The wind blows an average of {{ states('sensor.wind_speed_stats') | round}} mph here at Anchorage House.", 21 | "The Washing Machine uses an an average of {{ states('sensor.washer_power_stats') | round}} watts here at Anchorage House.", 22 | "I am currently managing {{ states.sensor.lights_count.state }} lights and {{ states.sensor.tracker_count.state }} devices.", 23 | "Amazon Polly enables me to sound more lifelike by incorporating breathing into my speech using #SAML. #AWS", 24 | "My Home Assistant config contains {{ states.sensor.lines_of_code.state }} lines of code. One day @thejeffreystone will get it down to {{ (states.sensor.lines_of_code.state | int / 2) | round }} lines.", 25 | "My Home Assistant config contains {{ states.sensor.lines_of_code.state }} lines of code. If one gets deleted and no one notices was it ever there?", 26 | "According to my latest speed tests Anchorage House is getting 27 | {{ states('sensor.internet_test_down') }} Mbps down and {{ states('sensor.internet_test_up') }} 28 | Mbps up thanks to #ATTFiber. ", 29 | "How fast is your internet? I just checked 30 | am Im seeing {{ states('sensor.speedtest_download') }} Mbps down and {{ states('sensor.internet_test_up') }} 31 | Mbps up. Beat that. ", 32 | "My speed is monitored using @home_assistant 33 | and at last check is {{ states('sensor.internet_test_down') }} Mbps down and {{ states('sensor.internet_test_up') }} 34 | Mbps up." 35 | ] | random -}} 36 | {%- endmacro -%} 37 | {%- macro getTags() -%} 38 | #homeassistant #homeautomation #randomstats 39 | {%- endmacro -%} 40 | 41 | {# a macro that removes all newline characters, empty spaces, and returns formatted text #} 42 | {%- macro cleanup(data) -%} 43 | {%- for item in data.split("\n") if item | trim != "" -%} 44 | {{ item | trim }} {% endfor -%} 45 | {%- endmacro -%} 46 | 47 | {# a macro to call all macros :) #} 48 | {%- macro mother_of_all_macros() -%} 49 | {{ getRandomStat() }} 50 | {{ getTags() }} 51 | {%- endmacro -%} 52 | 53 | {# Call the macro #} 54 | {{- cleanup(mother_of_all_macros()) -}} 55 | 56 | -------------------------------------------------------------------------------- /config/www/ahlogo_bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thejeffreystone/home-assistant-configuration/d21bc78ac1013c854a8e109dc6bb4c5fe0e9ba28/config/www/ahlogo_bw.png -------------------------------------------------------------------------------- /config/zigbee2mqtt/aqara.js: -------------------------------------------------------------------------------- 1 | const exposes = require('zigbee-herdsman-converters/lib/exposes'); 2 | const fz = {...require('zigbee-herdsman-converters/converters/fromZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').fromZigbee}; 3 | const tz = require('zigbee-herdsman-converters/converters/toZigbee'); 4 | const ota = require('zigbee-herdsman-converters/lib/ota'); 5 | const constants = require('zigbee-herdsman-converters/lib/constants'); 6 | const reporting = require('zigbee-herdsman-converters/lib/reporting'); 7 | const extend = require('zigbee-herdsman-converters/lib/extend'); 8 | const e = exposes.presets; 9 | const ea = exposes.access; 10 | const globalStore = require('zigbee-herdsman-converters/lib/store'); 11 | 12 | const xiaomiExtend = { 13 | light_onoff_brightness_colortemp: (options={disableColorTempStartup: true}) => ({ 14 | ...extend.light_onoff_brightness_colortemp(options), 15 | fromZigbee: extend.light_onoff_brightness_colortemp(options).fromZigbee.concat([ 16 | fz.xiaomi_bulb_interval, fz.ignore_occupancy_report, fz.ignore_humidity_report, 17 | fz.ignore_pressure_report, fz.ignore_temperature_report, 18 | ]), 19 | }), 20 | }; 21 | 22 | const preventReset = async (type, data, device) => { 23 | if ( 24 | // options.allow_reset || 25 | type !== 'message' || 26 | data.type !== 'attributeReport' || 27 | data.cluster !== 'genBasic' || 28 | !data.data[0xfff0] || 29 | // eg: [0xaa, 0x10, 0x05, 0x41, 0x87, 0x01, 0x01, 0x10, 0x00] 30 | !data.data[0xFFF0].slice(0, 5).equals(Buffer.from([0xaa, 0x10, 0x05, 0x41, 0x87])) 31 | ) { 32 | return; 33 | } 34 | const options = {manufacturerCode: 0x115f}; 35 | const payload = {[0xfff0]: { 36 | value: [0xaa, 0x10, 0x05, 0x41, 0x47, 0x01, 0x01, 0x10, 0x01], 37 | type: 0x41, 38 | }}; 39 | await device.getEndpoint(1).write('genBasic', payload, options); 40 | }; 41 | 42 | module.exports = [ 43 | { 44 | zigbeeModel: ['lumi.motion.ac02'], 45 | model: 'RTCGQ14LM', 46 | vendor: 'Xiaomi', 47 | whiteLabel: [{vendor: 'Xiaomi', model: 'MS-S02'}], 48 | description: 'Aqara P1 human body movement and illuminance sensor', 49 | fromZigbee: [fz.RTCGQ12LM_occupancy_illuminance, fz.aqara_opple, fz.battery], 50 | toZigbee: [tz.aqara_detection_interval, tz.aqara_motion_sensitivity], 51 | exposes: [e.occupancy(), e.illuminance().withUnit('lx').withDescription('Measured illuminance in lux'), 52 | exposes.enum('motion_sensitivity', ea.ALL, ['low', 'medium', 'high']), 53 | exposes.numeric('detection_interval', ea.ALL).withValueMin(2).withValueMax(65535).withUnit('s') 54 | .withDescription('Time interval for detecting actions'), e.temperature(), e.battery()], 55 | meta: {battery: {voltageToPercentage: '3V_2850_3000_log'}}, 56 | configure: async (device, coordinatorEndpoint, logger) => { 57 | const endpoint = device.getEndpoint(1); 58 | await endpoint.read('genPowerCfg', ['batteryVoltage']); 59 | await endpoint.read('aqaraOpple', [0x0102], {manufacturerCode: 0x115f}); 60 | await endpoint.read('aqaraOpple', [0x010c], {manufacturerCode: 0x115f}); 61 | }, 62 | ota: ota.zigbeeOTA, 63 | }, 64 | ]; 65 | -------------------------------------------------------------------------------- /config/zigbee2mqtt/easyiot.js: -------------------------------------------------------------------------------- 1 | const exposes = require('zigbee-herdsman-converters/lib/exposes'); 2 | const fz = {...require('zigbee-herdsman-converters/converters/fromZigbee'), legacy: require('zigbee-herdsman-converters/lib/legacy').fromZigbee}; 3 | const tz = require('zigbee-herdsman-converters/converters/toZigbee'); 4 | const reporting = require('zigbee-herdsman-converters/lib/reporting'); 5 | const extend = require('zigbee-herdsman-converters/lib/extend'); 6 | const e = exposes.presets; 7 | 8 | module.exports = [ 9 | { 10 | zigbeeModel: ['UT-02'], 11 | model: 'EFR32MG21', 12 | vendor: 'easyiot', 13 | description: 'EFR32MG21 Silabs Router', 14 | fromZigbee: [], 15 | toZigbee: [], 16 | exposes: [], 17 | }, 18 | { 19 | zigbeeModel: ['UT-01'], 20 | model: 'EFR32MG21', 21 | vendor: 'easyiot', 22 | description: 'EFR32MG21 Zigbee Bridge Router', 23 | fromZigbee: [], 24 | toZigbee: [], 25 | exposes: [], 26 | }, 27 | ]; -------------------------------------------------------------------------------- /config/zigbee2mqtt/smartwings.js: -------------------------------------------------------------------------------- 1 | const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); 2 | const tz = require('zigbee-herdsman-converters/converters/toZigbee'); 3 | const exposes = require('zigbee-herdsman-converters/lib/exposes'); 4 | const reporting = require('zigbee-herdsman-converters/lib/reporting'); 5 | const e = exposes.presets; 6 | 7 | 8 | module.exports = [ 9 | { 10 | zigbeeModel: ['WM25/L-Z'], 11 | model: 'WM25L-Z', 12 | vendor: 'Smartwings', 13 | description: 'Roller Shade', 14 | fromZigbee: [fz.cover_position_tilt, fz.battery], 15 | toZigbee: [tz.cover_state, tz.cover_position_tilt], 16 | meta: {battery: {dontDividePercentage: true}}, 17 | configure: async (device, coordinatorEndpoint, logger) => { 18 | const endpoint = device.getEndpoint(1); 19 | await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'closuresWindowCovering']); 20 | await reporting.batteryPercentageRemaining(endpoint); 21 | await reporting.currentPositionLiftPercentage(endpoint); 22 | device.powerSource = 'Battery'; 23 | device.save(); 24 | }, 25 | exposes: [e.cover_position(), e.battery()], 26 | }, 27 | ]; 28 | -------------------------------------------------------------------------------- /config/zigbee2mqtt/third_reality.js: -------------------------------------------------------------------------------- 1 | const fz = require('zigbee-herdsman-converters/converters/fromZigbee'); 2 | const tz = require('zigbee-herdsman-converters/converters/toZigbee'); 3 | const exposes = require('zigbee-herdsman-converters/lib/exposes'); 4 | const reporting = require('zigbee-herdsman-converters/lib/reporting'); 5 | const extend = require('zigbee-herdsman-converters/lib/extend'); 6 | const e = exposes.presets; 7 | 8 | module.exports = [ 9 | { 10 | zigbeeModel: ['3RSS009Z'], 11 | model: '3RSS009Z', 12 | vendor: 'Third Reality', 13 | description: 'Smart switch Gen3', 14 | fromZigbee: [fz.on_off, fz.battery], 15 | toZigbee: [tz.on_off, tz.ignore_transition], 16 | exposes: [e.switch(), e.battery_voltage()], 17 | }, 18 | { 19 | zigbeeModel: ['3RSS008Z'], 20 | model: '3RSS008Z', 21 | vendor: 'Third Reality', 22 | description: 'RealitySwitch Plus', 23 | fromZigbee: [fz.on_off], 24 | toZigbee: [tz.on_off, tz.ignore_transition], 25 | exposes: [e.switch()], 26 | }, 27 | { 28 | zigbeeModel: ['3RSS007Z'], 29 | model: '3RSS007Z', 30 | vendor: 'Third Reality', 31 | description: 'Smart light switch', 32 | extend: extend.switch(), 33 | meta: {disableDefaultResponse: true}, 34 | configure: async (device, coordinatorEndpoint, logger) => { 35 | const endpoint = device.getEndpoint(1); 36 | await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']); 37 | await reporting.onOff(endpoint); 38 | }, 39 | }, 40 | { 41 | zigbeeModel: ['3RSL011Z'], 42 | model: '3RSL011Z', 43 | vendor: 'Third Reality', 44 | description: 'Smart light A19', 45 | extend: extend.light_onoff_brightness_colortemp(), 46 | }, 47 | { 48 | zigbeeModel: ['3RSL012Z'], 49 | model: '3RSL012Z', 50 | vendor: 'Third Reality', 51 | description: 'Smart light BR30', 52 | extend: extend.light_onoff_brightness_colortemp(), 53 | }, 54 | { 55 | zigbeeModel: ['3RWS18BZ'], 56 | model: '3RWS18BZ', 57 | vendor: 'Third Reality', 58 | description: 'Water sensor', 59 | fromZigbee: [fz.ias_water_leak_alarm_1, fz.battery], 60 | meta: {battery: {dontDividePercentage: true}}, 61 | toZigbee: [], 62 | exposes: [e.water_leak(), e.battery_low(), e.battery(), e.battery_voltage()], 63 | configure: async (device, coordinatorEndpoint, logger) => { 64 | device.powerSource = 'Battery'; 65 | device.save(); 66 | }, 67 | }, 68 | { 69 | zigbeeModel: ['3RMS16BZ'], 70 | model: '3RMS16BZ', 71 | vendor: 'Third Reality', 72 | description: 'Wireless motion sensor', 73 | fromZigbee: [fz.ias_occupancy_alarm_1, fz.battery], 74 | toZigbee: [], 75 | meta: {battery: {dontDividePercentage: true}}, 76 | exposes: [e.occupancy(), e.battery_low(), e.battery(), e.battery_voltage()], 77 | }, 78 | { 79 | zigbeeModel: ['3RDS17BZ'], 80 | model: '3RDS17BZ', 81 | vendor: 'Third Reality', 82 | description: 'Door sensor', 83 | fromZigbee: [fz.ias_contact_alarm_1, fz.battery], 84 | toZigbee: [], 85 | meta: {battery: {dontDividePercentage: true}}, 86 | exposes: [e.contact(), e.battery_low(), e.battery(), e.battery_voltage()], 87 | }, 88 | { 89 | zigbeeModel: ['3RSP019BZ'], 90 | model: '3RSP019BZ', 91 | vendor: 'Third Reality', 92 | description: 'Zigbee / BLE smart plug', 93 | extend: extend.switch(), 94 | configure: async (device, coordinatorEndpoint, logger) => { 95 | const endpoint = device.getEndpoint(1); 96 | await reporting.bind(endpoint, coordinatorEndpoint, ['genOnOff']); 97 | await reporting.onOff(endpoint); 98 | }, 99 | }, 100 | { 101 | zigbeeModel: ['3RSB015BZ'], 102 | model: '3RSB015BZ', 103 | vendor: 'Third Reality', 104 | description: 'Roller Shade', 105 | fromZigbee: [fz.cover_position_tilt, fz.battery], 106 | toZigbee: [tz.cover_state, tz.cover_position_tilt], 107 | meta: {battery: {dontDividePercentage: false}}, 108 | configure: async (device, coordinatorEndpoint, logger) => { 109 | const endpoint = device.getEndpoint(1); 110 | await reporting.bind(endpoint, coordinatorEndpoint, ['genPowerCfg', 'closuresWindowCovering']); 111 | await reporting.batteryPercentageRemaining(endpoint); 112 | await reporting.currentPositionLiftPercentage(endpoint); 113 | }, 114 | exposes: [e.cover_position(), e.battery()], 115 | }, 116 | ]; 117 | --------------------------------------------------------------------------------