├── .github └── workflows │ └── hassci.yaml ├── .gitignore ├── LICENSE.md ├── README.md ├── apps ├── apps.yaml ├── flux.py ├── notify.py └── thermostat.py ├── automation ├── cloudy.yaml ├── daytime.yaml ├── daytime_bedroom.yaml ├── daytime_clear.yaml ├── evening.yaml ├── lights_inside_off.yaml ├── lights_outside_off.yaml ├── night.yaml ├── notify_leak_detected.yaml ├── notify_on_failed_login.yaml ├── notify_on_fire_co.yaml ├── notify_on_restart.yaml ├── sunset.yaml ├── wakeup.yaml └── wakeup_weekends.yaml ├── automations.yaml ├── bin ├── get_pihole_version.sh └── smash.sh ├── blueprints ├── automation │ └── homeassistant │ │ ├── motion_light.yaml │ │ └── notify_leaving_zone.yaml └── script │ └── homeassistant │ └── confirmable_notification.yaml ├── configuration.yaml ├── customize.yaml ├── customize ├── customize_climate.yaml ├── customize_input_boolean.yaml ├── customize_lights.yaml ├── customize_media.yaml ├── customize_misc_sensors.yaml ├── customize_presence.yaml ├── customize_scenes.yaml ├── customize_scripts.yaml ├── customize_switches.yaml └── customize_weather.yaml ├── gen_yaml.sh ├── images ├── ha_home_page.png └── ha_thermostat.png ├── includes ├── binary_sensor.yaml ├── blink.yaml ├── cameras.yaml ├── command_line.yaml ├── emulated_hue.yaml ├── fastdotcom.yaml ├── google_assistant.yaml ├── hue.yaml ├── influxdb.yaml ├── input_boolean.yaml ├── input_number.yaml ├── light.yaml ├── logger.yaml ├── notify.yaml ├── pihole.yaml ├── recorder.yaml ├── shell_command.yaml ├── speedtest.yaml └── tts.yaml ├── lovelace ├── ahome.yaml ├── climate.yaml ├── lovelace-gen.py ├── map.yaml ├── security.yaml └── status.yaml ├── scenes ├── blue.yaml ├── christmas.yaml ├── cyan.yaml ├── day.yaml ├── green.yaml ├── movies_family_room.yaml ├── movies_living_room.yaml ├── night.yaml ├── not_home_at_night.yaml ├── on_the_way_home.yaml ├── orange.yaml ├── pink.yaml ├── purple.yaml ├── sabres.yaml └── yellow.yaml ├── scripts.yaml ├── scripts ├── blink_trigger_camera.yaml ├── flux.yaml ├── github_pull.yaml ├── hass_upgrade.yaml ├── notify_all_engine.yaml ├── notify_kevin_engine.yaml ├── speech_engine.yaml ├── speech_processing.yaml ├── ssl_renew_certificate.yaml ├── upgrade_pihole.yaml ├── wake_computer.yaml └── zwave_fix_dead_node.yaml ├── sensors ├── appliances.yaml ├── fail2ban.yaml ├── history_stats.yaml ├── time.yaml └── weather_cond.yaml ├── smash.py ├── travis_secrets.yaml ├── ui-lovelace.yaml └── www ├── firetv.jpg ├── group-card.js ├── lovelace ├── bedroom.jpg ├── bedroom_off.jpg ├── kitchen.jpg ├── kitchen_off.jpg ├── living_room.jpg ├── living_room_off.jpg ├── nursery.jpg ├── nursery_off.jpg ├── office.png ├── office_off.png ├── outside_day.jpg ├── outside_night.jpg ├── playroom.jpg ├── playroom_off.jpg ├── theater.jpg └── theater_off.jpg ├── nvidia.jpg └── plex.png /.github/workflows/hassci.yaml: -------------------------------------------------------------------------------- 1 | name: Home Assistant CI 2 | on: 3 | push: 4 | branches: [master] 5 | pull_request: 6 | branches: [master] 7 | schedule: 8 | # Run at 1:05pm UTC every Saturday (8:05am EST) 9 | - cron: '5 13 * * 6' 10 | 11 | jobs: 12 | hassci: 13 | name: "Config Check" 14 | runs-on: ${{ matrix.platform }} 15 | strategy: 16 | max-parallel: 2 17 | matrix: 18 | platform: 19 | - ubuntu-latest 20 | hass-version: ["stable", "beta"] 21 | 22 | container: 23 | image: homeassistant/home-assistant:${{ matrix.hass-version }} 24 | env: 25 | TZ: "America/New_York" 26 | volumes: 27 | - /tmp:/tmp 28 | - /tmp:/images 29 | 30 | steps: 31 | - name: Getting config from github 32 | uses: actions/checkout@v2 33 | - name: HA Version Check 34 | run: python -m homeassistant --version 35 | - name: Copy secrets into configuration folder 36 | run: | 37 | cd "$GITHUB_WORKSPACE" 38 | cp travis_secrets.yaml secrets.yaml 39 | touch /tmp/test.txt 40 | - name: Config Check 41 | run: python -m homeassistant --config $GITHUB_WORKSPACE --script check_config 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .HA_VERSION 2 | .uuid 3 | *.log 4 | *.db* 5 | *.conf 6 | *.env 7 | secrets.yaml 8 | known_devices.yaml 9 | deps/ 10 | */secrets.yaml 11 | *.txt 12 | .xml 13 | *.sqlite 14 | tts/ 15 | jupyter 16 | *.json 17 | apps/__pycache__ 18 | *.pid 19 | *.xml 20 | *.csr 21 | *.crt 22 | *.key 23 | .tox/ 24 | bin/*.pipwd 25 | www/kevin.jpg 26 | www/allegra.jpg 27 | *.bak 28 | *.pickle 29 | custom_components 30 | bin/vm_shutdown.sh 31 | entity_registry.yaml 32 | .storage 33 | *.log.* 34 | *.fuse* 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Kevin Fronczak 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # githass ![Home Assistant CI](https://github.com/fronzbot/githass/workflows/Home%20Assistant%20CI/badge.svg?branch=master) 2 | 3 | ## Home Assistant Configuration 4 | Currently running on a home media server using [unRAID](https://lime-technology.com/) (Home Assistant runs in a docker) 5 | 6 | ### Components Used: 7 | - Weather: 8 | - [OpenWeatherMap](https://home-assistant.io/integrations/openweathermap/) 9 | - Climate: 10 | - [Nexia](https://home-assistant.io/integrations/nexia/) 11 | - Lights: 12 | - [Phillips Hue](https://home-assistant.io/components/light.hue/) 13 | - 5x 2nd Gen Color Ambience Bulbs 14 | - 8x White Ambience Bulbs 15 | - [Zwave](https://home-assistant.io/docs/z-wave/): 16 | - Aeotec Z-wave Stick 17 | - 1x GE Z-wave Switches 18 | - 1x Aeotec Smart Switch 19 | - 3x First Alert ZCOMBO Smoke/CO detectors 20 | - [Emulated Hue](https://home-assistant.io/components/emulated_hue/) 21 | - 1x Amazon Echo 22 | - 2x Amazon Echo Dot 23 | - [Google Assistant](https://home-assistant.io/components/google_assistant/) 24 | - 2x Google Home 25 | - 1x Google Home Mini 26 | - Notifications: 27 | - [HTML5](https://home-assistant.io/components/notify.html5/) Push Notifications 28 | - Other Components: 29 | - [Blink Camera](https://home-assistant.io/components/blink/) 30 | - [Google Wifi](https://home-assistant.io/components/sensor.google_wifi/) 31 | - [PiHole](https://home-assistant.io/components/sensor.pi_hole/) 32 | - [Speedtest](https://home-assistant.io/components/sensor.speedtest/) 33 | - [Fast.com](https://home-assistant.io/components/sensor.fastdotcom/) 34 | - Databases: 35 | - MySQL for default recorder 36 | - [Influx and Grafana](https://home-assistant.io/blog/2015/12/07/influxdb-and-grafana/) for more long-term trend plotting 37 | 38 | ### Automations: 39 | - Light control based on device presence and sun status 40 | - HA Reset notifications and memory leak notifications 41 | - Nightly data storage for daily average/max/min to be displayed as a graph in the front end (to get long-term history) 42 | 43 | 44 | (Images last updated March 3, 2019 may not reflect current configuration) 45 | ![](https://github.com/fronzbot/githass/blob/master/images/ha_home_page.png) 46 | ![](https://github.com/fronzbot/githass/blob/master/images/ha_thermostat.png) 47 | -------------------------------------------------------------------------------- /apps/apps.yaml: -------------------------------------------------------------------------------- 1 | flux_family_room: 2 | module: flux 3 | class: Flux 4 | constrain_input_boolean: input_boolean.flux_family_room 5 | light: light.family_room_couch_left,light.family_room_couch_right,light.family_room_fireplace 6 | 7 | flux_kitchen: 8 | module: flux 9 | class: Flux 10 | constrain_input_boolean: input_boolean.flux_kitchen 11 | light: light.kitchen_island_1,light.kitchen_island_2,light.kitchen_table_1,light.kitchen_table_2 12 | 13 | flux_living_room: 14 | module: flux 15 | class: Flux 16 | constrain_input_boolean: input_boolean.flux_living_room 17 | light: light.living_room_couch_1,light.living_room_corner_1,light.living_room_piano,light.living_room_foyer 18 | 19 | flux_office: 20 | module: flux 21 | class: Flux 22 | constrain_input_boolean: input_boolean.flux_office 23 | light: light.office_desk,light.office_corner 24 | 25 | flux_master_bedroom: 26 | module: flux 27 | class: Flux 28 | constrain_input_boolean: input_boolean.flux_master_bedroom 29 | light: light.master_bedroom_door,light.master_bedroom_window 30 | 31 | 32 | #thermostat: 33 | # module: thermostat 34 | # class: Thermostat 35 | # constrain_input_boolean: input_boolean.thermostat_enable 36 | # climate: climate.thermostat_73_5c_83 37 | # sensors: sensor.occupancy,sensor.dark_sky_temperature 38 | # input_number: input_number.ac_home,input_number.ac_away,input_number.ac_sleep,input_number.heat_home,input_number.heat_away,input_number.heat_sleep 39 | -------------------------------------------------------------------------------- /apps/flux.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Flux 3 | 4 | Module uses AppDaemon to dynamically set light color temperatures 5 | based on time of day. Note that this is similar to the homeassistant 6 | component flux switch, but built in a custom way to not have race 7 | conditions within the core (occasionally automations won't trigger 8 | and turning the switch off won't actually do anything... at least in 9 | my experience, that is) 10 | 11 | There are two color-changing segments: 12 | 13 | sunrise --> from sunrise+offset to day+offset 14 | sunset --> from sunset+offset to night+offset 15 | 16 | in between sunrise and sunset, we are at day 17 | in between sunset and sunrise we are at night 18 | 19 | -------------------------- 20 | appdaemon.yaml setup example: 21 | 22 | flux: 23 | module: flux 24 | class: Flux 25 | constrain_input_boolean: input_boolean.flux 26 | light: light.couch_left,light.couch_right,light.corner 27 | 28 | ''' 29 | 30 | import appdaemon.plugins.hass.hassapi as hass 31 | import datetime as dt 32 | import pytz 33 | 34 | DEBUG = False 35 | 36 | 37 | def utc_to_est(datetime_obj): 38 | """Naive timezone conversion because I'm lazy AF.""" 39 | tz_offset = dt.timedelta(hours=-5) 40 | return datetime_obj + tz_offset 41 | 42 | 43 | class Flux(hass.Hass): 44 | 45 | def initialize(self): 46 | # Colors dict contains: 47 | # Color temperature 48 | # Starting offset in minutes 49 | self.colors = { 50 | 'sunrise': {'temp': 3000, 'offset': -45}, 51 | 'day': {'temp': 4700, 'offset': 30}, 52 | 'sunset': {'temp': 3000, 'offset': -45}, 53 | 'night': {'temp': 2400, 'offset': 60} 54 | } 55 | self.offsets = {} 56 | for key, value in self.colors.items(): 57 | self.offsets[key] = dt.timedelta(minutes=value['offset']) 58 | 59 | self.current_time = utc_to_est(dt.datetime.now()).time() 60 | 61 | # Run every 10 minutes 62 | self.run_every(self.update_color, dt.datetime.now(), 600) 63 | 64 | for light in self.split_device_list(self.args['light']): 65 | self.listen_state(self.update_on_change, light) 66 | 67 | def sunrise_tz(self): 68 | return utc_to_est(self.sunrise()) 69 | 70 | def sunset_tz(self): 71 | return utc_to_est(self.sunset()) 72 | 73 | def update_on_change(self, entity, attribute, old, new, kwargs): 74 | if self.get_state(entity) == "on" and old == "off": 75 | self.update_color(None) 76 | 77 | def determine_color_state(self, now): 78 | sunrise = self.sunrise_tz() - dt.timedelta(days=1) 79 | sunset = self.sunset_tz() - dt.timedelta(days=1) 80 | 81 | self.times = { 82 | 'sunrise': sunrise + self.offsets['sunrise'], 83 | 'day': sunrise + self.offsets['day'], 84 | 'sunset': sunset + self.offsets['sunset'], 85 | 'night': sunset + self.offsets['night'] 86 | } 87 | 88 | now_time = now.time() 89 | 90 | if DEBUG: 91 | self.log("now: {}, sunset: {}, night: {}".format(now_time, self.times['sunrise'].time(), self.times['night'].time())) 92 | 93 | if now_time <= self.times['sunrise'].time(): 94 | return 'night' 95 | elif now_time >= self.times['sunrise'].time() and now_time < self.times['day'].time(): 96 | return 'sunrise' 97 | elif now_time >= self.times['day'].time() and now_time < self.times['sunset'].time(): 98 | return 'day' 99 | elif now_time >= self.times['sunset'].time() and now_time < self.times['night'].time(): 100 | return 'sunset' 101 | elif now_time >= self.times['night'].time(): 102 | return 'night' 103 | 104 | # If something errored, just assume we are in night mode 105 | return 'night' 106 | 107 | def calculate_progress(self, now, state): 108 | if state == 'sunrise': 109 | start = self.times['sunrise'] 110 | end = self.times['day'] 111 | elif state == 'sunset': 112 | start = self.times['sunset'] 113 | end = self.times['night'] 114 | else: 115 | return 1 116 | 117 | progress = round((now - start) / (end - start), 2) 118 | 119 | return progress 120 | 121 | def calculate_color(self, state, progress): 122 | if state == 'sunrise': 123 | color_delta = self.colors['day']['temp'] - self.colors['night']['temp'] 124 | new_color = self.colors['night']['temp'] + progress*color_delta 125 | if new_color > self.colors['day']['temp']: 126 | new_color = self.colors['day']['temp'] 127 | elif state == 'sunset': 128 | color_delta = self.colors['day']['temp'] - self.colors['night']['temp'] 129 | new_color = self.colors['day']['temp'] - progress*color_delta 130 | if new_color < self.colors['night']['temp']: 131 | new_color = self.colors['night']['temp'] 132 | elif state == 'day': 133 | new_color = self.colors['day']['temp'] 134 | elif state == 'night': 135 | new_color = self.colors['night']['temp'] 136 | 137 | return new_color 138 | 139 | def update_color(self, kwargs): 140 | 141 | now = utc_to_est(dt.datetime.now()) 142 | color_state = self.determine_color_state(now) 143 | progress = self.calculate_progress(now, color_state) 144 | new_color = self.calculate_color(color_state, progress) 145 | mired = int(1e6 / new_color) 146 | brightness = 254 147 | 148 | if DEBUG: 149 | self.log("Now={}: Sunrise={}, Sunset={}, State={}, Progress={}, Color={}".format( 150 | now.time(), self.sunrise_tz().time(), self.sunset_tz().time(), color_state, progress, new_color)) 151 | 152 | for light in self.split_device_list(self.args["light"]): 153 | if self.get_state(light) == 'on': 154 | self.turn_on(light, color_temp=mired) 155 | -------------------------------------------------------------------------------- /apps/notify.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Notify 3 | 4 | Module uses AppDaemon in order to push notifcations using notify 5 | service to determine if devices are offline (or when they come 6 | back online). 7 | 8 | appdaemon.cfg setup: 9 | 10 | [Notify] 11 | module = notify 12 | class = Notify 13 | notify = 1 14 | device_tracker = device_tracker.baratheon,device_tracker.echo,device_tracker.ecobee,device_tracker.google_home,device_tracker.hue_hub,device_tracker.tablo,device_tracker.winkhub 15 | 16 | ''' 17 | 18 | 19 | import appdaemon.appapi as appapi 20 | import datetime 21 | 22 | class Notify(appapi.AppDaemon): 23 | 24 | def initialize(self): 25 | if "device_tracker" in self.args: 26 | for tracker in self.split_device_list(self.args["device_tracker"]): 27 | self.listen_state(self.notify_change, tracker) 28 | 29 | 30 | def notify_change(self, entity, attribute, old, new, kwargs): 31 | if(new == "not_home" and old == "home"): 32 | self.log("{} is Offline".format(self.friendly_name(entity))) 33 | self.notify("{} is Offline".format(self.friendly_name(entity))) 34 | if(new == "home" and old == "not_home"): 35 | self.log("{} back Online".format(self.friendly_name(entity))) 36 | self.notify("{} back Online".format(self.friendly_name(entity))) 37 | -------------------------------------------------------------------------------- /apps/thermostat.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Thermostat 3 | 4 | AppDaemon module to set thermostat based on presence and weather 5 | conditions. Uses input_number instances in frontend to determine 6 | desired set points for Home, Away, Sleep 7 | -------------------------- 8 | appdaemon.yaml setup example: 9 | 10 | thermostat: 11 | module: thermostat 12 | class: Thermostat 13 | constrain_input_boolean: input_boolean.thermostat_enable 14 | climate: climate.thermostat_name 15 | sensors: sensor.whatever, sensor.another 16 | 17 | ''' 18 | 19 | import appdaemon.plugins.hass.hassapi as hass 20 | import datetime as dt 21 | import pytz 22 | 23 | DEBUG = False 24 | 25 | AC_THRESHOLD = 75 26 | HEAT_THRESHOLD = 56 27 | MAX_DEWPOINT = 60 28 | SLEEP_TIME = [5, 21] 29 | 30 | THERMOSTAT = 'climate.thermostat_73_5c_83' 31 | 32 | def utc_to_est(datetime_obj): 33 | """Naive timezone conversion because I'm lazy AF.""" 34 | tz_offset = dt.timedelta(hours=-5) 35 | return datetime_obj + tz_offset 36 | 37 | 38 | class Thermostat(hass.Hass): 39 | 40 | def initialize(self): 41 | self.ac = { 42 | 'home': float(self.get_state('input_number.ac_home')), 43 | 'away': float(self.get_state('input_number.ac_away')), 44 | 'sleep': float(self.get_state('input_number.ac_sleep')) 45 | } 46 | self.heat = { 47 | 'home': float(self.get_state('input_number.heat_home')), 48 | 'away': float(self.get_state('input_number.heat_away')), 49 | 'sleep': float(self.get_state('input_number.heat_sleep')) 50 | } 51 | 52 | self.current_time = utc_to_est(dt.datetime.now()).time() 53 | 54 | self.run_minutely(self.update_thermostat, self.current_time) 55 | 56 | for value in self.split_device_list(self.args['input_number']): 57 | self.listen_state(self.update_on_change, value) 58 | 59 | def update_on_change(self, entity, attribute, old, new, kwargs): 60 | if DEBUG: 61 | self.log("Updating thermostat on change") 62 | self.get_input_numbers() 63 | self.update_thermostat(None) 64 | 65 | def get_input_numbers(self): 66 | self.ac = { 67 | 'home': float(self.get_state('input_number.ac_home')), 68 | 'away': float(self.get_state('input_number.ac_away')), 69 | 'sleep': float(self.get_state('input_number.ac_sleep')) 70 | } 71 | self.heat = { 72 | 'home': float(self.get_state('input_number.heat_home')), 73 | 'away': float(self.get_state('input_number.heat_away')), 74 | 'sleep': float(self.get_state('input_number.heat_sleep')) 75 | } 76 | return None 77 | 78 | def get_desired_mode(self): 79 | current_temp = float(self.get_state('sensor.dark_sky_temperature')) 80 | current_feel = float(self.get_state('sensor.dark_sky_apparent_temperature')) 81 | current_dewpoint = float(self.get_state('sensor.dark_sky_dew_point')) 82 | if current_temp >= AC_THRESHOLD: 83 | return 'cool' 84 | elif current_dewpoint >= MAX_DEWPOINT and current_feel >= AC_THRESHOLD: 85 | return 'cool' 86 | elif current_temp <= HEAT_THRESHOLD: 87 | return 'heat' 88 | return 'off' 89 | 90 | def get_state_key(self): 91 | is_home = (self.get_state('sensor.occupancy') == 'home') 92 | guest = (self.get_state('input_boolean.guest_mode') == 'on') 93 | on_the_way_home = (self.get_state('input_boolean.on_the_way_home') == 'on') 94 | now = utc_to_est(dt.datetime.now()) 95 | if now.hour <= SLEEP_TIME[0] or now.hour >= SLEEP_TIME[1]: 96 | return 'sleep' 97 | elif is_home or guest or on_the_way_home: 98 | return 'home' 99 | return 'away' 100 | 101 | def get_target_temp(self, state_key, mode): 102 | if mode == 'cool': 103 | return self.ac[state_key] 104 | elif mode == 'heat': 105 | return self.heat[state_key] 106 | return None 107 | 108 | def set_temperature(self, temp, mode): 109 | if mode == 'off': 110 | return self.call_service('climate/turn_off', entity_id=THERMOSTAT) 111 | 112 | return self.call_service('climate/set_temperature', entity_id=THERMOSTAT, temperature=temp, hvac_mode=mode) 113 | 114 | def set_mode(self, mode='off', **kwargs): 115 | if mode == 'off': 116 | return self.call_service('climate/turn_off', entity_id=THERMOSTAT) 117 | 118 | return self.call_service('climate/set_hvac_mode', entity_id=THERMOSTAT, hvac_mode=mode) 119 | 120 | def update_thermostat(self, time, **kwargs): 121 | self.get_input_numbers() 122 | mode = self.get_desired_mode() 123 | state_key = self.get_state_key() 124 | target_temp = self.get_target_temp(state_key, mode) 125 | 126 | current_mode = self.get_state(THERMOSTAT) 127 | current_temp = self.get_state(THERMOSTAT, attribute='temperature') 128 | if DEBUG: 129 | self.log("Current Mode={}, Mode={}, State={}, Target={}, Current Temp={}".format(current_mode, mode, state_key, target_temp, current_temp)) 130 | 131 | if current_mode != mode or target_temp != current_temp: 132 | self.set_mode(mode=mode) 133 | if target_temp is not None: 134 | self.set_temperature(target_temp, mode) 135 | if DEBUG: 136 | self.log("Called thermostat service.") 137 | 138 | -------------------------------------------------------------------------------- /automation/cloudy.yaml: -------------------------------------------------------------------------------- 1 | # Turn on inside light if it's cloudy midday 2 | alias: Lights Cloudy 3 | trigger: 4 | - platform: state 5 | entity_id: sensor.weather_condition 6 | to: "lightning" 7 | - platform: state 8 | entity_id: sensor.weather_condition 9 | to: "rainy" 10 | - platform: state 11 | entity_id: sensor.weather_condition 12 | to: "cloudy" 13 | - platform: state 14 | entity_id: sensor.weather_condition 15 | to: "fog" 16 | condition: 17 | condition: and 18 | conditions: 19 | - condition: time 20 | after: '10:00:00' 21 | before: '18:00:00' 22 | weekday: 23 | - tue 24 | - thu 25 | - sat 26 | - sun 27 | - condition: state 28 | entity_id: sun.sun 29 | state: 'above_horizon' 30 | action: 31 | - service: light.turn_on 32 | entity_id: 33 | - light.family_room_couch_left 34 | - light.family_room_couch_right 35 | -------------------------------------------------------------------------------- /automation/daytime.yaml: -------------------------------------------------------------------------------- 1 | alias: Workday Routine 2 | trigger: 3 | - platform: time 4 | at: '10:30:00' 5 | condition: 6 | condition: and 7 | conditions: 8 | - condition: time 9 | weekday: 10 | - mon 11 | - tue 12 | - wed 13 | - thu 14 | - fri 15 | - sat 16 | - sun 17 | action: 18 | - service: light.turn_off 19 | entity_id: 20 | - light.living_room_couch 21 | - light.family_room_couch_left 22 | - light.family_room_couch_right 23 | - light.kitchen_island 24 | - light.kitchen_table 25 | -------------------------------------------------------------------------------- /automation/daytime_bedroom.yaml: -------------------------------------------------------------------------------- 1 | alias: Bedroom Daytime 2 | trigger: 3 | - platform: time 4 | at: '09:30:00' 5 | condition: 6 | - condition: time 7 | weekday: 8 | - mon 9 | - tue 10 | - wed 11 | - thu 12 | - fri 13 | action: 14 | - service: light.turn_off 15 | entity_id: 16 | - light.master_bedroom_door 17 | - light.master_bedroom_window 18 | -------------------------------------------------------------------------------- /automation/daytime_clear.yaml: -------------------------------------------------------------------------------- 1 | # Turn on inside lights off if it clears up during the day 2 | alias: Lights Clear 3 | trigger: 4 | - platform: state 5 | entity_id: sensor.weather_condition 6 | to: "sunny" 7 | for: "00:15:00" 8 | - platform: state 9 | entity_id: sensor.weather_condition 10 | to: "partly-cloudy" 11 | for: "00:15:00" 12 | condition: 13 | condition: and 14 | conditions: 15 | - condition: time 16 | after: '10:00:00' 17 | before: '18:00:00' 18 | - condition: state 19 | entity_id: sun.sun 20 | state: 'above_horizon' 21 | action: 22 | - service: light.turn_off 23 | entity_id: 24 | - light.family_room_couch_left 25 | - light.family_room_couch_right 26 | - light.living_room_couch 27 | - light.kitchen_island 28 | - light.kitchen_table 29 | -------------------------------------------------------------------------------- /automation/evening.yaml: -------------------------------------------------------------------------------- 1 | alias: Evening Routine 2 | trigger: 3 | - platform: sun 4 | event: sunset 5 | offset: '-01:30:00' 6 | action: 7 | - service: light.turn_on 8 | entity_id: 9 | - light.living_room_couch 10 | - light.living_room_piano 11 | - light.family_room_couch_left 12 | - light.family_room_couch_right 13 | - light.kitchen_lights 14 | - light.foyer 15 | 16 | -------------------------------------------------------------------------------- /automation/lights_inside_off.yaml: -------------------------------------------------------------------------------- 1 | # Turn inside lights off around midnight (before exterior) 2 | 3 | alias: Lights Inside Off 4 | trigger: 5 | - platform: time 6 | at: '00:12:09' 7 | action: 8 | - service: light.turn_off 9 | entity_id: light.interior_lights 10 | -------------------------------------------------------------------------------- /automation/lights_outside_off.yaml: -------------------------------------------------------------------------------- 1 | # Turn on outside lights off at 12:40 am 2 | 3 | alias: Lights Outdoor Off 4 | trigger: 5 | - platform: time 6 | at: '00:40:07' 7 | action: 8 | - service: light.turn_off 9 | entity_id: light.porch 10 | - service: switch.turn_off 11 | entity_id: switch.driveway 12 | -------------------------------------------------------------------------------- /automation/night.yaml: -------------------------------------------------------------------------------- 1 | alias: Night Routine 2 | trigger: 3 | - platform: time 4 | at: '21:03:13' 5 | action: 6 | - service: light.turn_off 7 | entity_id: 8 | - light.kitchen_island 9 | - light.kitchen_table 10 | - light.foyer 11 | -------------------------------------------------------------------------------- /automation/notify_leak_detected.yaml: -------------------------------------------------------------------------------- 1 | alias: Notify on Leak Detected 2 | trigger: 3 | - platform: state 4 | entity_id: binary_sensor.leak_sump 5 | from: 'off' 6 | to: 'on' 7 | action: 8 | - service: notify.notify 9 | data_template: 10 | message: > 11 | ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} Leak Detected with {{trigger.to_state.attributes.friendly_name}} 12 | -------------------------------------------------------------------------------- /automation/notify_on_failed_login.yaml: -------------------------------------------------------------------------------- 1 | alias: Notify on Failed Login 2 | trigger: 3 | - platform: state 4 | entity_id: sensor.fail2ban_nginx_http_auth 5 | - platform: state 6 | entity_id: sensor.fail2ban_hass_iptables 7 | - platform: state 8 | entity_id: sensor.fail2ban_organizr_auth 9 | condition: 10 | condition: or 11 | conditions: 12 | - condition: template 13 | value_template: '{{ states.sensor.fail2ban_hass_iptables.state != "None" }}' 14 | - condition: template 15 | value_template: '{{ states.sensor.fail2ban_organizr_auth.state != "None" }}' 16 | - condition: template 17 | value_template: '{{ states.sensor.fail2ban_nginx_http_auth.state != "None" }}' 18 | action: 19 | - service: script.notify_kevin_engine 20 | data: 21 | call_failed_login: 1 22 | -------------------------------------------------------------------------------- /automation/notify_on_fire_co.yaml: -------------------------------------------------------------------------------- 1 | alias: Notify on Fire/CO 2 | trigger: 3 | - platform: state 4 | entity_id: sensor.smoke_alarm_foyer 5 | to: "Fire" 6 | - platform: state 7 | entity_id: sensor.smoke_alarm_foyer 8 | to: "CO" 9 | - platform: state 10 | entity_id: sensor.smoke_alarm_family_room 11 | to: "Fire" 12 | - platform: state 13 | entity_id: sensor.smoke_alarm_family_room 14 | to: "CO" 15 | - platform: state 16 | entity_id: sensor.smoke_alarm_office 17 | to: "Fire" 18 | - platform: state 19 | entity_id: sensor.smoke_alarm_office 20 | to: "CO" 21 | - platform: state 22 | entity_id: sensor.smoke_alarm_basement 23 | to: "Fire" 24 | - platform: state 25 | entity_id: sensor.smoke_alarm_basement 26 | to: "CO" 27 | action: 28 | - service: notify.notify 29 | data_template: 30 | message: > 31 | ALERT! {{ now().strftime("%h %d, %Y at %H:%M:S") }} {{trigger.to_state.state}} detected by {{trigger.to_state.attributes.friendly_name}} 32 | -------------------------------------------------------------------------------- /automation/notify_on_restart.yaml: -------------------------------------------------------------------------------- 1 | alias: Notify on Restart 2 | trigger: 3 | - platform: homeassistant 4 | event: start 5 | action: 6 | - service: script.notify_kevin_engine 7 | data: 8 | call_on_restart: 1 9 | -------------------------------------------------------------------------------- /automation/sunset.yaml: -------------------------------------------------------------------------------- 1 | # Turn on outside lights 15 minutes after sunset 2 | 3 | alias: Lights Sunset 4 | trigger: 5 | - platform: sun 6 | event: sunset 7 | offset: '+00:15:00' 8 | action: 9 | - service: light.turn_on 10 | entity_id: light.porch 11 | - service: switch.turn_on 12 | entity_id: switch.driveway 13 | -------------------------------------------------------------------------------- /automation/wakeup.yaml: -------------------------------------------------------------------------------- 1 | alias: Wakeup Routine 2 | trigger: 3 | - platform: time 4 | at: '07:00:30' 5 | action: 6 | - service: light.turn_on 7 | entity_id: 8 | - light.family_room_couch_left 9 | - light.family_room_couch_right 10 | -------------------------------------------------------------------------------- /automation/wakeup_weekends.yaml: -------------------------------------------------------------------------------- 1 | alias: Wakeup Routine Weekends 2 | trigger: 3 | - platform: time 4 | at: '07:00:30' 5 | condition: 6 | - condition: time 7 | weekday: 8 | - sat 9 | - sun 10 | action: 11 | - service: light.turn_on 12 | entity_id: 13 | - light.living_room_couch 14 | -------------------------------------------------------------------------------- /automations.yaml: -------------------------------------------------------------------------------- 1 | #---------------- SMASH.PY ------------------ 2 | # Generated: 2023-Dec-04 11:23:52 3 | #-------------------------------------------- 4 | 5 | #--- automation/notify_on_failed_login.yaml --- 6 | - id: notify_on_failed_login 7 | alias: Notify on Failed Login 8 | trigger: 9 | - platform: state 10 | entity_id: sensor.fail2ban_nginx_http_auth 11 | - platform: state 12 | entity_id: sensor.fail2ban_hass_iptables 13 | - platform: state 14 | entity_id: sensor.fail2ban_organizr_auth 15 | condition: 16 | condition: or 17 | conditions: 18 | - condition: template 19 | value_template: '{{ states.sensor.fail2ban_hass_iptables.state != "None" }}' 20 | - condition: template 21 | value_template: '{{ states.sensor.fail2ban_organizr_auth.state != "None" }}' 22 | - condition: template 23 | value_template: '{{ states.sensor.fail2ban_nginx_http_auth.state != "None" }}' 24 | action: 25 | - service: script.notify_kevin_engine 26 | data: 27 | call_failed_login: 1 28 | 29 | #--- automation/notify_leak_detected.yaml --- 30 | - id: notify_on_leak_detected 31 | alias: Notify on Leak Detected 32 | trigger: 33 | - platform: state 34 | entity_id: binary_sensor.leak_sump 35 | from: 'off' 36 | to: 'on' 37 | action: 38 | - service: notify.notify 39 | data_template: 40 | message: > 41 | ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} Leak Detected with {{trigger.to_state.attributes.friendly_name}} 42 | 43 | #--- automation/lights_inside_off.yaml --- 44 | # Turn inside lights off around midnight (before exterior) 45 | 46 | - id: lights_inside_off 47 | alias: Lights Inside Off 48 | trigger: 49 | - platform: time 50 | at: '00:12:09' 51 | action: 52 | - service: light.turn_off 53 | entity_id: light.interior_lights 54 | 55 | #--- automation/notify_on_restart.yaml --- 56 | - id: notify_on_restart 57 | alias: Notify on Restart 58 | trigger: 59 | - platform: homeassistant 60 | event: start 61 | action: 62 | - service: script.notify_kevin_engine 63 | data: 64 | call_on_restart: 1 65 | 66 | #--- automation/lights_outside_off.yaml --- 67 | # Turn on outside lights off at 12:40 am 68 | 69 | - id: lights_outdoor_off 70 | alias: Lights Outdoor Off 71 | trigger: 72 | - platform: time 73 | at: '00:40:07' 74 | action: 75 | - service: light.turn_off 76 | entity_id: light.porch 77 | - service: switch.turn_off 78 | entity_id: switch.driveway 79 | 80 | #--- automation/notify_on_fire_co.yaml --- 81 | - id: notify_on_fire_co 82 | alias: Notify on Fire/CO 83 | trigger: 84 | - platform: state 85 | entity_id: sensor.smoke_alarm_foyer 86 | to: "Fire" 87 | - platform: state 88 | entity_id: sensor.smoke_alarm_foyer 89 | to: "CO" 90 | - platform: state 91 | entity_id: sensor.smoke_alarm_family_room 92 | to: "Fire" 93 | - platform: state 94 | entity_id: sensor.smoke_alarm_family_room 95 | to: "CO" 96 | - platform: state 97 | entity_id: sensor.smoke_alarm_office 98 | to: "Fire" 99 | - platform: state 100 | entity_id: sensor.smoke_alarm_office 101 | to: "CO" 102 | - platform: state 103 | entity_id: sensor.smoke_alarm_basement 104 | to: "Fire" 105 | - platform: state 106 | entity_id: sensor.smoke_alarm_basement 107 | to: "CO" 108 | action: 109 | - service: notify.notify 110 | data_template: 111 | message: > 112 | ALERT! {{ now().strftime("%h %d, %Y at %H:%M:S") }} {{trigger.to_state.state}} detected by {{trigger.to_state.attributes.friendly_name}} 113 | 114 | #--- automation/daytime_clear.yaml --- 115 | # Turn on inside lights off if it clears up during the day 116 | - id: lights_clear 117 | alias: Lights Clear 118 | trigger: 119 | - platform: state 120 | entity_id: sensor.weather_condition 121 | to: "sunny" 122 | for: "00:15:00" 123 | - platform: state 124 | entity_id: sensor.weather_condition 125 | to: "partly-cloudy" 126 | for: "00:15:00" 127 | condition: 128 | condition: and 129 | conditions: 130 | - condition: time 131 | after: '10:00:00' 132 | before: '18:00:00' 133 | - condition: state 134 | entity_id: sun.sun 135 | state: 'above_horizon' 136 | action: 137 | - service: light.turn_off 138 | entity_id: 139 | - light.family_room_couch_left 140 | - light.family_room_couch_right 141 | - light.living_room_couch 142 | - light.kitchen_island 143 | - light.kitchen_table 144 | 145 | #--- automation/daytime.yaml --- 146 | - id: workday_routine 147 | alias: Workday Routine 148 | trigger: 149 | - platform: time 150 | at: '10:30:00' 151 | condition: 152 | condition: and 153 | conditions: 154 | - condition: time 155 | weekday: 156 | - mon 157 | - tue 158 | - wed 159 | - thu 160 | - fri 161 | - sat 162 | - sun 163 | action: 164 | - service: light.turn_off 165 | entity_id: 166 | - light.living_room_couch 167 | - light.family_room_couch_left 168 | - light.family_room_couch_right 169 | - light.kitchen_island 170 | - light.kitchen_table 171 | 172 | #--- automation/cloudy.yaml --- 173 | # Turn on inside light if it's cloudy midday 174 | - id: lights_cloudy 175 | alias: Lights Cloudy 176 | trigger: 177 | - platform: state 178 | entity_id: sensor.weather_condition 179 | to: "lightning" 180 | - platform: state 181 | entity_id: sensor.weather_condition 182 | to: "rainy" 183 | - platform: state 184 | entity_id: sensor.weather_condition 185 | to: "cloudy" 186 | - platform: state 187 | entity_id: sensor.weather_condition 188 | to: "fog" 189 | condition: 190 | condition: and 191 | conditions: 192 | - condition: time 193 | after: '10:00:00' 194 | before: '18:00:00' 195 | weekday: 196 | - tue 197 | - thu 198 | - sat 199 | - sun 200 | - condition: state 201 | entity_id: sun.sun 202 | state: 'above_horizon' 203 | action: 204 | - service: light.turn_on 205 | entity_id: 206 | - light.family_room_couch_left 207 | - light.family_room_couch_right 208 | 209 | #--- automation/sunset.yaml --- 210 | # Turn on outside lights 15 minutes after sunset 211 | 212 | - id: lights_sunset 213 | alias: Lights Sunset 214 | trigger: 215 | - platform: sun 216 | event: sunset 217 | offset: '+00:15:00' 218 | action: 219 | - service: light.turn_on 220 | entity_id: light.porch 221 | - service: switch.turn_on 222 | entity_id: switch.driveway 223 | 224 | #--- automation/wakeup.yaml --- 225 | - id: wakeup_routine 226 | alias: Wakeup Routine 227 | trigger: 228 | - platform: time 229 | at: '07:00:30' 230 | action: 231 | - service: light.turn_on 232 | entity_id: 233 | - light.family_room_couch_left 234 | - light.family_room_couch_right 235 | 236 | #--- automation/daytime_bedroom.yaml --- 237 | - id: bedroom_daytime 238 | alias: Bedroom Daytime 239 | trigger: 240 | - platform: time 241 | at: '09:30:00' 242 | condition: 243 | - condition: time 244 | weekday: 245 | - mon 246 | - tue 247 | - wed 248 | - thu 249 | - fri 250 | action: 251 | - service: light.turn_off 252 | entity_id: 253 | - light.master_bedroom_door 254 | - light.master_bedroom_window 255 | 256 | #--- automation/evening.yaml --- 257 | - id: evening_routine 258 | alias: Evening Routine 259 | trigger: 260 | - platform: sun 261 | event: sunset 262 | offset: '-01:30:00' 263 | action: 264 | - service: light.turn_on 265 | entity_id: 266 | - light.living_room_couch 267 | - light.living_room_piano 268 | - light.family_room_couch_left 269 | - light.family_room_couch_right 270 | - light.kitchen_lights 271 | - light.foyer 272 | 273 | 274 | #--- automation/night.yaml --- 275 | - id: night_routine 276 | alias: Night Routine 277 | trigger: 278 | - platform: time 279 | at: '21:03:13' 280 | action: 281 | - service: light.turn_off 282 | entity_id: 283 | - light.kitchen_island 284 | - light.kitchen_table 285 | - light.foyer 286 | 287 | #--- automation/wakeup_weekends.yaml --- 288 | - id: wakeup_routine_weekends 289 | alias: Wakeup Routine Weekends 290 | trigger: 291 | - platform: time 292 | at: '07:00:30' 293 | condition: 294 | - condition: time 295 | weekday: 296 | - sat 297 | - sun 298 | action: 299 | - service: light.turn_on 300 | entity_id: 301 | - light.living_room_couch 302 | -------------------------------------------------------------------------------- /bin/get_pihole_version.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | pihole -v 4 | -------------------------------------------------------------------------------- /bin/smash.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | python3 smash.py --source automation/ --dest automations.yaml --ext yaml --use-ids --force-overwrite 3 | python3 smash.py --source scripts/ --dest scripts.yaml --ext yaml --force-overwrite 4 | python3 smash.py --source customize/ --dest customize.yaml --ext yaml --force-overwrite 5 | 6 | -------------------------------------------------------------------------------- /blueprints/automation/homeassistant/motion_light.yaml: -------------------------------------------------------------------------------- 1 | blueprint: 2 | name: Motion-activated Light 3 | description: Turn on a light when motion is detected. 4 | domain: automation 5 | source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/motion_light.yaml 6 | input: 7 | motion_entity: 8 | name: Motion Sensor 9 | selector: 10 | entity: 11 | domain: binary_sensor 12 | device_class: motion 13 | light_target: 14 | name: Light 15 | selector: 16 | target: 17 | entity: 18 | domain: light 19 | no_motion_wait: 20 | name: Wait time 21 | description: Time to leave the light on after last motion is detected. 22 | default: 120 23 | selector: 24 | number: 25 | min: 0 26 | max: 3600 27 | unit_of_measurement: seconds 28 | 29 | # If motion is detected within the delay, 30 | # we restart the script. 31 | mode: restart 32 | max_exceeded: silent 33 | 34 | trigger: 35 | platform: state 36 | entity_id: !input motion_entity 37 | from: "off" 38 | to: "on" 39 | 40 | action: 41 | - service: light.turn_on 42 | target: !input light_target 43 | - wait_for_trigger: 44 | platform: state 45 | entity_id: !input motion_entity 46 | from: "on" 47 | to: "off" 48 | - delay: !input no_motion_wait 49 | - service: light.turn_off 50 | target: !input light_target 51 | -------------------------------------------------------------------------------- /blueprints/automation/homeassistant/notify_leaving_zone.yaml: -------------------------------------------------------------------------------- 1 | blueprint: 2 | name: Zone Notification 3 | description: Send a notification to a device when a person leaves a specific zone. 4 | domain: automation 5 | source_url: https://github.com/home-assistant/core/blob/dev/homeassistant/components/automation/blueprints/notify_leaving_zone.yaml 6 | input: 7 | person_entity: 8 | name: Person 9 | selector: 10 | entity: 11 | domain: person 12 | zone_entity: 13 | name: Zone 14 | selector: 15 | entity: 16 | domain: zone 17 | notify_device: 18 | name: Device to notify 19 | description: Device needs to run the official Home Assistant app to receive notifications. 20 | selector: 21 | device: 22 | integration: mobile_app 23 | 24 | trigger: 25 | platform: state 26 | entity_id: !input person_entity 27 | 28 | variables: 29 | zone_entity: !input zone_entity 30 | # This is the state of the person when it's in this zone. 31 | zone_state: "{{ states[zone_entity].name }}" 32 | person_entity: !input person_entity 33 | person_name: "{{ states[person_entity].name }}" 34 | 35 | condition: 36 | condition: template 37 | value_template: "{{ trigger.from_state.state == zone_state and trigger.to_state.state != zone_state }}" 38 | 39 | action: 40 | domain: mobile_app 41 | type: notify 42 | device_id: !input notify_device 43 | message: "{{ person_name }} has left {{ zone_state }}" 44 | -------------------------------------------------------------------------------- /blueprints/script/homeassistant/confirmable_notification.yaml: -------------------------------------------------------------------------------- 1 | blueprint: 2 | name: Confirmable Notification 3 | description: >- 4 | A script that sends an actionable notification with a confirmation before 5 | running the specified action. 6 | domain: script 7 | source_url: https://github.com/home-assistant/core/blob/master/homeassistant/components/script/blueprints/confirmable_notification.yaml 8 | input: 9 | notify_device: 10 | name: Device to notify 11 | description: Device needs to run the official Home Assistant app to receive notifications. 12 | selector: 13 | device: 14 | integration: mobile_app 15 | title: 16 | name: "Title" 17 | description: "The title of the button shown in the notification." 18 | default: "" 19 | selector: 20 | text: 21 | message: 22 | name: "Message" 23 | description: "The message body" 24 | selector: 25 | text: 26 | confirm_text: 27 | name: "Confirmation Text" 28 | description: "Text to show on the confirmation button" 29 | default: "Confirm" 30 | selector: 31 | text: 32 | confirm_action: 33 | name: "Confirmation Action" 34 | description: "Action to run when notification is confirmed" 35 | default: [] 36 | selector: 37 | action: 38 | dismiss_text: 39 | name: "Dismiss Text" 40 | description: "Text to show on the dismiss button" 41 | default: "Dismiss" 42 | selector: 43 | text: 44 | dismiss_action: 45 | name: "Dismiss Action" 46 | description: "Action to run when notification is dismissed" 47 | default: [] 48 | selector: 49 | action: 50 | 51 | mode: restart 52 | 53 | sequence: 54 | - alias: "Send notification" 55 | domain: mobile_app 56 | type: notify 57 | device_id: !input notify_device 58 | title: !input title 59 | message: !input message 60 | data: 61 | actions: 62 | - action: "CONFIRM" 63 | title: !input confirm_text 64 | - action: "DISMISS" 65 | title: !input dismiss_text 66 | - alias: "Awaiting response" 67 | wait_for_trigger: 68 | - platform: event 69 | event_type: mobile_app_notification_action 70 | - choose: 71 | - conditions: "{{ wait.trigger.event.data.action == 'CONFIRM' }}" 72 | sequence: !input confirm_action 73 | - conditions: "{{ wait.trigger.event.data.action == 'DISMISS' }}" 74 | sequence: !input dismiss_action 75 | -------------------------------------------------------------------------------- /configuration.yaml: -------------------------------------------------------------------------------- 1 | homeassistant: 2 | name: Home 3 | latitude: !secret latitude 4 | longitude: !secret longitude 5 | elevation: 154 6 | temperature_unit: F 7 | time_zone: America/New_York 8 | customize: !include customize.yaml 9 | unit_system: imperial 10 | allowlist_external_dirs: 11 | - /images 12 | 13 | http: 14 | use_x_forwarded_for: True 15 | trusted_proxies: 16 | - 172.0.0.0/8 17 | # Includes 18 | automation: !include automations.yaml 19 | binary_sensor: !include includes/binary_sensor.yaml 20 | camera: !include includes/cameras.yaml 21 | command_line: !include includes/command_line.yaml 22 | fastdotcom: !include includes/fastdotcom.yaml 23 | google_assistant: !include includes/google_assistant.yaml 24 | input_boolean: !include includes/input_boolean.yaml 25 | input_number: !include includes/input_number.yaml 26 | influxdb: !include includes/influxdb.yaml 27 | light: !include includes/light.yaml 28 | logger: !include includes/logger.yaml 29 | notify: !include includes/notify.yaml 30 | recorder: !include includes/recorder.yaml 31 | scene: !include_dir_list scenes 32 | script: !include scripts.yaml 33 | sensor: !include_dir_merge_list sensors 34 | shell_command: !include includes/shell_command.yaml 35 | system_health: 36 | 37 | # Enables 38 | frontend: 39 | config: 40 | logbook: 41 | sun: 42 | history: 43 | -------------------------------------------------------------------------------- /customize.yaml: -------------------------------------------------------------------------------- 1 | #---------------- SMASH.PY ------------------ 2 | # Generated: 2023-Dec-04 11:23:53 3 | #-------------------------------------------- 4 | 5 | #--- customize/customize_scenes.yaml --- 6 | ################## 7 | # Scenes 8 | ################## 9 | scene.christmas: 10 | icon: mdi:gift 11 | emulated_hue_hidden: false 12 | emulated_hue_name: "Christmas" 13 | 14 | scene.movie_mode_living_room: 15 | icon: mdi:movie 16 | 17 | scene.movie_mode_family_room: 18 | icon: mdi:movie 19 | 20 | scene.daylight: 21 | icon: mdi:weather-sunny 22 | emulated_hue_hidden: false 23 | emulated_hue_name: "Day Time" 24 | 25 | scene.night: 26 | icon: mdi:weather-night 27 | emulated_hue_hidden: false 28 | emulated_hue_name: "Night Time" 29 | 30 | scene.sabres: 31 | icon: mdi:sword 32 | emulated_hue_hidden: false 33 | emulated_hue_name: "Sabres" 34 | 35 | scene.on_the_way_home: 36 | icon: mdi:map-marker 37 | emulated_hue_hidden: false 38 | 39 | scene.orange: 40 | icon: mdi:palette 41 | emulated_hue_hidden: false 42 | emulated_hue_name: "Orange" 43 | 44 | scene.yellow: 45 | icon: mdi:palette 46 | emulated_hue_hidden: false 47 | emulated_hue_name: "Yellow" 48 | 49 | scene.green: 50 | icon: mdi:palette 51 | emulated_hue_hidden: false 52 | emulated_hue_name: "Green" 53 | 54 | scene.cyan: 55 | icon: mdi:palette 56 | emulated_hue_hidden: false 57 | emulated_hue_name: "Ice" 58 | 59 | scene.blue: 60 | icon: mdi:palette 61 | emulated_hue_hidden: false 62 | emulated_hue_name: "Blue" 63 | 64 | scene.purple: 65 | icon: mdi:palette 66 | emulated_hue_hidden: false 67 | emulated_hue_name: "Purple" 68 | 69 | scene.pink: 70 | icon: mdi:palette 71 | emulated_hue_hidden: false 72 | emulated_hue_name: "Pink" 73 | 74 | 75 | #--- customize/customize_switches.yaml --- 76 | switch.outdoor_1_switch: 77 | friendly_name: Outside Porch Outlet 78 | icon: mdi:power-plug 79 | 80 | switch.outdoor_2_switch: 81 | friendly_name: Outside Driveway Outlet 82 | icon: mdi:power-plug 83 | 84 | switch.power_mon_switch_3_0: 85 | friendly_name: Washing Machine Power 86 | icon: mdi:power 87 | 88 | switch.driveway: 89 | friendly_name: Driveway 90 | icon: mdi:car 91 | emulated_hue_hidden: false 92 | emulated_hue_name: "Driveway" 93 | 94 | 95 | #--- customize/customize_input_boolean.yaml --- 96 | ################## 97 | # Input Boolean 98 | ################## 99 | input_boolean.flux_living_room: 100 | icon: mdi:theme-light-dark 101 | 102 | input_boolean.flux_family_room: 103 | icon: mdi:theme-light-dark 104 | 105 | input_boolean.flux_kitchen: 106 | icon: mdi:theme-light-dark 107 | 108 | input_boolean.flux_master_bedroom: 109 | icon: mdi:theme-light-dark 110 | 111 | input_boolean.flux_nursery: 112 | icon: mdi:theme-light-dark 113 | 114 | input_boolean.flux_office: 115 | icon: mdi:theme-light-dark 116 | 117 | input_boolean.christmas_lights: 118 | icon: mdi:gift 119 | 120 | input_boolean.on_the_way_home: 121 | icon: mdi:map-marker 122 | 123 | input_boolean.guest_mode: 124 | icon: mdi:account 125 | emulated_hue_hidden: false 126 | emulated_hue_name: "Guest Mode" 127 | 128 | input_boolean.thermostat_enable: 129 | icon: mdi:thermostat 130 | emulated_hue_hidden: false 131 | emulated_hue_name: "Thermostat" 132 | 133 | input_boolean.warmer_night_mode: 134 | icon: mdi:fire 135 | 136 | #--- customize/customize_weather.yaml --- 137 | #----------------------------------# 138 | # Weather Customization # 139 | #----------------------------------# 140 | sensor.weather_temperature: 141 | friendly_name: Outside Temperature 142 | icon: mdi:thermometer 143 | 144 | sensor.yr_weather_dewpoint_temperature: 145 | friendly_name: Dew Point 146 | icon: mdi:oil-temperature 147 | 148 | sensor.weather_humidity: 149 | friendly_name: Humidity 150 | icon: mdi:water-percent 151 | 152 | sensor.weather_precipitation: 153 | friendly_name: Precipitation 154 | icon: mdi:weather-pouring 155 | 156 | sensor.weather_pressure: 157 | friendly_name: Pressure 158 | icon: mdi:chart-bar 159 | 160 | sensor.yr_weather_fog: 161 | friendly_name: Fog 162 | icon: mdi:weather-fog 163 | 164 | sensor.weather_wind_speed: 165 | friendly_name: Wind Speed 166 | icon: mdi:weather-windy 167 | 168 | sensor.weather_cloud_coverage: 169 | friendly_name: Clouds 170 | icon: mdi:weather-cloudy 171 | 172 | sensor.weather_rain: 173 | friendly_name: Rain 174 | icon: mdi:weather-pouring 175 | 176 | sensor.weather_snow: 177 | friendly_name: Snow 178 | icon: mdi:weather-snowy 179 | 180 | sensor.yr_weather_cloudiness: 181 | friendly_name: Cloudiness 182 | icon: mdi:weather-cloudy 183 | 184 | sensor.weather_condition: 185 | friendly_name: Summary 186 | icon: mdi:clipboard-list-outline 187 | 188 | sensor.weather_wind_bearing: 189 | friendly_name: Wind Bearing 190 | icon: mdi:weather-windy 191 | 192 | sensor.weather_weather_code: 193 | friendly_name: Weather Code 194 | icon: mdi:code-array 195 | 196 | #--- customize/customize_media.yaml --- 197 | ################## 198 | # Media Players 199 | ################## 200 | 201 | #--- customize/customize_presence.yaml --- 202 | ################## 203 | # Entities 204 | ################## 205 | device_tracker.kevin_gps: 206 | icon: mdi:crosshairs-gps 207 | 208 | device_tracker.allegra_gps: 209 | icon: mdi:crosshairs-gps 210 | 211 | 212 | #--- customize/customize_scripts.yaml --- 213 | script.thermostat_control: 214 | icon: mdi:air-conditioner 215 | emulated_hue_hidden: false 216 | emulated_hue_name: "Thermostat" 217 | 218 | script.github_pull: 219 | icon: mdi:github-circle 220 | 221 | script.hass_upgrade: 222 | icon: mdi:home-assistant 223 | 224 | script.blink_trigger_camera: 225 | icon: mdi:camera 226 | can_cancel: false 227 | 228 | script.ssl_renew_certificate: 229 | icon: mdi:lock 230 | 231 | script.flux: 232 | icon: mdi:theme-light-dark 233 | emulated_hue_hidden: false 234 | emulated_hue_name: "Flux" 235 | 236 | script.wake_computer: 237 | icon: mdi:windows 238 | emulated_hue_hidden: false 239 | emulated_hue_name: "Desktop" 240 | 241 | script.upgrade_pihole: 242 | icon: mdi:arrow-up-bold-circle-outline 243 | friendly_name: "Upgrade Pihole" 244 | 245 | #--- customize/customize_lights.yaml --- 246 | ################## 247 | # Lights 248 | ################## 249 | light.family_room_lights: 250 | icon: mdi:sofa 251 | 252 | light.office_lights: 253 | icon: mdi:desktop-tower 254 | 255 | light.master_bedroom_lights: 256 | icon: mdi:bed 257 | 258 | light.living_room_couch: 259 | icon: mdi:sofa 260 | 261 | light.kitchen_lights: 262 | icon: mdi:food-variant 263 | 264 | light.interior_lights: 265 | icon: mdi:home 266 | 267 | ligh.porch: 268 | icon: mdi:gate 269 | 270 | #--- customize/customize_climate.yaml --- 271 | ################## 272 | # Thermostat 273 | ################## 274 | input_number.ac_setpoint: 275 | icon: mdi:air-conditioner 276 | 277 | input_number.heat_setpoint: 278 | icon: mdi:fire 279 | 280 | input_number.ac_on: 281 | icon: mdi:fan 282 | 283 | input_number.ac_off: 284 | icon: mdi:fan-off 285 | 286 | input_number.heat_on: 287 | icon: mdi:radiator 288 | 289 | input_number.heat_off: 290 | icon: mdi:radiator-off 291 | 292 | input_number.heat_emergency_delta: 293 | icon: mdi:alert 294 | 295 | #--- customize/customize_misc_sensors.yaml --- 296 | ################## 297 | # Sensors 298 | ################## 299 | sensor.speedtest_download: 300 | friendly_name: Download (Speedtest) 301 | icon: mdi:download 302 | 303 | sensor.speedtest_upload: 304 | friendly_name: Upload 305 | icon: mdi:upload 306 | 307 | sensor.speedtest_ping: 308 | friendly_name: Ping 309 | icon: mdi:message-alert 310 | 311 | sensor.fastcom_download: 312 | friendly_name: Download (Fast.com) 313 | icon: mdi:download 314 | 315 | sensor.ssl_cert_expiry: 316 | friendly_name: SSL Cert Expiry 317 | icon: mdi:lock 318 | 319 | #------------------------------- 320 | # Google Wifi 321 | #------------------------------- 322 | sensor.wifi_status: 323 | friendly_name: Network Status 324 | icon: mdi:google 325 | 326 | sensor.wifi_current_version: 327 | friendly_name: Router Firmware Version 328 | icon: mdi:checkbox-marked-circle-outline 329 | 330 | sensor.wifi_uptime: 331 | friendly_name: Network Uptime 332 | icon: mdi:update 333 | 334 | #------------------------------- 335 | # Pi-hole 336 | #------------------------------- 337 | sensor.pihole_dns_queries_today: 338 | friendly_name: DNS Queries 339 | icon: mdi:help-network 340 | 341 | sensor.pihole_ads_blocked_today: 342 | friendly_name: Ads Blocked 343 | icon: mdi:security-network 344 | 345 | sensor.pihole_ads_percentage_blocked_today: 346 | friendly_name: Percentage of Ads Blocked 347 | icon: mdi:security-network 348 | 349 | #------------------------------- 350 | # ip_ban_list 351 | #------------------------------- 352 | sensor.fail2ban_hass_iptables: 353 | friendly_name: Hass Bans 354 | icon: mdi:do-not-disturb 355 | 356 | sensor.fail2ban_nginx_http_auth: 357 | friendly_name: Nginx Bans 358 | icon: mdi:do-not-disturb 359 | 360 | sensor.fail2ban_organizr_auth: 361 | friendly_name: Organizr Bans 362 | icon: mdi:do-not-disturb 363 | 364 | 365 | sensor.pihole_version: 366 | friendly_name: Pihole Version 367 | icon: mdi:verified 368 | 369 | #------------------------------- 370 | # Zwave sensors 371 | #------------------------------- 372 | sensor.leak_sump: 373 | friendly_name: Sump Leak Sensor 374 | icon: mdi:pipe-leak 375 | 376 | sensor.aeon_labs_zw096_smart_switch_6_current: 377 | friendly_name: Sump Current 378 | icon: mdi:music-note-whole 379 | 380 | sensor.aeon_labs_zw096_smart_switch_6_voltage: 381 | friendly_name: Sump Voltage 382 | icon: mdi:car-battery 383 | 384 | sensor.aeon_labs_zw096_smart_switch_6_power: 385 | friendly_name: Sump Power 386 | icon: mdi:power 387 | 388 | sensor.smoke_alarm_foyer: 389 | friendly_name: Foyer Smoke Alarm 390 | icon: mdi:fire 391 | 392 | sensor.smoke_alarm_family_room: 393 | friendly_name: Family Room Smoke Alarm 394 | icon: mdi:fire 395 | 396 | sensor.smoke_alarm_Office: 397 | friendly_name: Office Smoke Alarm 398 | icon: mdi:fire 399 | 400 | sensor.smoke_alarm_basement: 401 | friendly_name: Basement Smoke Alarm 402 | icon: mdi:fire 403 | 404 | binary_sensor.blink_cameraks_motion_detected: 405 | friendly_name: Motion Detected - Garage 406 | 407 | binary_sensor.blink_cameraks_camera_armed: 408 | friendly_name: Armed - Garage 409 | 410 | sensor.blink_cameraks_status: 411 | friendly_name: Status - Garage 412 | 413 | sensor.blink_cameraks_battery: 414 | friendly_name: Battery - Garage 415 | 416 | sensor.blink_cameraks_temperature: 417 | friendly_name: Temperature - Garage 418 | 419 | sensor.blink_cameraks_wifi_signal: 420 | friendly_name: Wifi - Garage 421 | 422 | camera.blink_cameraks: 423 | friendly_name: Garage Camera 424 | 425 | binary_sensor.blink_camera1_motion_detected: 426 | friendly_name: Motion Detected - Porch 427 | 428 | binary_sensor.blink_camera1_camera_armed: 429 | friendly_name: Armed - Porch 430 | 431 | sensor.blink_camera1_status_2: 432 | friendly_name: Status - Porch 433 | 434 | sensor.blink_camera1_battery_2: 435 | friendly_name: Battery - Porch 436 | 437 | sensor.blink_camera1_temperature_2: 438 | friendly_name: Temperature - Porch 439 | 440 | sensor.blink_camera1_wifi_signal_2: 441 | friendly_name: Wifi - Porch 442 | 443 | camera.blink_camera1_2: 444 | friendly_name: Porch Camera 445 | 446 | #------------------------------- 447 | # Zwave Devices 448 | #------------------------------- 449 | zwave.aeotec_zw090_zstick_gen5: 450 | icon: mdi:router-wireless 451 | 452 | zwave.driveway: 453 | icon: mdi:spotlight-beam 454 | 455 | zwave.outdoor_1: 456 | icon: mdi:power-plug 457 | 458 | zwave.outdoor_2: 459 | icon: mdi:power-plug 460 | 461 | zwave.power_mon: 462 | icon: mdi:power 463 | 464 | zwave.smoke_kitchen: 465 | icon: mdi:smoke-detector 466 | 467 | zwave.smoke_living_room: 468 | icon: mdi:smoke-detector 469 | 470 | zwave.smoke_nursery: 471 | icon: mdi:smoke-detector 472 | 473 | #----------------------------- 474 | # Other 475 | # ---------------------------- 476 | sensor.sump_usage_per_hour: 477 | icon: mdi:home-flood 478 | friendly_name: Sump Frequency 479 | 480 | sensor.radon: 481 | icon: mdi:radioactive 482 | friendly_name: Radon 483 | 484 | sensor.radon_2: 485 | icon: mdi:radioactive 486 | friendly_name: Radon 2 487 | -------------------------------------------------------------------------------- /customize/customize_climate.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Thermostat 3 | ################## 4 | input_number.ac_setpoint: 5 | icon: mdi:air-conditioner 6 | 7 | input_number.heat_setpoint: 8 | icon: mdi:fire 9 | 10 | input_number.ac_on: 11 | icon: mdi:fan 12 | 13 | input_number.ac_off: 14 | icon: mdi:fan-off 15 | 16 | input_number.heat_on: 17 | icon: mdi:radiator 18 | 19 | input_number.heat_off: 20 | icon: mdi:radiator-off 21 | 22 | input_number.heat_emergency_delta: 23 | icon: mdi:alert 24 | -------------------------------------------------------------------------------- /customize/customize_input_boolean.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Input Boolean 3 | ################## 4 | input_boolean.flux_living_room: 5 | icon: mdi:theme-light-dark 6 | 7 | input_boolean.flux_family_room: 8 | icon: mdi:theme-light-dark 9 | 10 | input_boolean.flux_kitchen: 11 | icon: mdi:theme-light-dark 12 | 13 | input_boolean.flux_master_bedroom: 14 | icon: mdi:theme-light-dark 15 | 16 | input_boolean.flux_nursery: 17 | icon: mdi:theme-light-dark 18 | 19 | input_boolean.flux_office: 20 | icon: mdi:theme-light-dark 21 | 22 | input_boolean.christmas_lights: 23 | icon: mdi:gift 24 | 25 | input_boolean.on_the_way_home: 26 | icon: mdi:map-marker 27 | 28 | input_boolean.guest_mode: 29 | icon: mdi:account 30 | emulated_hue_hidden: false 31 | emulated_hue_name: "Guest Mode" 32 | 33 | input_boolean.thermostat_enable: 34 | icon: mdi:thermostat 35 | emulated_hue_hidden: false 36 | emulated_hue_name: "Thermostat" 37 | 38 | input_boolean.warmer_night_mode: 39 | icon: mdi:fire 40 | -------------------------------------------------------------------------------- /customize/customize_lights.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Lights 3 | ################## 4 | light.family_room_lights: 5 | icon: mdi:sofa 6 | 7 | light.office_lights: 8 | icon: mdi:desktop-tower 9 | 10 | light.master_bedroom_lights: 11 | icon: mdi:bed 12 | 13 | light.living_room_couch: 14 | icon: mdi:sofa 15 | 16 | light.kitchen_lights: 17 | icon: mdi:food-variant 18 | 19 | light.interior_lights: 20 | icon: mdi:home 21 | 22 | ligh.porch: 23 | icon: mdi:gate 24 | -------------------------------------------------------------------------------- /customize/customize_media.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Media Players 3 | ################## 4 | -------------------------------------------------------------------------------- /customize/customize_misc_sensors.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Sensors 3 | ################## 4 | sensor.speedtest_download: 5 | friendly_name: Download (Speedtest) 6 | icon: mdi:download 7 | 8 | sensor.speedtest_upload: 9 | friendly_name: Upload 10 | icon: mdi:upload 11 | 12 | sensor.speedtest_ping: 13 | friendly_name: Ping 14 | icon: mdi:message-alert 15 | 16 | sensor.fastcom_download: 17 | friendly_name: Download (Fast.com) 18 | icon: mdi:download 19 | 20 | sensor.ssl_cert_expiry: 21 | friendly_name: SSL Cert Expiry 22 | icon: mdi:lock 23 | 24 | #------------------------------- 25 | # Google Wifi 26 | #------------------------------- 27 | sensor.wifi_status: 28 | friendly_name: Network Status 29 | icon: mdi:google 30 | 31 | sensor.wifi_current_version: 32 | friendly_name: Router Firmware Version 33 | icon: mdi:checkbox-marked-circle-outline 34 | 35 | sensor.wifi_uptime: 36 | friendly_name: Network Uptime 37 | icon: mdi:update 38 | 39 | #------------------------------- 40 | # Pi-hole 41 | #------------------------------- 42 | sensor.pihole_dns_queries_today: 43 | friendly_name: DNS Queries 44 | icon: mdi:help-network 45 | 46 | sensor.pihole_ads_blocked_today: 47 | friendly_name: Ads Blocked 48 | icon: mdi:security-network 49 | 50 | sensor.pihole_ads_percentage_blocked_today: 51 | friendly_name: Percentage of Ads Blocked 52 | icon: mdi:security-network 53 | 54 | #------------------------------- 55 | # ip_ban_list 56 | #------------------------------- 57 | sensor.fail2ban_hass_iptables: 58 | friendly_name: Hass Bans 59 | icon: mdi:do-not-disturb 60 | 61 | sensor.fail2ban_nginx_http_auth: 62 | friendly_name: Nginx Bans 63 | icon: mdi:do-not-disturb 64 | 65 | sensor.fail2ban_organizr_auth: 66 | friendly_name: Organizr Bans 67 | icon: mdi:do-not-disturb 68 | 69 | 70 | sensor.pihole_version: 71 | friendly_name: Pihole Version 72 | icon: mdi:verified 73 | 74 | #------------------------------- 75 | # Zwave sensors 76 | #------------------------------- 77 | sensor.leak_sump: 78 | friendly_name: Sump Leak Sensor 79 | icon: mdi:pipe-leak 80 | 81 | sensor.aeon_labs_zw096_smart_switch_6_current: 82 | friendly_name: Sump Current 83 | icon: mdi:music-note-whole 84 | 85 | sensor.aeon_labs_zw096_smart_switch_6_voltage: 86 | friendly_name: Sump Voltage 87 | icon: mdi:car-battery 88 | 89 | sensor.aeon_labs_zw096_smart_switch_6_power: 90 | friendly_name: Sump Power 91 | icon: mdi:power 92 | 93 | sensor.smoke_alarm_foyer: 94 | friendly_name: Foyer Smoke Alarm 95 | icon: mdi:fire 96 | 97 | sensor.smoke_alarm_family_room: 98 | friendly_name: Family Room Smoke Alarm 99 | icon: mdi:fire 100 | 101 | sensor.smoke_alarm_Office: 102 | friendly_name: Office Smoke Alarm 103 | icon: mdi:fire 104 | 105 | sensor.smoke_alarm_basement: 106 | friendly_name: Basement Smoke Alarm 107 | icon: mdi:fire 108 | 109 | binary_sensor.blink_cameraks_motion_detected: 110 | friendly_name: Motion Detected - Garage 111 | 112 | binary_sensor.blink_cameraks_camera_armed: 113 | friendly_name: Armed - Garage 114 | 115 | sensor.blink_cameraks_status: 116 | friendly_name: Status - Garage 117 | 118 | sensor.blink_cameraks_battery: 119 | friendly_name: Battery - Garage 120 | 121 | sensor.blink_cameraks_temperature: 122 | friendly_name: Temperature - Garage 123 | 124 | sensor.blink_cameraks_wifi_signal: 125 | friendly_name: Wifi - Garage 126 | 127 | camera.blink_cameraks: 128 | friendly_name: Garage Camera 129 | 130 | binary_sensor.blink_camera1_motion_detected: 131 | friendly_name: Motion Detected - Porch 132 | 133 | binary_sensor.blink_camera1_camera_armed: 134 | friendly_name: Armed - Porch 135 | 136 | sensor.blink_camera1_status_2: 137 | friendly_name: Status - Porch 138 | 139 | sensor.blink_camera1_battery_2: 140 | friendly_name: Battery - Porch 141 | 142 | sensor.blink_camera1_temperature_2: 143 | friendly_name: Temperature - Porch 144 | 145 | sensor.blink_camera1_wifi_signal_2: 146 | friendly_name: Wifi - Porch 147 | 148 | camera.blink_camera1_2: 149 | friendly_name: Porch Camera 150 | 151 | #------------------------------- 152 | # Zwave Devices 153 | #------------------------------- 154 | zwave.aeotec_zw090_zstick_gen5: 155 | icon: mdi:router-wireless 156 | 157 | zwave.driveway: 158 | icon: mdi:spotlight-beam 159 | 160 | zwave.outdoor_1: 161 | icon: mdi:power-plug 162 | 163 | zwave.outdoor_2: 164 | icon: mdi:power-plug 165 | 166 | zwave.power_mon: 167 | icon: mdi:power 168 | 169 | zwave.smoke_kitchen: 170 | icon: mdi:smoke-detector 171 | 172 | zwave.smoke_living_room: 173 | icon: mdi:smoke-detector 174 | 175 | zwave.smoke_nursery: 176 | icon: mdi:smoke-detector 177 | 178 | #----------------------------- 179 | # Other 180 | # ---------------------------- 181 | sensor.sump_usage_per_hour: 182 | icon: mdi:home-flood 183 | friendly_name: Sump Frequency 184 | 185 | sensor.radon: 186 | icon: mdi:radioactive 187 | friendly_name: Radon 188 | 189 | sensor.radon_2: 190 | icon: mdi:radioactive 191 | friendly_name: Radon 2 192 | -------------------------------------------------------------------------------- /customize/customize_presence.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Entities 3 | ################## 4 | device_tracker.kevin_gps: 5 | icon: mdi:crosshairs-gps 6 | 7 | device_tracker.allegra_gps: 8 | icon: mdi:crosshairs-gps 9 | 10 | -------------------------------------------------------------------------------- /customize/customize_scenes.yaml: -------------------------------------------------------------------------------- 1 | ################## 2 | # Scenes 3 | ################## 4 | scene.christmas: 5 | icon: mdi:gift 6 | emulated_hue_hidden: false 7 | emulated_hue_name: "Christmas" 8 | 9 | scene.movie_mode_living_room: 10 | icon: mdi:movie 11 | 12 | scene.movie_mode_family_room: 13 | icon: mdi:movie 14 | 15 | scene.daylight: 16 | icon: mdi:weather-sunny 17 | emulated_hue_hidden: false 18 | emulated_hue_name: "Day Time" 19 | 20 | scene.night: 21 | icon: mdi:weather-night 22 | emulated_hue_hidden: false 23 | emulated_hue_name: "Night Time" 24 | 25 | scene.sabres: 26 | icon: mdi:sword 27 | emulated_hue_hidden: false 28 | emulated_hue_name: "Sabres" 29 | 30 | scene.on_the_way_home: 31 | icon: mdi:map-marker 32 | emulated_hue_hidden: false 33 | 34 | scene.orange: 35 | icon: mdi:palette 36 | emulated_hue_hidden: false 37 | emulated_hue_name: "Orange" 38 | 39 | scene.yellow: 40 | icon: mdi:palette 41 | emulated_hue_hidden: false 42 | emulated_hue_name: "Yellow" 43 | 44 | scene.green: 45 | icon: mdi:palette 46 | emulated_hue_hidden: false 47 | emulated_hue_name: "Green" 48 | 49 | scene.cyan: 50 | icon: mdi:palette 51 | emulated_hue_hidden: false 52 | emulated_hue_name: "Ice" 53 | 54 | scene.blue: 55 | icon: mdi:palette 56 | emulated_hue_hidden: false 57 | emulated_hue_name: "Blue" 58 | 59 | scene.purple: 60 | icon: mdi:palette 61 | emulated_hue_hidden: false 62 | emulated_hue_name: "Purple" 63 | 64 | scene.pink: 65 | icon: mdi:palette 66 | emulated_hue_hidden: false 67 | emulated_hue_name: "Pink" 68 | 69 | -------------------------------------------------------------------------------- /customize/customize_scripts.yaml: -------------------------------------------------------------------------------- 1 | script.thermostat_control: 2 | icon: mdi:air-conditioner 3 | emulated_hue_hidden: false 4 | emulated_hue_name: "Thermostat" 5 | 6 | script.github_pull: 7 | icon: mdi:github-circle 8 | 9 | script.hass_upgrade: 10 | icon: mdi:home-assistant 11 | 12 | script.blink_trigger_camera: 13 | icon: mdi:camera 14 | can_cancel: false 15 | 16 | script.ssl_renew_certificate: 17 | icon: mdi:lock 18 | 19 | script.flux: 20 | icon: mdi:theme-light-dark 21 | emulated_hue_hidden: false 22 | emulated_hue_name: "Flux" 23 | 24 | script.wake_computer: 25 | icon: mdi:windows 26 | emulated_hue_hidden: false 27 | emulated_hue_name: "Desktop" 28 | 29 | script.upgrade_pihole: 30 | icon: mdi:arrow-up-bold-circle-outline 31 | friendly_name: "Upgrade Pihole" 32 | -------------------------------------------------------------------------------- /customize/customize_switches.yaml: -------------------------------------------------------------------------------- 1 | switch.outdoor_1_switch: 2 | friendly_name: Outside Porch Outlet 3 | icon: mdi:power-plug 4 | 5 | switch.outdoor_2_switch: 6 | friendly_name: Outside Driveway Outlet 7 | icon: mdi:power-plug 8 | 9 | switch.power_mon_switch_3_0: 10 | friendly_name: Washing Machine Power 11 | icon: mdi:power 12 | 13 | switch.driveway: 14 | friendly_name: Driveway 15 | icon: mdi:car 16 | emulated_hue_hidden: false 17 | emulated_hue_name: "Driveway" 18 | 19 | -------------------------------------------------------------------------------- /customize/customize_weather.yaml: -------------------------------------------------------------------------------- 1 | #----------------------------------# 2 | # Weather Customization # 3 | #----------------------------------# 4 | sensor.weather_temperature: 5 | friendly_name: Outside Temperature 6 | icon: mdi:thermometer 7 | 8 | sensor.yr_weather_dewpoint_temperature: 9 | friendly_name: Dew Point 10 | icon: mdi:oil-temperature 11 | 12 | sensor.weather_humidity: 13 | friendly_name: Humidity 14 | icon: mdi:water-percent 15 | 16 | sensor.weather_precipitation: 17 | friendly_name: Precipitation 18 | icon: mdi:weather-pouring 19 | 20 | sensor.weather_pressure: 21 | friendly_name: Pressure 22 | icon: mdi:chart-bar 23 | 24 | sensor.yr_weather_fog: 25 | friendly_name: Fog 26 | icon: mdi:weather-fog 27 | 28 | sensor.weather_wind_speed: 29 | friendly_name: Wind Speed 30 | icon: mdi:weather-windy 31 | 32 | sensor.weather_cloud_coverage: 33 | friendly_name: Clouds 34 | icon: mdi:weather-cloudy 35 | 36 | sensor.weather_rain: 37 | friendly_name: Rain 38 | icon: mdi:weather-pouring 39 | 40 | sensor.weather_snow: 41 | friendly_name: Snow 42 | icon: mdi:weather-snowy 43 | 44 | sensor.yr_weather_cloudiness: 45 | friendly_name: Cloudiness 46 | icon: mdi:weather-cloudy 47 | 48 | sensor.weather_condition: 49 | friendly_name: Summary 50 | icon: mdi:clipboard-list-outline 51 | 52 | sensor.weather_wind_bearing: 53 | friendly_name: Wind Bearing 54 | icon: mdi:weather-windy 55 | 56 | sensor.weather_weather_code: 57 | friendly_name: Weather Code 58 | icon: mdi:code-array 59 | -------------------------------------------------------------------------------- /gen_yaml.sh: -------------------------------------------------------------------------------- 1 | docker exec -it home-assistant /bin/bash -c "cd /config;bash bin/smash.sh;exit" 2 | echo "Done" 3 | -------------------------------------------------------------------------------- /images/ha_home_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/images/ha_home_page.png -------------------------------------------------------------------------------- /images/ha_thermostat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/images/ha_thermostat.png -------------------------------------------------------------------------------- /includes/binary_sensor.yaml: -------------------------------------------------------------------------------- 1 | - platform: template 2 | sensors: 3 | sump_status: 4 | friendly_name: "Sump Status" 5 | device_class: 'moisture' 6 | delay_off: 7 | seconds: 2 8 | value_template: > 9 | {{ states.sensor.smart_switch_6_electric_consumption_w.state | float > 10 }} 10 | 11 | leak_sump: 12 | friendly_name: "Sump Leak Sensor" 13 | device_class: 'moisture' 14 | value_template: > 15 | {{ states.sensor.aeon_labs_zw122_water_sensor_6_flood.state == "2" or states.sensor.aeon_labs_zw122_water_sensor_6_flood_2.state == "2" }} 16 | 17 | -------------------------------------------------------------------------------- /includes/blink.yaml: -------------------------------------------------------------------------------- 1 | username: !secret blink_username 2 | password: !secret blink_password 3 | scan_interval: 180 4 | -------------------------------------------------------------------------------- /includes/cameras.yaml: -------------------------------------------------------------------------------- 1 | - platform: local_file 2 | name: blink_gif 3 | file_path: /images/gifs/output.gif 4 | -------------------------------------------------------------------------------- /includes/command_line.yaml: -------------------------------------------------------------------------------- 1 | - sensor: 2 | name: last_boot 3 | scan_interval: 480 4 | command: uptime | awk -F'( |,|:)+' '{print $6,$7,$8":"$9}' 5 | 6 | - sensor: 7 | name: pihole_version 8 | scan_interval: 20000 9 | command: ssh -oStrictHostKeyChecking=no pi@10.11.1.8 "pihole -v" | grep "Pi-hole version" | awk -F'( )+' '{print $5" "$6" "$7}' 10 | -------------------------------------------------------------------------------- /includes/emulated_hue.yaml: -------------------------------------------------------------------------------- 1 | host_ip: !secret server_url 2 | listen_port: 8387 3 | expose_by_default: false 4 | exposed_domains: 5 | - light 6 | - group 7 | - input_boolean 8 | - scene 9 | - switch 10 | -------------------------------------------------------------------------------- /includes/fastdotcom.yaml: -------------------------------------------------------------------------------- 1 | scan_interval: 2 | hours: 4 3 | -------------------------------------------------------------------------------- /includes/google_assistant.yaml: -------------------------------------------------------------------------------- 1 | project_id: hass-control 2 | exposed_domains: 3 | - scene 4 | - light 5 | - script 6 | expose_by_default: false 7 | entity_config: 8 | # ----------- 9 | # SCENES 10 | # ----------- 11 | #scene.movie_mode: 12 | # name: Movie Mode 13 | # expose: True 14 | #scene.movie_mode_basement: 15 | # name: Basement Movie Mode 16 | # expose: True 17 | #scene.christmas: 18 | # name: Christmas 19 | # expose: True 20 | # ---------- 21 | # SCRIPTS 22 | # ---------- 23 | script.flux: 24 | name: Flux 25 | expose: True 26 | #script.wake_computer: 27 | # name: Wake Computer 28 | # expose: True 29 | # ---------- 30 | # LIGHTS 31 | # ---------- 32 | light.family_room_couch_left: 33 | name: Family Room Couch Left 34 | expose: True 35 | light.family_room_couch_right: 36 | name: Family Room Couch Right 37 | expose: True 38 | light.family_room_fireplace: 39 | name: Family Room Fireplace 40 | expose: True 41 | light.living_room_couch_1: 42 | name: Living Room Couch Left 43 | expose: True 44 | light.living_room_corner_1: 45 | name: Living Room Couch Right 46 | expose: True 47 | light.living_room_piano: 48 | name: Living Room Piano 49 | expose: True 50 | light.office_desk: 51 | name: Office Desk 52 | expose: True 53 | light.office_corner: 54 | name: Office Corner 55 | expose: True 56 | light.master_bedroom_door: 57 | name: Bedroom Door 58 | expose: True 59 | light.master_bedroom_window: 60 | name: Bedroom Window 61 | expose: True 62 | light.kitchen_island: 63 | name: Kitchen Island 64 | expose: True 65 | light.kitchen_table: 66 | name: Kitchen Table 67 | expose: True 68 | light.porch: 69 | name: Porch 70 | expose: True 71 | light.foyer: 72 | name: Foyer 73 | expose: True 74 | # ------------ 75 | # SCENES 76 | # ------------ 77 | scene.movie_mode_family_room: 78 | name: Movie Mode Family Room 79 | expose: True 80 | scene.movie_mode_living_room: 81 | name: Movie Mode Living Room 82 | expose: True 83 | -------------------------------------------------------------------------------- /includes/hue.yaml: -------------------------------------------------------------------------------- 1 | bridges: 2 | - host: !secret hue_ip_addr 3 | allow_unreachable: true 4 | allow_hue_groups: false 5 | -------------------------------------------------------------------------------- /includes/influxdb.yaml: -------------------------------------------------------------------------------- 1 | #api_version: 1 2 | host: !secret server_url 3 | port: 8086 4 | #token: !secret influxdb_token 5 | username: !secret influxdb_user 6 | password: !secret influxdb_pass 7 | database: hass_db 8 | #organization: unraid 9 | #bucket: hass_db/a_year 10 | default_measurement: state 11 | -------------------------------------------------------------------------------- /includes/input_boolean.yaml: -------------------------------------------------------------------------------- 1 | on_the_way_home: 2 | name: On the Way Home 3 | initial: off 4 | 5 | flux_family_room: 6 | name: Flux Family Room 7 | initial: on 8 | 9 | flux_living_room: 10 | name: Flux Living Room 11 | initial: on 12 | 13 | flux_kitchen: 14 | name: Flux Kitchen 15 | initial: off 16 | 17 | flux_office: 18 | name: Flux Office 19 | initial: on 20 | 21 | flux_master_bedroom: 22 | name: Flux Master Bedroom 23 | 24 | flux_nursery: 25 | name: Flux Nursery 26 | 27 | christmas_lights: 28 | name: Christmas Lights 29 | initial: off 30 | 31 | guest_mode: 32 | name: Guest Mode 33 | initial: off 34 | 35 | thermostat_enable: 36 | name: Thermostat Enable 37 | initial: on 38 | 39 | warmer_night_mode: 40 | name: Warmer Night Mode 41 | initial: off 42 | 43 | movie_colors: 44 | name: Movie Colors 45 | initial: on 46 | -------------------------------------------------------------------------------- /includes/input_number.yaml: -------------------------------------------------------------------------------- 1 | ac_setpoint: 2 | name: AC Setpoint 3 | initial: 75 4 | min: 70 5 | max: 80 6 | step: 1 7 | 8 | heat_emergency_delta: 9 | name: Emergency Heat Delta 10 | initial: 3 11 | min: 0 12 | max: 5 13 | step: 2 14 | 15 | heat_setpoint: 16 | name: Heat Setpoint 17 | initial: 69 18 | min: 64 19 | max: 72 20 | step: 1 21 | -------------------------------------------------------------------------------- /includes/light.yaml: -------------------------------------------------------------------------------- 1 | - platform: group 2 | name: Family Room Lights 3 | entities: 4 | - light.family_room_couch_right 5 | - light.family_room_couch_left 6 | - light.family_room_fireplace 7 | 8 | - platform: group 9 | name: Office Lights 10 | entities: 11 | - light.office_desk 12 | - light.office_corner 13 | 14 | - platform: group 15 | name: Master Bedroom Lights 16 | entities: 17 | - light.master_bedroom_door 18 | - light.master_bedroom_window 19 | 20 | - platform: group 21 | name: Living Room Couch 22 | entities: 23 | - light.living_room_couch_1 24 | - light.living_room_corner_1 25 | 26 | - platform: group 27 | name: Living Room Lights 28 | entities: 29 | - light.living_room_couch_1 30 | - light.living_room_corner_1 31 | - light.living_room_piano 32 | 33 | - platform: group 34 | name: Kitchen Island 35 | entities: 36 | - light.kitchen_island_1 37 | - light.kitchen_island_2 38 | 39 | - platform: group 40 | name: Kitchen Table 41 | entities: 42 | - light.kitchen_table_1 43 | - light.kitchen_table_2 44 | 45 | - platform: group 46 | name: Kitchen Lights 47 | entities: 48 | - light.kitchen_island 49 | - light.kitchen_table 50 | 51 | - platform: group 52 | name: Interior Lights 53 | entities: 54 | - light.family_room_lights 55 | - light.office_lights 56 | - light.living_room_lights 57 | - light.kitchen_lights 58 | -------------------------------------------------------------------------------- /includes/logger.yaml: -------------------------------------------------------------------------------- 1 | default: warning 2 | logs: 3 | homeassistant.components.media_player: critical 4 | homeassistant.components.camera: error 5 | homeassistant.helpers.entity: error 6 | requests.packages.urllib3.connectionpool: error 7 | blinkpy.sync_module: error 8 | homeassistant.components.blink: error 9 | homeassistant.components.radiotherm: error 10 | -------------------------------------------------------------------------------- /includes/notify.yaml: -------------------------------------------------------------------------------- 1 | - name: notify 2 | platform: html5 3 | vapid_pub_key: !secret vapid_pub_key 4 | vapid_prv_key: !secret vapid_priv_key 5 | vapid_email: !secret vapid_email 6 | -------------------------------------------------------------------------------- /includes/pihole.yaml: -------------------------------------------------------------------------------- 1 | host: !secret pi_hole_addr 2 | -------------------------------------------------------------------------------- /includes/recorder.yaml: -------------------------------------------------------------------------------- 1 | db_url: !secret db_url 2 | purge_keep_days: 2 3 | commit_interval: 2 4 | exclude: 5 | domains: 6 | - automation 7 | - camera 8 | - media_player 9 | - scene 10 | - script 11 | - zwave 12 | entities: 13 | - sun.sun 14 | - sensor.date_time 15 | - sensor.last_boot 16 | - sensor.aeon_labs_zw096_smart_switch_6_energy 17 | - sensor.aeon_labs_zw096_smart_switch_6_previous_reading 18 | - sensor.aeon_labs_zw096_smart_switch_6_previous_reading_2 19 | - sensor.aeon_labs_zw096_smart_switch_6_previous_reading_3 20 | - sensor.aeon_labs_zw096_smart_switch_6_previous_reading_4 21 | - sensor.aeon_labs_zw096_smart_switch_6_switch 22 | -------------------------------------------------------------------------------- /includes/shell_command.yaml: -------------------------------------------------------------------------------- 1 | github_pull: bash /home/hass/.homeassistant/bin/gitpull.sh 2 | hass_upgrade: bash /home/hass/.homeassistant/bin/hass_upgrade.sh 3 | turn_off_linux_vm: 'ssh hass@192.168.86.210 sudo poweroff' 4 | pihole_upgrade: 'ssh pi@10.11.1.8 "pihole -up"' 5 | -------------------------------------------------------------------------------- /includes/speedtest.yaml: -------------------------------------------------------------------------------- 1 | server_id: 3156 2 | scan_interval: 3 | hours: 1 4 | minutes: 32 5 | -------------------------------------------------------------------------------- /includes/tts.yaml: -------------------------------------------------------------------------------- 1 | - platform: google 2 | cache: false -------------------------------------------------------------------------------- /lovelace/ahome.yaml: -------------------------------------------------------------------------------- 1 | icon: mdi:home-assistant 2 | title: Home 3 | id: home 4 | cards: 5 | #---------------- 6 | # Glance Summary 7 | #---------------- 8 | - type: glance 9 | entities: 10 | - entity: sensor.occupancy 11 | name: Home 12 | icon: mdi:home-map-marker 13 | - entity: sensor.living_room_temperature 14 | name: Living Room 15 | - entity: sensor.dark_sky_temperature 16 | name: Outside 17 | - entity: sensor.bedroom_temperature 18 | name: Bedroom 19 | - entity: sensor.thermo_hvac 20 | name: Status 21 | 22 | #---------------- 23 | # Living Room 24 | #---------------- 25 | - type: vertical-stack 26 | cards: 27 | - type: picture-glance 28 | title: Living Room 29 | entities: 30 | - light.couch_left 31 | - light.couch_right 32 | - light.corner 33 | - group.lights_living_room 34 | - scene.movie_mode 35 | - input_boolean.flux_living_room 36 | - sensor.smoke_alarm_living_room 37 | state_image: 38 | 'on': /local/lovelace/living_room.jpg 39 | 'off': /local/lovelace/living_room_off.jpg 40 | entity: group.lights_living_room 41 | aspect_ratio: 6:4 42 | 43 | #----------------- 44 | # Kitchen 45 | #----------------- 46 | - type: picture-glance 47 | title: Kitchen 48 | entities: 49 | - light.kitchen_table 50 | - group.lights_kitchen 51 | - sensor.smoke_alarm_kitchen 52 | state_image: 53 | 'on': /local/lovelace/kitchen.jpg 54 | 'off': /local/lovelace/kitchen_off.jpg 55 | entity: group.lights_kitchen 56 | aspect_ratio: 6:4 57 | 58 | #----------------- 59 | # Den 60 | #----------------- 61 | - type: picture-glance 62 | title: Playroom 63 | entities: 64 | - light.corner_den 65 | - light.back_den 66 | - group.lights_den 67 | state_image: 68 | 'on': /local/lovelace/playroom.jpg 69 | 'off': /local/lovelace/playroom_off.jpg 70 | entity: group.lights_den 71 | aspect_ratio: 6:4 72 | 73 | #------------------ 74 | # Bedroom 75 | #------------------ 76 | - type: picture-glance 77 | title: Bedroom 78 | entities: 79 | - light.bedroom_corner 80 | - light.bedroom_door 81 | - group.lights_bedroom 82 | - sensor.smoke_alarm_nursery 83 | state_image: 84 | 'on': /local/lovelace/bedroom.jpg 85 | 'off': /local/lovelace/bedroom_off.jpg 86 | entity: group.lights_bedroom 87 | aspect_ratio: 6:4 88 | 89 | #------------------ 90 | # Basement 91 | #------------------ 92 | - type: picture-glance 93 | title: Basement 94 | entities: 95 | - light.desk 96 | - light.basement_computer 97 | - light.basement_corner 98 | - light.fireplace_1 99 | - light.fireplace_2 100 | - group.lights_basement 101 | - input_boolean.flux_basement 102 | - scene.movie_mode_basement 103 | state_image: 104 | 'on': /local/lovelace/theater.jpg 105 | 'off': /local/lovelace/theater_off.jpg 106 | entity: group.lights_basement 107 | aspect_ratio: 6:4 108 | 109 | #------------------- 110 | # Outside 111 | #------------------- 112 | - type: picture-glance 113 | title: Outside 114 | entities: 115 | - light.porch 116 | - switch.driveway_switch 117 | - switch.outdoor_1_switch 118 | - switch.outdoor_2_switch 119 | - input_boolean.christmas_lights 120 | - alarm_control_panel.blink_xt_hub 121 | camera_image: camera.blink_camera1 122 | aspect_ratio: 6:4 123 | -------------------------------------------------------------------------------- /lovelace/climate.yaml: -------------------------------------------------------------------------------- 1 | icon: mdi:fan 2 | title: Climate 3 | id: climate 4 | cards: 5 | - type: entities 6 | entities: 7 | - input_boolean.thermostat_enable 8 | 9 | - type: thermostat 10 | entity: climate.living_room 11 | 12 | - type: vertical-stack 13 | cards: 14 | - type: horizontal-stack 15 | cards: 16 | - type: entity-button 17 | entity: input_number.ac_home 18 | icon: mdi:chevron-up 19 | tap_action: call-service 20 | service: input_number.increment 21 | 22 | - type: entity-button 23 | entity: input_number.ac_home 24 | icon: mdi:chevron-down 25 | tap_action: call-service 26 | service: input_number.decrement 27 | 28 | - type: entity-button 29 | entity: input_number.heat_home 30 | icon: mdi:chevron-up 31 | tap_action: call-service 32 | service: input_number.increment 33 | 34 | - type: entity-button 35 | entity: input_number.heat_home 36 | icon: mdi:chevron-down 37 | tap_action: call-service 38 | service: input_number.decrement 39 | 40 | - type: horizontal-stack 41 | cards: 42 | - type: entity-button 43 | entity: input_number.ac_sleep 44 | icon: mdi:chevron-up 45 | tap_action: call-service 46 | service: input_number.increment 47 | 48 | - type: entity-button 49 | entity: input_number.ac_sleep 50 | icon: mdi:chevron-down 51 | tap_action: call-service 52 | service: input_number.decrement 53 | 54 | - type: entity-button 55 | entity: input_number.heat_sleep 56 | icon: mdi:chevron-up 57 | tap_action: call-service 58 | service: input_number.increment 59 | 60 | - type: entity-button 61 | entity: input_number.heat_sleep 62 | icon: mdi:chevron-down 63 | tap_action: call-service 64 | service: input_number.decrement 65 | 66 | - type: glance 67 | entities: 68 | - input_number.ac_home 69 | - input_number.ac_away 70 | - input_number.ac_sleep 71 | - input_number.heat_home 72 | - input_number.heat_away 73 | - input_number.heat_sleep 74 | columns: 3 75 | 76 | - type: sensor 77 | entity: sensor.dark_sky_temperature 78 | line_color: '#009933' 79 | accuracy: 24 80 | 81 | - type: sensor 82 | entity: sensor.living_room_temperature 83 | line_color: '#0099ff' 84 | accuracy: 24 85 | 86 | - type: sensor 87 | entity: sensor.bedroom_temperature 88 | line_color: '#cc3300' 89 | accuracy: 24 90 | 91 | - type: sensor 92 | entity: sensor.living_room_humidity 93 | accuracy: 24 94 | 95 | -------------------------------------------------------------------------------- /lovelace/lovelace-gen.py: -------------------------------------------------------------------------------- 1 | """Generates lovelace config from multiple files.""" 2 | import os 3 | import sys 4 | 5 | try: 6 | import yaml 7 | except ImportError: 8 | import pip 9 | if hasattr(pip, 'main'): 10 | pip.main(['install', pyyaml]) 11 | else: 12 | pip._internal.main(['install', pyyaml]) 13 | import yaml 14 | 15 | DEFAULT_TITLE = "Home Assistant" 16 | LOVELACE_FILE = 'ui-lovelace.yaml' 17 | LOVELACE_DIR = 'lovelace' 18 | CONFIG = {'title': DEFAULT_TITLE, 'views': []} 19 | DISCLAIMER = """#------------------------------------------------------- 20 | # {} auto-generated by lovelace-gen.py. 21 | #------------------------------------------------------- 22 | 23 | """.format(LOVELACE_FILE) 24 | 25 | def get_files(directory): 26 | """Get all files in directory.""" 27 | yaml_files = [] 28 | all_files = os.listdir(directory) 29 | for filename in all_files: 30 | full_path = os.path.join(directory, filename) 31 | if os.path.isfile(full_path): 32 | if full_path.endswith(".yaml"): 33 | yaml_files.append(full_path) 34 | return yaml_files 35 | 36 | 37 | def merge_config(files): 38 | """Merge all files into a config.""" 39 | configs = [] 40 | for yaml_file in files: 41 | with open(yaml_file, 'r') as openfile: 42 | configs.append(yaml.load(openfile)) 43 | 44 | CONFIG['views'] = configs 45 | 46 | return CONFIG 47 | 48 | 49 | def write_to_config(config, config_path='/config', resources=None): 50 | """Write the config to main lovelace file.""" 51 | config_file = os.path.join(config_path, LOVELACE_FILE) 52 | with open(config_file, 'w') as outfile: 53 | outfile.write(DISCLAIMER) 54 | if resources is not None: 55 | yaml.dump(resources, outfile) 56 | yaml.dump(config, outfile) 57 | 58 | 59 | def add_resources(config_path): 60 | """Add javascript resources and increment version number.""" 61 | config_file = os.path.join(config_path, LOVELACE_FILE) 62 | version = 1 63 | if os.path.isfile(config_file): 64 | with open(config_file, 'r') as openfile: 65 | data = yaml.load(openfile) 66 | if 'resources' in data: 67 | # Get first resource and grab version number 68 | url = data['resources'][0]['url'] 69 | split_url = url.split('=') 70 | version = int(split_url[1]) + 1 71 | 72 | resources = ("resources:\n" 73 | " - url: /local/group-card.js?v={}\n" 74 | " type: js").format(version) 75 | 76 | return yaml.load(resources) 77 | 78 | 79 | if __name__ == '__main__': 80 | config_path = '/config' 81 | if len(sys.argv) > 1: 82 | config_path = sys.argv[1] 83 | lovelace_path = os.path.join(config_path, LOVELACE_DIR) 84 | files = get_files(lovelace_path) 85 | resources = add_resources(config_path) 86 | config = merge_config(sorted(files)) 87 | write_to_config(config, config_path=config_path, resources=resources) 88 | print("Done.") 89 | -------------------------------------------------------------------------------- /lovelace/map.yaml: -------------------------------------------------------------------------------- 1 | icon: mdi:google-maps 2 | title: Map 3 | id: map 4 | cards: 5 | - type: glance 6 | entities: 7 | - entity: device_tracker.kevin_gps 8 | icon: mdi:crosshairs-gps 9 | - entity: device_tracker.allegra_gps 10 | icon: mdi:crosshairs-gps 11 | - entity: sensor.occupancy 12 | name: 'Home' 13 | icon: mdi:home-map-marker 14 | - input_boolean.guest_mode 15 | - entity: scene.on_the_way_home 16 | icon: mdi:android-auto 17 | show_state: false 18 | 19 | - type: map 20 | aspect_ratio: 75% 21 | default_zoom: 12 22 | entities: 23 | - zone.home 24 | - device_tracker.kevin_gps 25 | - device_tracker.allegra_gps 26 | -------------------------------------------------------------------------------- /lovelace/security.yaml: -------------------------------------------------------------------------------- 1 | icon: mdi:security 2 | title: Security 3 | id: security 4 | cards: 5 | - type: alarm-panel 6 | entity: alarm_control_panel.blink_xt_hub 7 | states: 8 | - arm_away 9 | 10 | - type: vertical-stack 11 | cards: 12 | - type: horizontal-stack 13 | cards: 14 | - type: sensor 15 | entity: sensor.blink_camera1_temperature_2 16 | - type: sensor 17 | entity: sensor.blink_cameraks_temperature 18 | 19 | - type: horizontal-stack 20 | cards: 21 | - type: sensor 22 | entity: sensor.blink_camera1_battery_2 23 | - type: sensor 24 | entity: sensor.blink_cameraks_battery 25 | 26 | - type: picture-entity 27 | entity: camera.blink_gif 28 | 29 | - type: picture-entity 30 | entity: camera.blink_camera1_2 31 | 32 | - type: picture-entity 33 | entity: camera.blink_cameraks 34 | -------------------------------------------------------------------------------- /lovelace/status.yaml: -------------------------------------------------------------------------------- 1 | icon: mdi:pulse 2 | title: Status 3 | id: status 4 | cards: 5 | - type: horizontal-stack 6 | cards: 7 | - type: gauge 8 | entity: sensor.speedtest_download 9 | min: 0 10 | max: 120 11 | severity: 12 | red: 0 13 | yellow: 60 14 | green: 80 15 | - type: gauge 16 | entity: sensor.speedtest_upload 17 | min: 0 18 | max: 15 19 | severity: 20 | red: 0 21 | yellow: 5 22 | green: 8 23 | 24 | - type: glance 25 | name: Network 26 | entities: 27 | - sensor.wifi_status 28 | - sensor.wifi_uptime 29 | - sensor.wifi_current_version 30 | - sensor.pihole_ads_percentage_blocked_today 31 | - sensor.pihole_version 32 | 33 | - type: glance 34 | name: Home-Assistant 35 | entities: 36 | - sensor.hass_uptime 37 | - sensor.hass_version 38 | - sensor.fail2ban_hass_iptables 39 | - sensor.fail2ban_nginx_http_auth 40 | - sensor.fail2ban_organizr_auth 41 | 42 | - type: glance 43 | name: Z-Wave 44 | entities: 45 | - zwave.aeotec_zw090_zstick_gen5 46 | - zwave.power_mon 47 | - zwave.driveway 48 | - zwave.outdoor_1 49 | - zwave.outdoor_2 50 | - zwave.smoke_kitchen 51 | - zwave.smoke_living_room 52 | - zwave.smoke_nursery 53 | columns: 4 54 | 55 | - type: custom:group-card 56 | card: 57 | type: entities 58 | title: Scenes 59 | group: group.scenes 60 | 61 | - type: custom:group-card 62 | card: 63 | type: entities 64 | title: Automations 65 | group: group.all_automations 66 | 67 | - type: custom:group-card 68 | card: 69 | type: entities 70 | title: Script 71 | group: group.all_scripts 72 | -------------------------------------------------------------------------------- /scenes/blue.yaml: -------------------------------------------------------------------------------- 1 | name: Blue 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.2156,0.1355] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.2156,0.1355] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.2156,0.1355] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/christmas.yaml: -------------------------------------------------------------------------------- 1 | # Turn on lights in christmas colors 2 | # Left, Right are spring green, corner is crimson 3 | # http://www.developers.meethue.com/documentation/hue-xy-values 4 | name: Christmas 5 | entities: 6 | input_boolean.flux_living_room: 7 | state: off 8 | light.couch_left: 9 | state: on 10 | xy_color: [0.1972,0.6781] 11 | brightness: 278 12 | light.couch_right: 13 | state: on 14 | xy_color: [0.6508, 0.2881] 15 | brightness: 200 16 | light.corner: 17 | state: on 18 | xy_color: [0.1972,0.6781] 19 | brightness: 278 20 | light.kitchen_table: 21 | state: on 22 | xy_color: [0.1972,0.6781] 23 | brightness: 278 -------------------------------------------------------------------------------- /scenes/cyan.yaml: -------------------------------------------------------------------------------- 1 | name: Cyan 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.2534, 0.2103] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.2534, 0.2103] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.2534, 0.2103] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/day.yaml: -------------------------------------------------------------------------------- 1 | # Turn on lights for daytime colors 2 | # http://www.developers.meethue.com/documentation/hue-xy-values 3 | name: Daylight 4 | entities: 5 | input_boolean.flux_living_room: 6 | state: off 7 | light.couch_left: 8 | state: on 9 | color_temp: 278 10 | brightness: 278 11 | light.couch_right: 12 | state: on 13 | color_temp: 278 14 | brightness: 278 15 | light.corner: 16 | state: on 17 | color_temp: 278 18 | brightness: 278 19 | light.kitchen_table: 20 | state: on 21 | color_temp: 278 22 | brightness: 278 -------------------------------------------------------------------------------- /scenes/green.yaml: -------------------------------------------------------------------------------- 1 | name: Green 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.4084,0.5168] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.4084,0.5168] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.4084,0.5168] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/movies_family_room.yaml: -------------------------------------------------------------------------------- 1 | # Dim lights for movies 2 | # Left, Right are spring green, corner is crimson 3 | # http://www.developers.meethue.com/documentation/hue-xy-values 4 | name: Movie Mode Family Room 5 | entities: 6 | input_boolean.flux_family_room: 7 | state: off 8 | light.kitchen_table: 9 | state: off 10 | light.kitchen_island: 11 | state: off 12 | light.family_room_fireplace: 13 | state: off 14 | light.family_room_couch_right: 15 | state: on 16 | color_temp: 500 17 | brightness: 50 18 | light.family_room_couch_left: 19 | state: on 20 | color_temp: 500 21 | brightness: 50 22 | -------------------------------------------------------------------------------- /scenes/movies_living_room.yaml: -------------------------------------------------------------------------------- 1 | # Dim lights for movies 2 | # Left, Right are spring green, corner is crimson 3 | # http://www.developers.meethue.com/documentation/hue-xy-values 4 | name: Movie Mode Living Room 5 | entities: 6 | input_boolean.flux_living_room: 7 | state: off 8 | light.living_room_couch: 9 | state: on 10 | color_temp: 500 11 | brightness: 50 12 | -------------------------------------------------------------------------------- /scenes/night.yaml: -------------------------------------------------------------------------------- 1 | # Turn on lights for nightime colors 2 | # http://www.developers.meethue.com/documentation/hue-xy-values 3 | name: Night 4 | entities: 5 | input_boolean.flux_living_room: 6 | state: off 7 | light.couch_left: 8 | state: on 9 | color_temp: 400 10 | brightness: 278 11 | light.couch_right: 12 | state: on 13 | color_temp: 400 14 | brightness: 278 15 | light.corner: 16 | state: on 17 | color_temp: 400 18 | brightness: 278 19 | light.kitchen_table: 20 | state: on 21 | color_temp: 400 22 | brightness: 278 -------------------------------------------------------------------------------- /scenes/not_home_at_night.yaml: -------------------------------------------------------------------------------- 1 | # Turn on lights at a reduced brightness 2 | name: Not Home At Night 3 | entities: 4 | input_boolean.flux_living_room: 5 | state: off 6 | light.couch_left: 7 | state: on 8 | transition: 2 9 | brightness: 100 10 | light.couch_right: 11 | state: on 12 | transition: 2 13 | brightness: 100 14 | light.computer: 15 | state: on 16 | transistion: 2 17 | brightness: 100 -------------------------------------------------------------------------------- /scenes/on_the_way_home.yaml: -------------------------------------------------------------------------------- 1 | name: On the Way Home 2 | entities: 3 | # This triggers thermostat automations 4 | input_boolean.on_the_way_home: 5 | state: on 6 | group.couch: 7 | state: on -------------------------------------------------------------------------------- /scenes/orange.yaml: -------------------------------------------------------------------------------- 1 | name: Orange 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.5097,0.3767] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.5097,0.3767] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.5097,0.3767] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/pink.yaml: -------------------------------------------------------------------------------- 1 | name: Pink 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.4053,0.2591] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.4053,0.2591] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.4053,0.2591] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/purple.yaml: -------------------------------------------------------------------------------- 1 | name: Purple 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.2573,0.1348] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.2573,0.1348] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.2573,0.1348] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scenes/sabres.yaml: -------------------------------------------------------------------------------- 1 | # Turn on lights in Buffalo Sabres colors 2 | # http://www.developers.meethue.com/documentation/hue-xy-values 3 | name: Sabres 4 | entities: 5 | input_boolean.flux_living_room: 6 | state: off 7 | light.couch_left: 8 | state: on 9 | xy_color: [0.4871, 0.4681] 10 | brightness: 278 11 | light.couch_right: 12 | state: on 13 | xy_color: [0.1559,0.1599] 14 | brightness: 200 15 | light.corner: 16 | state: on 17 | xy_color: [0.4871, 0.4681] 18 | brightness: 278 -------------------------------------------------------------------------------- /scenes/yellow.yaml: -------------------------------------------------------------------------------- 1 | name: Yellow 2 | entities: 3 | input_boolean.flux_living_room: 4 | state: off 5 | light.couch_left: 6 | state: on 7 | xy_color: [0.4930,0.4547] 8 | brightness: 278 9 | light.couch_right: 10 | state: on 11 | xy_color: [0.4930,0.4547] 12 | brightness: 278 13 | light.corner: 14 | state: on 15 | xy_color: [0.4930,0.4547] 16 | brightness: 278 17 | -------------------------------------------------------------------------------- /scripts.yaml: -------------------------------------------------------------------------------- 1 | #---------------- SMASH.PY ------------------ 2 | # Generated: 2023-Dec-04 11:23:53 3 | #-------------------------------------------- 4 | 5 | #--- scripts/blink_trigger_camera.yaml --- 6 | blink_trigger_camera: 7 | alias: Script - Blink Trigger Camera 8 | sequence: 9 | - service: blink.trigger_camera 10 | data: 11 | name: "Camera1" 12 | - delay: 00:00:05 13 | - service: blink.trigger_camera 14 | data: 15 | name: "CameraKS" 16 | - delay: 00:00:05 17 | - service: blink.blink_update 18 | 19 | 20 | #--- scripts/github_pull.yaml --- 21 | github_pull: 22 | alias: Pull Config from Github 23 | sequence: 24 | - service: shell_command.github_pull 25 | - service: homeassistant.restart 26 | 27 | #--- scripts/speech_engine.yaml --- 28 | # For all TTS processing 29 | # Inspired by @CCOSTAN https://github.com/CCOSTAN/Home-AssistantConfig 30 | 31 | speech_engine: 32 | sequence: 33 | - condition: or 34 | conditions: 35 | - condition: state 36 | entity_id: sensor.occupancy 37 | state: 'home' 38 | - condition: state 39 | entity_id: input_boolean.guest_mode 40 | state: 'on' 41 | 42 | # Speak to all google home devices 43 | - service: script.speech_processing 44 | data_template: 45 | speech_message: > 46 | {%- macro dark_outside() -%} 47 | {{ [ 48 | "It's getting late, I will turn on the outside lights.", 49 | "The sun has set, time to turn the lights on outside. I'm on it.", 50 | "I'll go ahead and turn the outside lights on, it's getting dark.", 51 | "Looks like it's time to turn the lights on outside. I got it." 52 | ] | random }} 53 | {%- endmacro -%} 54 | {%- macro garbage_night() -%} 55 | {%if now().strftime("%a") == 'Mon' %} 56 | {{ [ 57 | "Just a reminder to take the garbage out. Pickup is tomorrow.", 58 | "Beep beep. I don't mean to interrupt, but I wanted to make sure to remind you that it's garbage night.", 59 | "It's starting to smell in here. I think someone should take the trash out considering pick up is tomorrow.", 60 | "Garbage pickup is tomorrow morning. Just a friendly reminder!" 61 | ] | random }} 62 | {% endif %} 63 | {%- endmacro -%} 64 | {%- macro washer_status() -%} 65 | {% if states.sensor.washer.state == 'Not Running' %} 66 | {{ [ 67 | "Washer cycle is complete, time to throw the clothes into the dryer.", 68 | "Looks like the wash just finished. Figured I should let you know.", 69 | "Just popping in to let you know the wash is done.", 70 | ] | random }} 71 | {% endif %} 72 | {%- endmacro -%} 73 | {%- macro fire_co2() -%} 74 | {% if states.sensor.smoke_alarm_kitchen.state == 'Fire' %} 75 | {{ [ 76 | "Are you cooking? Because there seems to be a fire in the kitchen.", 77 | "There's a fire... sale. OH MY GOD THE BURNING. Seriously though, you should probably check the Kitchen because a fire has been detected.", 78 | "Warning, fire detected in Kitchen.", 79 | ] | random }} 80 | {% elif (states.sensor.smoke_alarm_living_room.state == 'Fire') or (states.sensor.smoke_alarm_nursery.state == 'Fire') %} 81 | {{ [ 82 | "Fire detected in the house. Please find a safe exit.", 83 | "Warning, there seems to be a fire in the house!", 84 | "Fire! Please leave the house immediately. I repeat: Fire!", 85 | ] | random }} 86 | {% elif (states.sensor.smoke_alarm_living_room.state == 'CO') or (states.sensor.smoke_alarm_nursery.state == 'CO') or (states.sensor.smoke_alarm_kitchen.state == 'CO') %} 87 | {{ [ 88 | "Alert! Carbon Monoxide detected, please exit the house and call nine one one", 89 | "Warning! Carbon Monoxide detected in house. I repeat: Warning! Carbon Monoxide has been detected in the house.", 90 | ] | random }} 91 | {% endif %} 92 | {%- endmacro -%} 93 | 94 | {% if call_dark_outside == 1 %} 95 | {{ dark_outside() }} 96 | {% endif %} 97 | {% if call_garbage_night == 1 %} 98 | {{ garbage_night() }} 99 | {% endif %} 100 | {% if call_washer_status == 1 %} 101 | {{ washer_status() }} 102 | {% endif %} 103 | {% if call_fire_co2 == 1 %} 104 | {{ fire_co2() }} 105 | {% endif %} 106 | 107 | #--- scripts/ssl_renew_certificate.yaml --- 108 | ssl_renew_certificate: 109 | alias: SSL Renew Certificate 110 | sequence: 111 | - service: notify.notify_kevin_phone 112 | data: 113 | message: "SSL Renew Instructions - 1) Open Port 80 2) Restart router 3) Run ./ssl_renew from pi's home directory 4) Close Port 80 5) Restart router" 114 | 115 | #--- scripts/wake_computer.yaml --- 116 | # Wake computer and turn on lights 117 | wake_computer: 118 | alias: Wake Computer 119 | sequence: 120 | - service: light.turn_on 121 | entity_id: 122 | - light.basement_corner 123 | - light.basement_computer 124 | - light.desk 125 | - service: wake_on_lan.send_magic_packet 126 | data: 127 | mac: !secret wake_mac_address 128 | 129 | #--- scripts/flux.yaml --- 130 | flux: 131 | alias: Flux - Global 132 | sequence: 133 | - service: input_boolean.turn_on 134 | entity_id: 135 | - input_boolean.flux_living_room 136 | - input_boolean.flux_family_room 137 | - input_boolean.flux_master_bedroom 138 | - input_boolean.flux_office 139 | 140 | 141 | #--- scripts/notify_all_engine.yaml --- 142 | notify_all_engine: 143 | sequence: 144 | - service: notify.notify 145 | data_template: 146 | message: > 147 | {%- macro fire_co2() -%} 148 | 'ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} triggered by {{trigger.entity_id}} with staus {{ trigger.to_state.state }}' 149 | {%- endmacro -%} 150 | {%- macro leak_detected() -%} 151 | 'ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} Leak Detected with {{trigger.entity_id}}' 152 | {%- endmacro %} 153 | {##################} 154 | {# BEGIN ROUTINES #} 155 | {##################} 156 | {% if call_fire_co2 == 1 %} 157 | {{ fire_co2() }} 158 | {% endif %} 159 | {% if call_leak_detected == 1 %} 160 | {{ leak_detected() }} 161 | {% endif %} 162 | 163 | 164 | #--- scripts/hass_upgrade.yaml --- 165 | hass_upgrade: 166 | alias: Upgrade Homeassistant 167 | sequence: 168 | - service: shell_command.hass_upgrade 169 | - service: homeassistant.restart 170 | 171 | #--- scripts/notify_kevin_engine.yaml --- 172 | notify_kevin_engine: 173 | sequence: 174 | - service: notify.notify_kevin_phone 175 | data_template: 176 | message: > 177 | {%- macro on_restart() -%} 178 | Home Assistant restarted {{ now().strftime("%h %d, %Y at %H:%M:%S") }} 179 | {%- endmacro -%} 180 | {%- macro system_use() -%} 181 | {% if states.sensor.glances_ram_use.state | float <= 100.0 %} 182 | RAM Usage at {{states.sensor.glances_ram_use.state}}% and Swap at {{states.sensor.glances_swap_use.state}}%! 183 | {% elif states.sensor.glances_ram_use_2.state | float <= 100.0 %} 184 | RAM Usage at {{states.sensor.glances_ram_use_2.state}}% and Swap at {{states.sensor.glances_swap_use.state}}%! 185 | {% endif %} 186 | {%- endmacro -%} 187 | {%- macro ssl_cert_expiry() -%} 188 | Warning - SSL Certificate expires in {{states.sensor.ssl_cert_expiry.state}} days and has not been renewed! 189 | {%- endmacro -%} 190 | {%- macro failed_login() -%} 191 | Failed Login! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} 192 | {% if states.sensor.fail2ban_hass_iptables.state != "None" %} 193 | HASS Attempt(s) from {{states.sensor.fail2ban_hass_iptables.state}} {% endif %} {% if states.sensor.fail2ban_nginx_http_auth.state != "None" %} 194 | NGINX Attempt(s) from {{states.sensor.fail2ban_nginx_http_auth.state}}{% endif %}{% if states.sensor.fail2ban_organizr_auth.state != "None" %} 195 | Organizr Attempt(s) from {{states.sensor.fail2ban_organizr_auth.state}} 196 | {% endif %} 197 | {%- endmacro -%} 198 | {##################} 199 | {# BEGIN ROUTINES #} 200 | {##################} 201 | {% if call_on_restart == 1 %} 202 | {{ on_restart() }} 203 | {% endif %} 204 | {% if call_system_use == 1 %} 205 | {{ system_use() }} 206 | {% endif %} 207 | {% if call_ssl_cert_expiry == 1 %} 208 | {{ ssl_cert_expiry() }} 209 | {% endif %} 210 | {% if call_failed_login == 1 %} 211 | {{ failed_login() }} 212 | {% endif %} 213 | 214 | #--- scripts/speech_processing.yaml --- 215 | speech_processing: 216 | sequence: 217 | - service: media_player.volume_set 218 | entity_id: media_player.google_home 219 | data: 220 | volume_level: 0.5 221 | - service: tts.google_say 222 | entity_id: media_player.google_home 223 | data_template: 224 | message: > 225 | {{ speech_message }} 226 | 227 | #--- scripts/upgrade_pihole.yaml --- 228 | upgrade_pihole: 229 | alias: Upgrade PiHole 230 | sequence: 231 | - service: shell_command.pihole_upgrade 232 | 233 | #--- scripts/zwave_fix_dead_node.yaml --- 234 | zwave_fix_dead_node: 235 | alias: Script - Fix Dead ZWave Node 236 | sequence: 237 | - condition: or 238 | conditions: 239 | - condition: template 240 | value_template: '{{ states.zwave.driveway.attributes.is_failed }}' 241 | - condition: template 242 | value_template: '{{ 1 < 0 }}' 243 | - service: zwave.test_node 244 | data_template: 245 | node_id: '{{states.zwave.driveway.attributes.node_id}}' 246 | - service: notify.notify_kevin_phone 247 | data_template: 248 | message: 'Driveway switch dead, trying to fix. {{now().strftime("h %d, %Y at %H:%M:%S")}}' 249 | -------------------------------------------------------------------------------- /scripts/blink_trigger_camera.yaml: -------------------------------------------------------------------------------- 1 | blink_trigger_camera: 2 | alias: Script - Blink Trigger Camera 3 | sequence: 4 | - service: blink.trigger_camera 5 | data: 6 | name: "Camera1" 7 | - delay: 00:00:05 8 | - service: blink.trigger_camera 9 | data: 10 | name: "CameraKS" 11 | - delay: 00:00:05 12 | - service: blink.blink_update 13 | 14 | -------------------------------------------------------------------------------- /scripts/flux.yaml: -------------------------------------------------------------------------------- 1 | flux: 2 | alias: Flux - Global 3 | sequence: 4 | - service: input_boolean.turn_on 5 | entity_id: 6 | - input_boolean.flux_living_room 7 | - input_boolean.flux_family_room 8 | - input_boolean.flux_master_bedroom 9 | - input_boolean.flux_office 10 | 11 | -------------------------------------------------------------------------------- /scripts/github_pull.yaml: -------------------------------------------------------------------------------- 1 | github_pull: 2 | alias: Pull Config from Github 3 | sequence: 4 | - service: shell_command.github_pull 5 | - service: homeassistant.restart -------------------------------------------------------------------------------- /scripts/hass_upgrade.yaml: -------------------------------------------------------------------------------- 1 | hass_upgrade: 2 | alias: Upgrade Homeassistant 3 | sequence: 4 | - service: shell_command.hass_upgrade 5 | - service: homeassistant.restart -------------------------------------------------------------------------------- /scripts/notify_all_engine.yaml: -------------------------------------------------------------------------------- 1 | notify_all_engine: 2 | sequence: 3 | - service: notify.notify 4 | data_template: 5 | message: > 6 | {%- macro fire_co2() -%} 7 | 'ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} triggered by {{trigger.entity_id}} with staus {{ trigger.to_state.state }}' 8 | {%- endmacro -%} 9 | {%- macro leak_detected() -%} 10 | 'ALERT! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} Leak Detected with {{trigger.entity_id}}' 11 | {%- endmacro %} 12 | {##################} 13 | {# BEGIN ROUTINES #} 14 | {##################} 15 | {% if call_fire_co2 == 1 %} 16 | {{ fire_co2() }} 17 | {% endif %} 18 | {% if call_leak_detected == 1 %} 19 | {{ leak_detected() }} 20 | {% endif %} 21 | 22 | -------------------------------------------------------------------------------- /scripts/notify_kevin_engine.yaml: -------------------------------------------------------------------------------- 1 | notify_kevin_engine: 2 | sequence: 3 | - service: notify.notify_kevin_phone 4 | data_template: 5 | message: > 6 | {%- macro on_restart() -%} 7 | Home Assistant restarted {{ now().strftime("%h %d, %Y at %H:%M:%S") }} 8 | {%- endmacro -%} 9 | {%- macro system_use() -%} 10 | {% if states.sensor.glances_ram_use.state | float <= 100.0 %} 11 | RAM Usage at {{states.sensor.glances_ram_use.state}}% and Swap at {{states.sensor.glances_swap_use.state}}%! 12 | {% elif states.sensor.glances_ram_use_2.state | float <= 100.0 %} 13 | RAM Usage at {{states.sensor.glances_ram_use_2.state}}% and Swap at {{states.sensor.glances_swap_use.state}}%! 14 | {% endif %} 15 | {%- endmacro -%} 16 | {%- macro ssl_cert_expiry() -%} 17 | Warning - SSL Certificate expires in {{states.sensor.ssl_cert_expiry.state}} days and has not been renewed! 18 | {%- endmacro -%} 19 | {%- macro failed_login() -%} 20 | Failed Login! {{ now().strftime("%h %d, %Y at %H:%M:%S") }} 21 | {% if states.sensor.fail2ban_hass_iptables.state != "None" %} 22 | HASS Attempt(s) from {{states.sensor.fail2ban_hass_iptables.state}} {% endif %} {% if states.sensor.fail2ban_nginx_http_auth.state != "None" %} 23 | NGINX Attempt(s) from {{states.sensor.fail2ban_nginx_http_auth.state}}{% endif %}{% if states.sensor.fail2ban_organizr_auth.state != "None" %} 24 | Organizr Attempt(s) from {{states.sensor.fail2ban_organizr_auth.state}} 25 | {% endif %} 26 | {%- endmacro -%} 27 | {##################} 28 | {# BEGIN ROUTINES #} 29 | {##################} 30 | {% if call_on_restart == 1 %} 31 | {{ on_restart() }} 32 | {% endif %} 33 | {% if call_system_use == 1 %} 34 | {{ system_use() }} 35 | {% endif %} 36 | {% if call_ssl_cert_expiry == 1 %} 37 | {{ ssl_cert_expiry() }} 38 | {% endif %} 39 | {% if call_failed_login == 1 %} 40 | {{ failed_login() }} 41 | {% endif %} 42 | -------------------------------------------------------------------------------- /scripts/speech_engine.yaml: -------------------------------------------------------------------------------- 1 | # For all TTS processing 2 | # Inspired by @CCOSTAN https://github.com/CCOSTAN/Home-AssistantConfig 3 | 4 | speech_engine: 5 | sequence: 6 | - condition: or 7 | conditions: 8 | - condition: state 9 | entity_id: sensor.occupancy 10 | state: 'home' 11 | - condition: state 12 | entity_id: input_boolean.guest_mode 13 | state: 'on' 14 | 15 | # Speak to all google home devices 16 | - service: script.speech_processing 17 | data_template: 18 | speech_message: > 19 | {%- macro dark_outside() -%} 20 | {{ [ 21 | "It's getting late, I will turn on the outside lights.", 22 | "The sun has set, time to turn the lights on outside. I'm on it.", 23 | "I'll go ahead and turn the outside lights on, it's getting dark.", 24 | "Looks like it's time to turn the lights on outside. I got it." 25 | ] | random }} 26 | {%- endmacro -%} 27 | {%- macro garbage_night() -%} 28 | {%if now().strftime("%a") == 'Mon' %} 29 | {{ [ 30 | "Just a reminder to take the garbage out. Pickup is tomorrow.", 31 | "Beep beep. I don't mean to interrupt, but I wanted to make sure to remind you that it's garbage night.", 32 | "It's starting to smell in here. I think someone should take the trash out considering pick up is tomorrow.", 33 | "Garbage pickup is tomorrow morning. Just a friendly reminder!" 34 | ] | random }} 35 | {% endif %} 36 | {%- endmacro -%} 37 | {%- macro washer_status() -%} 38 | {% if states.sensor.washer.state == 'Not Running' %} 39 | {{ [ 40 | "Washer cycle is complete, time to throw the clothes into the dryer.", 41 | "Looks like the wash just finished. Figured I should let you know.", 42 | "Just popping in to let you know the wash is done.", 43 | ] | random }} 44 | {% endif %} 45 | {%- endmacro -%} 46 | {%- macro fire_co2() -%} 47 | {% if states.sensor.smoke_alarm_kitchen.state == 'Fire' %} 48 | {{ [ 49 | "Are you cooking? Because there seems to be a fire in the kitchen.", 50 | "There's a fire... sale. OH MY GOD THE BURNING. Seriously though, you should probably check the Kitchen because a fire has been detected.", 51 | "Warning, fire detected in Kitchen.", 52 | ] | random }} 53 | {% elif (states.sensor.smoke_alarm_living_room.state == 'Fire') or (states.sensor.smoke_alarm_nursery.state == 'Fire') %} 54 | {{ [ 55 | "Fire detected in the house. Please find a safe exit.", 56 | "Warning, there seems to be a fire in the house!", 57 | "Fire! Please leave the house immediately. I repeat: Fire!", 58 | ] | random }} 59 | {% elif (states.sensor.smoke_alarm_living_room.state == 'CO') or (states.sensor.smoke_alarm_nursery.state == 'CO') or (states.sensor.smoke_alarm_kitchen.state == 'CO') %} 60 | {{ [ 61 | "Alert! Carbon Monoxide detected, please exit the house and call nine one one", 62 | "Warning! Carbon Monoxide detected in house. I repeat: Warning! Carbon Monoxide has been detected in the house.", 63 | ] | random }} 64 | {% endif %} 65 | {%- endmacro -%} 66 | 67 | {% if call_dark_outside == 1 %} 68 | {{ dark_outside() }} 69 | {% endif %} 70 | {% if call_garbage_night == 1 %} 71 | {{ garbage_night() }} 72 | {% endif %} 73 | {% if call_washer_status == 1 %} 74 | {{ washer_status() }} 75 | {% endif %} 76 | {% if call_fire_co2 == 1 %} 77 | {{ fire_co2() }} 78 | {% endif %} 79 | -------------------------------------------------------------------------------- /scripts/speech_processing.yaml: -------------------------------------------------------------------------------- 1 | speech_processing: 2 | sequence: 3 | - service: media_player.volume_set 4 | entity_id: media_player.google_home 5 | data: 6 | volume_level: 0.5 7 | - service: tts.google_say 8 | entity_id: media_player.google_home 9 | data_template: 10 | message: > 11 | {{ speech_message }} -------------------------------------------------------------------------------- /scripts/ssl_renew_certificate.yaml: -------------------------------------------------------------------------------- 1 | ssl_renew_certificate: 2 | alias: SSL Renew Certificate 3 | sequence: 4 | - service: notify.notify_kevin_phone 5 | data: 6 | message: "SSL Renew Instructions - 1) Open Port 80 2) Restart router 3) Run ./ssl_renew from pi's home directory 4) Close Port 80 5) Restart router" 7 | -------------------------------------------------------------------------------- /scripts/upgrade_pihole.yaml: -------------------------------------------------------------------------------- 1 | upgrade_pihole: 2 | alias: Upgrade PiHole 3 | sequence: 4 | - service: shell_command.pihole_upgrade 5 | -------------------------------------------------------------------------------- /scripts/wake_computer.yaml: -------------------------------------------------------------------------------- 1 | # Wake computer and turn on lights 2 | wake_computer: 3 | alias: Wake Computer 4 | sequence: 5 | - service: light.turn_on 6 | entity_id: 7 | - light.basement_corner 8 | - light.basement_computer 9 | - light.desk 10 | - service: wake_on_lan.send_magic_packet 11 | data: 12 | mac: !secret wake_mac_address 13 | -------------------------------------------------------------------------------- /scripts/zwave_fix_dead_node.yaml: -------------------------------------------------------------------------------- 1 | zwave_fix_dead_node: 2 | alias: Script - Fix Dead ZWave Node 3 | sequence: 4 | - condition: or 5 | conditions: 6 | - condition: template 7 | value_template: '{{ states.zwave.driveway.attributes.is_failed }}' 8 | - condition: template 9 | value_template: '{{ 1 < 0 }}' 10 | - service: zwave.test_node 11 | data_template: 12 | node_id: '{{states.zwave.driveway.attributes.node_id}}' 13 | - service: notify.notify_kevin_phone 14 | data_template: 15 | message: 'Driveway switch dead, trying to fix. {{now().strftime("h %d, %Y at %H:%M:%S")}}' 16 | -------------------------------------------------------------------------------- /sensors/appliances.yaml: -------------------------------------------------------------------------------- 1 | - platform: template 2 | sensors: 3 | radon: 4 | unit_of_measurement: 'pCi/L' 5 | value_template: "{{ (states.sensor.basement_radon.state | float * 1 / 37) | round(2) }}" 6 | radon_2: 7 | unit_of_measurement: 'pCi/L' 8 | value_template: "{{ (states.sensor.bedroom_radon.state | float * 1 / 37) | round(2) }}" 9 | 10 | 11 | smoke_alarm_foyer: 12 | value_template: > 13 | {% if is_state("sensor.smoke_detector_1_alarm_level", "0") %} 14 | Idle 15 | {% elif is_state("sensor.smoke_detector_1_alarm_type", "13") %} 16 | Idle 17 | {% elif is_state("sensor.smoke_detector_1_alarm_type", "12") %} 18 | Testing 19 | {% elif is_state("sensor.smoke_detector_1_alarm_type", "1") %} 20 | Fire 21 | {% elif is_state("sensor.smoke_detector_1_alarm_type", "2") %} 22 | CO 23 | {% else %} 24 | Unknown 25 | {% endif %} 26 | 27 | smoke_alarm_family_room: 28 | value_template: > 29 | {% if is_state("sensor.smoke_detector_2_alarm_level", "0") %} 30 | Idle 31 | {% elif is_state("sensor.smoke_detector_2_alarm_type", "13") %} 32 | Idle 33 | {% elif is_state("sensor.smoke_detector_2_alarm_type", "12") %} 34 | Testing 35 | {% elif is_state("sensor.smoke_detector_2_alarm_type", "1") %} 36 | Fire 37 | {% elif is_state("sensor.smoke_detector_2_alarm_type", "2") %} 38 | CO 39 | {% else %} 40 | Unknown 41 | {% endif %} 42 | 43 | smoke_alarm_office: 44 | value_template: > 45 | {% if is_state("sensor.smoke_detector_3_level", "0") %} 46 | Idle 47 | {% elif is_state("sensor.smoke_detector_3_alarm_type", "13") %} 48 | Idle 49 | {% elif is_state("sensor.smoke_detector_3_alarm_type", "12") %} 50 | Testing 51 | {% elif is_state("sensor.smoke_detector_3_alarm_type", "1") %} 52 | Fire 53 | {% elif is_state("sensor.smoke_detector_3_alarm_type", "2") %} 54 | CO 55 | {% else %} 56 | Unknown 57 | {% endif %} 58 | 59 | smoke_alarm_basement: 60 | value_template: > 61 | {% if is_state("sensor.smoke_detector_4_level", "0") %} 62 | Idle 63 | {% elif is_state("sensor.smoke_detector_4_alarm_type", "13") %} 64 | Idle 65 | {% elif is_state("sensor.smoke_detector_4_alarm_type", "12") %} 66 | Testing 67 | {% elif is_state("sensor.smoke_detector_4_alarm_type", "1") %} 68 | Fire 69 | {% elif is_state("sensor.smoke_detector_4_alarm_type", "2") %} 70 | CO 71 | {% else %} 72 | Unknown 73 | {% endif %} 74 | -------------------------------------------------------------------------------- /sensors/fail2ban.yaml: -------------------------------------------------------------------------------- 1 | # Note, filepath --> /fail2ban/fail2ban.log 2 | # Using secret so that travis builds don't fail 3 | - platform: fail2ban 4 | file_path: !secret fail2ban_log 5 | scan_interval: 120 6 | jails: 7 | - hass-iptables 8 | - nginx-http-auth 9 | - organizr-auth 10 | -------------------------------------------------------------------------------- /sensors/history_stats.yaml: -------------------------------------------------------------------------------- 1 | - platform: history_stats 2 | name: Sump Usage Per Hour 3 | entity_id: binary_sensor.sump_status 4 | state: 'on' 5 | type: count 6 | end: '{{ now() }}' 7 | duration: 8 | hours: 1 9 | -------------------------------------------------------------------------------- /sensors/time.yaml: -------------------------------------------------------------------------------- 1 | - platform: time_date 2 | display_options: 3 | - "date_time" -------------------------------------------------------------------------------- /sensors/weather_cond.yaml: -------------------------------------------------------------------------------- 1 | - platform: template 2 | sensors: 3 | weather_cond: 4 | value_template: > 5 | {% set thunder = ['200', '201', '202', '210', '211', '221', '230', '231', '232'] %} 6 | {% set drizzle = ['300', '301', '310', '311', '312', '313', '314', '321'] %} 7 | {% set rain = ['500', '501', '502', '503', '504', '511', '520', '521', '522', '531'] %} 8 | {% set clouds = ['804'] %} 9 | {% if states('sensor.weather_weather_code') in thunder %} 10 | Thunder 11 | {% elif states('sensor.weather_weather_code') in drizzle %} 12 | Drizzle 13 | {% elif states('sensor.weather_weather_code') in rain %} 14 | Rain 15 | {% elif states('sensor.weather_weather_code') in clouds %} 16 | Clouds 17 | {% else %} 18 | Clear 19 | {% endif %} 20 | 21 | -------------------------------------------------------------------------------- /smash.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Name: smash.py 3 | Author: Kevin Fronczak 4 | Date: August 29, 2017 5 | 6 | Usage: 7 | python3 smash.py --source --dest [opts] 8 | 9 | Use --help flag to see available options. 10 | 11 | Description: 12 | Parses a directory and merges contents of each file into a destination file. 13 | If the destination already exists, it is diff'd against the new contents and 14 | merged if possible. If not, a manual edit is needed (with offending lines 15 | highlighted in terminal). 16 | ''' 17 | 18 | from os import listdir, getcwd 19 | from os.path import isfile, join 20 | from datetime import datetime 21 | import sys 22 | import argparse 23 | import difflib 24 | 25 | class Smasher(object): 26 | '''Class that creates a generic smashing object.''' 27 | 28 | def __init__(self, args): 29 | '''Instantiates class.''' 30 | self.opts = self.get_options(args) 31 | self.src = self.opts['source'] 32 | if self.src.endswith('/'): 33 | self.src = self.src[:-1] 34 | self.dest = self.opts['dest'] 35 | self.color = ColorLog() 36 | 37 | def get_options(self, args): 38 | '''Returns dictionary of command line arguments.''' 39 | opts = dict() 40 | for arg in vars(args): 41 | opts[arg] = getattr(args, arg) 42 | 43 | return opts 44 | 45 | def begin(self): 46 | '''Start smashing routine.''' 47 | file_lines = list() 48 | for line in self.lines_file_top(): 49 | file_lines.append(line) 50 | for line in self.get_source_contents(): 51 | file_lines.append(line) 52 | if self.diff_with_destination(file_lines): 53 | self.write_source(self.dest, file_lines) 54 | sys.exit(0) 55 | else: 56 | self.color.colorize('Smash aborted. Manually merge files and run again.', 'red') 57 | sys.exit(1) 58 | 59 | def diff_with_destination(self, lines): 60 | '''Check if destination exists, if it does, diff files.''' 61 | if isfile(self.dest) and not self.opts['force_overwrite']: 62 | tempfile = self.dest + ' NEW' 63 | with open(self.dest) as f: 64 | content = f.readlines() 65 | # Perform diff 66 | diff_lines = list() 67 | for line in difflib.unified_diff(content, lines, fromfile=self.dest, tofile=tempfile, lineterm='\n'): 68 | if line.startswith('-'): 69 | color_line = self.color.colorize(line, 'red') 70 | elif line.startswith('+'): 71 | color_line = self.color.colorize(line, 'green') 72 | else: 73 | color_line = self.color.colorize(line, 'white') 74 | 75 | diff_lines.append(line) 76 | print(color_line) 77 | 78 | return self.continue_prompt() 79 | else: 80 | return True 81 | 82 | 83 | def write_source(self, file, lines): 84 | '''Writes lines to file.''' 85 | with open(file, mode='w') as f: 86 | f.write(''.join(lines)) 87 | 88 | def continue_prompt(self): 89 | '''Prompt to determine is smash should continue or abort.''' 90 | prompt = self.color.colorize('File differences found!\nContinue with smash anyways? y/n:\n', 'yellow') 91 | response = input(prompt) 92 | print(self.color.colors['reset']) 93 | if response.lower() in ['y', 'yes']: 94 | return True 95 | else: 96 | return False 97 | 98 | def lines_file_top(self): 99 | '''String to append to top of file.''' 100 | top_lines = list() 101 | if not self.opts['no_comment']: 102 | comment = self.opts['comment'] 103 | top_lines.append('{}---------------- SMASH.PY ------------------\n'.format(comment)) 104 | if not self.opts['no_date']: 105 | date_string = 'Generated: {:%Y-%b-%d %H:%M:%S}'.format(datetime.now()) 106 | top_lines.append('{} {} \n'.format(comment, date_string)) 107 | top_lines.append('{}--------------------------------------------\n'.format(comment)) 108 | return top_lines 109 | 110 | def get_source_contents(self): 111 | '''Retrieves source file contents.''' 112 | lines = list() 113 | files = list() 114 | for file in listdir(self.src): 115 | if file.endswith(self.opts['ext']) and file not in self.opts['exclude']: 116 | files.append(file) 117 | 118 | for filename in files: 119 | full_file = '{}/{}'.format(self.src, filename) 120 | 121 | with open(full_file) as f: 122 | content = f.readlines() 123 | 124 | if not self.opts['no_comment']: 125 | lines.append('\n{}--- {} ---\n'.format(self.opts['comment'], full_file)) 126 | 127 | for line in content: 128 | # Add newline if missing 129 | if not line.endswith('\n'): 130 | line = line + '\n' 131 | # Just copy comments over directly 132 | if line.startswith(self.opts['comment']): 133 | lines.append(line) 134 | 135 | # Check alias line and use as id 136 | elif self.opts['use_ids'] and line.startswith('alias:'): 137 | clean_line = line 138 | clean_line = clean_line.replace('alias: ', "") 139 | clean_line = clean_line.replace(" ", "_") 140 | clean_line = clean_line.replace("/", "_") 141 | clean_line = clean_line.replace("-", "_") 142 | id_line = '- id: ' + clean_line.lower() 143 | lines.append(id_line) 144 | lines.append(' ' + line) 145 | else: 146 | lines.append(' ' + line) 147 | 148 | return lines 149 | 150 | class Parser(object): 151 | '''Argument parsing object.''' 152 | 153 | def __init__(self): 154 | '''Initialize arguments for parser.''' 155 | self.parser = argparse.ArgumentParser(__name__) 156 | self.parser.add_argument('--source', help='Source directory of files to be smashed', 157 | type=str, required=True) 158 | self.parser.add_argument('--dest', help='Destination file for smashing', 159 | type=str, required=True) 160 | self.parser.add_argument('--ext', help='Extension of files to smash', 161 | type=str, required=False, default='yaml') 162 | self.parser.add_argument('--exclude', help='Space seperated list of files to exclude from smashing', 163 | nargs='+', required=False, default=[]) 164 | self.parser.add_argument('--comment', help='Comment flag for file (default is "#")', 165 | type=str, required=False, default='#') 166 | self.parser.add_argument('--no-date', help='Do not append date to contents of destination file', 167 | action='store_true') 168 | self.parser.add_argument('--no-comment', help='Do not add additional comments to contents of destination file', 169 | action='store_true') 170 | self.parser.add_argument('--force-overwrite', help='Do not attempt a file merge, overwrite the destination file', 171 | action='store_true') 172 | self.parser.add_argument('--use-ids', help='Adds an "id" line to file (used for home assistant automations)', 173 | action='store_true') 174 | 175 | self.args = self.parser.parse_args() 176 | 177 | class ColorLog(object): 178 | '''Class to colorize log output''' 179 | 180 | def __init__(self): 181 | from colorama import init, Fore, Style 182 | 183 | init(autoreset=True) 184 | self.colors = {'red': Fore.RED, 185 | 'yellow': Fore.YELLOW, 186 | 'green': Fore.GREEN, 187 | 'white': Fore.WHITE, 188 | 'cyan': Fore.CYAN, 189 | 'reset': Style.RESET_ALL 190 | } 191 | 192 | def colorize(self, string, type): 193 | try: 194 | return (self.colors[type] + string) 195 | except KeyError: 196 | print('Unkown key {}'.format(type)) 197 | sys.exit(1) 198 | 199 | if __name__ == '__main__': 200 | p = Parser() 201 | smash = Smasher(p.args) 202 | smash.begin() 203 | -------------------------------------------------------------------------------- /travis_secrets.yaml: -------------------------------------------------------------------------------- 1 | latitude: 0.00 2 | longitude: 0.00 3 | password: fake_pasword 4 | darksky_api: FAKE123 5 | wunderground_api: 123FAKE 6 | radar_link: https://fake.radar.com 7 | ecobee_api: fakemcfakerson 8 | db_url: mysql://mydb.totallyreal.com 9 | blink_username: someone@example.com 10 | blink_password: mypasswordforrealzzzbutjknotreally 11 | server_url: 111.111.111.1 12 | pi_hole_addr: 200.200.202.1 13 | hue_ip_addr: 101.001.100.1 14 | influxdb_user: foo 15 | influxdb_pass: bar 16 | influxdb_token: foobar 17 | emby_api_key: deadbeef 18 | wake_mac_address: 00:00:00:00:00 19 | fail2ban_log: /tmp/test.txt 20 | google_assistant_client_id: feedbeef 21 | google_assistant_access_token: deadbeef 22 | google_assistant_api_key: deadbeefdad 23 | google_assistant_user_id: foobar 24 | vapid_pub_key: 1234 25 | vapid_priv_key: 5678 26 | vapid_email: test@example.com 27 | openweather_apikey: abc123 28 | -------------------------------------------------------------------------------- /ui-lovelace.yaml: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------- 2 | # ui-lovelace.yaml auto-generated by lovelace-gen.py. 3 | #------------------------------------------------------- 4 | 5 | resources: 6 | - {type: js, url: '/local/group-card.js?v=17'} 7 | title: Home Assistant 8 | views: 9 | - cards: 10 | - entities: 11 | - {entity: sensor.occupancy, icon: 'mdi:home-map-marker', name: Home} 12 | - {entity: sensor.living_room_temperature, name: Living Room} 13 | - {entity: sensor.dark_sky_temperature, name: Outside} 14 | - {entity: sensor.bedroom_temperature, name: Bedroom} 15 | - {entity: sensor.thermo_hvac, name: Status} 16 | type: glance 17 | - cards: 18 | - aspect_ratio: 364 19 | entities: [light.couch_left, light.couch_right, light.corner, group.lights_living_room, 20 | scene.movie_mode, input_boolean.flux_living_room, sensor.smoke_alarm_living_room] 21 | entity: group.lights_living_room 22 | state_image: {'off': /local/lovelace/living_room_off.jpg, 'on': /local/lovelace/living_room.jpg} 23 | title: Living Room 24 | type: picture-glance 25 | type: vertical-stack 26 | - aspect_ratio: 364 27 | entities: [light.kitchen_table, group.lights_kitchen, sensor.smoke_alarm_kitchen] 28 | entity: group.lights_kitchen 29 | state_image: {'off': /local/lovelace/kitchen_off.jpg, 'on': /local/lovelace/kitchen.jpg} 30 | title: Kitchen 31 | type: picture-glance 32 | - aspect_ratio: 364 33 | entities: [light.corner_den, light.back_den, group.lights_den] 34 | entity: group.lights_den 35 | state_image: {'off': /local/lovelace/playroom_off.jpg, 'on': /local/lovelace/playroom.jpg} 36 | title: Playroom 37 | type: picture-glance 38 | - aspect_ratio: 364 39 | entities: [light.bedroom_corner, light.bedroom_door, group.lights_bedroom, sensor.smoke_alarm_nursery] 40 | entity: group.lights_bedroom 41 | state_image: {'off': /local/lovelace/bedroom_off.jpg, 'on': /local/lovelace/bedroom.jpg} 42 | title: Bedroom 43 | type: picture-glance 44 | - aspect_ratio: 364 45 | entities: [light.desk, light.basement_computer, light.basement_corner, light.fireplace_1, 46 | light.fireplace_2, group.lights_basement, input_boolean.flux_basement, scene.movie_mode_basement] 47 | entity: group.lights_basement 48 | state_image: {'off': /local/lovelace/theater_off.jpg, 'on': /local/lovelace/theater.jpg} 49 | title: Basement 50 | type: picture-glance 51 | - aspect_ratio: 364 52 | camera_image: camera.blink_camera1 53 | entities: [light.porch, switch.driveway_switch, switch.outdoor_1_switch, switch.outdoor_2_switch, 54 | input_boolean.christmas_lights, alarm_control_panel.blink_xt_hub] 55 | title: Outside 56 | type: picture-glance 57 | icon: mdi:home-assistant 58 | id: home 59 | title: Home 60 | - cards: 61 | - entities: [input_boolean.thermostat_enable] 62 | type: entities 63 | - {entity: climate.living_room, type: thermostat} 64 | - cards: 65 | - cards: 66 | - {entity: input_number.ac_home, icon: 'mdi:chevron-up', service: input_number.increment, 67 | tap_action: call-service, type: entity-button} 68 | - {entity: input_number.ac_home, icon: 'mdi:chevron-down', service: input_number.decrement, 69 | tap_action: call-service, type: entity-button} 70 | - {entity: input_number.heat_home, icon: 'mdi:chevron-up', service: input_number.increment, 71 | tap_action: call-service, type: entity-button} 72 | - {entity: input_number.heat_home, icon: 'mdi:chevron-down', service: input_number.decrement, 73 | tap_action: call-service, type: entity-button} 74 | type: horizontal-stack 75 | - cards: 76 | - {entity: input_number.ac_sleep, icon: 'mdi:chevron-up', service: input_number.increment, 77 | tap_action: call-service, type: entity-button} 78 | - {entity: input_number.ac_sleep, icon: 'mdi:chevron-down', service: input_number.decrement, 79 | tap_action: call-service, type: entity-button} 80 | - {entity: input_number.heat_sleep, icon: 'mdi:chevron-up', service: input_number.increment, 81 | tap_action: call-service, type: entity-button} 82 | - {entity: input_number.heat_sleep, icon: 'mdi:chevron-down', service: input_number.decrement, 83 | tap_action: call-service, type: entity-button} 84 | type: horizontal-stack 85 | type: vertical-stack 86 | - columns: 3 87 | entities: [input_number.ac_home, input_number.ac_away, input_number.ac_sleep, 88 | input_number.heat_home, input_number.heat_away, input_number.heat_sleep] 89 | type: glance 90 | - {accuracy: 24, entity: sensor.dark_sky_temperature, line_color: '#009933', type: sensor} 91 | - {accuracy: 24, entity: sensor.living_room_temperature, line_color: '#0099ff', 92 | type: sensor} 93 | - {accuracy: 24, entity: sensor.bedroom_temperature, line_color: '#cc3300', type: sensor} 94 | - {accuracy: 24, entity: sensor.living_room_humidity, type: sensor} 95 | icon: mdi:fan 96 | id: climate 97 | title: Climate 98 | - cards: 99 | - entities: 100 | - {entity: device_tracker.kevin_gps, icon: 'mdi:crosshairs-gps'} 101 | - {entity: device_tracker.allegra_gps, icon: 'mdi:crosshairs-gps'} 102 | - {entity: sensor.occupancy, icon: 'mdi:home-map-marker', name: Home} 103 | - input_boolean.guest_mode 104 | - {entity: scene.on_the_way_home, icon: 'mdi:android-auto', show_state: false} 105 | type: glance 106 | - aspect_ratio: 75% 107 | default_zoom: 12 108 | entities: [zone.home, device_tracker.kevin_gps, device_tracker.allegra_gps] 109 | type: map 110 | icon: mdi:google-maps 111 | id: map 112 | title: Map 113 | - cards: 114 | - entity: alarm_control_panel.blink_xt_hub 115 | states: [arm_away] 116 | type: alarm-panel 117 | - cards: 118 | - cards: 119 | - {entity: sensor.blink_camera1_temperature_2, type: sensor} 120 | - {entity: sensor.blink_cameraks_temperature, type: sensor} 121 | type: horizontal-stack 122 | - cards: 123 | - {entity: sensor.blink_camera1_battery_2, type: sensor} 124 | - {entity: sensor.blink_cameraks_battery, type: sensor} 125 | type: horizontal-stack 126 | type: vertical-stack 127 | - {entity: camera.blink_gif, type: picture-entity} 128 | - {entity: camera.blink_camera1_2, type: picture-entity} 129 | - {entity: camera.blink_cameraks, type: picture-entity} 130 | icon: mdi:security 131 | id: security 132 | title: Security 133 | - cards: 134 | - cards: 135 | - entity: sensor.speedtest_download 136 | max: 120 137 | min: 0 138 | severity: {green: 80, red: 0, yellow: 60} 139 | type: gauge 140 | - entity: sensor.speedtest_upload 141 | max: 15 142 | min: 0 143 | severity: {green: 8, red: 0, yellow: 5} 144 | type: gauge 145 | type: horizontal-stack 146 | - entities: [sensor.wifi_status, sensor.wifi_uptime, sensor.wifi_current_version, 147 | sensor.pihole_ads_percentage_blocked_today, sensor.pihole_version] 148 | name: Network 149 | type: glance 150 | - entities: [sensor.hass_uptime, sensor.hass_version, sensor.fail2ban_hass_iptables, 151 | sensor.fail2ban_nginx_http_auth, sensor.fail2ban_organizr_auth] 152 | name: Home-Assistant 153 | type: glance 154 | - columns: 4 155 | entities: [zwave.aeotec_zw090_zstick_gen5, zwave.power_mon, zwave.driveway, zwave.outdoor_1, 156 | zwave.outdoor_2, zwave.smoke_kitchen, zwave.smoke_living_room, zwave.smoke_nursery] 157 | name: Z-Wave 158 | type: glance 159 | - card: {title: Scenes, type: entities} 160 | group: group.scenes 161 | type: custom:group-card 162 | - card: {title: Automations, type: entities} 163 | group: group.all_automations 164 | type: custom:group-card 165 | - card: {title: Script, type: entities} 166 | group: group.all_scripts 167 | type: custom:group-card 168 | icon: mdi:pulse 169 | id: status 170 | title: Status 171 | -------------------------------------------------------------------------------- /www/firetv.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/firetv.jpg -------------------------------------------------------------------------------- /www/group-card.js: -------------------------------------------------------------------------------- 1 | class GroupCard extends HTMLElement { 2 | 3 | setConfig(config) { 4 | if (!config.group) { 5 | throw new Error('Please specify a group'); 6 | } 7 | 8 | if (this.lastChild) this.removeChild(this.lastChild); 9 | const cardConfig = Object.assign({}, config); 10 | if (!cardConfig.card) cardConfig.card = {}; 11 | if (!cardConfig.card.type) cardConfig.card.type = 'entities'; 12 | const element = document.createElement(`hui-${cardConfig.card.type}-card`); 13 | this.appendChild(element); 14 | this._config = cardConfig; 15 | } 16 | 17 | set hass(hass) { 18 | const config = this._config; 19 | const entities = hass.states[config.group].attributes['entity_id']; 20 | if (!config.card.entities || config.card.entities.length !== entities.length || 21 | !config.card.entities.every((value, index) => value.entity === entities[index].entity)) { 22 | config.card.entities = entities; 23 | } 24 | this.lastChild.setConfig(config.card); 25 | this.lastChild.hass = hass; 26 | } 27 | 28 | getCardSize() { 29 | return 'getCardSize' in this.lastChild ? this.lastChild.getCardSize() : 1; 30 | } 31 | } 32 | 33 | customElements.define('group-card', GroupCard); 34 | -------------------------------------------------------------------------------- /www/lovelace/bedroom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/bedroom.jpg -------------------------------------------------------------------------------- /www/lovelace/bedroom_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/bedroom_off.jpg -------------------------------------------------------------------------------- /www/lovelace/kitchen.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/kitchen.jpg -------------------------------------------------------------------------------- /www/lovelace/kitchen_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/kitchen_off.jpg -------------------------------------------------------------------------------- /www/lovelace/living_room.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/living_room.jpg -------------------------------------------------------------------------------- /www/lovelace/living_room_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/living_room_off.jpg -------------------------------------------------------------------------------- /www/lovelace/nursery.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/nursery.jpg -------------------------------------------------------------------------------- /www/lovelace/nursery_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/nursery_off.jpg -------------------------------------------------------------------------------- /www/lovelace/office.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/office.png -------------------------------------------------------------------------------- /www/lovelace/office_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/office_off.png -------------------------------------------------------------------------------- /www/lovelace/outside_day.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/outside_day.jpg -------------------------------------------------------------------------------- /www/lovelace/outside_night.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/outside_night.jpg -------------------------------------------------------------------------------- /www/lovelace/playroom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/playroom.jpg -------------------------------------------------------------------------------- /www/lovelace/playroom_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/playroom_off.jpg -------------------------------------------------------------------------------- /www/lovelace/theater.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/theater.jpg -------------------------------------------------------------------------------- /www/lovelace/theater_off.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/lovelace/theater_off.jpg -------------------------------------------------------------------------------- /www/nvidia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/nvidia.jpg -------------------------------------------------------------------------------- /www/plex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fronzbot/githass/8e5c9b83d53816ba029d64e0d20f3dbf6e71c570/www/plex.png --------------------------------------------------------------------------------