Upgraded to 0.105.0!
This commit is contained in:
parent
87961b393c
commit
db7eef5aa7
|
@ -56,6 +56,8 @@ config:
|
||||||
# description: Xiaomi Gateway Light
|
# description: Xiaomi Gateway Light
|
||||||
|
|
||||||
discovery:
|
discovery:
|
||||||
|
ignore:
|
||||||
|
- homekit
|
||||||
|
|
||||||
homekit:
|
homekit:
|
||||||
autostart: true
|
autostart: true
|
||||||
|
@ -71,6 +73,12 @@ homekit:
|
||||||
- binary_sensor.single_car_garage_door_tilt_sensor_sensor
|
- binary_sensor.single_car_garage_door_tilt_sensor_sensor
|
||||||
- binary_sensor.two_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:
|
mobile_app:
|
||||||
# map:
|
# map:
|
||||||
# updater:
|
# updater:
|
||||||
|
@ -108,6 +116,11 @@ binary_sensor:
|
||||||
lovelace:
|
lovelace:
|
||||||
mode: yaml
|
mode: yaml
|
||||||
|
|
||||||
|
# Google Calendar
|
||||||
|
google:
|
||||||
|
client_id: !secret google_client_id
|
||||||
|
client_secret: !secret google_client_secret
|
||||||
|
|
||||||
emulated_hue:
|
emulated_hue:
|
||||||
expose_by_default: false
|
expose_by_default: false
|
||||||
host_ip: !secret ha_ip_address
|
host_ip: !secret ha_ip_address
|
||||||
|
|
|
@ -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),
|
|
||||||
}
|
|
|
@ -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),
|
||||||
|
# }
|
|
@ -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
|
|
|
@ -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
|
|
@ -67,7 +67,7 @@ The output of the above script would look like the following:
|
||||||
title: Alarm Control Panel
|
title: Alarm Control Panel
|
||||||
show_header_toggle: true
|
show_header_toggle: true
|
||||||
entities:
|
entities:
|
||||||
- alarm_control_panel.simplisafe
|
- alarm_control_panel.home
|
||||||
name: Home Security System
|
name: Home Security System
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
|
@ -105,6 +105,7 @@ The output of the above script would look like the following:
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
```
|
```
|
||||||
|
|
||||||
The output of above would look something like:
|
The output of above would look something like:
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
|
@ -4,7 +4,7 @@ cards:
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: "custom:button-card"
|
||||||
entity: alarm_control_panel.simplisafe
|
entity: alarm_control_panel.home
|
||||||
icon: mdi:security
|
icon: mdi:security
|
||||||
color_type: card
|
color_type: card
|
||||||
show_state: true
|
show_state: true
|
||||||
|
@ -52,7 +52,7 @@ cards:
|
||||||
name: Srinika
|
name: Srinika
|
||||||
- entity: device_tracker.life360_hasika
|
- entity: device_tracker.life360_hasika
|
||||||
name: Hasika
|
name: Hasika
|
||||||
- entity: device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker
|
- entity: device_tracker.mahasri_tesla_location_tracker
|
||||||
name: Tesla
|
name: Tesla
|
||||||
state_filter:
|
state_filter:
|
||||||
- "home"
|
- "home"
|
||||||
|
@ -60,6 +60,16 @@ cards:
|
||||||
type: glance
|
type: glance
|
||||||
title: Kalavala Family
|
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
|
- type: entity-filter
|
||||||
title: For Your Information
|
title: For Your Information
|
||||||
show_empty: false
|
show_empty: false
|
||||||
|
@ -105,23 +115,23 @@ cards:
|
||||||
- script.emergency_script
|
- script.emergency_script
|
||||||
- script.emergency_script_loop
|
- script.emergency_script_loop
|
||||||
|
|
||||||
# - type: horizontal-stack
|
- type: horizontal-stack
|
||||||
# cards:
|
cards:
|
||||||
# - type: glance
|
- type: glance
|
||||||
# entities:
|
entities:
|
||||||
# - input_label.mallika_birthday_days2go
|
- input_label.mallika_birthday_days2go
|
||||||
# - type: glance
|
- type: glance
|
||||||
# entities:
|
entities:
|
||||||
# - input_label.srinika_birthday_days2go
|
- input_label.srinika_birthday_days2go
|
||||||
# - type: glance
|
- type: glance
|
||||||
# entities:
|
entities:
|
||||||
# - input_label.hasika_birthday_days2go
|
- input_label.hasika_birthday_days2go
|
||||||
|
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
title: Doors
|
title: Doors
|
||||||
show_empty: false
|
show_empty: false
|
||||||
entities:
|
entities:
|
||||||
- alarm_control_panel.simplisafe
|
- alarm_control_panel.home
|
||||||
- entity: binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor
|
- entity: binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor
|
||||||
name: Front Door
|
name: Front Door
|
||||||
- entity: binary_sensor.back_door_sensor_sensor
|
- entity: binary_sensor.back_door_sensor_sensor
|
||||||
|
@ -207,6 +217,53 @@ cards:
|
||||||
- sensor.tv_multi_sensor_luminance
|
- sensor.tv_multi_sensor_luminance
|
||||||
- sensor.upstairs_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
|
- type: conditional
|
||||||
conditions:
|
conditions:
|
||||||
- entity: sensor.season
|
- entity: sensor.season
|
||||||
|
@ -253,43 +310,6 @@ cards:
|
||||||
yellow: 4
|
yellow: 4
|
||||||
red: 7
|
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
|
- type: entities
|
||||||
title: Z-Wave Batteries
|
title: Z-Wave Batteries
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
|
@ -23,6 +23,7 @@ cards:
|
||||||
title: Downstairs
|
title: Downstairs
|
||||||
show_header_toggle: true
|
show_header_toggle: true
|
||||||
entities:
|
entities:
|
||||||
|
- switch.front_room
|
||||||
- switch.basement_left
|
- switch.basement_left
|
||||||
- switch.basement_right
|
- switch.basement_right
|
||||||
- switch.kitchen
|
- switch.kitchen
|
||||||
|
|
|
@ -40,10 +40,11 @@ cards:
|
||||||
title: Tesla Car
|
title: Tesla Car
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker
|
- device_tracker.mahasri_tesla_location_tracker
|
||||||
- binary_sensor.tesla_model_3_parking_brake_sensor
|
- binary_sensor.tesla_model_3_parking_brake_sensor
|
||||||
- lock.tesla_model_3_door_lock
|
- lock.tesla_model_3_door_lock
|
||||||
- sensor.tesla_model_3_mileage_sensor
|
- sensor.tesla_model_3_mileage_sensor
|
||||||
|
- switch.tesla_model_3_update_switch
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Charging
|
title: Charging
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
title: Multi Room Audio & TTS
|
title: Multi Room Audio & TTS
|
||||||
icon: mdi:television
|
icon: mdi:television
|
||||||
cards:
|
cards:
|
||||||
- type: entities
|
# - type: entities
|
||||||
title: Snapcast Server Commands
|
# title: Snapcast Server Commands
|
||||||
show_header_toggle: false
|
# show_header_toggle: false
|
||||||
entities:
|
# entities:
|
||||||
- entity: input_select.snapcast_server
|
# - entity: input_select.snapcast_server
|
||||||
name: Snapcast Server Command
|
# name: Snapcast Server Command
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Raspberry Pi Commands
|
title: Raspberry Pi Commands
|
||||||
|
@ -43,37 +43,39 @@ cards:
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
# - media_player.denon_avr_x2400h
|
# - media_player.denon_avr_x2400h
|
||||||
- media_player.gstreamer
|
# - media_player.gstreamer
|
||||||
- media_player.mpd
|
# - media_player.mpd
|
||||||
- media_player.attic_tv
|
- media_player.attic_tv
|
||||||
|
- media_player.living_room
|
||||||
|
- media_player.upstairs
|
||||||
# - media_player.my_denon_receiver
|
# - media_player.my_denon_receiver
|
||||||
|
|
||||||
- type: vertical-stack
|
- type: vertical-stack
|
||||||
cards:
|
cards:
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.mpd
|
entity: media_player.living_room
|
||||||
|
- type: media-control
|
||||||
|
entity: media_player.upstairs
|
||||||
|
|
||||||
# - type: media-control
|
# - type: media-control
|
||||||
# entity: media_player.denon_avr_x2400h
|
# entity: media_player.denon_avr_x2400h
|
||||||
|
|
||||||
- type: media-control
|
# - type: media-control
|
||||||
entity: media_player.gstreamer
|
# entity: media_player.gstreamer
|
||||||
|
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.attic_tv
|
entity: media_player.attic_tv
|
||||||
|
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.chromecastultra7021
|
entity: media_player.chromecastultra7021
|
||||||
|
|
||||||
# - type: media-control
|
# - type: media-control
|
||||||
# entity: media_player.my_denon_receiver
|
# entity: media_player.my_denon_receiver
|
||||||
|
# - type: entities
|
||||||
- type: entities
|
# title: Snapcast Clients
|
||||||
title: Snapcast Clients
|
# show_header_toggle: false
|
||||||
show_header_toggle: false
|
# entities:
|
||||||
entities:
|
# - media_player.snapcast_client_b827eb011e00
|
||||||
- media_player.snapcast_client_b827eb011e00
|
# - media_player.snapcast_client_b827eb4445b1
|
||||||
- media_player.snapcast_client_b827eb4445b1
|
# - media_player.snapcast_client_b827eb505e2d
|
||||||
- media_player.snapcast_client_b827eb505e2d
|
# - media_player.snapcast_client_b827eba8e7ef
|
||||||
- media_player.snapcast_client_b827eba8e7ef
|
# - media_player.snapcast_client_b827ebaa08f7
|
||||||
- media_player.snapcast_client_b827ebaa08f7
|
|
||||||
|
|
|
@ -90,6 +90,3 @@ cards:
|
||||||
- script.restart_all_raspberrypis
|
- script.restart_all_raspberrypis
|
||||||
- script.restart_all_snapclients
|
- script.restart_all_snapclients
|
||||||
- script.shutdown_all_raspberrypis
|
- script.shutdown_all_raspberrypis
|
||||||
- script.restart_snapcast_server
|
|
||||||
- script.start_snapcast_server
|
|
||||||
- script.stop_snapcast_server
|
|
||||||
|
|
|
@ -63,7 +63,6 @@ cards:
|
||||||
- automation.notify_charger_switch_state
|
- automation.notify_charger_switch_state
|
||||||
- automation.notify_charging_status
|
- automation.notify_charging_status
|
||||||
- automation.notify_door_status
|
- automation.notify_door_status
|
||||||
- automation.notify_entry_door_status
|
|
||||||
- automation.notify_holiday_state_change
|
- automation.notify_holiday_state_change
|
||||||
- automation.notify_indian_holidays
|
- automation.notify_indian_holidays
|
||||||
- automation.notify_low_battery
|
- automation.notify_low_battery
|
||||||
|
@ -157,8 +156,6 @@ cards:
|
||||||
- automation.restore_familyroom_lights
|
- automation.restore_familyroom_lights
|
||||||
- automation.animate_master_bedroom_lights
|
- automation.animate_master_bedroom_lights
|
||||||
- automation.restore_masterbedroom_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_indoor_lights_on_before_sunset
|
||||||
- automation.evening_outdoor_lights_on_at_sunset
|
- automation.evening_outdoor_lights_on_at_sunset
|
||||||
- automation.garage_lights_on_when_door_is_opened
|
- automation.garage_lights_on_when_door_is_opened
|
||||||
|
@ -266,7 +263,6 @@ cards:
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- automation.keep_chromecast_on
|
- automation.keep_chromecast_on
|
||||||
- automation.snapcast_action
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Home Assistant Automations
|
title: Home Assistant Automations
|
||||||
|
|
|
@ -18,7 +18,7 @@ script:
|
||||||
away_mode: "true"
|
away_mode: "true"
|
||||||
- service: alarm_control_panel.alarm_arm_away
|
- service: alarm_control_panel.alarm_arm_away
|
||||||
data:
|
data:
|
||||||
entity_id: alarm_control_panel.simplisafe
|
entity_id: alarm_control_panel.home
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data:
|
data:
|
||||||
message: >
|
message: >
|
||||||
|
|
|
@ -366,7 +366,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.home_mode_away') == 'off' }}"
|
value_template: "{{ states('input_boolean.home_mode_away') == 'off' }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') | lower != 'armed_away' }}"
|
value_template: "{{ states('alarm_control_panel.home') | lower != 'armed_away' }}"
|
||||||
action:
|
action:
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
|
|
|
@ -73,9 +73,6 @@ automation:
|
||||||
- input_label.hasika_birthday_days2go
|
- input_label.hasika_birthday_days2go
|
||||||
- input_label.mallika_birthday_days2go
|
- input_label.mallika_birthday_days2go
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.to_state.state | int > 0 and trigger.to_state.state | int < 30 }}"
|
value_template: "{{ trigger.to_state.state | int > 0 and trigger.to_state.state | int < 30 }}"
|
||||||
action:
|
action:
|
||||||
|
@ -95,9 +92,6 @@ automation:
|
||||||
- input_label.hasika_birthday_days2go
|
- input_label.hasika_birthday_days2go
|
||||||
- input_label.mallika_birthday_days2go
|
- input_label.mallika_birthday_days2go
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ trigger.to_state.state | int == 0 }}"
|
value_template: "{{ trigger.to_state.state | int == 0 }}"
|
||||||
action:
|
action:
|
||||||
|
@ -118,9 +112,6 @@ automation:
|
||||||
condition:
|
condition:
|
||||||
condition: and
|
condition: and
|
||||||
conditions:
|
conditions:
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: time
|
- condition: time
|
||||||
after: "07:00:00"
|
after: "07:00:00"
|
||||||
before: "21:00:00"
|
before: "21:00:00"
|
||||||
|
|
|
@ -312,7 +312,7 @@ automation:
|
||||||
url: !secret frontdoor_camera_stream_url
|
url: !secret frontdoor_camera_stream_url
|
||||||
name: "frontyard"
|
name: "frontyard"
|
||||||
- condition: template
|
- 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
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_frontdoor_camera
|
entity_id: image_processing.tensorflow_frontdoor_camera
|
||||||
|
@ -392,7 +392,7 @@ automation:
|
||||||
url: !secret driveway_camera_stream_url
|
url: !secret driveway_camera_stream_url
|
||||||
name: "driveway"
|
name: "driveway"
|
||||||
- condition: template
|
- 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
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_driveway_camera
|
entity_id: image_processing.tensorflow_driveway_camera
|
||||||
|
@ -468,7 +468,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
||||||
- condition: template
|
- 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:
|
action:
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
|
@ -547,7 +547,7 @@ automation:
|
||||||
url: !secret playarea_camera_stream_url
|
url: !secret playarea_camera_stream_url
|
||||||
name: "backyard"
|
name: "backyard"
|
||||||
- condition: template
|
- 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
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_patio_camera
|
entity_id: image_processing.tensorflow_patio_camera
|
||||||
|
@ -641,7 +641,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
||||||
- condition: template
|
- 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:
|
action:
|
||||||
- delay: "{{ '00:00:08' if states('binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor') == 'on' else '0:0:0' }}"
|
- delay: "{{ '00:00:08' if states('binary_sensor.aeotec_zw120_door_window_sensor_gen5_sensor') == 'on' else '0:0:0' }}"
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
|
@ -712,7 +712,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
||||||
- condition: template
|
- 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:
|
action:
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
|
@ -782,7 +782,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
||||||
- condition: template
|
- 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:
|
action:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
|
@ -866,29 +866,29 @@ automation:
|
||||||
- service: script.frontdoor_camera_text_overlay
|
- service: script.frontdoor_camera_text_overlay
|
||||||
data_template:
|
data_template:
|
||||||
text: >
|
text: >
|
||||||
{{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or
|
{{ '* ' if states('alarm_control_panel.home') == 'armed_home' or
|
||||||
states('alarm_control_panel.simplisafe') == 'armed_away' -}}
|
states('alarm_control_panel.home') == 'armed_away' -}}
|
||||||
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
||||||
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
||||||
- service: script.driveway_camera_text_overlay
|
- service: script.driveway_camera_text_overlay
|
||||||
data_template:
|
data_template:
|
||||||
text: >
|
text: >
|
||||||
{{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or
|
{{ '* ' if states('alarm_control_panel.home') == 'armed_home' or
|
||||||
states('alarm_control_panel.simplisafe') == 'armed_away' -}}
|
states('alarm_control_panel.home') == 'armed_away' -}}
|
||||||
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
||||||
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
||||||
- service: script.playarea_camera_text_overlay
|
- service: script.playarea_camera_text_overlay
|
||||||
data_template:
|
data_template:
|
||||||
text: >
|
text: >
|
||||||
{{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or
|
{{ '* ' if states('alarm_control_panel.home') == 'armed_home' or
|
||||||
states('alarm_control_panel.simplisafe') == 'armed_away' -}}
|
states('alarm_control_panel.home') == 'armed_away' -}}
|
||||||
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
||||||
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
||||||
- service: script.patio_camera_text_overlay
|
- service: script.patio_camera_text_overlay
|
||||||
data_template:
|
data_template:
|
||||||
text: >
|
text: >
|
||||||
{{ '* ' if states('alarm_control_panel.simplisafe') == 'armed_home' or
|
{{ '* ' if states('alarm_control_panel.home') == 'armed_home' or
|
||||||
states('alarm_control_panel.simplisafe') == 'armed_away' -}}
|
states('alarm_control_panel.home') == 'armed_away' -}}
|
||||||
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
{{- states('sensor.dark_sky_temperature')|int}} °F, Feels like
|
||||||
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
{{- ' ' ~ states('sensor.dark_sky_apparent_temperature') |int -}}
|
||||||
|
|
||||||
|
|
|
@ -290,9 +290,6 @@ automation:
|
||||||
platform: time
|
platform: time
|
||||||
at: "22:10:00"
|
at: "22:10:00"
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.nightly_report') == 'on' }}"
|
value_template: "{{ states('input_boolean.nightly_report') == 'on' }}"
|
||||||
action:
|
action:
|
||||||
|
|
|
@ -219,6 +219,65 @@ automation:
|
||||||
data:
|
data:
|
||||||
entity_id: switch.garage
|
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
|
# When I open the garage door
|
||||||
# if it is dark outside, OR
|
# if it is dark outside, OR
|
||||||
|
@ -247,69 +306,3 @@ automation:
|
||||||
entity_id: switch.garage
|
entity_id: switch.garage
|
||||||
- service: timer.start
|
- service: timer.start
|
||||||
entity_id: timer.timer_garage
|
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
|
|
||||||
|
|
|
@ -150,7 +150,7 @@
|
||||||
# initial_state: true
|
# initial_state: true
|
||||||
# trigger:
|
# trigger:
|
||||||
# platform: state
|
# platform: state
|
||||||
# entity_id: alarm_control_panel.simplisafe
|
# entity_id: alarm_control_panel.home
|
||||||
# to: 'disarmed'
|
# to: 'disarmed'
|
||||||
# condition:
|
# condition:
|
||||||
# - condition: template
|
# - condition: template
|
||||||
|
@ -186,7 +186,7 @@
|
||||||
# value_template: "{{ trigger.from_state }}"
|
# value_template: "{{ trigger.from_state }}"
|
||||||
# - condition: template
|
# - condition: template
|
||||||
# value_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" %}
|
# {% if state != "" and state != "unknown" and state == "armed_away" %}
|
||||||
# true
|
# true
|
||||||
# {% else %}
|
# {% else %}
|
||||||
|
|
|
@ -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
|
|
|
@ -9,7 +9,7 @@ homeassistant:
|
||||||
group.home_security_system:
|
group.home_security_system:
|
||||||
order: 7
|
order: 7
|
||||||
|
|
||||||
alarm_control_panel.simplisafe:
|
alarm_control_panel.home:
|
||||||
friendly_name: Home Security System
|
friendly_name: Home Security System
|
||||||
icon: mdi:security
|
icon: mdi:security
|
||||||
sensor.my_alarm_control_panel:
|
sensor.my_alarm_control_panel:
|
||||||
|
@ -40,35 +40,35 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: alarm_control_panel.simplisafe
|
entity_id: alarm_control_panel.home
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{% if trigger.from_state %} True {% else %} False {% endif %}"
|
value_template: "{% if trigger.from_state %} True {% else %} False {% endif %}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') != 'unknown' }}"
|
value_template: "{{ states('alarm_control_panel.home') != 'unknown' }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') | trim != '' }}"
|
value_template: "{{ states('alarm_control_panel.home') | trim != '' }}"
|
||||||
action:
|
action:
|
||||||
- service_template: >
|
- service_template: >
|
||||||
{% if states('alarm_control_panel.simplisafe') == "armed_home" %}
|
{% if states('alarm_control_panel.home') == "armed_home" %}
|
||||||
script.xiaomi_blue
|
script.xiaomi_blue
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "armed_away" %}
|
{% elif states('alarm_control_panel.home') == "armed_away" %}
|
||||||
script.xiaomi_green
|
script.xiaomi_green
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "triggered" %}
|
{% elif states('alarm_control_panel.home') == "triggered" %}
|
||||||
script.xiaomi_red
|
script.xiaomi_red
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "disarmed" %}
|
{% elif states('alarm_control_panel.home') == "disarmed" %}
|
||||||
script.xiaomi_red
|
script.xiaomi_red
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: script.ifttt_leeo_color_change
|
- service: script.ifttt_leeo_color_change
|
||||||
data_template:
|
data_template:
|
||||||
value1: >
|
value1: >
|
||||||
{% if states('alarm_control_panel.simplisafe') == "armed_home" %}
|
{% if states('alarm_control_panel.home') == "armed_home" %}
|
||||||
"#0000FF"
|
"#0000FF"
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "armed_away" %}
|
{% elif states('alarm_control_panel.home') == "armed_away" %}
|
||||||
"#00FF00"
|
"#00FF00"
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "triggered" %}
|
{% elif states('alarm_control_panel.home') == "triggered" %}
|
||||||
"#FF0000"
|
"#FF0000"
|
||||||
{% elif states('alarm_control_panel.simplisafe') == "disarmed" %}
|
{% elif states('alarm_control_panel.home') == "disarmed" %}
|
||||||
"#FF0000"
|
"#FF0000"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: alarm_control_panel.simplisafe
|
entity_id: alarm_control_panel.home
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
||||||
|
@ -94,29 +94,29 @@ automation:
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data_template:
|
data_template:
|
||||||
message: >
|
message: >
|
||||||
{% if states('alarm_control_panel.simplisafe') == "armed_home" %}
|
{% if states('alarm_control_panel.home') == "armed_home" %}
|
||||||
Your home is now secured!
|
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!
|
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.
|
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.
|
Attention!: Your Home Security System is turned OFF.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
message: >
|
message: >
|
||||||
{% if states('alarm_control_panel.simplisafe') == "armed_home" %}
|
{% if states('alarm_control_panel.home') == "armed_home" %}
|
||||||
Your home is now secured!
|
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!
|
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.
|
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.
|
Attention!: Your Home Security System is turned OFF.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') != 'disarmed' }}"
|
value_template: "{{ states('alarm_control_panel.home') != 'disarmed' }}"
|
||||||
- service: input_boolean.turn_on
|
- service: input_boolean.turn_on
|
||||||
entity_id: input_boolean.notify_camera_motion
|
entity_id: input_boolean.notify_camera_motion
|
||||||
|
|
||||||
|
@ -128,14 +128,10 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- alarm_control_panel.simplisafe
|
- alarm_control_panel.home
|
||||||
to: "disarmed"
|
to: "disarmed"
|
||||||
for:
|
for:
|
||||||
minutes: 10
|
minutes: 10
|
||||||
condition:
|
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
action:
|
action:
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data:
|
data:
|
||||||
|
@ -149,14 +145,11 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- alarm_control_panel.simplisafe
|
- alarm_control_panel.home
|
||||||
to: "disarmed"
|
to: "disarmed"
|
||||||
for:
|
for:
|
||||||
minutes: 30
|
minutes: 30
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
||||||
action:
|
action:
|
||||||
|
@ -172,7 +165,7 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: alarm_control_panel.simplisafe
|
entity_id: alarm_control_panel.home
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
|
@ -203,18 +196,15 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('sensor.bedtime_minute')|int == now().minute|int }}"
|
value_template: "{{ states('sensor.bedtime_minute')|int == now().minute|int }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') != 'away' }}"
|
value_template: "{{ states('alarm_control_panel.home') != 'away' }}"
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('alarm_control_panel.simplisafe') == 'disarmed' }}"
|
value_template: "{{ states('alarm_control_panel.home') == 'disarmed' }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.security_system_alerts') == 'on' }}"
|
||||||
action:
|
action:
|
||||||
- service: alarm_control_panel.alarm_arm_home
|
- service: alarm_control_panel.alarm_arm_home
|
||||||
data:
|
data:
|
||||||
entity_id: alarm_control_panel.simplisafe
|
entity_id: alarm_control_panel.home
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data:
|
data:
|
||||||
message: "It's bedtime, you forgot to turn ON Home Security System. Turned it ON for you."
|
message: "It's bedtime, you forgot to turn ON Home Security System. Turned it ON for you."
|
||||||
|
@ -231,7 +221,7 @@ automation:
|
||||||
# condition: and
|
# condition: and
|
||||||
# conditions:
|
# conditions:
|
||||||
# - condition: template
|
# - 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
|
# - condition: or
|
||||||
# conditions:
|
# conditions:
|
||||||
# - condition: template
|
# - condition: template
|
||||||
|
@ -244,7 +234,7 @@ automation:
|
||||||
# - service: script.notify_me
|
# - service: script.notify_me
|
||||||
# data_template:
|
# data_template:
|
||||||
# message: >
|
# 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!
|
# 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
|
# - service: camera.snapshot
|
||||||
# data_template:
|
# data_template:
|
||||||
|
@ -279,14 +269,14 @@ automation:
|
||||||
# {% elif states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') == "on" %}
|
# {% 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 %}
|
# {% set doors = states('binary_sensor.two_car_garage_door_tilt_sensor_sensor.name %}
|
||||||
# {% endif %}
|
# {% 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:
|
# data:
|
||||||
# images:
|
# 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/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/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' }}"
|
# - "{{ '/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
|
# - condition: template
|
||||||
# value_template: '{{ states('alarm_control_panel.simplisafe') == "armed_home" }}'
|
# value_template: '{{ states('alarm_control_panel.home') == "armed_home" }}'
|
||||||
# - service: script.voice_notify
|
# - service: script.voice_notify
|
||||||
# data_template:
|
# data_template:
|
||||||
# message: >
|
# message: >
|
||||||
|
@ -298,7 +288,7 @@ automation:
|
||||||
# {% elif states('binary_sensor.single_car_garage_door_tilt_sensor_sensor') == "on" %}
|
# {% 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 %}
|
# {% set doors = states('binary_sensor.two_car_garage_door_tilt_sensor_sensor.name %}
|
||||||
# {% endif %}
|
# {% 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.
|
# BUT the {{ doors }} {{ 'are' if doors.endswith('s') else 'is' }} open.
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -312,10 +302,7 @@ automation:
|
||||||
# offset: '+00:00:00'
|
# offset: '+00:00:00'
|
||||||
# condition:
|
# condition:
|
||||||
# - condition: state
|
# - condition: state
|
||||||
# entity_id: group.all_devices
|
# entity_id: alarm_control_panel.home
|
||||||
# state: 'home'
|
|
||||||
# - condition: state
|
|
||||||
# entity_id: alarm_control_panel.simplisafe
|
|
||||||
# state: 'disarmed'
|
# state: 'disarmed'
|
||||||
# action:
|
# action:
|
||||||
# - service_template: >-
|
# - service_template: >-
|
||||||
|
@ -328,7 +315,7 @@ automation:
|
||||||
# alarm_control_panel.disarm
|
# alarm_control_panel.disarm
|
||||||
# {% endif %}
|
# {% endif %}
|
||||||
# data:
|
# data:
|
||||||
# entity_id: alarm_control_panel.simplisafe
|
# entity_id: alarm_control_panel.home
|
||||||
# - service: script.voice_notify
|
# - service: script.voice_notify
|
||||||
# data_template:
|
# data_template:
|
||||||
# message: >
|
# message: >
|
||||||
|
@ -417,9 +404,9 @@ automation:
|
||||||
# condition: or
|
# condition: or
|
||||||
# conditions:
|
# conditions:
|
||||||
# - condition: template
|
# - condition: template
|
||||||
# value_template: '{{ states('alarm_control_panel.simplisafe') | lower == "armed_away" }}'
|
# value_template: '{{ states('alarm_control_panel.home') | lower == "armed_away" }}'
|
||||||
# - condition: template
|
# - condition: template
|
||||||
# value_template: '{{ states('alarm_control_panel.simplisafe') | lower == "armed_home" }}'
|
# value_template: '{{ states('alarm_control_panel.home') | lower == "armed_home" }}'
|
||||||
# action:
|
# action:
|
||||||
# - service: notify.ios_suresh
|
# - service: notify.ios_suresh
|
||||||
# data_template:
|
# data_template:
|
||||||
|
@ -444,7 +431,7 @@ automation:
|
||||||
# to: 'on'
|
# to: 'on'
|
||||||
# condition:
|
# condition:
|
||||||
# - condition: template
|
# - 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:
|
# action:
|
||||||
# - service: notify.ios_suresh
|
# - service: notify.ios_suresh
|
||||||
# data_template:
|
# data_template:
|
||||||
|
@ -468,7 +455,7 @@ automation:
|
||||||
# actionName: 'DISABLE_SECURITY'
|
# actionName: 'DISABLE_SECURITY'
|
||||||
# action:
|
# action:
|
||||||
# - service: alarm_control_panel.alarm_disarm
|
# - service: alarm_control_panel.alarm_disarm
|
||||||
# entity_id: alarm_control_panel.simplisafe
|
# entity_id: alarm_control_panel.home
|
||||||
# - service: notify.ios_suresh
|
# - service: notify.ios_suresh
|
||||||
# data:
|
# data:
|
||||||
# message: "Unlocked your home!"
|
# message: "Unlocked your home!"
|
||||||
|
|
|
@ -53,6 +53,14 @@ homeassistant:
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
icon: mdi:lightbulb
|
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:
|
switch.basement_left:
|
||||||
friendly_name: Basement Theater Lights
|
friendly_name: Basement Theater Lights
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
|
@ -131,6 +139,7 @@ tplink:
|
||||||
- host: !secret tplink_basement_right
|
- host: !secret tplink_basement_right
|
||||||
- host: !secret tplink_kitchen
|
- host: !secret tplink_kitchen
|
||||||
- host: !secret tplink_office_room
|
- host: !secret tplink_office_room
|
||||||
|
- host: !secret tplink_front_room
|
||||||
|
|
||||||
# Smart Outlets
|
# Smart Outlets
|
||||||
- host: !secret tplink_smart_outlet1
|
- host: !secret tplink_smart_outlet1
|
||||||
|
|
|
@ -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
|
|
||||||
# <module 'gi' from '/srv/homeassistant/lib/python3.6/site-packages/gi/__init__.py'>
|
|
||||||
# 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 %}
|
|
|
@ -122,22 +122,8 @@ script:
|
||||||
value_template: "{{ states('input_boolean.voice_notifications') == 'on' }}"
|
value_template: "{{ states('input_boolean.voice_notifications') == 'on' }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.do_not_disturb') | lower == 'off' }}"
|
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
|
- condition: template
|
||||||
value_template: "{{ message | trim != '' }}"
|
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
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
{% if only_at_night | default('no', true ) == "yes" %}
|
{% if only_at_night | default('no', true ) == "yes" %}
|
||||||
|
@ -150,7 +136,8 @@ script:
|
||||||
true
|
true
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: media_player.volume_set
|
- 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:
|
data_template:
|
||||||
volume_level: >
|
volume_level: >
|
||||||
{% if states('input_boolean.emergency_mode') == "on" %}
|
{% if states('input_boolean.emergency_mode') == "on" %}
|
||||||
|
@ -165,7 +152,8 @@ script:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: tts.amazon_polly_say
|
- 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:
|
data_template:
|
||||||
cache: true
|
cache: true
|
||||||
message: >
|
message: >
|
||||||
|
@ -200,7 +188,8 @@ script:
|
||||||
voice_greeting:
|
voice_greeting:
|
||||||
sequence:
|
sequence:
|
||||||
- service: tts.amazon_polly_say
|
- 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:
|
data_template:
|
||||||
cache: true
|
cache: true
|
||||||
message: >
|
message: >
|
||||||
|
|
|
@ -310,9 +310,6 @@ automation:
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ states.input_boolean.hourly_report.state == "on" }}'
|
value_template: '{{ states.input_boolean.hourly_report.state == "on" }}'
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
{% set hour = now().hour | int %}
|
{% set hour = now().hour | int %}
|
||||||
|
|
|
@ -1,30 +1,32 @@
|
||||||
homeassistant:
|
homeassistant:
|
||||||
customize:
|
customize:
|
||||||
binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor:
|
binary_sensor.tesla_model_3_charger_sensor:
|
||||||
friendly_name: Charger
|
friendly_name: Charger
|
||||||
binary_sensor.tesla_model_3_5yj3e1ea8jf010610_parking_brake_sensor:
|
binary_sensor.tesla_model_3_parking_brake_sensor:
|
||||||
friendly_name: Parking Break
|
friendly_name: Parking Break
|
||||||
climate.tesla_model_3_5yj3e1ea8jf010610_hvac_climate_system:
|
climate.tesla_model_3_hvac_climate_system:
|
||||||
friendly_name: Tesla Climate
|
friendly_name: Tesla Climate
|
||||||
device_tracker.tesla_model_3_5yj3e1ea8jf010610_location_tracker:
|
device_tracker.mahasri_tesla_location_tracker:
|
||||||
friendly_name: Tesla
|
friendly_name: Tesla
|
||||||
lock.tesla_model_3_5yj3e1ea8jf010610_door_lock:
|
lock.tesla_model_3_charger_door_lock:
|
||||||
friendly_name: Tesla Door Lock
|
friendly_name: Tesla Door Lock
|
||||||
sensor.tesla_model_3_5yj3e1ea8jf010610_battery_sensor:
|
sensor.tesla_model_3_battery_sensor:
|
||||||
friendly_name: Battery Percentage
|
friendly_name: Battery Percentage
|
||||||
icon: mdi:battery
|
icon: mdi:battery
|
||||||
sensor.tesla_model_3_5yj3e1ea8jf010610_mileage_sensor:
|
sensor.tesla_model_3_mileage_sensor:
|
||||||
friendly_name: Total Mileage
|
friendly_name: Total Mileage
|
||||||
sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor:
|
sensor.tesla_model_3_range_sensor:
|
||||||
friendly_name: Battery Range
|
friendly_name: Battery Range
|
||||||
sensor.tesla_model_3_5yj3e1ea8jf010610_temperature_sensor_inside:
|
sensor.tesla_model_3_temperature_sensor_inside:
|
||||||
friendly_name: Temperature Inside
|
friendly_name: Temperature Inside
|
||||||
sensor.tesla_model_3_5yj3e1ea8jf010610_temperature_sensor_outside:
|
sensor.tesla_model_3_temperature_sensor_outside:
|
||||||
friendly_name: Temperature Outside
|
friendly_name: Temperature Outside
|
||||||
switch.tesla_model_3_5yj3e1ea8jf010610_charger_switch:
|
switch.tesla_model_3_charger_switch:
|
||||||
friendly_name: Charger Switch
|
friendly_name: Charger Switch
|
||||||
switch.tesla_model_3_5yj3e1ea8jf010610_maxrange_switch:
|
switch.tesla_model_3_maxrange_switch:
|
||||||
friendly_name: Max Range 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
|
# 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
|
||||||
|
@ -50,7 +52,7 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor
|
entity_id: binary_sensor.tesla_model_3_charger_sensor
|
||||||
action:
|
action:
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data_template:
|
data_template:
|
||||||
|
@ -60,7 +62,7 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: lock.tesla_model_3_5yj3e1ea8jf010610_door_lock
|
entity_id: lock.tesla_model_3_door_lock
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
||||||
|
@ -73,7 +75,7 @@ automation:
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: switch.tesla_model_3_5yj3e1ea8jf010610_charger_switch
|
entity_id: switch.tesla_model_3_charger_switch
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
||||||
|
|
|
@ -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
|
|
@ -4,6 +4,20 @@
|
||||||
# @package : TV
|
# @package : TV
|
||||||
# @description : Tv Automations
|
# @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 }}"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# _ _ _
|
# _ _ _
|
||||||
|
@ -15,7 +29,6 @@
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
automation:
|
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
|
- alias: TV Dim Indoor Lights when TV is ON
|
||||||
|
@ -23,15 +36,15 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: binary_sensor.sharp_tv
|
entity_id: binary_sensor.sharp_tv
|
||||||
from: 'off'
|
from: "off"
|
||||||
to: 'on'
|
to: "on"
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: sun.sun
|
entity_id: sun.sun
|
||||||
state: 'below_horizon'
|
state: "below_horizon"
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_boolean.light_automations
|
entity_id: input_boolean.light_automations
|
||||||
state: 'on'
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
|
@ -51,7 +64,7 @@ automation:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: /home/tv/backlight
|
topic: /home/tv/backlight
|
||||||
payload: 'on'
|
payload: "on"
|
||||||
retain: true
|
retain: true
|
||||||
|
|
||||||
# Restore Family Room Lights to TV mode
|
# Restore Family Room Lights to TV mode
|
||||||
|
@ -61,15 +74,15 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id: group.family_room_lights
|
entity_id: group.family_room_lights
|
||||||
from: 'off'
|
from: "off"
|
||||||
to: 'on'
|
to: "on"
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: binary_sensor.sharp_tv
|
entity_id: binary_sensor.sharp_tv
|
||||||
state: 'on'
|
state: "on"
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_boolean.light_automations
|
entity_id: input_boolean.light_automations
|
||||||
state: 'on'
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
|
@ -97,12 +110,12 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: binary_sensor.sharp_tv
|
entity_id: binary_sensor.sharp_tv
|
||||||
to: 'off'
|
to: "off"
|
||||||
action:
|
action:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: /home/tv/backlight
|
topic: /home/tv/backlight
|
||||||
payload: 'off'
|
payload: "off"
|
||||||
retain: true
|
retain: true
|
||||||
|
|
||||||
# Turn TV backlights when TV is turned ON
|
# Turn TV backlights when TV is turned ON
|
||||||
|
@ -112,12 +125,12 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: binary_sensor.sharp_tv
|
entity_id: binary_sensor.sharp_tv
|
||||||
to: 'on'
|
to: "on"
|
||||||
action:
|
action:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: /home/tv/backlight
|
topic: /home/tv/backlight
|
||||||
payload: 'on'
|
payload: "on"
|
||||||
retain: true
|
retain: true
|
||||||
|
|
||||||
# Turn back Family room lights when TV is switched OFF
|
# Turn back Family room lights when TV is switched OFF
|
||||||
|
@ -127,14 +140,14 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: binary_sensor.sharp_tv
|
entity_id: binary_sensor.sharp_tv
|
||||||
to: 'off'
|
to: "off"
|
||||||
condition:
|
condition:
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: sun.sun
|
entity_id: sun.sun
|
||||||
state: 'below_horizon'
|
state: "below_horizon"
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_boolean.light_automations
|
entity_id: input_boolean.light_automations
|
||||||
state: 'on'
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
|
@ -157,5 +170,5 @@ automation:
|
||||||
- service: mqtt.publish
|
- service: mqtt.publish
|
||||||
data:
|
data:
|
||||||
topic: /home/tv/backlight
|
topic: /home/tv/backlight
|
||||||
payload: 'off'
|
payload: "off"
|
||||||
retain: true
|
retain: true
|
|
@ -291,9 +291,6 @@ automation:
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ trigger.to_state.state | lower == "rain" }}'
|
value_template: '{{ trigger.to_state.state | lower == "rain" }}'
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: sun.sun
|
entity_id: sun.sun
|
||||||
state: "above_horizon"
|
state: "above_horizon"
|
||||||
|
@ -324,9 +321,6 @@ automation:
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ states.sensor.season.state | lower == "winter" }}'
|
value_template: '{{ states.sensor.season.state | lower == "winter" }}'
|
||||||
- condition: state
|
|
||||||
entity_id: group.all_devices
|
|
||||||
state: "home"
|
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: sun.sun
|
entity_id: sun.sun
|
||||||
state: "above_horizon"
|
state: "above_horizon"
|
||||||
|
|
|
@ -87,9 +87,9 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: light.family_room
|
entity_id: light.family_room
|
||||||
rgb_color:
|
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
|
# Shake: Toggle Do Not Disturb Mode
|
||||||
- alias: Family Room Cube Event Shake
|
- alias: Family Room Cube Event Shake
|
||||||
|
@ -122,7 +122,7 @@ automation:
|
||||||
action_type: flip90
|
action_type: flip90
|
||||||
action:
|
action:
|
||||||
- service_template: switch.toggle
|
- service_template: switch.toggle
|
||||||
entity_id: switch.rf_switch_four
|
entity_id: switch.front_room
|
||||||
|
|
||||||
# Flip 180: Toggle Office Room Accent Lights
|
# Flip 180: Toggle Office Room Accent Lights
|
||||||
- alias: Family Room Cube Event flip180
|
- alias: Family Room Cube Event flip180
|
||||||
|
@ -326,9 +326,9 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: light.master_bedroom
|
entity_id: light.master_bedroom
|
||||||
rgb_color:
|
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
|
# Shake: Toggle Do Not Disturb Mode
|
||||||
- alias: Master Bedroom Cube Event Shake
|
- alias: Master Bedroom Cube Event Shake
|
||||||
|
|
|
@ -17,7 +17,9 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro USPS() -%}
|
{%- macro USPS() -%}
|
||||||
|
{%- if states('sensor.usps_mail') | int > 0 -%}
|
||||||
USPS is going to deliver {{ states('sensor.usps_mail') }} mails today.
|
USPS is going to deliver {{ states('sensor.usps_mail') }} mails today.
|
||||||
|
{%- endif -%}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro alert_battery_levels() %}
|
{%- macro alert_battery_levels() %}
|
||||||
|
@ -27,13 +29,15 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro tesla_status() -%}
|
{%- macro tesla_status() -%}
|
||||||
{%- if states("sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor") != "unknown" -%}
|
{%- if states("sensor.tesla_model_3_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).
|
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 -%}
|
{%- endif -%}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro pollen_levels() -%}
|
{%- macro pollen_levels() -%}
|
||||||
|
{% if states('sensor.pollen_level') != 'unknown' %}
|
||||||
Pollen level is {{ states('sensor.pollen_level') }}.
|
Pollen level is {{ states('sensor.pollen_level') }}.
|
||||||
|
{% endif %}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro humidity_status() -%}
|
{%- macro humidity_status() -%}
|
||||||
|
@ -41,18 +45,18 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro alarm_status() -%}
|
{%- 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 -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro single_car_garage_door_status() -%}
|
{%- macro single_car_garage_door_status() -%}
|
||||||
{%- if states('binary_sensor.single_car_garage_door_tilt_sensor_sensor') |lower == "on" -%}
|
{%- 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
|
{{ states.binary_sensor.single_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN!
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro two_car_garage_door_status() -%}
|
{%- macro two_car_garage_door_status() -%}
|
||||||
{% if states('binary_sensor.two_car_garage_door_tilt_sensor_sensor') |lower == "on" %}
|
{% 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
|
{{ states.binary_sensor.two_car_garage_door_tilt_sensor_sensor.attributes.friendly_name }} is OPEN!
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
|
@ -60,9 +64,9 @@
|
||||||
{%- set single_car_garage = single_car_garage_door_status() -%}
|
{%- set single_car_garage = single_car_garage_door_status() -%}
|
||||||
{%- set two_car_garage = two_car_garage_door_status() -%}
|
{%- set two_car_garage = two_car_garage_door_status() -%}
|
||||||
{%- if single_car_garage | trim == "" and two_car_garage | trim == "" -%}
|
{%- if single_car_garage | trim == "" and two_car_garage | trim == "" -%}
|
||||||
Both the garage doors are CLOSED!
|
Both the garage doors are closed.
|
||||||
{%- elif single_car_garage | trim != "" and two_car_garage | trim != "" -%}
|
{%- elif single_car_garage | trim != "" and two_car_garage | trim != "" -%}
|
||||||
Warning! Both garage doors are OPEN.
|
Warning! Both garage doors are OPEN!
|
||||||
{% else %}
|
{% else %}
|
||||||
Warning! {{ single_car_garage }} {{ two_car_garage }}
|
Warning! {{ single_car_garage }} {{ two_car_garage }}
|
||||||
{%- endif -%}
|
{%- endif -%}
|
||||||
|
@ -72,6 +76,13 @@
|
||||||
{{- "true" if name.endswith("s") else "false" -}}
|
{{- "true" if name.endswith("s") else "false" -}}
|
||||||
{%- endmacro -%}
|
{%- 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() -%}
|
{%- macro light_status() -%}
|
||||||
{%- set lights_switches = ["light.family_room",
|
{%- set lights_switches = ["light.family_room",
|
||||||
"light.master_bedroom",
|
"light.master_bedroom",
|
||||||
|
@ -108,4 +119,4 @@
|
||||||
{{ light_status() }}
|
{{ light_status() }}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{{- mother_of_all_macros() -}}
|
{{- cleanup(mother_of_all_macros()) -}}
|
||||||
|
|
|
@ -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" -%}
|
{%- 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 item.attributes.battery|int < level -%}
|
||||||
{%- if states("sensor." ~ item.friendly_name |lower ~"s_iphone_battery_state") | lower != "charging" %}
|
{%- 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 %}
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
|
@ -46,11 +46,11 @@
|
||||||
|
|
||||||
{#- Provides Home Security System Status -#}
|
{#- Provides Home Security System Status -#}
|
||||||
{%- macro alarm_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.
|
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.
|
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.
|
Your home security system is ON, and your home is secured.
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro charging_status() -%}
|
{%- 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] -}}
|
{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{- item.name.split(' ')[0] -}}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
@ -115,12 +115,12 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro tesla_status() %}
|
{%- macro tesla_status() %}
|
||||||
{%- if states("binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor") != "unknown" -%}
|
{%- if states("binary_sensor.tesla_model_3_charger_sensor") != "unknown" -%}
|
||||||
Your Tesla Car is {{ 'not' if states('binary_sensor.tesla_model_3_5yj3e1ea8jf010610_charger_sensor') == "off" }} plugged in.
|
Your Tesla Car is {{ 'not' if states('binary_sensor.tesla_model_3_charger_sensor') == "off" }} plugged in.
|
||||||
{% endif %}
|
{% 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 -%}
|
{%- 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_5yj3e1ea8jf010610_battery_sensor') }}%, and you can drive about {{ (states.sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor.state | int) | round(0) }} miles.
|
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 %}
|
{% endif %}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
|
|
|
@ -19,10 +19,10 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro tesla_status() -%}
|
{%- macro tesla_status() -%}
|
||||||
{% if states("sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor") != "unknown" %}
|
{% if states("sensor.tesla_model_3_range_sensor") != "unknown" %}
|
||||||
{%- if (states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) < 75 and
|
{%- if (states('sensor.tesla_model_3_range_sensor') | int) | round(0) < 75 and
|
||||||
(states('sensor.tesla_model_3_5yj3e1ea8jf010610_range_sensor') | int) | round(0) > 0 -%}
|
(states('sensor.tesla_model_3_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.
|
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 -%}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
|
@ -34,10 +34,10 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="63.6" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="63.1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="4" label="Power" units="W" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="46" />
|
<Value type="decimal" genre="user" instance="1" index="4" label="Power" units="W" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="46" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="32" />
|
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="33" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" after_mark="true" innif="true">
|
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" after_mark="true" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="48" />
|
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -208,7 +208,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="48" name="COMMAND_CLASS_SENSOR_BINARY" version="1" request_flags="4" innif="true">
|
<CommandClass id="48" name="COMMAND_CLASS_SENSOR_BINARY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="bool" genre="user" instance="1" index="0" label="Sensor" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="True" />
|
<Value type="bool" genre="user" instance="1" index="0" label="Sensor" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="False" />
|
||||||
<SensorMap index="0" type="46" />
|
<SensorMap index="0" type="46" />
|
||||||
<SensorMap index="0" type="62" />
|
<SensorMap index="0" type="62" />
|
||||||
<SensorMap index="0" type="193" />
|
<SensorMap index="0" type="193" />
|
||||||
|
@ -216,7 +216,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="63.8" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="62.9" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="31" />
|
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="31" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
|
@ -350,7 +350,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="30" />
|
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="88" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -379,7 +379,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="4" name="Two Car Garage Door Tilt Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="4" name="Two Car Garage Door Tilt Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="3" name="Garage Door Tilt Sensor" />
|
<Product type="4" id="3" name="Garage Door Tilt Sensor" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -490,7 +490,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="5" name="Single Car Garage Door Tilt Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="5" name="Single Car Garage Door Tilt Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Session">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="3" name="Garage Door Tilt Sensor" />
|
<Product type="4" id="3" name="Garage Door Tilt Sensor" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -601,7 +601,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="6" name="Back Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="6" name="Back Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="2" name="Door Sensor" />
|
<Product type="4" id="2" name="Door Sensor" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -710,7 +710,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="11" name="Front Room Multi Sensor" location="" basic="4" generic="33" specific="1" roletype="6" devicetype="3079" nodetype="0" type="Routing Multilevel Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="11" name="Front Room Multi Sensor" location="" basic="4" generic="33" specific="1" roletype="6" devicetype="3079" nodetype="0" type="Routing Multilevel Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="86" name="Aeotec">
|
<Manufacturer id="86" name="Aeotec">
|
||||||
<Product type="102" id="64" name="ZW100 MultiSensor 6" />
|
<Product type="102" id="64" name="ZW100 MultiSensor 6" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -728,9 +728,9 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="67.9" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="67.4" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="2" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="35" />
|
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="39" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" innif="true">
|
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" innif="true">
|
||||||
|
@ -984,7 +984,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="37" name="COMMAND_CLASS_SWITCH_BINARY" version="1" request_flags="4" innif="true">
|
<CommandClass id="37" name="COMMAND_CLASS_SWITCH_BINARY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="bool" genre="user" instance="1" index="0" label="Switch" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="True" />
|
<Value type="bool" genre="user" instance="1" index="0" label="Switch" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="False" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="38" name="COMMAND_CLASS_SWITCH_MULTILEVEL" version="2" innif="true">
|
<CommandClass id="38" name="COMMAND_CLASS_SWITCH_MULTILEVEL" version="2" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -1006,12 +1006,12 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="50" name="COMMAND_CLASS_METER" version="3" request_flags="2" innif="true">
|
<CommandClass id="50" name="COMMAND_CLASS_METER" version="3" request_flags="2" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="0" label="Energy" units="kWh" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="53.036" />
|
<Value type="decimal" genre="user" instance="1" index="0" label="Energy" units="kWh" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="59.018" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Previous Reading" units="kWh" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="52.609" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Previous Reading" units="kWh" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="59.018" />
|
||||||
<Value type="int" genre="user" instance="1" index="2" label="Interval" units="seconds" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="-2147483648" max="2147483647" value="65535" />
|
<Value type="int" genre="user" instance="1" index="2" label="Interval" units="seconds" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="-2147483648" max="2147483647" value="583" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="8" label="Power" units="W" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="12.274" />
|
<Value type="decimal" genre="user" instance="1" index="8" label="Power" units="W" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0.000" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="16" label="Voltage" units="V" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="123.389" />
|
<Value type="decimal" genre="user" instance="1" index="16" label="Voltage" units="V" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="122.775" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="20" label="Current" units="A" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0.179" />
|
<Value type="decimal" genre="user" instance="1" index="20" label="Current" units="A" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0.000" />
|
||||||
<Value type="bool" genre="user" instance="1" index="32" label="Exporting" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="False" />
|
<Value type="bool" genre="user" instance="1" index="32" label="Exporting" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="False" />
|
||||||
<Value type="button" genre="system" instance="1" index="33" label="Reset" units="" read_only="false" write_only="true" verify_changes="false" poll_intensity="0" min="0" max="0" />
|
<Value type="button" genre="system" instance="1" index="33" label="Reset" units="" read_only="false" write_only="true" verify_changes="false" poll_intensity="0" min="0" max="0" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
|
@ -1181,7 +1181,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="129" name="COMMAND_CLASS_CLOCK" version="1" request_flags="4" innif="true">
|
<CommandClass id="129" name="COMMAND_CLASS_CLOCK" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="list" genre="user" instance="1" index="0" label="Day" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" vindex="0" size="1">
|
<Value type="list" genre="user" instance="1" index="0" label="Day" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" vindex="1" size="1">
|
||||||
<Item label="Monday" value="1" />
|
<Item label="Monday" value="1" />
|
||||||
<Item label="Tuesday" value="2" />
|
<Item label="Tuesday" value="2" />
|
||||||
<Item label="Wednesday" value="3" />
|
<Item label="Wednesday" value="3" />
|
||||||
|
@ -1190,8 +1190,8 @@
|
||||||
<Item label="Saturday" value="6" />
|
<Item label="Saturday" value="6" />
|
||||||
<Item label="Sunday" value="7" />
|
<Item label="Sunday" value="7" />
|
||||||
</Value>
|
</Value>
|
||||||
<Value type="byte" genre="user" instance="1" index="1" label="Hour" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="1" />
|
<Value type="byte" genre="user" instance="1" index="1" label="Hour" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="5" />
|
||||||
<Value type="byte" genre="user" instance="1" index="2" label="Minute" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="45" />
|
<Value type="byte" genre="user" instance="1" index="2" label="Minute" units="" read_only="false" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="33" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
<CommandClass id="130" name="COMMAND_CLASS_HAIL" version="1" request_flags="4" after_mark="true" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -1213,7 +1213,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="16" name="Kitchen Motion Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
<Node id="16" name="Kitchen Motion Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Session">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="1" name="Motion Detector" />
|
<Product type="4" id="1" name="Motion Detector" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -1328,7 +1328,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="17" name="Stairs Motion Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="17" name="Stairs Motion Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="1" name="Motion Detector" />
|
<Product type="4" id="1" name="Motion Detector" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -1416,7 +1416,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
<CommandClass id="128" name="COMMAND_CLASS_BATTERY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="100" />
|
<Value type="byte" genre="user" instance="1" index="0" label="Battery Level" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="99" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="132" name="COMMAND_CLASS_WAKE_UP" version="2" request_flags="2" innif="true">
|
<CommandClass id="132" name="COMMAND_CLASS_WAKE_UP" version="2" request_flags="2" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -1703,7 +1703,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="25" name="Basement Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="25" name="Basement Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="2" name="Unknown: type=0004, id=0002" />
|
<Product type="4" id="2" name="Unknown: type=0004, id=0002" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -1809,7 +1809,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="27" name="Wallmote" location="" basic="4" generic="24" specific="1" roletype="4" devicetype="7172" nodetype="0" type="Basic Wall Controller" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
<Node id="27" name="Wallmote" location="" basic="4" generic="24" specific="1" roletype="4" devicetype="7172" nodetype="0" type="Basic Wall Controller" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Associations">
|
||||||
<Manufacturer id="86" name="Aeotec">
|
<Manufacturer id="86" name="Aeotec">
|
||||||
<Product type="102" id="82" name="ZW130 WallMote Quad" />
|
<Product type="102" id="82" name="ZW130 WallMote Quad" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -2023,7 +2023,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="28" name="Audio Detector" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3073" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="28" name="Audio Detector" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3073" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="5" id="f" name="FireFighter" />
|
<Product type="5" id="f" name="FireFighter" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -2038,7 +2038,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="7" innif="true">
|
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="7" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="66.02" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="68.18" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" innif="true">
|
<CommandClass id="90" name="COMMAND_CLASS_DEVICE_RESET_LOCALLY" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
@ -2132,7 +2132,7 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
</CommandClasses>
|
</CommandClasses>
|
||||||
</Node>
|
</Node>
|
||||||
<Node id="29" name="Garage Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="Complete">
|
<Node id="29" name="Garage Door Sensor" location="" basic="4" generic="7" specific="1" roletype="6" devicetype="3072" nodetype="0" type="Notification Sensor" listening="false" frequentListening="false" beaming="true" routing="true" max_baud_rate="40000" version="4" query_stage="CacheLoad">
|
||||||
<Manufacturer id="14a" name="Ecolink">
|
<Manufacturer id="14a" name="Ecolink">
|
||||||
<Product type="4" id="2" name="Unknown: type=0004, id=0002" />
|
<Product type="4" id="2" name="Unknown: type=0004, id=0002" />
|
||||||
</Manufacturer>
|
</Manufacturer>
|
||||||
|
@ -2405,9 +2405,9 @@
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
<CommandClass id="49" name="COMMAND_CLASS_SENSOR_MULTILEVEL" version="5" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="69.4" />
|
<Value type="decimal" genre="user" instance="1" index="1" label="Temperature" units="F" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="68.8" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="3" label="Luminance" units="lux" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="34" />
|
<Value type="decimal" genre="user" instance="1" index="5" label="Relative Humidity" units="%" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="35" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
<Value type="decimal" genre="user" instance="1" index="27" label="Ultraviolet" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="0" />
|
||||||
<Value type="decimal" genre="user" instance="1" index="37" label="Radon Concentration" units="bq/m3" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="60" />
|
<Value type="decimal" genre="user" instance="1" index="37" label="Radon Concentration" units="bq/m3" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="0" value="60" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
|
@ -2580,7 +2580,7 @@
|
||||||
<Value type="byte" genre="user" instance="1" index="0" label="Alarm Type" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
<Value type="byte" genre="user" instance="1" index="0" label="Alarm Type" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
||||||
<Value type="byte" genre="user" instance="1" index="1" label="Alarm Level" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
<Value type="byte" genre="user" instance="1" index="1" label="Alarm Level" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
||||||
<Value type="byte" genre="user" instance="1" index="2" label="SourceNodeId" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
<Value type="byte" genre="user" instance="1" index="2" label="SourceNodeId" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
||||||
<Value type="byte" genre="user" instance="1" index="10" label="Burglar" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="254" />
|
<Value type="byte" genre="user" instance="1" index="10" label="Burglar" units="" read_only="true" write_only="false" verify_changes="false" poll_intensity="0" min="0" max="255" value="0" />
|
||||||
</CommandClass>
|
</CommandClass>
|
||||||
<CommandClass id="114" name="COMMAND_CLASS_MANUFACTURER_SPECIFIC" version="1" request_flags="4" innif="true">
|
<CommandClass id="114" name="COMMAND_CLASS_MANUFACTURER_SPECIFIC" version="1" request_flags="4" innif="true">
|
||||||
<Instance index="1" />
|
<Instance index="1" />
|
||||||
|
|
Loading…
Reference in New Issue