diff --git a/configuration.yaml b/configuration.yaml index 3c26497..4f48b25 100644 --- a/configuration.yaml +++ b/configuration.yaml @@ -56,6 +56,8 @@ config: # description: Xiaomi Gateway Light discovery: + ignore: + - homekit homekit: autostart: true @@ -71,6 +73,12 @@ homekit: - binary_sensor.single_car_garage_door_tilt_sensor_sensor - binary_sensor.two_car_garage_door_tilt_sensor_sensor +sonos: + media_player: + hosts: + - 192.168.1.195 + - 192.168.1.186 + mobile_app: # map: # updater: @@ -108,6 +116,11 @@ binary_sensor: lovelace: mode: yaml +# Google Calendar +google: + client_id: !secret google_client_id + client_secret: !secret google_client_secret + emulated_hue: expose_by_default: false host_ip: !secret ha_ip_address diff --git a/custom_components/image_processing/tagbox.py b/custom_components/image_processing/tagbox.py deleted file mode 100644 index dfb9780..0000000 --- a/custom_components/image_processing/tagbox.py +++ /dev/null @@ -1,179 +0,0 @@ -""" -Search images for tagged objects via a local Tagbox instance. - -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/image_processing.tagbox - -This file is stolen from @robmarkcole's repo -""" -import base64 -import requests -import logging -import voluptuous as vol - -from homeassistant.core import ( - callback, split_entity_id) -import homeassistant.helpers.config_validation as cv -from homeassistant.components.image_processing import ( - PLATFORM_SCHEMA, ImageProcessingEntity, ATTR_CONFIDENCE, CONF_CONFIDENCE, - CONF_SOURCE, CONF_ENTITY_ID, CONF_NAME) -from homeassistant.const import ( - ATTR_ENTITY_ID, ATTR_NAME, CONF_IP_ADDRESS, CONF_PORT) -from homeassistant.util.async_ import run_callback_threadsafe - -_LOGGER = logging.getLogger(__name__) - -CLASSIFIER = 'tagbox' -EVENT_DETECT_TAG = 'image_processing.detect_tag' -TIMEOUT = 9 - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Required(CONF_IP_ADDRESS): cv.string, - vol.Required(CONF_PORT): cv.port, -}) - - -def encode_image(image): - """base64 encode an image stream.""" - base64_img = base64.b64encode(image).decode('ascii') - return base64_img - - -def get_matched_tags(tags, confidence): - """Return the name and rounded confidence of matched tags.""" - return {tag['name']: tag['confidence'] - for tag in tags if tag['confidence'] > confidence} - - -def parse_tags(api_tags): - """Parse the API tag data into the format required.""" - parsed_tags = [] - for entry in api_tags: - tag = {} - tag[ATTR_NAME] = entry['tag'] - tag[ATTR_CONFIDENCE] = round(100.0*entry['confidence'], 2) - parsed_tags.append(tag) - return parsed_tags - - -def post_image(url, image): - """Post an image to the classifier.""" - try: - response = requests.post( - url, - json={"base64": encode_image(image)}, - timeout=TIMEOUT - ) - return response - except requests.exceptions.ConnectionError: - _LOGGER.error("ConnectionError: Is %s running?", CLASSIFIER) - - -def setup_platform(hass, config, add_devices, discovery_info=None): - """Set up the classifier.""" - entities = [] - for camera in config[CONF_SOURCE]: - entities.append(ImageProcessingTagEntity( - config[CONF_IP_ADDRESS], - config[CONF_PORT], - camera[CONF_ENTITY_ID], - camera.get(CONF_NAME), - config[CONF_CONFIDENCE], - )) - add_devices(entities) - - -class ImageProcessingTagEntity(ImageProcessingEntity): - """Perform a tag search via a Tagbox.""" - - def __init__(self, ip, port, camera_entity, name, confidence): - """Init with the IP and PORT""" - super().__init__() - self._url_check = "http://{}:{}/{}/check".format(ip, port, CLASSIFIER) - self._camera = camera_entity - if name: - self._name = name - else: - camera_name = split_entity_id(camera_entity)[1] - self._name = "{} {}".format( - CLASSIFIER, camera_name) - self._confidence = confidence - self.tags = [] - self._matched = {} - - def process_image(self, image): - """Process an image.""" - response = post_image(self._url_check, image) - if response is not None: - response_json = response.json() - if response_json['success']: - api_tags = response_json['tags'] + response_json['custom_tags'] - tags = parse_tags(api_tags) - self.process_tags(tags) - self._matched = get_matched_tags(tags, self.confidence) - else: - self.tags = [] - self._matched = {} - - @property - def confidence(self): - """Return minimum confidence for send events.""" - return self._confidence - - @property - def state(self): - """Return the state of the entity.""" - state = None - - if len(self._matched) > 0: - return self.tags[0][ATTR_NAME] - - return state - - def process_tags(self, tags): - """Send event with detected tags and store data.""" - run_callback_threadsafe( - self.hass.loop, self.async_process_tags, tags).result() - - @callback - def async_process_tags(self, tags): - """Send event with detected tags and store data. - Tags are a dict in follow format: - [ - { - ATTR_CONFIDENCE: 80, - ATTR_NAME: 'people', - }, - ] - This method must be run in the event loop. - """ - # Send events - for tag in tags: - tag.update({ATTR_ENTITY_ID: self.entity_id}) - if tag[ATTR_CONFIDENCE] > self.confidence: - self.hass.async_add_job( - self.hass.bus.async_fire, EVENT_DETECT_TAG, tag - ) - - # Update entity store - self.tags = tags - - @property - def camera_entity(self): - """Return camera entity id from process pictures.""" - return self._camera - - @property - def name(self): - """Return the name of the sensor.""" - return self._name - - @property - def device_state_attributes(self): - """Return other details about the sensor state.""" - return { - 'tags': self.tags, - 'total_tags': len(self.tags), - 'matched_tags': self._matched, - 'total_matched_tags': len(self._matched), - } \ No newline at end of file diff --git a/custom_components/image_processing/tagbox.pyx b/custom_components/image_processing/tagbox.pyx new file mode 100644 index 0000000..54cc367 --- /dev/null +++ b/custom_components/image_processing/tagbox.pyx @@ -0,0 +1,179 @@ +# """ +# Search images for tagged objects via a local Tagbox instance. + +# For more details about this platform, please refer to the documentation at +# https://home-assistant.io/components/image_processing.tagbox + +# This file is stolen from @robmarkcole's repo +# """ +# import base64 +# import requests +# import logging +# import voluptuous as vol + +# from homeassistant.core import ( +# callback, split_entity_id) +# import homeassistant.helpers.config_validation as cv +# from homeassistant.components.image_processing import ( +# PLATFORM_SCHEMA, ImageProcessingEntity, ATTR_CONFIDENCE, CONF_CONFIDENCE, +# CONF_SOURCE, CONF_ENTITY_ID, CONF_NAME) +# from homeassistant.const import ( +# ATTR_ENTITY_ID, ATTR_NAME, CONF_IP_ADDRESS, CONF_PORT) +# from homeassistant.util.async_ import run_callback_threadsafe + +# _LOGGER = logging.getLogger(__name__) + +# CLASSIFIER = 'tagbox' +# EVENT_DETECT_TAG = 'image_processing.detect_tag' +# TIMEOUT = 9 + +# PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ +# vol.Required(CONF_IP_ADDRESS): cv.string, +# vol.Required(CONF_PORT): cv.port, +# }) + + +# def encode_image(image): +# """base64 encode an image stream.""" +# base64_img = base64.b64encode(image).decode('ascii') +# return base64_img + + +# def get_matched_tags(tags, confidence): +# """Return the name and rounded confidence of matched tags.""" +# return {tag['name']: tag['confidence'] +# for tag in tags if tag['confidence'] > confidence} + + +# def parse_tags(api_tags): +# """Parse the API tag data into the format required.""" +# parsed_tags = [] +# for entry in api_tags: +# tag = {} +# tag[ATTR_NAME] = entry['tag'] +# tag[ATTR_CONFIDENCE] = round(100.0*entry['confidence'], 2) +# parsed_tags.append(tag) +# return parsed_tags + + +# def post_image(url, image): +# """Post an image to the classifier.""" +# try: +# response = requests.post( +# url, +# json={"base64": encode_image(image)}, +# timeout=TIMEOUT +# ) +# return response +# except requests.exceptions.ConnectionError: +# _LOGGER.error("ConnectionError: Is %s running?", CLASSIFIER) + + +# def setup_platform(hass, config, add_devices, discovery_info=None): +# """Set up the classifier.""" +# entities = [] +# for camera in config[CONF_SOURCE]: +# entities.append(ImageProcessingTagEntity( +# config[CONF_IP_ADDRESS], +# config[CONF_PORT], +# camera[CONF_ENTITY_ID], +# camera.get(CONF_NAME), +# config[CONF_CONFIDENCE], +# )) +# add_devices(entities) + + +# class ImageProcessingTagEntity(ImageProcessingEntity): +# """Perform a tag search via a Tagbox.""" + +# def __init__(self, ip, port, camera_entity, name, confidence): +# """Init with the IP and PORT""" +# super().__init__() +# self._url_check = "http://{}:{}/{}/check".format(ip, port, CLASSIFIER) +# self._camera = camera_entity +# if name: +# self._name = name +# else: +# camera_name = split_entity_id(camera_entity)[1] +# self._name = "{} {}".format( +# CLASSIFIER, camera_name) +# self._confidence = confidence +# self.tags = [] +# self._matched = {} + +# def process_image(self, image): +# """Process an image.""" +# response = post_image(self._url_check, image) +# if response is not None: +# response_json = response.json() +# if response_json['success']: +# api_tags = response_json['tags'] + response_json['custom_tags'] +# tags = parse_tags(api_tags) +# self.process_tags(tags) +# self._matched = get_matched_tags(tags, self.confidence) +# else: +# self.tags = [] +# self._matched = {} + +# @property +# def confidence(self): +# """Return minimum confidence for send events.""" +# return self._confidence + +# @property +# def state(self): +# """Return the state of the entity.""" +# state = None + +# if len(self._matched) > 0: +# return self.tags[0][ATTR_NAME] + +# return state + +# def process_tags(self, tags): +# """Send event with detected tags and store data.""" +# run_callback_threadsafe( +# self.hass.loop, self.async_process_tags, tags).result() + +# @callback +# def async_process_tags(self, tags): +# """Send event with detected tags and store data. +# Tags are a dict in follow format: +# [ +# { +# ATTR_CONFIDENCE: 80, +# ATTR_NAME: 'people', +# }, +# ] +# This method must be run in the event loop. +# """ +# # Send events +# for tag in tags: +# tag.update({ATTR_ENTITY_ID: self.entity_id}) +# if tag[ATTR_CONFIDENCE] > self.confidence: +# self.hass.async_add_job( +# self.hass.bus.async_fire, EVENT_DETECT_TAG, tag +# ) + +# # Update entity store +# self.tags = tags + +# @property +# def camera_entity(self): +# """Return camera entity id from process pictures.""" +# return self._camera + +# @property +# def name(self): +# """Return the name of the sensor.""" +# return self._name + +# @property +# def device_state_attributes(self): +# """Return other details about the sensor state.""" +# return { +# 'tags': self.tags, +# 'total_tags': len(self.tags), +# 'matched_tags': self._matched, +# 'total_matched_tags': len(self._matched), +# } \ No newline at end of file diff --git a/custom_components/image_processing/tensorflow.py b/custom_components/image_processing/tensorflow.py deleted file mode 100644 index d711e97..0000000 --- a/custom_components/image_processing/tensorflow.py +++ /dev/null @@ -1,347 +0,0 @@ -""" -Component that performs TensorFlow classification on images. - -For a quick start, pick a pre-trained COCO model from: -https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md - -For more details about this platform, please refer to the documentation at -https://home-assistant.io/components/image_processing.tensorflow/ -""" -import logging -import sys -import os - -import voluptuous as vol - -from homeassistant.components.image_processing import ( - CONF_CONFIDENCE, CONF_ENTITY_ID, CONF_NAME, CONF_SOURCE, PLATFORM_SCHEMA, - ImageProcessingEntity) -from homeassistant.core import split_entity_id -from homeassistant.helpers import template -import homeassistant.helpers.config_validation as cv - -REQUIREMENTS = ['numpy==1.15.3', 'pillow==5.2.0', 'protobuf==3.6.1'] - -_LOGGER = logging.getLogger(__name__) - -ATTR_MATCHES = 'matches' -ATTR_SUMMARY = 'summary' -ATTR_TOTAL_MATCHES = 'total_matches' - -CONF_FILE_OUT = 'file_out' -CONF_MODEL = 'model' -CONF_GRAPH = 'graph' -CONF_LABELS = 'labels' -CONF_MODEL_DIR = 'model_dir' -CONF_CATEGORIES = 'categories' -CONF_CATEGORY = 'category' -CONF_AREA = 'area' -CONF_TOP = 'top' -CONF_LEFT = 'left' -CONF_BOTTOM = 'bottom' -CONF_RIGHT = 'right' - -AREA_SCHEMA = vol.Schema({ - vol.Optional(CONF_TOP, default=0): cv.small_float, - vol.Optional(CONF_LEFT, default=0): cv.small_float, - vol.Optional(CONF_BOTTOM, default=1): cv.small_float, - vol.Optional(CONF_RIGHT, default=1): cv.small_float -}) - -CATEGORY_SCHEMA = vol.Schema({ - vol.Required(CONF_CATEGORY): cv.string, - vol.Optional(CONF_AREA): AREA_SCHEMA -}) - -PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ - vol.Optional(CONF_FILE_OUT, default=[]): - vol.All(cv.ensure_list, [cv.template]), - vol.Required(CONF_MODEL): vol.Schema({ - vol.Required(CONF_GRAPH): cv.isfile, - vol.Optional(CONF_LABELS): cv.isfile, - vol.Optional(CONF_MODEL_DIR): cv.isdir, - vol.Optional(CONF_AREA): AREA_SCHEMA, - vol.Optional(CONF_CATEGORIES, default=[]): - vol.All(cv.ensure_list, [vol.Any( - cv.string, - CATEGORY_SCHEMA - )]) - }) -}) - - -def draw_box(draw, box, img_width, - img_height, text='', color=(255, 255, 0)): - """Draw bounding box on image.""" - ymin, xmin, ymax, xmax = box - (left, right, top, bottom) = (xmin * img_width, xmax * img_width, - ymin * img_height, ymax * img_height) - draw.line([(left, top), (left, bottom), (right, bottom), - (right, top), (left, top)], width=5, fill=color) - if text: - draw.text((left, abs(top-15)), text, fill=color) - - -def setup_platform(hass, config, add_entities, discovery_info=None): - """Set up the TensorFlow image processing platform.""" - model_config = config.get(CONF_MODEL) - model_dir = model_config.get(CONF_MODEL_DIR) \ - or hass.config.path('tensorflow') - labels = model_config.get(CONF_LABELS) \ - or hass.config.path('tensorflow', 'object_detection', - 'data', 'mscoco_label_map.pbtxt') - - # Make sure locations exist - if not os.path.isdir(model_dir) or not os.path.exists(labels): - _LOGGER.error("Unable to locate tensorflow models or label map.") - return - - # append custom model path to sys.path - sys.path.append(model_dir) - - try: - # Verify that the TensorFlow Object Detection API is pre-installed - # pylint: disable=unused-import,unused-variable - os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' - import tensorflow as tf # noqa - from object_detection.utils import label_map_util # noqa - except ImportError: - # pylint: disable=line-too-long - _LOGGER.error( - "No TensorFlow Object Detection library found! Install or compile " - "for your system following instructions here: " - "https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md") # noqa - return - - try: - # Display warning that PIL will be used if no OpenCV is found. - # pylint: disable=unused-import,unused-variable - import cv2 # noqa - except ImportError: - _LOGGER.warning("No OpenCV library found. " - "TensorFlow will process image with " - "PIL at reduced resolution.") - - # setup tensorflow graph, session, and label map to pass to processor - # pylint: disable=no-member - detection_graph = tf.Graph() - with detection_graph.as_default(): - od_graph_def = tf.GraphDef() - with tf.gfile.GFile(model_config.get(CONF_GRAPH), 'rb') as fid: - serialized_graph = fid.read() - od_graph_def.ParseFromString(serialized_graph) - tf.import_graph_def(od_graph_def, name='') - - session = tf.Session(graph=detection_graph) - label_map = label_map_util.load_labelmap(labels) - categories = label_map_util.convert_label_map_to_categories( - label_map, max_num_classes=90, use_display_name=True) - category_index = label_map_util.create_category_index(categories) - - entities = [] - - for camera in config[CONF_SOURCE]: - entities.append(TensorFlowImageProcessor( - hass, camera[CONF_ENTITY_ID], camera.get(CONF_NAME), - session, detection_graph, category_index, config)) - - add_entities(entities) - - -class TensorFlowImageProcessor(ImageProcessingEntity): - """Representation of an TensorFlow image processor.""" - - def __init__(self, hass, camera_entity, name, session, detection_graph, - category_index, config): - """Initialize the TensorFlow entity.""" - model_config = config.get(CONF_MODEL) - self.hass = hass - self._camera_entity = camera_entity - if name: - self._name = name - else: - self._name = "TensorFlow {0}".format( - split_entity_id(camera_entity)[1]) - self._session = session - self._graph = detection_graph - self._category_index = category_index - self._min_confidence = config.get(CONF_CONFIDENCE) - self._file_out = config.get(CONF_FILE_OUT) - - # handle categories and specific detection areas - categories = model_config.get(CONF_CATEGORIES) - self._include_categories = [] - self._category_areas = {} - for category in categories: - if isinstance(category, dict): - category_name = category.get(CONF_CATEGORY) - category_area = category.get(CONF_AREA) - self._include_categories.append(category_name) - self._category_areas[category_name] = [0, 0, 1, 1] - if category_area: - self._category_areas[category_name] = [ - category_area.get(CONF_TOP), - category_area.get(CONF_LEFT), - category_area.get(CONF_BOTTOM), - category_area.get(CONF_RIGHT) - ] - else: - self._include_categories.append(category) - self._category_areas[category] = [0, 0, 1, 1] - - # Handle global detection area - self._area = [0, 0, 1, 1] - area_config = model_config.get(CONF_AREA) - if area_config: - self._area = [ - area_config.get(CONF_TOP), - area_config.get(CONF_LEFT), - area_config.get(CONF_BOTTOM), - area_config.get(CONF_RIGHT) - ] - - template.attach(hass, self._file_out) - - self._matches = {} - self._total_matches = 0 - self._last_image = None - - @property - def camera_entity(self): - """Return camera entity id from process pictures.""" - return self._camera_entity - - @property - def name(self): - """Return the name of the image processor.""" - return self._name - - @property - def state(self): - """Return the state of the entity.""" - return self._total_matches - - @property - def device_state_attributes(self): - """Return device specific state attributes.""" - return { - ATTR_MATCHES: self._matches, - ATTR_SUMMARY: {category: len(values) - for category, values in self._matches.items()}, - ATTR_TOTAL_MATCHES: self._total_matches - } - - def _save_image(self, image, matches, paths): - from PIL import Image, ImageDraw - import io - img = Image.open(io.BytesIO(bytearray(image))).convert('RGB') - img_width, img_height = img.size - draw = ImageDraw.Draw(img) - - # Draw custom global region/area - if self._area != [0, 0, 1, 1]: - draw_box(draw, self._area, - img_width, img_height, - "Detection Area", (0, 255, 255)) - - for category, values in matches.items(): - # Draw custom category regions/areas - if (category in self._category_areas - and self._category_areas[category] != [0, 0, 1, 1]): - label = "{} Detection Area".format(category.capitalize()) - draw_box(draw, self._category_areas[category], img_width, - img_height, label, (0, 255, 0)) - - # Draw detected objects - for instance in values: - label = "{0} {1:.1f}%".format(category, instance['score']) - draw_box(draw, instance['box'], - img_width, img_height, - label, (255, 255, 0)) - - for path in paths: - _LOGGER.info("Saving results image to %s", path) - img.save(path) - - def process_image(self, image): - """Process the image.""" - import numpy as np - - try: - import cv2 # pylint: disable=import-error - img = cv2.imdecode( - np.asarray(bytearray(image)), cv2.IMREAD_UNCHANGED) - inp = img[:, :, [2, 1, 0]] # BGR->RGB - inp_expanded = inp.reshape(1, inp.shape[0], inp.shape[1], 3) - except ImportError: - from PIL import Image - import io - img = Image.open(io.BytesIO(bytearray(image))).convert('RGB') - img.thumbnail((460, 460), Image.ANTIALIAS) - img_width, img_height = img.size - inp = np.array(img.getdata()).reshape( - (img_height, img_width, 3)).astype(np.uint8) - inp_expanded = np.expand_dims(inp, axis=0) - - image_tensor = self._graph.get_tensor_by_name('image_tensor:0') - boxes = self._graph.get_tensor_by_name('detection_boxes:0') - scores = self._graph.get_tensor_by_name('detection_scores:0') - classes = self._graph.get_tensor_by_name('detection_classes:0') - boxes, scores, classes = self._session.run( - [boxes, scores, classes], - feed_dict={image_tensor: inp_expanded}) - boxes, scores, classes = map(np.squeeze, [boxes, scores, classes]) - classes = classes.astype(int) - - matches = {} - total_matches = 0 - for box, score, obj_class in zip(boxes, scores, classes): - score = score * 100 - boxes = box.tolist() - - # Exclude matches below min confidence value - if score < self._min_confidence: - continue - - # Exclude matches outside global area definition - if (boxes[0] < self._area[0] or boxes[1] < self._area[1] - or boxes[2] > self._area[2] or boxes[3] > self._area[3]): - continue - - category = self._category_index[obj_class]['name'] - - # Exclude unlisted categories - if (self._include_categories - and category not in self._include_categories): - continue - - # Exclude matches outside category specific area definition - if (self._category_areas - and (boxes[0] < self._category_areas[category][0] - or boxes[1] < self._category_areas[category][1] - or boxes[2] > self._category_areas[category][2] - or boxes[3] > self._category_areas[category][3])): - continue - - # If we got here, we should include it - if category not in matches.keys(): - matches[category] = [] - matches[category].append({ - 'score': float(score), - 'box': boxes - }) - total_matches += 1 - - # Save Images - if total_matches and self._file_out: - paths = [] - for path_template in self._file_out: - if isinstance(path_template, template.Template): - paths.append(path_template.render( - camera_entity=self._camera_entity)) - else: - paths.append(path_template) - self._save_image(image, matches, paths) - - self._matches = matches - self._total_matches = total_matches \ No newline at end of file diff --git a/custom_components/image_processing/tensorflow.pyx b/custom_components/image_processing/tensorflow.pyx new file mode 100644 index 0000000..41c7296 --- /dev/null +++ b/custom_components/image_processing/tensorflow.pyx @@ -0,0 +1,347 @@ +# """ +# Component that performs TensorFlow classification on images. + +# For a quick start, pick a pre-trained COCO model from: +# https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/detection_model_zoo.md + +# For more details about this platform, please refer to the documentation at +# https://home-assistant.io/components/image_processing.tensorflow/ +# """ +# import logging +# import sys +# import os + +# import voluptuous as vol + +# from homeassistant.components.image_processing import ( +# CONF_CONFIDENCE, CONF_ENTITY_ID, CONF_NAME, CONF_SOURCE, PLATFORM_SCHEMA, +# ImageProcessingEntity) +# from homeassistant.core import split_entity_id +# from homeassistant.helpers import template +# import homeassistant.helpers.config_validation as cv + +# REQUIREMENTS = ['numpy==1.15.3', 'pillow==5.2.0', 'protobuf==3.6.1'] + +# _LOGGER = logging.getLogger(__name__) + +# ATTR_MATCHES = 'matches' +# ATTR_SUMMARY = 'summary' +# ATTR_TOTAL_MATCHES = 'total_matches' + +# CONF_FILE_OUT = 'file_out' +# CONF_MODEL = 'model' +# CONF_GRAPH = 'graph' +# CONF_LABELS = 'labels' +# CONF_MODEL_DIR = 'model_dir' +# CONF_CATEGORIES = 'categories' +# CONF_CATEGORY = 'category' +# CONF_AREA = 'area' +# CONF_TOP = 'top' +# CONF_LEFT = 'left' +# CONF_BOTTOM = 'bottom' +# CONF_RIGHT = 'right' + +# AREA_SCHEMA = vol.Schema({ +# vol.Optional(CONF_TOP, default=0): cv.small_float, +# vol.Optional(CONF_LEFT, default=0): cv.small_float, +# vol.Optional(CONF_BOTTOM, default=1): cv.small_float, +# vol.Optional(CONF_RIGHT, default=1): cv.small_float +# }) + +# CATEGORY_SCHEMA = vol.Schema({ +# vol.Required(CONF_CATEGORY): cv.string, +# vol.Optional(CONF_AREA): AREA_SCHEMA +# }) + +# PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ +# vol.Optional(CONF_FILE_OUT, default=[]): +# vol.All(cv.ensure_list, [cv.template]), +# vol.Required(CONF_MODEL): vol.Schema({ +# vol.Required(CONF_GRAPH): cv.isfile, +# vol.Optional(CONF_LABELS): cv.isfile, +# vol.Optional(CONF_MODEL_DIR): cv.isdir, +# vol.Optional(CONF_AREA): AREA_SCHEMA, +# vol.Optional(CONF_CATEGORIES, default=[]): +# vol.All(cv.ensure_list, [vol.Any( +# cv.string, +# CATEGORY_SCHEMA +# )]) +# }) +# }) + + +# def draw_box(draw, box, img_width, +# img_height, text='', color=(255, 255, 0)): +# """Draw bounding box on image.""" +# ymin, xmin, ymax, xmax = box +# (left, right, top, bottom) = (xmin * img_width, xmax * img_width, +# ymin * img_height, ymax * img_height) +# draw.line([(left, top), (left, bottom), (right, bottom), +# (right, top), (left, top)], width=5, fill=color) +# if text: +# draw.text((left, abs(top-15)), text, fill=color) + + +# def setup_platform(hass, config, add_entities, discovery_info=None): +# """Set up the TensorFlow image processing platform.""" +# model_config = config.get(CONF_MODEL) +# model_dir = model_config.get(CONF_MODEL_DIR) \ +# or hass.config.path('tensorflow') +# labels = model_config.get(CONF_LABELS) \ +# or hass.config.path('tensorflow', 'object_detection', +# 'data', 'mscoco_label_map.pbtxt') + +# # Make sure locations exist +# if not os.path.isdir(model_dir) or not os.path.exists(labels): +# _LOGGER.error("Unable to locate tensorflow models or label map.") +# return + +# # append custom model path to sys.path +# sys.path.append(model_dir) + +# try: +# # Verify that the TensorFlow Object Detection API is pre-installed +# # pylint: disable=unused-import,unused-variable +# os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' +# import tensorflow as tf # noqa +# from object_detection.utils import label_map_util # noqa +# except ImportError: +# # pylint: disable=line-too-long +# _LOGGER.error( +# "No TensorFlow Object Detection library found! Install or compile " +# "for your system following instructions here: " +# "https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/installation.md") # noqa +# return + +# try: +# # Display warning that PIL will be used if no OpenCV is found. +# # pylint: disable=unused-import,unused-variable +# import cv2 # noqa +# except ImportError: +# _LOGGER.warning("No OpenCV library found. " +# "TensorFlow will process image with " +# "PIL at reduced resolution.") + +# # setup tensorflow graph, session, and label map to pass to processor +# # pylint: disable=no-member +# detection_graph = tf.Graph() +# with detection_graph.as_default(): +# od_graph_def = tf.GraphDef() +# with tf.gfile.GFile(model_config.get(CONF_GRAPH), 'rb') as fid: +# serialized_graph = fid.read() +# od_graph_def.ParseFromString(serialized_graph) +# tf.import_graph_def(od_graph_def, name='') + +# session = tf.Session(graph=detection_graph) +# label_map = label_map_util.load_labelmap(labels) +# categories = label_map_util.convert_label_map_to_categories( +# label_map, max_num_classes=90, use_display_name=True) +# category_index = label_map_util.create_category_index(categories) + +# entities = [] + +# for camera in config[CONF_SOURCE]: +# entities.append(TensorFlowImageProcessor( +# hass, camera[CONF_ENTITY_ID], camera.get(CONF_NAME), +# session, detection_graph, category_index, config)) + +# add_entities(entities) + + +# class TensorFlowImageProcessor(ImageProcessingEntity): +# """Representation of an TensorFlow image processor.""" + +# def __init__(self, hass, camera_entity, name, session, detection_graph, +# category_index, config): +# """Initialize the TensorFlow entity.""" +# model_config = config.get(CONF_MODEL) +# self.hass = hass +# self._camera_entity = camera_entity +# if name: +# self._name = name +# else: +# self._name = "TensorFlow {0}".format( +# split_entity_id(camera_entity)[1]) +# self._session = session +# self._graph = detection_graph +# self._category_index = category_index +# self._min_confidence = config.get(CONF_CONFIDENCE) +# self._file_out = config.get(CONF_FILE_OUT) + +# # handle categories and specific detection areas +# categories = model_config.get(CONF_CATEGORIES) +# self._include_categories = [] +# self._category_areas = {} +# for category in categories: +# if isinstance(category, dict): +# category_name = category.get(CONF_CATEGORY) +# category_area = category.get(CONF_AREA) +# self._include_categories.append(category_name) +# self._category_areas[category_name] = [0, 0, 1, 1] +# if category_area: +# self._category_areas[category_name] = [ +# category_area.get(CONF_TOP), +# category_area.get(CONF_LEFT), +# category_area.get(CONF_BOTTOM), +# category_area.get(CONF_RIGHT) +# ] +# else: +# self._include_categories.append(category) +# self._category_areas[category] = [0, 0, 1, 1] + +# # Handle global detection area +# self._area = [0, 0, 1, 1] +# area_config = model_config.get(CONF_AREA) +# if area_config: +# self._area = [ +# area_config.get(CONF_TOP), +# area_config.get(CONF_LEFT), +# area_config.get(CONF_BOTTOM), +# area_config.get(CONF_RIGHT) +# ] + +# template.attach(hass, self._file_out) + +# self._matches = {} +# self._total_matches = 0 +# self._last_image = None + +# @property +# def camera_entity(self): +# """Return camera entity id from process pictures.""" +# return self._camera_entity + +# @property +# def name(self): +# """Return the name of the image processor.""" +# return self._name + +# @property +# def state(self): +# """Return the state of the entity.""" +# return self._total_matches + +# @property +# def device_state_attributes(self): +# """Return device specific state attributes.""" +# return { +# ATTR_MATCHES: self._matches, +# ATTR_SUMMARY: {category: len(values) +# for category, values in self._matches.items()}, +# ATTR_TOTAL_MATCHES: self._total_matches +# } + +# def _save_image(self, image, matches, paths): +# from PIL import Image, ImageDraw +# import io +# img = Image.open(io.BytesIO(bytearray(image))).convert('RGB') +# img_width, img_height = img.size +# draw = ImageDraw.Draw(img) + +# # Draw custom global region/area +# if self._area != [0, 0, 1, 1]: +# draw_box(draw, self._area, +# img_width, img_height, +# "Detection Area", (0, 255, 255)) + +# for category, values in matches.items(): +# # Draw custom category regions/areas +# if (category in self._category_areas +# and self._category_areas[category] != [0, 0, 1, 1]): +# label = "{} Detection Area".format(category.capitalize()) +# draw_box(draw, self._category_areas[category], img_width, +# img_height, label, (0, 255, 0)) + +# # Draw detected objects +# for instance in values: +# label = "{0} {1:.1f}%".format(category, instance['score']) +# draw_box(draw, instance['box'], +# img_width, img_height, +# label, (255, 255, 0)) + +# for path in paths: +# _LOGGER.info("Saving results image to %s", path) +# img.save(path) + +# def process_image(self, image): +# """Process the image.""" +# import numpy as np + +# try: +# import cv2 # pylint: disable=import-error +# img = cv2.imdecode( +# np.asarray(bytearray(image)), cv2.IMREAD_UNCHANGED) +# inp = img[:, :, [2, 1, 0]] # BGR->RGB +# inp_expanded = inp.reshape(1, inp.shape[0], inp.shape[1], 3) +# except ImportError: +# from PIL import Image +# import io +# img = Image.open(io.BytesIO(bytearray(image))).convert('RGB') +# img.thumbnail((460, 460), Image.ANTIALIAS) +# img_width, img_height = img.size +# inp = np.array(img.getdata()).reshape( +# (img_height, img_width, 3)).astype(np.uint8) +# inp_expanded = np.expand_dims(inp, axis=0) + +# image_tensor = self._graph.get_tensor_by_name('image_tensor:0') +# boxes = self._graph.get_tensor_by_name('detection_boxes:0') +# scores = self._graph.get_tensor_by_name('detection_scores:0') +# classes = self._graph.get_tensor_by_name('detection_classes:0') +# boxes, scores, classes = self._session.run( +# [boxes, scores, classes], +# feed_dict={image_tensor: inp_expanded}) +# boxes, scores, classes = map(np.squeeze, [boxes, scores, classes]) +# classes = classes.astype(int) + +# matches = {} +# total_matches = 0 +# for box, score, obj_class in zip(boxes, scores, classes): +# score = score * 100 +# boxes = box.tolist() + +# # Exclude matches below min confidence value +# if score < self._min_confidence: +# continue + +# # Exclude matches outside global area definition +# if (boxes[0] < self._area[0] or boxes[1] < self._area[1] +# or boxes[2] > self._area[2] or boxes[3] > self._area[3]): +# continue + +# category = self._category_index[obj_class]['name'] + +# # Exclude unlisted categories +# if (self._include_categories +# and category not in self._include_categories): +# continue + +# # Exclude matches outside category specific area definition +# if (self._category_areas +# and (boxes[0] < self._category_areas[category][0] +# or boxes[1] < self._category_areas[category][1] +# or boxes[2] > self._category_areas[category][2] +# or boxes[3] > self._category_areas[category][3])): +# continue + +# # If we got here, we should include it +# if category not in matches.keys(): +# matches[category] = [] +# matches[category].append({ +# 'score': float(score), +# 'box': boxes +# }) +# total_matches += 1 + +# # Save Images +# if total_matches and self._file_out: +# paths = [] +# for path_template in self._file_out: +# if isinstance(path_template, template.Template): +# paths.append(path_template.render( +# camera_entity=self._camera_entity)) +# else: +# paths.append(path_template) +# self._save_image(image, matches, paths) + +# self._matches = matches +# self._total_matches = total_matches \ No newline at end of file diff --git a/jinja_helpers/jinja_lovelace.md b/jinja_helpers/jinja_lovelace.md index 2afe38a..b7c50c6 100644 --- a/jinja_helpers/jinja_lovelace.md +++ b/jinja_helpers/jinja_lovelace.md @@ -67,7 +67,7 @@ The output of the above script would look like the following: title: Alarm Control Panel show_header_toggle: true entities: - - alarm_control_panel.simplisafe + - alarm_control_panel.home name: Home Security System - type: entities @@ -76,7 +76,7 @@ The output of the above script would look like the following: entities: - sun.sun name: Sun - + - type: entities title: Proximity show_header_toggle: true @@ -105,6 +105,7 @@ The output of the above script would look like the following: {%- endfor %} {% endfor %} ``` + The output of above would look something like: ``` diff --git a/lovelace/00_myhome_view.yaml b/lovelace/00_myhome_view.yaml index 552245f..36428cb 100644 --- a/lovelace/00_myhome_view.yaml +++ b/lovelace/00_myhome_view.yaml @@ -4,7 +4,7 @@ cards: - type: horizontal-stack cards: - type: "custom:button-card" - entity: alarm_control_panel.simplisafe + entity: alarm_control_panel.home icon: mdi:security color_type: card show_state: true @@ -52,7 +52,7 @@ cards: name: Srinika - entity: device_tracker.life360_hasika name: Hasika - - entity: device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker + - entity: device_tracker.mahasri_tesla_location_tracker name: Tesla state_filter: - "home" @@ -60,6 +60,16 @@ cards: type: glance title: Kalavala Family + - type: entities + title: Tile Devices + show_header_toggle: false + entities: + - device_tracker.tile_08beea8370ec23b7 + - device_tracker.tile_43a0d518532978f8 + - device_tracker.tile_49318f5ab14343a5 + - device_tracker.tile_63ca05b6a3619232 + - device_tracker.tile_p_32c03dc7f21001d36d16b47646e4c421 + - type: entity-filter title: For Your Information show_empty: false @@ -105,23 +115,23 @@ cards: - script.emergency_script - script.emergency_script_loop - # - type: horizontal-stack - # cards: - # - type: glance - # entities: - # - input_label.mallika_birthday_days2go - # - type: glance - # entities: - # - input_label.srinika_birthday_days2go - # - type: glance - # entities: - # - input_label.hasika_birthday_days2go + - type: horizontal-stack + cards: + - type: glance + entities: + - input_label.mallika_birthday_days2go + - type: glance + entities: + - input_label.srinika_birthday_days2go + - type: glance + entities: + - input_label.hasika_birthday_days2go - type: entity-filter title: Doors show_empty: false entities: - - alarm_control_panel.simplisafe + - alarm_control_panel.home - entity: binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor name: Front Door - entity: binary_sensor.back_door_sensor_sensor @@ -207,6 +217,53 @@ cards: - sensor.tv_multi_sensor_luminance - sensor.upstairs_multi_sensor_luminance + - type: entities + title: Xiaomi Motion Sensors + show_header_toggle: false + entities: + - binary_sensor.garage_motion + - binary_sensor.patio_camera_motion + - binary_sensor.playarea_camera_motion + - binary_sensor.frontdoor_camera_motion + - binary_sensor.driveway_camera_motion + + - type: entity-filter + title: Motion Sensors + show_empty: false + entities: + - binary_sensor.motion_sensor_158d0001a662fe + - binary_sensor.motion_sensor_158d0001a25041 + - binary_sensor.motion_sensor_158d00016db6d2 + - binary_sensor.motion_sensor_158d00016c2d0e + - binary_sensor.garage_motion + - binary_sensor.patio_camera_motion + - binary_sensor.playarea_camera_motion + - binary_sensor.frontdoor_camera_motion + - binary_sensor.driveway_camera_motion + - binary_sensor.aeotec_water_sensor_sensor + - binary_sensor.audio_detector_sensor + - binary_sensor.basement_door_sensor_sensor + - binary_sensor.downstairs_multi_sensor_sensor + - binary_sensor.front_room_multi_sensor_sensor + - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor + - binary_sensor.garage_door_sensor_sensor + - binary_sensor.kitchen_motion_sensor_sensor + - binary_sensor.back_door_sensor_sensor + - binary_sensor.stairs_motion_sensor_sensor + - binary_sensor.tv_multi_sensor_sensor + - binary_sensor.single_car_garage_door_tilt_sensor_sensor + - binary_sensor.two_car_garage_door_tilt_sensor_sensor + - binary_sensor.upstairs_multi_sensor_sensor + state_filter: + - "on" + - "detected" + - "opened" + - "Open" + card: + type: entities + title: Motion Sensors + show_header_toggle: false + - type: conditional conditions: - entity: sensor.season @@ -253,43 +310,6 @@ cards: yellow: 4 red: 7 - - type: entity-filter - title: Motion Sensors - show_empty: false - entities: - - binary_sensor.motion_sensor_158d0001a662fe - - binary_sensor.motion_sensor_158d0001a25041 - - binary_sensor.motion_sensor_158d00016db6d2 - - binary_sensor.motion_sensor_158d00016c2d0e - - binary_sensor.garage_motion - - binary_sensor.patio_camera_motion - - binary_sensor.playarea_camera_motion - - binary_sensor.frontdoor_camera_motion - - binary_sensor.driveway_camera_motion - - binary_sensor.aeotec_water_sensor_sensor - - binary_sensor.audio_detector_sensor - - binary_sensor.basement_door_sensor_sensor - - binary_sensor.downstairs_multi_sensor_sensor - - binary_sensor.front_room_multi_sensor_sensor - - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor - - binary_sensor.garage_door_sensor_sensor - - binary_sensor.kitchen_motion_sensor_sensor - - binary_sensor.back_door_sensor_sensor - - binary_sensor.stairs_motion_sensor_sensor - - binary_sensor.tv_multi_sensor_sensor - - binary_sensor.single_car_garage_door_tilt_sensor_sensor - - binary_sensor.two_car_garage_door_tilt_sensor_sensor - - binary_sensor.upstairs_multi_sensor_sensor - state_filter: - - "on" - - "detected" - - "opened" - - "Open" - card: - type: entities - title: Motion Sensors - show_header_toggle: false - - type: entities title: Z-Wave Batteries show_header_toggle: false diff --git a/lovelace/01_lights_view.yaml b/lovelace/01_lights_view.yaml index 824c70b..3f1a26b 100644 --- a/lovelace/01_lights_view.yaml +++ b/lovelace/01_lights_view.yaml @@ -23,6 +23,7 @@ cards: title: Downstairs show_header_toggle: true entities: + - switch.front_room - switch.basement_left - switch.basement_right - switch.kitchen diff --git a/lovelace/06_tesla_view.yaml b/lovelace/06_tesla_view.yaml index 67064d8..9d79309 100644 --- a/lovelace/06_tesla_view.yaml +++ b/lovelace/06_tesla_view.yaml @@ -40,10 +40,11 @@ cards: title: Tesla Car show_header_toggle: false entities: - - device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker + - device_tracker.mahasri_tesla_location_tracker - binary_sensor.tesla_model_3_parking_brake_sensor - lock.tesla_model_3_door_lock - sensor.tesla_model_3_mileage_sensor + - switch.tesla_model_3_update_switch - type: entities title: Charging diff --git a/lovelace/08_multimedia_view.yaml b/lovelace/08_multimedia_view.yaml index 078f646..f76ff6b 100644 --- a/lovelace/08_multimedia_view.yaml +++ b/lovelace/08_multimedia_view.yaml @@ -1,12 +1,12 @@ title: Multi Room Audio & TTS icon: mdi:television cards: - - type: entities - title: Snapcast Server Commands - show_header_toggle: false - entities: - - entity: input_select.snapcast_server - name: Snapcast Server Command + # - type: entities + # title: Snapcast Server Commands + # show_header_toggle: false + # entities: + # - entity: input_select.snapcast_server + # name: Snapcast Server Command - type: entities title: Raspberry Pi Commands @@ -43,37 +43,39 @@ cards: show_header_toggle: false entities: # - media_player.denon_avr_x2400h - - media_player.gstreamer - - media_player.mpd + # - media_player.gstreamer + # - media_player.mpd - media_player.attic_tv + - media_player.living_room + - media_player.upstairs # - media_player.my_denon_receiver - type: vertical-stack cards: - type: media-control - entity: media_player.mpd + entity: media_player.living_room + - type: media-control + entity: media_player.upstairs # - type: media-control - # entity: media_player.denon_avr_x2400h + # entity: media_player.denon_avr_x2400h - - type: media-control - entity: media_player.gstreamer + # - type: media-control + # entity: media_player.gstreamer - type: media-control entity: media_player.attic_tv - + - type: media-control entity: media_player.chromecastultra7021 - # - type: media-control # entity: media_player.my_denon_receiver - - - type: entities - title: Snapcast Clients - show_header_toggle: false - entities: - - media_player.snapcast_client_b827eb011e00 - - media_player.snapcast_client_b827eb4445b1 - - media_player.snapcast_client_b827eb505e2d - - media_player.snapcast_client_b827eba8e7ef - - media_player.snapcast_client_b827ebaa08f7 \ No newline at end of file + # - type: entities + # title: Snapcast Clients + # show_header_toggle: false + # entities: + # - media_player.snapcast_client_b827eb011e00 + # - media_player.snapcast_client_b827eb4445b1 + # - media_player.snapcast_client_b827eb505e2d + # - media_player.snapcast_client_b827eba8e7ef + # - media_player.snapcast_client_b827ebaa08f7 diff --git a/lovelace/10_raspberrypi_view.yaml b/lovelace/10_raspberrypi_view.yaml index becf115..5144bf4 100644 --- a/lovelace/10_raspberrypi_view.yaml +++ b/lovelace/10_raspberrypi_view.yaml @@ -90,6 +90,3 @@ cards: - script.restart_all_raspberrypis - script.restart_all_snapclients - script.shutdown_all_raspberrypis - - script.restart_snapcast_server - - script.start_snapcast_server - - script.stop_snapcast_server diff --git a/lovelace/12_automations_view.yaml b/lovelace/12_automations_view.yaml index 4d0bde6..c2e9ae0 100644 --- a/lovelace/12_automations_view.yaml +++ b/lovelace/12_automations_view.yaml @@ -63,7 +63,6 @@ cards: - automation.notify_charger_switch_state - automation.notify_charging_status - automation.notify_door_status - - automation.notify_entry_door_status - automation.notify_holiday_state_change - automation.notify_indian_holidays - automation.notify_low_battery @@ -157,8 +156,6 @@ cards: - automation.restore_familyroom_lights - automation.animate_master_bedroom_lights - automation.restore_masterbedroom_lights - - automation.basement_accent_lights_off_after_5_minutes - - automation.basement_accent_lights_on_when_basement_door_opened - automation.evening_indoor_lights_on_before_sunset - automation.evening_outdoor_lights_on_at_sunset - automation.garage_lights_on_when_door_is_opened @@ -266,7 +263,6 @@ cards: show_header_toggle: false entities: - automation.keep_chromecast_on - - automation.snapcast_action - type: entities title: Home Assistant Automations diff --git a/packages/away.yaml b/packages/away.yaml index c29beb7..a307541 100644 --- a/packages/away.yaml +++ b/packages/away.yaml @@ -18,7 +18,7 @@ script: away_mode: "true" - service: alarm_control_panel.alarm_arm_away data: - entity_id: alarm_control_panel.simplisafe + entity_id: alarm_control_panel.home - service: script.notify_me data: message: > diff --git a/packages/batteries.yaml b/packages/batteries.yaml index 5c38e8a..5897305 100644 --- a/packages/batteries.yaml +++ b/packages/batteries.yaml @@ -366,7 +366,7 @@ automation: - condition: template value_template: "{{ states('input_boolean.home_mode_away') == 'off' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') | lower != 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') | lower != 'armed_away' }}" action: - service: script.voice_notify data_template: diff --git a/packages/birthday.yaml b/packages/birthday.yaml index 0d7ec44..f6ea5f1 100644 --- a/packages/birthday.yaml +++ b/packages/birthday.yaml @@ -73,9 +73,6 @@ automation: - input_label.hasika_birthday_days2go - input_label.mallika_birthday_days2go condition: - - condition: state - entity_id: group.all_devices - state: "home" - condition: template value_template: "{{ trigger.to_state.state | int > 0 and trigger.to_state.state | int < 30 }}" action: @@ -95,9 +92,6 @@ automation: - input_label.hasika_birthday_days2go - input_label.mallika_birthday_days2go condition: - - condition: state - entity_id: group.all_devices - state: "home" - condition: template value_template: "{{ trigger.to_state.state | int == 0 }}" action: @@ -118,9 +112,6 @@ automation: condition: condition: and conditions: - - condition: state - entity_id: group.all_devices - state: "home" - condition: time after: "07:00:00" before: "21:00:00" diff --git a/packages/cameras.yaml b/packages/cameras.yaml index 3d93e0e..d423c2e 100644 --- a/packages/cameras.yaml +++ b/packages/cameras.yaml @@ -312,7 +312,7 @@ automation: url: !secret frontdoor_camera_stream_url name: "frontyard" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" - service: image_processing.scan data_template: entity_id: image_processing.tensorflow_frontdoor_camera @@ -392,7 +392,7 @@ automation: url: !secret driveway_camera_stream_url name: "driveway" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" - service: image_processing.scan data_template: entity_id: image_processing.tensorflow_driveway_camera @@ -468,7 +468,7 @@ automation: - condition: template value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" action: - service: image_processing.scan data_template: @@ -547,7 +547,7 @@ automation: url: !secret playarea_camera_stream_url name: "backyard" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" - service: image_processing.scan data_template: entity_id: image_processing.tensorflow_patio_camera @@ -641,7 +641,7 @@ automation: - condition: template value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" action: - delay: "{{ '00:00:08' if states('binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor') == 'on' else '0:0:0' }}" - service: camera.snapshot @@ -712,7 +712,7 @@ automation: - condition: template value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" action: - service: camera.snapshot data_template: @@ -782,7 +782,7 @@ automation: - condition: template value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'armed_home' or states('alarm_control_panel.simplisafe') == 'armed_away' }}" + value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == 'armed_away' }}" action: - condition: template value_template: >- @@ -866,29 +866,29 @@ automation: - service: script.frontdoor_camera_text_overlay data_template: text: > - {{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or - states('alarm_control_panel.simplisafe') == 'armed_away' -}} + {{ '* ' if states('alarm_control_panel.home') == 'armed_home' or + states('alarm_control_panel.home') == 'armed_away' -}} {{- states('sensor.dark_sky_temperature')|int}} °F, Feels like {{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}} - service: script.driveway_camera_text_overlay data_template: text: > - {{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or - states('alarm_control_panel.simplisafe') == 'armed_away' -}} + {{ '* ' if states('alarm_control_panel.home') == 'armed_home' or + states('alarm_control_panel.home') == 'armed_away' -}} {{- states('sensor.dark_sky_temperature')|int}} °F, Feels like {{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}} - service: script.playarea_camera_text_overlay data_template: text: > - {{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or - states('alarm_control_panel.simplisafe') == 'armed_away' -}} + {{ '* ' if states('alarm_control_panel.home') == 'armed_home' or + states('alarm_control_panel.home') == 'armed_away' -}} {{- states('sensor.dark_sky_temperature')|int}} °F, Feels like {{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}} - service: script.patio_camera_text_overlay data_template: text: > - {{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or - states('alarm_control_panel.simplisafe') == 'armed_away' -}} + {{ '* ' if states('alarm_control_panel.home') == 'armed_home' or + states('alarm_control_panel.home') == 'armed_away' -}} {{- states('sensor.dark_sky_temperature')|int}} °F, Feels like {{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}} diff --git a/packages/daily_routines.yaml b/packages/daily_routines.yaml index e76b93a..65f0159 100644 --- a/packages/daily_routines.yaml +++ b/packages/daily_routines.yaml @@ -290,9 +290,6 @@ automation: platform: time at: "22:10:00" condition: - - condition: state - entity_id: group.all_devices - state: "home" - condition: template value_template: "{{ states('input_boolean.nightly_report') == 'on' }}" action: diff --git a/packages/door_sensors.yaml b/packages/door_sensors.yaml index c88592c..eb7d149 100644 --- a/packages/door_sensors.yaml +++ b/packages/door_sensors.yaml @@ -219,6 +219,65 @@ automation: data: entity_id: switch.garage + # Notify Entry Door Status + ############################################################################### + - alias: Voice Notify Entry Door Status + initial_state: true + trigger: + platform: state + entity_id: + - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor + - binary_sensor.back_door_sensor_sensor + condition: + - condition: template + value_template: "{% if trigger.from_state %} True {% else %} False {% endif %}" + action: + - service: script.voice_notify + data_template: + message: > + {% if trigger.to_state.state | lower == "on" %} + Your {{ trigger.to_state.attributes.friendly_name.replace('Sensor', '') }} is OPEN, + {% if states('alarm_control_panel.home') == 'armed_home' or + states('alarm_control_panel.home') == 'armed_away' %} + But your home security system is ON. + {% endif %} + {% elif trigger.to_state.state | lower == "off" %} + Your {{ trigger.to_state.attributes.friendly_name.replace('Sensor', '') }} is CLOSED! + {% endif %} + greeting: "no" + only_at_night: > + {% if states('alarm_control_panel.home') == 'armed_home' %} + no + {% else %} + yes + {% endif %} + + - alias: When Front Door Opens Turn Front Room Lights ON + initial_state: true + trigger: + platform: state + entity_id: binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor + to: "on" + condition: + - condition: template + value_template: "{{ states('sun.sun') == 'below_horizon' }}" + action: + - service: switch.turn_on + entity_id: switch.front_room + + - alias: When Back Door Opens Turn Kitchen Lights ON + initial_state: true + trigger: + platform: state + entity_id: binary_sensor.back_door_sensor_sensor + to: "on" + condition: + - condition: template + value_template: "{{ states('sun.sun') == 'below_horizon' }}" + action: + - service: switch.turn_on + entity_id: switch.kitchen + ################################################################################ # When I open the garage door # if it is dark outside, OR @@ -247,69 +306,3 @@ automation: entity_id: switch.garage - service: timer.start entity_id: timer.timer_garage - - # Notify Entry Door Status - ############################################################################### - - alias: Notify Entry Door Status - initial_state: true - trigger: - platform: state - entity_id: - - binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor - - binary_sensor.back_door_sensor_sensor - condition: - - condition: template - value_template: "{% if trigger.from_state %} True {% else %} False {% endif %}" - action: - - service: script.voice_notify - data_template: - message: > - {% if trigger.to_state.state | lower == "on" %} - Your {{ trigger.to_state.attributes.friendly_name.replace('Sensor', '') }} is OPEN, - {% if states('alarm_control_panel.simplisafe') == 'armed_home' or - states('alarm_control_panel.simplisafe') == 'armed_away' %} - But your home security system is ON. - {% endif %} - {% elif trigger.to_state.state | lower == "off" %} - Your {{ trigger.to_state.attributes.friendly_name.replace('Sensor', '') }} is CLOSED! - {% endif %} - greeting: "no" - only_at_night: > - {% if states('alarm_control_panel.simplisafe') == 'armed_home' %} - no - {% else %} - yes - {% endif %} - - # Turn ON and OFF basement ambient lights - ############################################################################### - - alias: Basement Accent Lights ON When Basement Door Opened - initial_state: true - trigger: - platform: state - entity_id: binary_sensor.basement_door_sensor_sensor - to: "on" - condition: - - condition: state - entity_id: input_boolean.light_automations - state: "on" - action: - - service: homeassistant.turn_on - entity_id: switch.rf_switch_one - - - alias: Basement Accent Lights OFF After 5 minutes - initial_state: true - trigger: - platform: state - entity_id: - - switch.rf_switch_one - to: "on" - for: - minutes: 5 - condition: - - condition: state - entity_id: input_boolean.light_automations - state: "on" - action: - - service: homeassistant.turn_off - entity_id: switch.rf_switch_one diff --git a/packages/emergency.yaml b/packages/emergency.yaml index 2385ffa..37ba173 100644 --- a/packages/emergency.yaml +++ b/packages/emergency.yaml @@ -150,7 +150,7 @@ # initial_state: true # trigger: # platform: state -# entity_id: alarm_control_panel.simplisafe +# entity_id: alarm_control_panel.home # to: 'disarmed' # condition: # - condition: template @@ -186,7 +186,7 @@ # value_template: "{{ trigger.from_state }}" # - condition: template # value_template: > -# {% set state = states.alarm_control_panel.simplisafe.state %} +# {% set state = states.alarm_control_panel.home.state %} # {% if state != "" and state != "unknown" and state == "armed_away" %} # true # {% else %} diff --git a/packages/google_geocode.yaml b/packages/google_geocode.yaml deleted file mode 100644 index a535465..0000000 --- a/packages/google_geocode.yaml +++ /dev/null @@ -1,51 +0,0 @@ -# homeassistant: -# customize: -# # Locations -# sensor.suresh_location: -# friendly_name: Suresh -# icon: mdi:map-marker -# sensor.mallika_location: -# friendly_name: Mallika -# icon: mdi:map-marker -# sensor.srinika_location: -# friendly_name: Srinika -# icon: mdi:map-marker -# sensor.hasika_location: -# friendly_name: Hasika -# icon: mdi:map-marker - -# # Google Calendar -# google: -# client_id: !secret google_client_id -# client_secret: !secret google_client_secret - -# # Google Travel Times and Geo Code/Location -# sensor: -# # Address/Location Details -# - platform: google_geocode -# name: Suresh Location -# api_key: !secret google_maps_geocoding_api -# origin: device_tracker.life360_suresh -# options: formatted_address -# display_zone: hide - -# - platform: google_geocode -# name: Mallika Location -# api_key: !secret google_maps_geocoding_api -# origin: device_tracker.life360_mallika -# options: formatted_address -# display_zone: hide - -# - platform: google_geocode -# name: Srinika Location -# api_key: !secret google_maps_geocoding_api -# origin: device_tracker.life360_srinika -# options: formatted_address -# display_zone: hide - -# - platform: google_geocode -# name: Hasika Location -# api_key: !secret google_maps_geocoding_api -# origin: device_tracker.life360_hasika -# options: formatted_address -# display_zone: hide diff --git a/packages/homesecurity.yaml b/packages/homesecurity.yaml index 34e37c7..9415d33 100644 --- a/packages/homesecurity.yaml +++ b/packages/homesecurity.yaml @@ -9,7 +9,7 @@ homeassistant: group.home_security_system: order: 7 - alarm_control_panel.simplisafe: + alarm_control_panel.home: friendly_name: Home Security System icon: mdi:security sensor.my_alarm_control_panel: @@ -40,35 +40,35 @@ automation: initial_state: true trigger: platform: state - entity_id: alarm_control_panel.simplisafe + entity_id: alarm_control_panel.home condition: - condition: template value_template: "{% if trigger.from_state %} True {% else %} False {% endif %}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') != 'unknown' }}" + value_template: "{{ states('alarm_control_panel.home') != 'unknown' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') | trim != '' }}" + value_template: "{{ states('alarm_control_panel.home') | trim != '' }}" action: - service_template: > - {% if states('alarm_control_panel.simplisafe') == "armed_home" %} + {% if states('alarm_control_panel.home') == "armed_home" %} script.xiaomi_blue - {% elif states('alarm_control_panel.simplisafe') == "armed_away" %} + {% elif states('alarm_control_panel.home') == "armed_away" %} script.xiaomi_green - {% elif states('alarm_control_panel.simplisafe') == "triggered" %} + {% elif states('alarm_control_panel.home') == "triggered" %} script.xiaomi_red - {% elif states('alarm_control_panel.simplisafe') == "disarmed" %} + {% elif states('alarm_control_panel.home') == "disarmed" %} script.xiaomi_red {% endif %} - service: script.ifttt_leeo_color_change data_template: value1: > - {% if states('alarm_control_panel.simplisafe') == "armed_home" %} + {% if states('alarm_control_panel.home') == "armed_home" %} "#0000FF" - {% elif states('alarm_control_panel.simplisafe') == "armed_away" %} + {% elif states('alarm_control_panel.home') == "armed_away" %} "#00FF00" - {% elif states('alarm_control_panel.simplisafe') == "triggered" %} + {% elif states('alarm_control_panel.home') == "triggered" %} "#FF0000" - {% elif states('alarm_control_panel.simplisafe') == "disarmed" %} + {% elif states('alarm_control_panel.home') == "disarmed" %} "#FF0000" {% endif %} @@ -79,7 +79,7 @@ automation: initial_state: true trigger: platform: state - entity_id: alarm_control_panel.simplisafe + entity_id: alarm_control_panel.home condition: - condition: template value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}" @@ -94,29 +94,29 @@ automation: - service: script.notify_me data_template: message: > - {% if states('alarm_control_panel.simplisafe') == "armed_home" %} + {% if states('alarm_control_panel.home') == "armed_home" %} Your home is now secured! - {% elif states('alarm_control_panel.simplisafe') == "armed_away" %} + {% elif states('alarm_control_panel.home') == "armed_away" %} Your Home Security System is now set to Away mode! - {% elif states('alarm_control_panel.simplisafe') == "triggered" %} + {% elif states('alarm_control_panel.home') == "triggered" %} Attention!: Your Home Security System is triggered! It has been notified to the authorities. - {% elif states('alarm_control_panel.simplisafe') == "disarmed" %} + {% elif states('alarm_control_panel.home') == "disarmed" %} Attention!: Your Home Security System is turned OFF. {% endif %} - service: script.voice_notify data_template: message: > - {% if states('alarm_control_panel.simplisafe') == "armed_home" %} + {% if states('alarm_control_panel.home') == "armed_home" %} Your home is now secured! - {% elif states('alarm_control_panel.simplisafe') == "armed_away" %} + {% elif states('alarm_control_panel.home') == "armed_away" %} Your Home Security System is now set to Away mode! - {% elif states('alarm_control_panel.simplisafe') == "triggered" %} + {% elif states('alarm_control_panel.home') == "triggered" %} Attention!: Your Home Security System is triggered! It has been notified to the authorities. - {% elif states('alarm_control_panel.simplisafe') == "disarmed" %} + {% elif states('alarm_control_panel.home') == "disarmed" %} Attention!: Your Home Security System is turned OFF. {% endif %} - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') != 'disarmed' }}" + value_template: "{{ states('alarm_control_panel.home') != 'disarmed' }}" - service: input_boolean.turn_on entity_id: input_boolean.notify_camera_motion @@ -128,14 +128,10 @@ automation: trigger: - platform: state entity_id: - - alarm_control_panel.simplisafe + - alarm_control_panel.home to: "disarmed" for: minutes: 10 - condition: - - condition: state - entity_id: group.all_devices - state: "home" action: - service: script.notify_me data: @@ -149,14 +145,11 @@ automation: trigger: - platform: state entity_id: - - alarm_control_panel.simplisafe + - alarm_control_panel.home to: "disarmed" for: minutes: 30 condition: - - condition: state - entity_id: group.all_devices - state: "home" - condition: template value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}" action: @@ -172,7 +165,7 @@ automation: initial_state: true trigger: platform: state - entity_id: alarm_control_panel.simplisafe + entity_id: alarm_control_panel.home condition: - condition: template value_template: > @@ -203,18 +196,15 @@ automation: - condition: template value_template: "{{ states('sensor.bedtime_minute')|int == now().minute|int }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') != 'away' }}" - - condition: state - entity_id: group.all_devices - state: "home" + value_template: "{{ states('alarm_control_panel.home') != 'away' }}" - condition: template - value_template: "{{ states('alarm_control_panel.simplisafe') == 'disarmed' }}" + value_template: "{{ states('alarm_control_panel.home') == 'disarmed' }}" - condition: template value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}" action: - service: alarm_control_panel.alarm_arm_home data: - entity_id: alarm_control_panel.simplisafe + entity_id: alarm_control_panel.home - service: script.notify_me data: message: "It's bedtime, you forgot to turn ON Home Security System. Turned it ON for you." @@ -231,7 +221,7 @@ automation: # condition: and # conditions: # - condition: template -# value_template: '{{ states('alarm_control_panel.simplisafe') == "armed_home" or states('alarm_control_panel.simplisafe') == "armed_away" }}' +# value_template: '{{ states('alarm_control_panel.home') == "armed_home" or states('alarm_control_panel.home') == "armed_away" }}' # - condition: or # conditions: # - condition: template @@ -244,7 +234,7 @@ automation: # - service: script.notify_me # data_template: # message: > -# Attention! Your home Security system is set to {{ states('alarm_control_panel.simplisafe').split('_')[1] | upper }} mode. +# Attention! Your home Security system is set to {{ states('alarm_control_panel.home').split('_')[1] | upper }} mode. # BUT THE {% if states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') == "on" -%}DOUBLE CAR {%- else %}SINGLE CAR {% endif %}GARAGE DOOR IS STILL OPEN! # - service: camera.snapshot # data_template: @@ -279,14 +269,14 @@ automation: # {% elif states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') == "on" %} # {% set doors = states('binary_sensor.two_car_garage_door_tilt_sensor_sensor.name %} # {% endif %} -# Your {{ doors }} seem to be open while your home security system is set to "{{ states('alarm_control_panel.simplisafe').split('_')[1]| title }}" mode. Today is {{ get_date(now()) }}, and time is {{ now().strftime("%I:%M:%S %p") }}. Please see the attached pictures and make sure everything is okay. +# Your {{ doors }} seem to be open while your home security system is set to "{{ states('alarm_control_panel.home').split('_')[1]| title }}" mode. Today is {{ get_date(now()) }}, and time is {{ now().strftime("%I:%M:%S %p") }}. Please see the attached pictures and make sure everything is okay. # data: # images: # - "{{ '/home/homeassistant/.homeassistant/www/downloads/camera/garage/garage_' ~ (states('automation.home_security_system_and_garage_door_check.last_updated ~ '').replace('-','_').replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}" # - "{{ '/home/homeassistant/.homeassistant/www/downloads/camera/driveway/driveway_' ~ (states('automation.home_security_system_and_garage_door_check.last_updated ~ '').replace('-','_').replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}" # - "{{ '/home/homeassistant/.homeassistant/www/downloads/camera/frontdoor/frontdoor_' ~ (states('automation.home_security_system_and_garage_door_check.last_updated ~ '').replace('-','_').replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}" # - condition: template -# value_template: '{{ states('alarm_control_panel.simplisafe') == "armed_home" }}' +# value_template: '{{ states('alarm_control_panel.home') == "armed_home" }}' # - service: script.voice_notify # data_template: # message: > @@ -298,7 +288,7 @@ automation: # {% elif states('binary_sensor.single_car_garage_door_tilt_sensor_sensor') == "on" %} # {% set doors = states('binary_sensor.two_car_garage_door_tilt_sensor_sensor.name %} # {% endif %} -# Attention! Your home Security system is set to {{ states('alarm_control_panel.simplisafe').split('_')[1] | upper }} mode. +# Attention! Your home Security system is set to {{ states('alarm_control_panel.home').split('_')[1] | upper }} mode. # BUT the {{ doors }} {{ 'are' if doors.endswith('s') else 'is' }} open. ############################################################################### @@ -312,10 +302,7 @@ automation: # offset: '+00:00:00' # condition: # - condition: state -# entity_id: group.all_devices -# state: 'home' -# - condition: state -# entity_id: alarm_control_panel.simplisafe +# entity_id: alarm_control_panel.home # state: 'disarmed' # action: # - service_template: >- @@ -328,7 +315,7 @@ automation: # alarm_control_panel.disarm # {% endif %} # data: -# entity_id: alarm_control_panel.simplisafe +# entity_id: alarm_control_panel.home # - service: script.voice_notify # data_template: # message: > @@ -417,9 +404,9 @@ automation: # condition: or # conditions: # - condition: template -# value_template: '{{ states('alarm_control_panel.simplisafe') | lower == "armed_away" }}' +# value_template: '{{ states('alarm_control_panel.home') | lower == "armed_away" }}' # - condition: template -# value_template: '{{ states('alarm_control_panel.simplisafe') | lower == "armed_home" }}' +# value_template: '{{ states('alarm_control_panel.home') | lower == "armed_home" }}' # action: # - service: notify.ios_suresh # data_template: @@ -444,7 +431,7 @@ automation: # to: 'on' # condition: # - condition: template -# value_template: '{{ states('alarm_control_panel.simplisafe') == "armed_home" or states('alarm_control_panel.simplisafe') == "armed_away" }}' +# value_template: '{{ states('alarm_control_panel.home') == "armed_home" or states('alarm_control_panel.home') == "armed_away" }}' # action: # - service: notify.ios_suresh # data_template: @@ -468,7 +455,7 @@ automation: # actionName: 'DISABLE_SECURITY' # action: # - service: alarm_control_panel.alarm_disarm -# entity_id: alarm_control_panel.simplisafe +# entity_id: alarm_control_panel.home # - service: notify.ios_suresh # data: # message: "Unlocked your home!" diff --git a/packages/lights.yaml b/packages/lights.yaml index b6311f0..7df427a 100644 --- a/packages/lights.yaml +++ b/packages/lights.yaml @@ -53,6 +53,14 @@ homeassistant: assumed_state: false icon: mdi:lightbulb + switch.kids_bed_accent: + friendly_name: Hasika's Bed Accent Lights + assumed_state: false + icon: mdi:lightbulb + switch.front_room: + friendly_name: Front Room Light + assumed_state: false + icon: mdi:lightbulb switch.basement_left: friendly_name: Basement Theater Lights assumed_state: false @@ -131,6 +139,7 @@ tplink: - host: !secret tplink_basement_right - host: !secret tplink_kitchen - host: !secret tplink_office_room + - host: !secret tplink_front_room # Smart Outlets - host: !secret tplink_smart_outlet1 diff --git a/packages/media_players.yaml b/packages/media_players.yaml deleted file mode 100644 index 057dcc9..0000000 --- a/packages/media_players.yaml +++ /dev/null @@ -1,170 +0,0 @@ -############################################################################### -# @author : Mahasri Kalavala -# @date : 04/15/2017 -# @package : Media Player -# @description : Media Player Sensors, Automations -############################################################################### - -homeassistant: - customize: - # Media Players - media_player.snapcast_client_b827eb8604f5: - friendly_name: Front Room Music - media_player.snapcast_client_b827ebaa08f7: - friendly_name: Kitchen Music - media_player.snapcast_client_b827eb011e00: - friendly_name: TV Room Music - media_player.snapcast_client_b827eb4445b1: - friendly_name: Master Bedroom Music - media_player.snapcast_client_b827eba8e7ef: - friendly_name: Guest Bedroom 1 Music - media_player.snapcast_client_b827eb505e2d: - friendly_name: Guest Bedroom 2 Music - media_player.snapcast_client_001e8c40c713: - friendly_name: Basement Music - media_player.snapcast_client_b827ebf10965: - friendly_name: Office Room Music - media_player.snapcast_client_0018e7c4488f: - friendly_name: HA Server (Basement) - - script.stop_snapcast_server: - friendly_name: Stop Snapcast Server - script.start_snapcast_server: - friendly_name: Start Snapcast Server - script.restart_snapcast_server: - friendly_name: Restart Snapcast Server - - media_player.mpd: - friendly_name: Mopidy Media Player - hidden: false - media_player.gstreamer: - friendly_name: Gstreamer Media Player - hidden: false - media_player.attic_tv: - friendly_name: Chromecast Media Player - hidden: false - -media_player: - - platform: snapcast - host: !secret snapcast_server_ip - - platform: mpd - name: mpd - host: !secret mopidy_server_ip - port: !secret mopidy_server_port - - # - platform: denon - # host: !secret denon_avr_ip_address - # name: DENON - - # - platform: denonavr - # host: !secret denon_avr_ip_address - # name: MY DENON RECEIVER - # show_all_sources: true - # timeout: 5 - - # If you get errors about GI not found, run the command below to link gsp/gi path to HA for Gstreamer to function properly - - # For python 3.4: - # sudo ln -s /usr/lib/python3/dist-packages/gi /srv/homeassistant/lib/python3.6/site-packages - - # If you get GST not found error, run the following command - # sudo apt-get install python-gst-1.0 \ - # gir1.2-gstreamer-1.0 gir1.2-gst-plugins-base-1.0 \ - # gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly \ - # gstreamer1.0-tools - - # Steps to set it up: - # - # 1. Setup venv using correct version of python - in this case, it is python3.6 - # 2. As homeassistant user, inside the venv, run python3.6 command - # $ sudo -u homeassistant -H -s - # $ source /srv/homeassistant/bin/activate - # $ python3.6 - # Inside the python CLI, run - # >>> import gi - # >>> print (gi) - # 3. That should print something like - # - # 4. Map that path to the GI location - # $ sudo ln -s /usr/lib/python3/dist-packages/gi /srv/homeassistant/lib/python3.6/site-packages - # restart machine - - - platform: gstreamer - pipeline: "audioresample ! audioconvert ! audio/x-raw,rate=48000,channels=2,format=S16LE ! wavenc ! filesink location=/tmp/snapfifo" - -binary_sensor: - - platform: mqtt - name: Sharp TV - state_topic: "/home/sharptv" - payload_on: "on" - payload_off: "off" - value_template: "{{ value }}" - - - platform: mqtt - name: Sharp TV Command State - state_topic: "/home/sharp_tv_cmd" - payload_on: "on" - payload_off: "off" - value_template: "{{ value }}" - -input_select: - snapcast_server: - name: Snapcast Server - options: - - Select One - - Stop - - Start - - Restart - initial: Select One - icon: mdi:music - -shell_command: - stop_snapserver: >- - sudo systemctl stop snapserver - start_snapserver: >- - sudo systemctl start snapserver - restart_snapserver: >- - sudo systemctl restart snapserver - -script: - stop_snapcast_server: - sequence: - - service: shell_command.stop_snapserver - start_snapcast_server: - sequence: - - service: shell_command.start_snapserver - restart_snapcast_server: - sequence: - - service: shell_command.restart_snapserver - -############################################################################### -# _ _ _ -# /\ | | | | (_) -# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___ -# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| -# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \ -# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/ -# -############################################################################### - -automation: - ############################################################################### - # Snapcast Server Management - ############################################################################### - - alias: Snapcast Action - initial_state: true - trigger: - platform: state - entity_id: input_select.snapcast_server - condition: - - condition: template - value_template: "{{ states('input_select.snapcast_server') | lower != 'select one' }}" - action: - - service_template: >- - {% if states('input_select.snapcast_server') | lower == "stop" %} - shell_command.stop_snapserver - {% elif states('input_select.snapcast_server') | lower == "start" %} - shell_command.start_snapserver - {% else %} - shell_command.restart_snapserver - {% endif %} diff --git a/packages/notify.yaml b/packages/notify.yaml index f8c71f6..4d8c00f 100644 --- a/packages/notify.yaml +++ b/packages/notify.yaml @@ -122,22 +122,8 @@ script: value_template: "{{ states('input_boolean.voice_notifications') == 'on' }}" - condition: template value_template: "{{ states('input_boolean.do_not_disturb') | lower == 'off' }}" - - condition: template - value_template: "{{ states('media_player.gstreamer') == 'idle' }}" - - condition: template - value_template: "{{ states('media_player.mpd') != 'playing' }}" - condition: template value_template: "{{ message | trim != '' }}" - - condition: state - entity_id: group.all_devices - state: "home" - - condition: template - value_template: > - {% if states('input_boolean.emergency_mode') == "on" %} - true - {% else %} - {{ states('group.all_devices') == "home" }} - {% endif %} - condition: template value_template: > {% if only_at_night | default('no', true ) == "yes" %} @@ -150,7 +136,8 @@ script: true {% endif %} - service: media_player.volume_set - entity_id: media_player.gstreamer + # entity_id: media_player.gstreamer + entity_id: media_player.living_room, media_player.upstairs data_template: volume_level: > {% if states('input_boolean.emergency_mode') == "on" %} @@ -165,7 +152,8 @@ script: {% endif %} {% endif %} - service: tts.amazon_polly_say - entity_id: media_player.gstreamer + #entity_id: media_player.gstreamer + entity_id: media_player.living_room, media_player.upstairs data_template: cache: true message: > @@ -200,7 +188,8 @@ script: voice_greeting: sequence: - service: tts.amazon_polly_say - entity_id: media_player.gstreamer + #entity_id: media_player.gstreamer + entity_id: media_player.living_room, media_player.upstairs data_template: cache: true message: > diff --git a/packages/settings.yaml b/packages/settings.yaml index 070eac5..5b612a0 100644 --- a/packages/settings.yaml +++ b/packages/settings.yaml @@ -310,9 +310,6 @@ automation: condition: - condition: template value_template: '{{ states.input_boolean.hourly_report.state == "on" }}' - - condition: state - entity_id: group.all_devices - state: "home" - condition: template value_template: > {% set hour = now().hour | int %} diff --git a/packages/tesla.yaml b/packages/tesla.yaml index 9285a42..7c838dd 100644 --- a/packages/tesla.yaml +++ b/packages/tesla.yaml @@ -1,33 +1,35 @@ homeassistant: customize: - binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor: + binary_sensor.tesla_model_3_charger_sensor: friendly_name: Charger - binary_sensor.tesla_model_3_5yj3e1ea8jf010610_parking_brake_sensor: + binary_sensor.tesla_model_3_parking_brake_sensor: friendly_name: Parking Break - climate.tesla_model_3_5yj3e1ea8jf010610_hvac_climate_system: + climate.tesla_model_3_hvac_climate_system: friendly_name: Tesla Climate - device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker: + device_tracker.mahasri_tesla_location_tracker: friendly_name: Tesla - lock.tesla_model_3_5yj3e1ea8jf010610_door_lock: + lock.tesla_model_3_charger_door_lock: friendly_name: Tesla Door Lock - sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor: + sensor.tesla_model_3_battery_sensor: friendly_name: Battery Percentage icon: mdi:battery - sensor.tesla_model_3_5yj3e1ea8jf010610_mileage_sensor: + sensor.tesla_model_3_mileage_sensor: friendly_name: Total Mileage - sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor: + sensor.tesla_model_3_range_sensor: friendly_name: Battery Range - sensor.tesla_model_3_5yj3e1ea8jf010610_temperature_sensor_inside: + sensor.tesla_model_3_temperature_sensor_inside: friendly_name: Temperature Inside - sensor.tesla_model_3_5yj3e1ea8jf010610_temperature_sensor_outside: + sensor.tesla_model_3_temperature_sensor_outside: friendly_name: Temperature Outside - switch.tesla_model_3_5yj3e1ea8jf010610_charger_switch: + switch.tesla_model_3_charger_switch: friendly_name: Charger Switch - switch.tesla_model_3_5yj3e1ea8jf010610_maxrange_switch: + switch.tesla_model_3_maxrange_switch: friendly_name: Max Range Switch + switch.tesla_model_3_update_switch: + friendly_name: Update Tesla # The scan_interval is now set to 6 hours -# Leaving it to the default (which is 5 minutes, or 300 seconds) will drain battery at a rate of +# Leaving it to the default (which is 5 minutes, or 300 seconds) will drain battery at a rate of # 10 miles per day (or 3% battery use) on an average. Use this setting carefully! tesla: @@ -36,13 +38,13 @@ tesla: scan_interval: 21600 ############################################################################### -# _ _ _ -# /\ | | | | (_) -# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___ +# _ _ _ +# /\ | | | | (_) +# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___ # / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| # / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \ # /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/ -# +# ############################################################################### automation: @@ -50,7 +52,7 @@ automation: initial_state: true trigger: - platform: state - entity_id: binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor + entity_id: binary_sensor.tesla_model_3_charger_sensor action: - service: script.notify_me data_template: @@ -60,7 +62,7 @@ automation: initial_state: true trigger: - platform: state - entity_id: lock.tesla_model_3_5yj3e1ea8jf010610_door_lock + entity_id: lock.tesla_model_3_door_lock condition: - condition: template value_template: '{{ trigger.from_state.state | lower != "unknown" }}' @@ -73,11 +75,11 @@ automation: initial_state: true trigger: - platform: state - entity_id: switch.tesla_model_3_5yj3e1ea8jf010610_charger_switch + entity_id: switch.tesla_model_3_charger_switch condition: - condition: template value_template: '{{ trigger.from_state.state | lower != "unknown" }}' action: - service: script.notify_me data_template: - message: "Tesla Door is now: {{ trigger.to_state.state| upper }}" \ No newline at end of file + message: "Tesla Door is now: {{ trigger.to_state.state| upper }}" diff --git a/packages/tile.yaml b/packages/tile.yaml new file mode 100644 index 0000000..edbe516 --- /dev/null +++ b/packages/tile.yaml @@ -0,0 +1,23 @@ +############################################################################### +# @author : Mahasri Kalavala +# @date : 02/05/2020 +# @package : Tile +# @description : Tile Package +############################################################################### +homeassistant: + customize: + device_tracker.tile_08beea8370ec23b7: + friendly_name: Back Pack + device_tracker.tile_43a0d518532978f8: + friendly_name: Passport Bag + device_tracker.tile_49318f5ab14343a5: + friendly_name: Suresh's Laptop Bag + device_tracker.tile_63ca05b6a3619232: + friendly_name: Mallika's Purse + device_tracker.tile_p_32c03dc7f21001d36d16b47646e4c421: + friendly_name: Tile Tracker + +device_tracker: + - platform: tile + username: !secret tile_username + password: !secret tile_password diff --git a/packages/tv.yaml b/packages/tv.yaml index a8408fb..5e5c3c9 100644 --- a/packages/tv.yaml +++ b/packages/tv.yaml @@ -4,34 +4,47 @@ # @package : TV # @description : Tv Automations ############################################################################### +binary_sensor: + - platform: mqtt + name: Sharp TV + state_topic: "/home/sharptv" + payload_on: "on" + payload_off: "off" + value_template: "{{ value }}" + + - platform: mqtt + name: Sharp TV Command State + state_topic: "/home/sharp_tv_cmd" + payload_on: "on" + payload_off: "off" + value_template: "{{ value }}" ############################################################################### -# _ _ _ -# /\ | | | | (_) -# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___ +# _ _ _ +# /\ | | | | (_) +# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___ # / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __| # / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \ # /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/ -# +# ############################################################################### automation: - -# Dim Family Room Lights When TV is Turned ON -############################################################################### + # Dim Family Room Lights When TV is Turned ON + ############################################################################### - alias: TV Dim Indoor Lights when TV is ON initial_state: true trigger: platform: state entity_id: binary_sensor.sharp_tv - from: 'off' - to: 'on' + from: "off" + to: "on" condition: - condition: state entity_id: sun.sun - state: 'below_horizon' + state: "below_horizon" - condition: state entity_id: input_boolean.light_automations - state: 'on' + state: "on" action: - service: light.turn_on data: @@ -51,25 +64,25 @@ automation: - service: mqtt.publish data: topic: /home/tv/backlight - payload: 'on' + payload: "on" retain: true - -# Restore Family Room Lights to TV mode -############################################################################### + + # Restore Family Room Lights to TV mode + ############################################################################### - alias: TV Restore Family Room Lights To TV Mode initial_state: true trigger: - platform: state entity_id: group.family_room_lights - from: 'off' - to: 'on' + from: "off" + to: "on" condition: - condition: state entity_id: binary_sensor.sharp_tv - state: 'on' + state: "on" - condition: state entity_id: input_boolean.light_automations - state: 'on' + state: "on" action: - service: light.turn_on data: @@ -89,52 +102,52 @@ automation: brightness: 5 color_temp: 154 transition: 5 - -# Turn Backlights Off when TV is turned OFF -############################################################################### + + # Turn Backlights Off when TV is turned OFF + ############################################################################### - alias: TV Backlight OFF when TV is OFF initial_state: true trigger: platform: state entity_id: binary_sensor.sharp_tv - to: 'off' + to: "off" action: - service: mqtt.publish data: topic: /home/tv/backlight - payload: 'off' + payload: "off" retain: true - -# Turn TV backlights when TV is turned ON -############################################################################### + + # Turn TV backlights when TV is turned ON + ############################################################################### - alias: TV Backlight is ON when TV is ON initial_state: true trigger: platform: state entity_id: binary_sensor.sharp_tv - to: 'on' + to: "on" action: - service: mqtt.publish data: topic: /home/tv/backlight - payload: 'on' + payload: "on" retain: true -# Turn back Family room lights when TV is switched OFF -############################################################################### + # Turn back Family room lights when TV is switched OFF + ############################################################################### - alias: TV Turn Lights ON When TV is turned OFF initial_state: true trigger: platform: state entity_id: binary_sensor.sharp_tv - to: 'off' + to: "off" condition: - condition: state entity_id: sun.sun - state: 'below_horizon' + state: "below_horizon" - condition: state entity_id: input_boolean.light_automations - state: 'on' + state: "on" action: - service: light.turn_on data: @@ -153,9 +166,9 @@ automation: entity_id: light.hue_color_lamp_3 brightness: 255 color_temp: 154 - transition: 5 + transition: 5 - service: mqtt.publish data: topic: /home/tv/backlight - payload: 'off' - retain: true \ No newline at end of file + payload: "off" + retain: true diff --git a/packages/weather.yaml b/packages/weather.yaml index 99c126b..d771f86 100644 --- a/packages/weather.yaml +++ b/packages/weather.yaml @@ -291,9 +291,6 @@ automation: condition: - condition: template value_template: '{{ trigger.to_state.state | lower == "rain" }}' - - condition: state - entity_id: group.all_devices - state: "home" - condition: state entity_id: sun.sun state: "above_horizon" @@ -324,9 +321,6 @@ automation: condition: - condition: template value_template: '{{ states.sensor.season.state | lower == "winter" }}' - - condition: state - entity_id: group.all_devices - state: "home" - condition: state entity_id: sun.sun state: "above_horizon" diff --git a/packages/xiaomi_magic_cubes.yaml b/packages/xiaomi_magic_cubes.yaml index 6dacfce..ce68b3d 100644 --- a/packages/xiaomi_magic_cubes.yaml +++ b/packages/xiaomi_magic_cubes.yaml @@ -20,15 +20,15 @@ script: ################################################################################ automation: -################################################################################ -# ______ _ _ _____ -# | ____| (_) | | __ \ -# | |__ __ _ _ __ ___ _| |_ _ | |__) |___ ___ _ __ ___ -# | __/ _` | '_ ` _ \| | | | | | | _ // _ \ / _ \| '_ ` _ \ -# | | | (_| | | | | | | | | |_| | | | \ \ (_) | (_) | | | | | | -# |_| \__,_|_| |_| |_|_|_|\__, | |_| \_\___/ \___/|_| |_| |_| -# __/ | -# |___/ + ################################################################################ + # ______ _ _ _____ + # | ____| (_) | | __ \ + # | |__ __ _ _ __ ___ _| |_ _ | |__) |___ ___ _ __ ___ + # | __/ _` | '_ ` _ \| | | | | | | _ // _ \ / _ \| '_ ` _ \ + # | | | (_| | | | | | | | | |_| | | | \ \ (_) | (_) | | | | | | + # |_| \__,_|_| |_| |_|_|_|\__, | |_| \_\___/ \___/|_| |_| |_| + # __/ | + # |___/ # Flip 90: Toggle Family Room Lights - alias: Family Room Cube Event flip90 @@ -87,9 +87,9 @@ automation: data_template: entity_id: light.family_room rgb_color: - - '{{ range(0,255) |random }}' - - '{{ range(0,255) |random }}' - - '{{ range(0,255) |random }}' + - "{{ range(0,255) |random }}" + - "{{ range(0,255) |random }}" + - "{{ range(0,255) |random }}" # Shake: Toggle Do Not Disturb Mode - alias: Family Room Cube Event Shake @@ -103,13 +103,13 @@ automation: action: - service: script.toggle_do_not_disturb -################################################################################ -# ______ _ _____ -# | ____| | | | __ \ -# | |__ _ __ ___ _ __ | |_ | |__) |___ ___ _ __ ___ -# | __| '__/ _ \| '_ \| __| | _ // _ \ / _ \| '_ ` _ \ -# | | | | | (_) | | | | |_ | | \ \ (_) | (_) | | | | | | -# |_| |_| \___/|_| |_|\__| |_| \_\___/ \___/|_| |_| |_| + ################################################################################ + # ______ _ _____ + # | ____| | | | __ \ + # | |__ _ __ ___ _ __ | |_ | |__) |___ ___ _ __ ___ + # | __| '__/ _ \| '_ \| __| | _ // _ \ / _ \| '_ ` _ \ + # | | | | | (_) | | | | |_ | | \ \ (_) | (_) | | | | | | + # |_| |_| \___/|_| |_|\__| |_| \_\___/ \___/|_| |_| |_| # Flip 90: Toggle Front Room Lights - alias: Front Room Cube Event flip90 @@ -122,7 +122,7 @@ automation: action_type: flip90 action: - service_template: switch.toggle - entity_id: switch.rf_switch_four + entity_id: switch.front_room # Flip 180: Toggle Office Room Accent Lights - alias: Family Room Cube Event flip180 @@ -162,13 +162,13 @@ automation: action: - service: script.toggle_do_not_disturb -############################################################################### -# _____ _ _ _ _ _____ -# / ____| (_) (_) | ( ) | __ \ -# | (___ _ __ _ _ __ _| | ____ _|/ ___ | |__) |___ ___ _ __ ___ -# \___ \| '__| | '_ \| | |/ / _` | / __| | _ // _ \ / _ \| '_ ` _ \ -# ____) | | | | | | | | < (_| | \__ \ | | \ \ (_) | (_) | | | | | | -# |_____/|_| |_|_| |_|_|_|\_\__,_| |___/ |_| \_\___/ \___/|_| |_| |_| + ############################################################################### + # _____ _ _ _ _ _____ + # / ____| (_) (_) | ( ) | __ \ + # | (___ _ __ _ _ __ _| | ____ _|/ ___ | |__) |___ ___ _ __ ___ + # \___ \| '__| | '_ \| | |/ / _` | / __| | _ // _ \ / _ \| '_ ` _ \ + # ____) | | | | | | | | < (_| | \__ \ | | \ \ (_) | (_) | | | | | | + # |_____/|_| |_|_| |_|_|_|\_\__,_| |___/ |_| \_\___/ \___/|_| |_| |_| # Flip 90: Toggle Srinika's Room Lights - alias: Srinika Room Cube Event flip90 @@ -195,14 +195,14 @@ automation: action: - service: script.toggle_do_not_disturb -############################################################################## -# _ _ _ _ _ _____ -# | | | | (_) | ( ) | __ \ -# | |__| | __ _ ___ _| | ____ _|/ ___ | |__) |___ ___ _ __ ___ -# | __ |/ _` / __| | |/ / _` | / __| | _ // _ \ / _ \| '_ ` _ \ -# | | | | (_| \__ \ | < (_| | \__ \ | | \ \ (_) | (_) | | | | | | -# |_| |_|\__,_|___/_|_|\_\__,_| |___/ |_| \_\___/ \___/|_| |_| |_| - + ############################################################################## + # _ _ _ _ _ _____ + # | | | | (_) | ( ) | __ \ + # | |__| | __ _ ___ _| | ____ _|/ ___ | |__) |___ ___ _ __ ___ + # | __ |/ _` / __| | |/ / _` | / __| | _ // _ \ / _ \| '_ ` _ \ + # | | | | (_| \__ \ | < (_| | \__ \ | | \ \ (_) | (_) | | | | | | + # |_| |_|\__,_|___/_|_|\_\__,_| |___/ |_| \_\___/ \___/|_| |_| |_| + # Flip 90: Toggle Hasika's Room Lights - alias: Hasika Room Cube Event flip90 initial_state: true @@ -228,15 +228,15 @@ automation: action: - service: script.toggle_do_not_disturb -################################################################################ -# _____ _ _ _____ -# / ____| | | | | __ \ -# | (___ | |_ _ _ __| |_ _ | |__) |___ ___ _ __ ___ -# \___ \| __| | | |/ _` | | | | | _ // _ \ / _ \| '_ ` _ \ -# ____) | |_| |_| | (_| | |_| | | | \ \ (_) | (_) | | | | | | -# |_____/ \__|\__,_|\__,_|\__, | |_| \_\___/ \___/|_| |_| |_| -# __/ | -# |___/ + ################################################################################ + # _____ _ _ _____ + # / ____| | | | | __ \ + # | (___ | |_ _ _ __| |_ _ | |__) |___ ___ _ __ ___ + # \___ \| __| | | |/ _` | | | | | _ // _ \ / _ \| '_ ` _ \ + # ____) | |_| |_| | (_| | |_| | | | \ \ (_) | (_) | | | | | | + # |_____/ \__|\__,_|\__,_|\__, | |_| \_\___/ \___/|_| |_| |_| + # __/ | + # |___/ # Flip 90: Toggle Study Room Lights - alias: Study Room Cube Event Flip90 @@ -263,13 +263,13 @@ automation: action: - service: script.toggle_do_not_disturb -################################################################################ -# __ __ _ ____ _ -# | \/ | | | | _ \ | | -# | \ / | __ _ ___| |_ ___ _ __ | |_) | ___ __| |_ __ ___ ___ _ __ ___ -# | |\/| |/ _` / __| __/ _ \ '__| | _ < / _ \/ _` | '__/ _ \ / _ \| '_ ` _ \ -# | | | | (_| \__ \ || __/ | | |_) | __/ (_| | | | (_) | (_) | | | | | | -# |_| |_|\__,_|___/\__\___|_| |____/ \___|\__,_|_| \___/ \___/|_| |_| |_| + ################################################################################ + # __ __ _ ____ _ + # | \/ | | | | _ \ | | + # | \ / | __ _ ___| |_ ___ _ __ | |_) | ___ __| |_ __ ___ ___ _ __ ___ + # | |\/| |/ _` / __| __/ _ \ '__| | _ < / _ \/ _` | '__/ _ \ / _ \| '_ ` _ \ + # | | | | (_| \__ \ || __/ | | |_) | __/ (_| | | | (_) | (_) | | | | | | + # |_| |_|\__,_|___/\__\___|_| |____/ \___|\__,_|_| \___/ \___/|_| |_| |_| # Flip 90: All Lights OFF (upstairs and downstairs) - alias: Master Bedroom Cube Event Flip90 @@ -326,9 +326,9 @@ automation: data_template: entity_id: light.master_bedroom rgb_color: - - '{{ range(0,255) |random }}' - - '{{ range(0,255) |random }}' - - '{{ range(0,255) |random }}' + - "{{ range(0,255) |random }}" + - "{{ range(0,255) |random }}" + - "{{ range(0,255) |random }}" # Shake: Toggle Do Not Disturb Mode - alias: Master Bedroom Cube Event Shake diff --git a/templates/away_status.yaml b/templates/away_status.yaml index d8f018a..4240c60 100644 --- a/templates/away_status.yaml +++ b/templates/away_status.yaml @@ -1,75 +1,86 @@ > {% macro weather_update() -%} - Outside temperature is {{ states('sensor.dark_sky_apparent_temperature') | round(0) }} degrees. + Outside temperature is {{ states('sensor.dark_sky_apparent_temperature') | round(0) }} degrees. {%- endmacro -%} {%- macro uv_levels() -%} - {%- set uv = states('sensor.pws_uv') | int -%} - {%- if uv >= 6 and uv <= 7 -%} - Current UV index is high. Please be careful outdoors. - {%- elif uv >= 8 and uv <= 10 -%} - Current UV index is very high. It is not advised to go out. - {%- elif uv >= 11 -%} - Current UV index is extremely high. It is highly advised to stay indoors. - {%- else -%} - Good UV levels. - {%- endif -%} + {%- set uv = states('sensor.pws_uv') | int -%} + {%- if uv >= 6 and uv <= 7 -%} + Current UV index is high. Please be careful outdoors. + {%- elif uv >= 8 and uv <= 10 -%} + Current UV index is very high. It is not advised to go out. + {%- elif uv >= 11 -%} + Current UV index is extremely high. It is highly advised to stay indoors. + {%- else -%} + Good UV levels. + {%- endif -%} {%- endmacro -%} {%- macro USPS() -%} - USPS is going to deliver {{ states('sensor.usps_mail') }} mails today. + {%- if states('sensor.usps_mail') | int > 0 -%} + USPS is going to deliver {{ states('sensor.usps_mail') }} mails today. + {%- endif -%} {%- endmacro -%} {%- macro alert_battery_levels() %} - {% for item in states if 'battery_level' in item.attributes and item.attributes.battery_level | int > 0 and item.attributes.battery_level | float <= 10.0 -%}{{- item.attributes.friendly_name ~ " battery is less than 10 percent" -}} - {%- if loop.first %}, {% elif loop.last %}, {% else %}, {% endif -%} - {%- endfor -%} + {% for item in states if 'battery_level' in item.attributes and item.attributes.battery_level | int > 0 and item.attributes.battery_level | float <= 10.0 -%}{{- item.attributes.friendly_name ~ " battery is less than 10 percent" -}} + {%- if loop.first %}, {% elif loop.last %}, {% else %}, {% endif -%} + {%- endfor -%} {%- endmacro -%} {%- macro tesla_status() -%} - {%- if states("sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor") != "unknown" -%} - Your Tesla car battery is at {{ states('sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor') }} percent ({{ (states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) }} miles). - {%- endif -%} + {%- if states("sensor.tesla_model_3_range_sensor") != "unknown" -%} + Your Tesla car battery is at {{ states('sensor.tesla_model_3_battery_sensor') }} percent ({{ (states('sensor.tesla_model_3_range_sensor') | int) | round(0) }} miles). + {%- endif -%} {%- endmacro -%} {%- macro pollen_levels() -%} - Pollen level is {{ states('sensor.pollen_level') }}. + {% if states('sensor.pollen_level') != 'unknown' %} + Pollen level is {{ states('sensor.pollen_level') }}. + {% endif %} {%- endmacro -%} {%- macro humidity_status() -%} - Home humidity is {{ states('sensor.dining_room_thermostat_humidity') }} percent. + Home humidity is {{ states('sensor.dining_room_thermostat_humidity') }} percent. {%- endmacro -%} {%- macro alarm_status() -%} - Your home is {{ "SECURED!" if states('alarm_control_panel.simplisafe') == "armed_away" or states('alarm_control_panel.simplisafe') == "armed_home" else "UNSECURED!" }} + Your home is {{ "SECURED!" if states('alarm_control_panel.home') == "armed_away" or states('alarm_control_panel.home') == "armed_home" else "UNSECURED!" }} {%- endmacro -%} {%- macro single_car_garage_door_status() -%} - {%- if states('binary_sensor.single_car_garage_door_tilt_sensor_sensor') |lower == "on" -%} - {{ states.binary_sensor.single_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN - {%- endif -%} + {%- if states('binary_sensor.single_car_garage_door_tilt_sensor_sensor') |lower == "on" -%} + {{ states.binary_sensor.single_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN! + {%- endif -%} {%- endmacro -%} {%- macro two_car_garage_door_status() -%} - {% if states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') |lower == "on" %} - {{ states.binary_sensor.two_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN - {% endif %} + {% if states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') |lower == "on" %} + {{ states.binary_sensor.two_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN! + {% endif %} {%- endmacro -%} {%- macro garage_status() -%} - {%- set single_car_garage = single_car_garage_door_status() -%} - {%- set two_car_garage = two_car_garage_door_status() -%} - {%- if single_car_garage | trim == "" and two_car_garage | trim == "" -%} - Both the garage doors are CLOSED! - {%- elif single_car_garage | trim != "" and two_car_garage | trim != "" -%} - Warning! Both garage doors are OPEN. - {% else %} - Warning! {{ single_car_garage }} {{ two_car_garage }} - {%- endif -%} + {%- set single_car_garage = single_car_garage_door_status() -%} + {%- set two_car_garage = two_car_garage_door_status() -%} + {%- if single_car_garage | trim == "" and two_car_garage | trim == "" -%} + Both the garage doors are closed. + {%- elif single_car_garage | trim != "" and two_car_garage | trim != "" -%} + Warning! Both garage doors are OPEN! + {% else %} + Warning! {{ single_car_garage }} {{ two_car_garage }} + {%- endif -%} {%- endmacro -%} {%- macro plural(name) -%} - {{- "true" if name.endswith("s") else "false" -}} + {{- "true" if name.endswith("s") else "false" -}} + {%- endmacro -%} + + {# a macro that removes all newline characters, empty spaces, and returns formatted text #} + {%- macro cleanup(data) -%} + {% for item in data.split("\n") if item | trim != "" -%} + {{ item | trim }} + {% endfor %} {%- endmacro -%} {%- macro light_status() -%} @@ -87,25 +98,25 @@ "switch.office_room", "switch.wemobackyardlightswitch", "switch.zwave_smart_switch_switch"] %} - {% for item in lights_switches -%} - {%- if states[item.split('.')[0]][item.split('.')[1]].state == "on" -%} - {%- set friendly_name = states[item.split('.')[0]][item.split('.')[1]].attributes.friendly_name -%} - {{ friendly_name }} {{ 'are' if plural(friendly_name) == "true" else 'is' }} ON. - {% endif %} - {%- endfor -%} + {% for item in lights_switches -%} + {%- if states[item.split('.')[0]][item.split('.')[1]].state == "on" -%} + {%- set friendly_name = states[item.split('.')[0]][item.split('.')[1]].attributes.friendly_name -%} + {{ friendly_name }} {{ 'are' if plural(friendly_name) == "true" else 'is' }} ON. + {% endif %} + {%- endfor -%} {%- endmacro -%} {%- macro mother_of_all_macros() -%} - {{ alarm_status() }} - {{ garage_status() }} - {{ USPS() }} - {{ tesla_status() }} - {{ weather_update() }} - {{ humidity_status() }} - {{ uv_levels() }} - {{ pollen_levels() }} - {{ alert_battery_levels() }} - {{ light_status() }} + {{ alarm_status() }} + {{ garage_status() }} + {{ USPS() }} + {{ tesla_status() }} + {{ weather_update() }} + {{ humidity_status() }} + {{ uv_levels() }} + {{ pollen_levels() }} + {{ alert_battery_levels() }} + {{ light_status() }} {%- endmacro -%} - {{- mother_of_all_macros() -}} + {{- cleanup(mother_of_all_macros()) -}} diff --git a/templates/goodnight.yaml b/templates/goodnight.yaml index 476c268..6ff9134 100644 --- a/templates/goodnight.yaml +++ b/templates/goodnight.yaml @@ -10,7 +10,7 @@ {%- for item in states.device_tracker if '_' in item.entity_id.split('.')[1] and state_attr(item.entity_id, "battery") |lower != "none" -%} {%- if item.attributes.battery|int < level -%} {%- if states("sensor." ~ item.friendly_name |lower ~"s_iphone_battery_state") | lower != "charging" %} - {{- item.attributes.friendly_name}}s iPhone battery is at {{ item.attributes.battery }} percent. + {{- item.attributes.friendly_name | replace("life360", "") |title }}'s iPhone battery is at {{ item.attributes.battery }} percent. {%- endif %} {%- endif %} {%- endfor -%} @@ -46,11 +46,11 @@ {#- Provides Home Security System Status -#} {%- macro alarm_status() -%} - {%- if states('alarm_control_panel.simplisafe') | lower == "disarmed" -%} + {%- if states('alarm_control_panel.home') | lower == "disarmed" -%} Your home security system is switched OFF. You may want to turn it ON. - {%- elif states('alarm_control_panel.simplisafe') | lower == "armed_away" -%} + {%- elif states('alarm_control_panel.home') | lower == "armed_away" -%} Your home security system is set to away mode. - {%- elif states('alarm_control_panel.simplisafe') | lower == "armed_home" -%} + {%- elif states('alarm_control_panel.home') | lower == "armed_home" -%} Your home security system is ON, and your home is secured. {%- endif %} {%- endmacro -%} @@ -87,7 +87,7 @@ {%- endmacro -%} {%- macro charging_status() -%} - {%- for item in states if "iphone_battery_state" in item.entity_id and item.state != "Charging" %} + {%- for item in states if "_iphone_battery_state" in item.entity_id and item.state != "Charging" %} {%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{- item.name.split(' ')[0] -}} {%- endfor -%} {%- endmacro -%} @@ -115,12 +115,12 @@ {%- endmacro -%} {%- macro tesla_status() %} - {%- if states("binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor") != "unknown" -%} - Your Tesla Car is {{ 'not' if states('binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor') == "off" }} plugged in. + {%- if states("binary_sensor.tesla_model_3_charger_sensor") != "unknown" -%} + Your Tesla Car is {{ 'not' if states('binary_sensor.tesla_model_3_charger_sensor') == "off" }} plugged in. {% endif %} - {%- if states("sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor") != "unknown" and states("sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor") != "unknown" and states('sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor') | int > 0 -%} - Tesla Car battery is at {{ states('sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor') }}%, and you can drive about {{ (states.sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor.state | int) | round(0) }} miles. + {%- if states("sensor.tesla_model_3_battery_sensor") != "unknown" and states("sensor.tesla_model_3_range_sensor") != "unknown" and states('sensor.tesla_model_3_battery_sensor') | int > 0 -%} + Tesla Car battery is at {{ states('sensor.tesla_model_3_battery_sensor') }}%, and you can drive about {{ (states.sensor.tesla_model_3_range_sensor.state | int) | round(0) }} miles. {% endif %} {%- endmacro %} diff --git a/templates/home_status.yaml b/templates/home_status.yaml index c20968c..e7bef4f 100644 --- a/templates/home_status.yaml +++ b/templates/home_status.yaml @@ -19,10 +19,10 @@ {%- endmacro -%} {%- macro tesla_status() -%} - {% if states("sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor") != "unknown" %} - {%- if (states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) < 75 and - (states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) > 0 -%} - Attention!. Your Tesla car battery is at {{ states('sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor') }} percent. and you can only drive about {{ (states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) }} miles. Please charge your car if you want to go anywhere. + {% if states("sensor.tesla_model_3_range_sensor") != "unknown" %} + {%- if (states('sensor.tesla_model_3_range_sensor') | int) | round(0) < 75 and + (states('sensor.tesla_model_3_range_sensor') | int) | round(0) > 0 -%} + Attention!. Your Tesla car battery is at {{ states('sensor.tesla_model_3_battery_sensor') }} percent. and you can only drive about {{ (states('sensor.tesla_model_3_range_sensor') | int) | round(0) }} miles. Please charge your car if you want to go anywhere. {%- endif -%} {% endif %} {%- endmacro -%} diff --git a/zwcfg_0xd89c4f0c.xml b/zwcfg_0xd89c4f0c.xml index 58c8e55..4cb94bf 100644 --- a/zwcfg_0xd89c4f0c.xml +++ b/zwcfg_0xd89c4f0c.xml @@ -34,10 +34,10 @@ - + - + @@ -168,7 +168,7 @@ - + @@ -208,7 +208,7 @@ - + @@ -216,7 +216,7 @@ - + @@ -350,7 +350,7 @@ - + @@ -379,7 +379,7 @@ - + @@ -490,7 +490,7 @@ - + @@ -601,7 +601,7 @@ - + @@ -710,7 +710,7 @@ - + @@ -728,9 +728,9 @@ - - - + + + @@ -984,7 +984,7 @@ - + @@ -1006,12 +1006,12 @@ - - - - - - + + + + + + @@ -1181,7 +1181,7 @@ - + @@ -1190,8 +1190,8 @@ - - + + @@ -1213,7 +1213,7 @@ - + @@ -1328,7 +1328,7 @@ - + @@ -1416,7 +1416,7 @@ - + @@ -1703,7 +1703,7 @@ - + @@ -1809,7 +1809,7 @@ - + @@ -2023,7 +2023,7 @@ - + @@ -2038,7 +2038,7 @@ - + @@ -2132,7 +2132,7 @@ - + @@ -2405,9 +2405,9 @@ - + - + @@ -2580,7 +2580,7 @@ - +