cleaned up, and updated to latest version.
This commit is contained in:
parent
9a8c586542
commit
3bedcbdc20
|
@ -56,7 +56,14 @@ apps/__pycache__/*.pyc
|
||||||
docker/streamer
|
docker/streamer
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
packages/telegram_commands.yaml
|
packages/telegram_commands.yaml
|
||||||
custom_components/input_label/input_labelpy
|
config.yml
|
||||||
custom_components/input_label/services.yaml
|
example.yaml
|
||||||
custom_components/input_label/__init__.py
|
home-assistant.log.1
|
||||||
custom_components/input_label/manifest.json
|
home-assistant.log.fault
|
||||||
|
custom_components/input_label/*
|
||||||
|
custom_components/hacs/*
|
||||||
|
etc-pihole/*
|
||||||
|
models/*
|
||||||
|
packages/tesla.zamlx
|
||||||
|
packages/tesla.yaml
|
||||||
|
packages/zwave_sensors.yaml
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Please contact me if you found any issues. Thank you!
|
|
|
@ -22,8 +22,6 @@ homeassistant:
|
||||||
- /config/www/downloads/camera/playarea/
|
- /config/www/downloads/camera/playarea/
|
||||||
- /config/www/downloads/camera/driveway/
|
- /config/www/downloads/camera/driveway/
|
||||||
- /config/www/downloads/camera/frontdoor/
|
- /config/www/downloads/camera/frontdoor/
|
||||||
- /config/www/downloads/camera/kitchen/
|
|
||||||
- /config/www/downloads/camera/frontroom/
|
|
||||||
- /config/www/downloads/camera/3d/
|
- /config/www/downloads/camera/3d/
|
||||||
|
|
||||||
sun:
|
sun:
|
||||||
|
@ -35,9 +33,7 @@ discovery:
|
||||||
|
|
||||||
frontend:
|
frontend:
|
||||||
|
|
||||||
octoprint:
|
media_source:
|
||||||
host: !secret octoprint_ip
|
|
||||||
api_key: !secret octoprint_key
|
|
||||||
|
|
||||||
homekit:
|
homekit:
|
||||||
autostart: true
|
autostart: true
|
||||||
|
@ -63,47 +59,14 @@ logger: !include logging.yaml
|
||||||
zeroconf:
|
zeroconf:
|
||||||
system_health:
|
system_health:
|
||||||
|
|
||||||
life360:
|
|
||||||
accounts:
|
|
||||||
- username: !secret life360_username
|
|
||||||
password: !secret life360_password
|
|
||||||
circles:
|
|
||||||
include: [Family]
|
|
||||||
|
|
||||||
mqtt:
|
|
||||||
broker: !secret mqtt_server
|
|
||||||
port: !secret mqtt_port
|
|
||||||
username: !secret mqtt_username
|
|
||||||
password: !secret mqtt_password
|
|
||||||
keepalive: 60
|
|
||||||
client_id: HA_SERVER
|
|
||||||
|
|
||||||
sonos:
|
|
||||||
media_player:
|
|
||||||
hosts:
|
|
||||||
- !secret sonos_living_room_ip
|
|
||||||
- !secret sonos_front_room_ip
|
|
||||||
|
|
||||||
binary_sensor:
|
binary_sensor:
|
||||||
- platform: workday
|
- platform: workday
|
||||||
country: US
|
country: US
|
||||||
|
|
||||||
lovelace:
|
lovelace:
|
||||||
mode: yaml
|
mode: yaml
|
||||||
resources:
|
|
||||||
- url: /local/button-card.js
|
|
||||||
type: module
|
|
||||||
|
|
||||||
# Google Calendar
|
# Google Calendar
|
||||||
google:
|
# google:
|
||||||
client_id: !secret google_client_id
|
# client_id: !secret google_client_id
|
||||||
client_secret: !secret google_client_secret
|
# client_secret: !secret google_client_secret
|
||||||
#emulated_hue:
|
|
||||||
# expose_by_default: false
|
|
||||||
# host_ip: !secret ha_ip_address
|
|
||||||
# listen_port: 8300
|
|
||||||
# exposed_domains:
|
|
||||||
# - light
|
|
||||||
# - switch
|
|
||||||
# - input_boolean
|
|
||||||
# - group
|
|
||||||
|
|
|
@ -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),
|
|
||||||
# }
|
|
|
@ -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
|
|
|
@ -1,267 +0,0 @@
|
||||||
"""
|
|
||||||
@ Author : Suresh Kalavala
|
|
||||||
@ Date : 05/24/2017
|
|
||||||
@ Description : Life365 Sensor - It queries Life360 API and retrieves
|
|
||||||
data at a specified interval and dumps into MQTT
|
|
||||||
|
|
||||||
@ Notes: Copy this file and place it in your
|
|
||||||
"Home Assistant Config folder\custom_components\sensor\" folder
|
|
||||||
Copy corresponding Life365 Package frommy repo,
|
|
||||||
and make sure you have MQTT installed and Configured
|
|
||||||
Make sure the life365 password doesn't contain '#' or '$' symbols
|
|
||||||
"""
|
|
||||||
|
|
||||||
from datetime import timedelta
|
|
||||||
import logging
|
|
||||||
import subprocess
|
|
||||||
import json
|
|
||||||
|
|
||||||
import voluptuous as vol
|
|
||||||
import homeassistant.components.mqtt as mqtt
|
|
||||||
|
|
||||||
from io import StringIO
|
|
||||||
from homeassistant.components.mqtt import (CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
|
|
||||||
from homeassistant.helpers import template
|
|
||||||
from homeassistant.exceptions import TemplateError
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|
||||||
from homeassistant.const import (
|
|
||||||
CONF_NAME, CONF_VALUE_TEMPLATE, CONF_UNIT_OF_MEASUREMENT,
|
|
||||||
STATE_UNKNOWN)
|
|
||||||
from homeassistant.helpers.entity import Entity
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
DEPENDENCIES = ['mqtt']
|
|
||||||
|
|
||||||
DEFAULT_NAME = 'Life365 Sensor'
|
|
||||||
CONST_MQTT_TOPIC = "mqtt_topic"
|
|
||||||
CONST_STATE_ERROR = "error"
|
|
||||||
CONST_STATE_RUNNING = "running"
|
|
||||||
CONST_USERNAME = "username"
|
|
||||||
CONST_PASSWORD = "password"
|
|
||||||
|
|
||||||
COMMAND1 = "curl -s -X POST -H \"Authorization: Basic cFJFcXVnYWJSZXRyZTRFc3RldGhlcnVmcmVQdW1hbUV4dWNyRUh1YzptM2ZydXBSZXRSZXN3ZXJFQ2hBUHJFOTZxYWtFZHI0Vg==\" -F \"grant_type=password\" -F \"username=USERNAME360\" -F \"password=PASSWORD360\" https://api.life360.com/v3/oauth2/token.json | grep -Po '(?<=\"access_token\":\")\\w*'"
|
|
||||||
COMMAND2 = "curl -s -X GET -H \"Authorization: Bearer ACCESS_TOKEN\" https://api.life360.com/v3/circles.json | grep -Po '(?<=\"id\":\")[\\w-]*'"
|
|
||||||
COMMAND3 = "curl -s -X GET -H \"Authorization: Bearer ACCESS_TOKEN\" https://api.life360.com/v3/circles/ID"
|
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(seconds=60)
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
||||||
vol.Required(CONST_USERNAME): cv.string,
|
|
||||||
vol.Required(CONST_PASSWORD): cv.string,
|
|
||||||
vol.Required(CONST_MQTT_TOPIC): cv.string,
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
|
||||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
|
||||||
})
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
|
||||||
"""Set up the Life365 Sensor."""
|
|
||||||
name = config.get(CONF_NAME)
|
|
||||||
username = config.get(CONST_USERNAME)
|
|
||||||
password = config.get(CONST_PASSWORD)
|
|
||||||
mqtt_topic = config.get(CONST_MQTT_TOPIC)
|
|
||||||
|
|
||||||
unit = config.get(CONF_UNIT_OF_MEASUREMENT)
|
|
||||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
|
||||||
if value_template is not None:
|
|
||||||
value_template.hass = hass
|
|
||||||
|
|
||||||
data = Life365SensorData(username, password, COMMAND1, COMMAND2, COMMAND3, mqtt_topic, hass)
|
|
||||||
|
|
||||||
add_devices([Life365Sensor(hass, data, name, unit, value_template)])
|
|
||||||
|
|
||||||
|
|
||||||
class Life365Sensor(Entity):
|
|
||||||
"""Representation of a sensor."""
|
|
||||||
|
|
||||||
def __init__(self, hass, data, name, unit_of_measurement, value_template):
|
|
||||||
"""Initialize the sensor."""
|
|
||||||
self._hass = hass
|
|
||||||
self.data = data
|
|
||||||
self._name = name
|
|
||||||
self._state = STATE_UNKNOWN
|
|
||||||
self._unit_of_measurement = unit_of_measurement
|
|
||||||
self._value_template = value_template
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return self._name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Return the unit the value is expressed in."""
|
|
||||||
return self._unit_of_measurement
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Return the state of the device."""
|
|
||||||
return self._state
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
"""Get the latest data and updates the state."""
|
|
||||||
self.data.update()
|
|
||||||
value = self.data.value
|
|
||||||
|
|
||||||
if value is None:
|
|
||||||
value = STATE_UNKNOWN
|
|
||||||
elif self._value_template is not None:
|
|
||||||
self._state = self._value_template.render_with_possible_json_value(
|
|
||||||
value, STATE_UNKNOWN)
|
|
||||||
else:
|
|
||||||
self._state = value
|
|
||||||
|
|
||||||
|
|
||||||
class Life365SensorData(object):
|
|
||||||
"""The class for handling the data retrieval."""
|
|
||||||
|
|
||||||
def __init__(self, username, password, command1, command2, command3, mqtt_topic, hass):
|
|
||||||
"""Initialize the data object."""
|
|
||||||
self.username = username
|
|
||||||
self.password = password
|
|
||||||
self.COMMAND_ACCESS_TOKEN = command1
|
|
||||||
self.COMMAND_ID = command2
|
|
||||||
self.COMMAND_MEMBERS = command3
|
|
||||||
self.hass = hass
|
|
||||||
self.value = None
|
|
||||||
self.mqtt_topic = mqtt_topic
|
|
||||||
self.mqtt_retain = True
|
|
||||||
self.mqtt_qos = 0
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
|
|
||||||
try:
|
|
||||||
""" Prepare and Execute Commands """
|
|
||||||
self.COMMAND_ACCESS_TOKEN = self.COMMAND_ACCESS_TOKEN.replace("USERNAME360", self.username)
|
|
||||||
self.COMMAND_ACCESS_TOKEN = self.COMMAND_ACCESS_TOKEN.replace("PASSWORD360", self.password)
|
|
||||||
access_token = self.exec_shell_command( self.COMMAND_ACCESS_TOKEN )
|
|
||||||
|
|
||||||
if access_token == None:
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
return None
|
|
||||||
|
|
||||||
self.COMMAND_ID = self.COMMAND_ID.replace("ACCESS_TOKEN", access_token)
|
|
||||||
id = self.exec_shell_command( self.COMMAND_ID )
|
|
||||||
|
|
||||||
if id == None:
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
return None
|
|
||||||
|
|
||||||
self.COMMAND_MEMBERS = self.COMMAND_MEMBERS.replace("ACCESS_TOKEN", access_token)
|
|
||||||
self.COMMAND_MEMBERS = self.COMMAND_MEMBERS.replace("ID", id)
|
|
||||||
payload = self.exec_shell_command( self.COMMAND_MEMBERS )
|
|
||||||
|
|
||||||
if payload != None:
|
|
||||||
self.save_payload_to_mqtt ( self.mqtt_topic, payload )
|
|
||||||
data = json.loads ( payload )
|
|
||||||
for member in data["members"]:
|
|
||||||
topic = StringBuilder()
|
|
||||||
topic.Append("owntracks/")
|
|
||||||
topic.Append(member["firstName"].lower())
|
|
||||||
topic.Append("/")
|
|
||||||
topic.Append(member["firstName"].lower())
|
|
||||||
topic = topic
|
|
||||||
|
|
||||||
msgPayload = StringBuilder()
|
|
||||||
msgPayload.Append("{")
|
|
||||||
msgPayload.Append("\"t\":\"p\"")
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"tst\":")
|
|
||||||
msgPayload.Append(member['location']['timestamp'])
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"acc\":")
|
|
||||||
msgPayload.Append(member['location']['accuracy'])
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"_type\":\"location\"")
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"alt\":\"0\"")
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"_cp\":\"false\"")
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"lon\":")
|
|
||||||
msgPayload.Append(member['location']['longitude'])
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"lat\":")
|
|
||||||
msgPayload.Append(member['location']['latitude'])
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"batt\":")
|
|
||||||
msgPayload.Append(member['location']['battery'])
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
if str(member['location']['wifiState']) == "1":
|
|
||||||
msgPayload.Append("\"conn\":\"w\"")
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"vel\":")
|
|
||||||
msgPayload.Append(str(member['location']['speed']))
|
|
||||||
msgPayload.Append(",")
|
|
||||||
|
|
||||||
msgPayload.Append("\"charging\":")
|
|
||||||
msgPayload.Append(member['location']['charge'])
|
|
||||||
msgPayload.Append("}")
|
|
||||||
|
|
||||||
self.save_payload_to_mqtt ( str(topic), str(msgPayload) )
|
|
||||||
self.value = CONST_STATE_RUNNING
|
|
||||||
else:
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
|
|
||||||
def exec_shell_command( self, command ):
|
|
||||||
|
|
||||||
output = None
|
|
||||||
try:
|
|
||||||
output = subprocess.check_output( command, shell=True, timeout=50 )
|
|
||||||
output = output.strip().decode('utf-8')
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
""" _LOGGER.error("Command failed: %s", command)"""
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
output = None
|
|
||||||
except subprocess.TimeoutExpired:
|
|
||||||
""" _LOGGER.error("Timeout for command: %s", command)"""
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
output = None
|
|
||||||
|
|
||||||
if output == None:
|
|
||||||
_LOGGER.error( "Life365 has not responsed well. Nothing to worry, will try again!" )
|
|
||||||
self.value = CONST_STATE_ERROR
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return output
|
|
||||||
|
|
||||||
def save_payload_to_mqtt( self, topic, payload ):
|
|
||||||
|
|
||||||
try:
|
|
||||||
"""mqtt.async_publish ( self.hass, topic, payload, self.mqtt_qos, self.mqtt_retain )"""
|
|
||||||
_LOGGER.info("topic: %s", topic)
|
|
||||||
_LOGGER.info("payload: %s", payload)
|
|
||||||
mqtt.publish ( self.hass, topic, payload, self.mqtt_qos, self.mqtt_retain )
|
|
||||||
|
|
||||||
except:
|
|
||||||
_LOGGER.error( "Error saving Life365 data to mqtt." )
|
|
||||||
|
|
||||||
class StringBuilder:
|
|
||||||
_file_str = None
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self._file_str = StringIO()
|
|
||||||
|
|
||||||
def Append(self, str):
|
|
||||||
self._file_str.write(str)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self._file_str.getvalue()
|
|
|
@ -1,269 +0,0 @@
|
||||||
"""
|
|
||||||
@Author: Suresh Kalavala
|
|
||||||
@Date: 03/03/2018
|
|
||||||
|
|
||||||
Custom Sensor: Palo Alto device integration with Home Assistant.
|
|
||||||
|
|
||||||
For more details about this platform, please refer to the documentation at
|
|
||||||
https://home-assistant.io/components/sensor.paloalto/
|
|
||||||
"""
|
|
||||||
import ssl
|
|
||||||
import logging
|
|
||||||
import urllib.request
|
|
||||||
import voluptuous as vol
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
import xml.etree.ElementTree as ET
|
|
||||||
|
|
||||||
from enum import Enum
|
|
||||||
from datetime import timedelta
|
|
||||||
from homeassistant.helpers.entity import Entity
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|
||||||
from homeassistant.const import (CONF_NAME, CONF_API_KEY, CONF_IP_ADDRESS,
|
|
||||||
CONF_SSL, CONF_VERIFY_SSL,
|
|
||||||
CONF_MONITORED_CONDITIONS)
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
DEFAULT_NAME = 'PaloAlto'
|
|
||||||
DEFAULT_SSL = False
|
|
||||||
DEFAULT_VERIFY_SSL = True
|
|
||||||
|
|
||||||
CONST_COMMAND = "COMMAND"
|
|
||||||
CONST_OPS_ENDPOINT = '/api/?type=op&cmd=COMMAND'
|
|
||||||
CONST_CONFIG_ENDPOINT = '/api/?type=config&action=get&xpath=COMMAND'
|
|
||||||
|
|
||||||
PA_OPS_ACTIVE_USERS = "<show><admins></admins></show>"
|
|
||||||
PA_CONF_SYS_INFO = "<show><system><info></info></system></show>"
|
|
||||||
PA_CONF_GP_USERS = "<show><global-protect-portal><current-user>" \
|
|
||||||
"</current-user></global-protect-portal></show>"
|
|
||||||
PA_CONF_TEMPERATURE = "<show><system><environmentals><thermal>" \
|
|
||||||
"</thermal></environmentals></system></show>"
|
|
||||||
|
|
||||||
SCAN_INTERVAL = timedelta(seconds=120)
|
|
||||||
|
|
||||||
MONITORED_CONDITIONS = {
|
|
||||||
'host_name': ['Host Name', 'x', 'mdi:fire'],
|
|
||||||
'up_time': ['Up Time', 'x', 'mdi:clock'],
|
|
||||||
'serial_no': ['Serial Number', 'x', 'mdi:counter'],
|
|
||||||
'sw_version': ['Software Version', 'x', 'mdi:counter'],
|
|
||||||
'gp_version': ['Global protect Version', 'x', 'mdi:counter'],
|
|
||||||
'logdb_version': ['LogDB Version', 'x', 'mdi:book-open'],
|
|
||||||
'operation_mode': ['Operation Mode', 'x', 'mdi:book-open'],
|
|
||||||
'core_temp': ['Core Temperature', 'x', 'mdi:oil-temperature'],
|
|
||||||
'sys_temp': ['System Temperature', 'x', 'mdi:oil-temperature'],
|
|
||||||
'gp_user_count': ['Global Protect User Count', 'vpn users', 'mdi:counter'],
|
|
||||||
'gp_users': ['Global Protect Users', 'vpn users', 'mdi:account-multiple'],
|
|
||||||
'loggedin_user_count': ['Loggedin User Count', 'users', 'mdi:counter'],
|
|
||||||
'loggedin_users': ['Loggedin Users', 'users', 'mdi:account-multiple'],
|
|
||||||
}
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Required(CONF_API_KEY): cv.string,
|
|
||||||
vol.Required(CONF_IP_ADDRESS): cv.string,
|
|
||||||
vol.Optional(CONF_SSL, default=DEFAULT_SSL): cv.boolean,
|
|
||||||
vol.Optional(CONF_MONITORED_CONDITIONS,
|
|
||||||
default=list(MONITORED_CONDITIONS)):
|
|
||||||
vol.All(cv.ensure_list, [vol.In(MONITORED_CONDITIONS)]),
|
|
||||||
vol.Optional(CONF_VERIFY_SSL, default=DEFAULT_VERIFY_SSL): cv.boolean,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=unused-argument
|
|
||||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
|
||||||
"""Set up the Palo Alto VPN User Sensor."""
|
|
||||||
name = config.get(CONF_NAME)
|
|
||||||
host = config.get(CONF_IP_ADDRESS)
|
|
||||||
use_ssl = config.get(CONF_SSL)
|
|
||||||
verify_ssl = config.get(CONF_VERIFY_SSL)
|
|
||||||
api_key = config.get(CONF_API_KEY)
|
|
||||||
sensors = []
|
|
||||||
|
|
||||||
try:
|
|
||||||
api = PaloAltoApi(host, use_ssl, verify_ssl, api_key)
|
|
||||||
for condition in config[CONF_MONITORED_CONDITIONS]:
|
|
||||||
sensor = PaloAltoSensor(hass, api, name, condition)
|
|
||||||
sensors.append(sensor)
|
|
||||||
add_devices(sensors, True)
|
|
||||||
except Exception as err:
|
|
||||||
_LOGGER.error("Failed to setup Palo Alto Sensor. Error: " + str(err))
|
|
||||||
|
|
||||||
|
|
||||||
class PaloAltoSensor(Entity):
|
|
||||||
"""Representation of a sensor."""
|
|
||||||
|
|
||||||
def __init__(self, hass, api, name, variable):
|
|
||||||
"""Initialize the sensor."""
|
|
||||||
self._hass = hass
|
|
||||||
self._api = api
|
|
||||||
self._name = name
|
|
||||||
self._var_id = variable
|
|
||||||
|
|
||||||
variable_info = MONITORED_CONDITIONS[variable]
|
|
||||||
self._var_name = variable_info[0]
|
|
||||||
self._var_units = variable_info[1]
|
|
||||||
self._var_icon = variable_info[2]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of the sensor."""
|
|
||||||
return "{} {}".format(self._name, self._var_name)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def icon(self):
|
|
||||||
"""Icon to use in the frontend, if any."""
|
|
||||||
return self._var_icon
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Return the state of the device."""
|
|
||||||
return self._api.data[self._var_id]
|
|
||||||
|
|
||||||
@property
|
|
||||||
def available(self):
|
|
||||||
"""Could the device be accessed during the last update call."""
|
|
||||||
return self._api.available
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
"""Get the latest data and updates the state."""
|
|
||||||
self._api.update()
|
|
||||||
|
|
||||||
|
|
||||||
class PaloAltoApi(object):
|
|
||||||
"""The class for handling the data retrieval from Palo Alto Device."""
|
|
||||||
|
|
||||||
def __init__(self, host, use_ssl, verify_ssl, api_key):
|
|
||||||
"""Initialize the Palo Alto API."""
|
|
||||||
self._host = host
|
|
||||||
self._use_ssl = use_ssl
|
|
||||||
self._verify_ssl = verify_ssl
|
|
||||||
self._api_key = api_key
|
|
||||||
self._usersdata = None
|
|
||||||
self._sysinfo = None
|
|
||||||
self._gp_users = None
|
|
||||||
self._temperature = None
|
|
||||||
self.available = True
|
|
||||||
self._sensors = {}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def data(self):
|
|
||||||
"""Return data."""
|
|
||||||
return self._sensors
|
|
||||||
|
|
||||||
def get_uri_scheme(self, use_ssl):
|
|
||||||
"""Return proper uril scheme based on config setting."""
|
|
||||||
return 'https://' if use_ssl else 'http://'
|
|
||||||
|
|
||||||
def get_resource(self, use_ssl, host, api_key, endpoint):
|
|
||||||
"""Prepare the URL."""
|
|
||||||
uri_scheme = self.get_uri_scheme(use_ssl)
|
|
||||||
if endpoint == EndPointType.Operational:
|
|
||||||
return "{}{}{}&key={}".format(uri_scheme, self._host,
|
|
||||||
CONST_OPS_ENDPOINT, self._api_key)
|
|
||||||
else:
|
|
||||||
return "{}{}{}&key={}".format(uri_scheme, self._host,
|
|
||||||
CONST_CONFIG_ENDPOINT, self._api_key)
|
|
||||||
|
|
||||||
def http_request(self, url):
|
|
||||||
"""HTTP request to the Palo Alto device."""
|
|
||||||
content = None
|
|
||||||
context = None
|
|
||||||
try:
|
|
||||||
if self._use_ssl and not self._verify_ssl:
|
|
||||||
context = ssl._create_unverified_context()
|
|
||||||
response = urllib.request.urlopen(url, context=context)
|
|
||||||
content = response.read()
|
|
||||||
except Exception as ex:
|
|
||||||
_LOGGER.error(str(ex))
|
|
||||||
content = None
|
|
||||||
|
|
||||||
return content
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
"""Get Operational and Configuration urls."""
|
|
||||||
ops_url = self.get_resource(self._use_ssl, self._host,
|
|
||||||
self._api_key, EndPointType.Operational)
|
|
||||||
|
|
||||||
users_url = ops_url.replace(CONST_COMMAND, PA_OPS_ACTIVE_USERS)
|
|
||||||
self._usersdata = self.http_request(users_url)
|
|
||||||
|
|
||||||
sysinfo_url = ops_url.replace(CONST_COMMAND, PA_CONF_SYS_INFO)
|
|
||||||
self._sysinfo = self.http_request(sysinfo_url)
|
|
||||||
|
|
||||||
gp_users_url = ops_url.replace(CONST_COMMAND, PA_CONF_GP_USERS)
|
|
||||||
self._gp_users = self.http_request(gp_users_url)
|
|
||||||
|
|
||||||
temperature_url = ops_url.replace(CONST_COMMAND, PA_CONF_TEMPERATURE)
|
|
||||||
self._temperature = self.http_request(temperature_url)
|
|
||||||
|
|
||||||
"""parse the xml data"""
|
|
||||||
self.parse_data()
|
|
||||||
|
|
||||||
def parse_globalprotect_users(self):
|
|
||||||
"""Parses global protect users xml."""
|
|
||||||
user_count = 0
|
|
||||||
vpn_users = []
|
|
||||||
root = ET.fromstring(self._gp_users)
|
|
||||||
nodes = root.findall('result/gp-portal-users/user')
|
|
||||||
for user in nodes:
|
|
||||||
user_count += 1
|
|
||||||
vpn_users.append(user.find('username').text)
|
|
||||||
|
|
||||||
if user_count != 0:
|
|
||||||
self._sensors["gp_users"] = ', '.join(vpn_users)
|
|
||||||
else:
|
|
||||||
self._sensors["gp_users"] = "None"
|
|
||||||
self._sensors["gp_user_count"] = user_count
|
|
||||||
|
|
||||||
def parse_temperature(self):
|
|
||||||
"""Parses environment/temperature values."""
|
|
||||||
root = ET.fromstring(self._temperature)
|
|
||||||
nodes = root.findall('result/thermal/Slot1/entry/DegreesC')
|
|
||||||
self._sensors["core_temp"] = round(float(nodes[0].text), 2)
|
|
||||||
self._sensors["sys_temp"] = round(float(nodes[1].text), 2)
|
|
||||||
|
|
||||||
def parse_system_info(self):
|
|
||||||
"""Parses System Information."""
|
|
||||||
root = ET.fromstring(self._sysinfo)
|
|
||||||
sys_node = root.findall('result/system')
|
|
||||||
self._sensors["up_time"] = sys_node[0].find('uptime').text
|
|
||||||
self._sensors["serial_no"] = sys_node[0].find('serial').text
|
|
||||||
self._sensors["host_name"] = sys_node[0].find('hostname').text
|
|
||||||
self._sensors["sw_version"] = sys_node[0].find('sw-version').text
|
|
||||||
self._sensors["logdb_version"] = sys_node[0].find(
|
|
||||||
'logdb-version').text
|
|
||||||
self._sensors["operation_mode"] = sys_node[0].find(
|
|
||||||
'operational-mode').text
|
|
||||||
self._sensors["gp_version"] = sys_node[0].find(
|
|
||||||
'global-protect-client-package-version').text
|
|
||||||
|
|
||||||
def parse_active_users(self):
|
|
||||||
"""Parses Active Users XML."""
|
|
||||||
root = ET.fromstring(self._usersdata)
|
|
||||||
nodes = root.findall('result/admins/entry')
|
|
||||||
count = 0
|
|
||||||
users = []
|
|
||||||
for item in nodes:
|
|
||||||
count += 1
|
|
||||||
users.append(item.find('admin').text)
|
|
||||||
|
|
||||||
if count > 0:
|
|
||||||
self._sensors["loggedin_users"] = ', '.join(users)
|
|
||||||
else:
|
|
||||||
self._sensors["loggedin_users"] = "None"
|
|
||||||
|
|
||||||
self._sensors["loggedin_user_count"] = count
|
|
||||||
|
|
||||||
def parse_data(self):
|
|
||||||
"""Parses data and populates sensors."""
|
|
||||||
self.parse_globalprotect_users()
|
|
||||||
self.parse_temperature()
|
|
||||||
self.parse_system_info()
|
|
||||||
self.parse_active_users()
|
|
||||||
|
|
||||||
|
|
||||||
class EndPointType(Enum):
|
|
||||||
"""Enum that indicates that type of endpoint that is."""
|
|
||||||
|
|
||||||
Operational = "operational"
|
|
||||||
Configuration = "configuration"
|
|
|
@ -0,0 +1,988 @@
|
||||||
|
"""Support to send and receive Telegram messages."""
|
||||||
|
from functools import partial
|
||||||
|
import importlib
|
||||||
|
import io
|
||||||
|
from ipaddress import ip_network
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import requests
|
||||||
|
from requests.auth import HTTPBasicAuth, HTTPDigestAuth
|
||||||
|
from telegram import (
|
||||||
|
Bot,
|
||||||
|
InlineKeyboardButton,
|
||||||
|
InlineKeyboardMarkup,
|
||||||
|
ReplyKeyboardMarkup,
|
||||||
|
ReplyKeyboardRemove,
|
||||||
|
)
|
||||||
|
from telegram.error import TelegramError
|
||||||
|
from telegram.parsemode import ParseMode
|
||||||
|
from telegram.utils.request import Request
|
||||||
|
import voluptuous as vol
|
||||||
|
|
||||||
|
from homeassistant.const import (
|
||||||
|
ATTR_COMMAND,
|
||||||
|
ATTR_LATITUDE,
|
||||||
|
ATTR_LONGITUDE,
|
||||||
|
CONF_API_KEY,
|
||||||
|
CONF_PLATFORM,
|
||||||
|
CONF_URL,
|
||||||
|
HTTP_BEARER_AUTHENTICATION,
|
||||||
|
HTTP_DIGEST_AUTHENTICATION,
|
||||||
|
)
|
||||||
|
from homeassistant.core import HomeAssistant, ServiceCall
|
||||||
|
from homeassistant.exceptions import TemplateError
|
||||||
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.typing import ConfigType
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
ATTR_DATA = "data"
|
||||||
|
ATTR_MESSAGE = "message"
|
||||||
|
ATTR_TITLE = "title"
|
||||||
|
|
||||||
|
ATTR_ARGS = "args"
|
||||||
|
ATTR_AUTHENTICATION = "authentication"
|
||||||
|
ATTR_CALLBACK_QUERY = "callback_query"
|
||||||
|
ATTR_CALLBACK_QUERY_ID = "callback_query_id"
|
||||||
|
ATTR_CAPTION = "caption"
|
||||||
|
ATTR_CHAT_ID = "chat_id"
|
||||||
|
ATTR_CHAT_INSTANCE = "chat_instance"
|
||||||
|
ATTR_DISABLE_NOTIF = "disable_notification"
|
||||||
|
ATTR_DISABLE_WEB_PREV = "disable_web_page_preview"
|
||||||
|
ATTR_EDITED_MSG = "edited_message"
|
||||||
|
ATTR_FILE = "file"
|
||||||
|
ATTR_FROM_FIRST = "from_first"
|
||||||
|
ATTR_FROM_LAST = "from_last"
|
||||||
|
ATTR_KEYBOARD = "keyboard"
|
||||||
|
ATTR_KEYBOARD_INLINE = "inline_keyboard"
|
||||||
|
ATTR_MESSAGEID = "message_id"
|
||||||
|
ATTR_MSG = "message"
|
||||||
|
ATTR_MSGID = "id"
|
||||||
|
ATTR_PARSER = "parse_mode"
|
||||||
|
ATTR_PASSWORD = "password"
|
||||||
|
ATTR_REPLY_TO_MSGID = "reply_to_message_id"
|
||||||
|
ATTR_REPLYMARKUP = "reply_markup"
|
||||||
|
ATTR_SHOW_ALERT = "show_alert"
|
||||||
|
ATTR_STICKER_ID = "sticker_id"
|
||||||
|
ATTR_TARGET = "target"
|
||||||
|
ATTR_TEXT = "text"
|
||||||
|
ATTR_URL = "url"
|
||||||
|
ATTR_USER_ID = "user_id"
|
||||||
|
ATTR_USERNAME = "username"
|
||||||
|
ATTR_VERIFY_SSL = "verify_ssl"
|
||||||
|
ATTR_TIMEOUT = "timeout"
|
||||||
|
ATTR_MESSAGE_TAG = "message_tag"
|
||||||
|
ATTR_CHANNEL_POST = "channel_post"
|
||||||
|
|
||||||
|
CONF_ALLOWED_CHAT_IDS = "allowed_chat_ids"
|
||||||
|
CONF_PROXY_URL = "proxy_url"
|
||||||
|
CONF_PROXY_PARAMS = "proxy_params"
|
||||||
|
CONF_TRUSTED_NETWORKS = "trusted_networks"
|
||||||
|
|
||||||
|
DOMAIN = "telegram_bot"
|
||||||
|
|
||||||
|
SERVICE_SEND_MESSAGE = "send_message"
|
||||||
|
SERVICE_SEND_PHOTO = "send_photo"
|
||||||
|
SERVICE_SEND_STICKER = "send_sticker"
|
||||||
|
SERVICE_SEND_ANIMATION = "send_animation"
|
||||||
|
SERVICE_SEND_VIDEO = "send_video"
|
||||||
|
SERVICE_SEND_VOICE = "send_voice"
|
||||||
|
SERVICE_SEND_DOCUMENT = "send_document"
|
||||||
|
SERVICE_SEND_LOCATION = "send_location"
|
||||||
|
SERVICE_EDIT_MESSAGE = "edit_message"
|
||||||
|
SERVICE_EDIT_CAPTION = "edit_caption"
|
||||||
|
SERVICE_EDIT_REPLYMARKUP = "edit_replymarkup"
|
||||||
|
SERVICE_ANSWER_CALLBACK_QUERY = "answer_callback_query"
|
||||||
|
SERVICE_DELETE_MESSAGE = "delete_message"
|
||||||
|
SERVICE_LEAVE_CHAT = "leave_chat"
|
||||||
|
|
||||||
|
EVENT_TELEGRAM_CALLBACK = "telegram_callback"
|
||||||
|
EVENT_TELEGRAM_COMMAND = "telegram_command"
|
||||||
|
EVENT_TELEGRAM_TEXT = "telegram_text"
|
||||||
|
EVENT_TELEGRAM_SENT = "telegram_sent"
|
||||||
|
|
||||||
|
PARSER_HTML = "html"
|
||||||
|
PARSER_MD = "markdown"
|
||||||
|
|
||||||
|
DEFAULT_TRUSTED_NETWORKS = [ip_network("149.154.160.0/20"), ip_network("91.108.4.0/22")]
|
||||||
|
|
||||||
|
CONFIG_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
DOMAIN: vol.All(
|
||||||
|
cv.ensure_list,
|
||||||
|
[
|
||||||
|
vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(CONF_PLATFORM): vol.In(
|
||||||
|
("broadcast", "polling", "webhooks")
|
||||||
|
),
|
||||||
|
vol.Required(CONF_API_KEY): cv.string,
|
||||||
|
vol.Required(CONF_ALLOWED_CHAT_IDS): vol.All(
|
||||||
|
cv.ensure_list, [vol.Coerce(int)]
|
||||||
|
),
|
||||||
|
vol.Optional(ATTR_PARSER, default=PARSER_MD): cv.string,
|
||||||
|
vol.Optional(CONF_PROXY_URL): cv.string,
|
||||||
|
vol.Optional(CONF_PROXY_PARAMS): dict,
|
||||||
|
# webhooks
|
||||||
|
vol.Optional(CONF_URL): cv.url,
|
||||||
|
vol.Optional(
|
||||||
|
CONF_TRUSTED_NETWORKS, default=DEFAULT_TRUSTED_NETWORKS
|
||||||
|
): vol.All(cv.ensure_list, [ip_network]),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
BASE_SERVICE_SCHEMA = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Optional(ATTR_TARGET): vol.All(cv.ensure_list, [vol.Coerce(int)]),
|
||||||
|
vol.Optional(ATTR_PARSER): cv.string,
|
||||||
|
vol.Optional(ATTR_DISABLE_NOTIF): cv.boolean,
|
||||||
|
vol.Optional(ATTR_DISABLE_WEB_PREV): cv.boolean,
|
||||||
|
vol.Optional(ATTR_KEYBOARD): vol.All(cv.ensure_list, [cv.string]),
|
||||||
|
vol.Optional(ATTR_KEYBOARD_INLINE): cv.ensure_list,
|
||||||
|
vol.Optional(ATTR_TIMEOUT): cv.positive_int,
|
||||||
|
vol.Optional(ATTR_MESSAGE_TAG): cv.string,
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_SEND_MESSAGE = BASE_SERVICE_SCHEMA.extend(
|
||||||
|
{vol.Required(ATTR_MESSAGE): cv.template, vol.Optional(ATTR_TITLE): cv.template}
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_SEND_FILE = BASE_SERVICE_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
vol.Optional(ATTR_URL): cv.template,
|
||||||
|
vol.Optional(ATTR_FILE): cv.template,
|
||||||
|
vol.Optional(ATTR_CAPTION): cv.template,
|
||||||
|
vol.Optional(ATTR_USERNAME): cv.string,
|
||||||
|
vol.Optional(ATTR_PASSWORD): cv.string,
|
||||||
|
vol.Optional(ATTR_AUTHENTICATION): cv.string,
|
||||||
|
vol.Optional(ATTR_VERIFY_SSL): cv.boolean,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_SEND_STICKER = SERVICE_SCHEMA_SEND_FILE.extend(
|
||||||
|
{vol.Optional(ATTR_STICKER_ID): cv.string}
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_SEND_LOCATION = BASE_SERVICE_SCHEMA.extend(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_LONGITUDE): cv.template,
|
||||||
|
vol.Required(ATTR_LATITUDE): cv.template,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_EDIT_MESSAGE = SERVICE_SCHEMA_SEND_MESSAGE.extend(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_MESSAGEID): vol.Any(
|
||||||
|
cv.positive_int, vol.All(cv.string, "last")
|
||||||
|
),
|
||||||
|
vol.Required(ATTR_CHAT_ID): vol.Coerce(int),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_EDIT_CAPTION = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_MESSAGEID): vol.Any(
|
||||||
|
cv.positive_int, vol.All(cv.string, "last")
|
||||||
|
),
|
||||||
|
vol.Required(ATTR_CHAT_ID): vol.Coerce(int),
|
||||||
|
vol.Required(ATTR_CAPTION): cv.template,
|
||||||
|
vol.Optional(ATTR_KEYBOARD_INLINE): cv.ensure_list,
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_EDIT_REPLYMARKUP = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_MESSAGEID): vol.Any(
|
||||||
|
cv.positive_int, vol.All(cv.string, "last")
|
||||||
|
),
|
||||||
|
vol.Required(ATTR_CHAT_ID): vol.Coerce(int),
|
||||||
|
vol.Required(ATTR_KEYBOARD_INLINE): cv.ensure_list,
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_ANSWER_CALLBACK_QUERY = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_MESSAGE): cv.template,
|
||||||
|
vol.Required(ATTR_CALLBACK_QUERY_ID): vol.Coerce(int),
|
||||||
|
vol.Optional(ATTR_SHOW_ALERT): cv.boolean,
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_DELETE_MESSAGE = vol.Schema(
|
||||||
|
{
|
||||||
|
vol.Required(ATTR_CHAT_ID): vol.Coerce(int),
|
||||||
|
vol.Required(ATTR_MESSAGEID): vol.Any(
|
||||||
|
cv.positive_int, vol.All(cv.string, "last")
|
||||||
|
),
|
||||||
|
},
|
||||||
|
extra=vol.ALLOW_EXTRA,
|
||||||
|
)
|
||||||
|
|
||||||
|
SERVICE_SCHEMA_LEAVE_CHAT = vol.Schema({vol.Required(ATTR_CHAT_ID): vol.Coerce(int)})
|
||||||
|
|
||||||
|
SERVICE_MAP = {
|
||||||
|
SERVICE_SEND_MESSAGE: SERVICE_SCHEMA_SEND_MESSAGE,
|
||||||
|
SERVICE_SEND_PHOTO: SERVICE_SCHEMA_SEND_FILE,
|
||||||
|
SERVICE_SEND_STICKER: SERVICE_SCHEMA_SEND_STICKER,
|
||||||
|
SERVICE_SEND_ANIMATION: SERVICE_SCHEMA_SEND_FILE,
|
||||||
|
SERVICE_SEND_VIDEO: SERVICE_SCHEMA_SEND_FILE,
|
||||||
|
SERVICE_SEND_VOICE: SERVICE_SCHEMA_SEND_FILE,
|
||||||
|
SERVICE_SEND_DOCUMENT: SERVICE_SCHEMA_SEND_FILE,
|
||||||
|
SERVICE_SEND_LOCATION: SERVICE_SCHEMA_SEND_LOCATION,
|
||||||
|
SERVICE_EDIT_MESSAGE: SERVICE_SCHEMA_EDIT_MESSAGE,
|
||||||
|
SERVICE_EDIT_CAPTION: SERVICE_SCHEMA_EDIT_CAPTION,
|
||||||
|
SERVICE_EDIT_REPLYMARKUP: SERVICE_SCHEMA_EDIT_REPLYMARKUP,
|
||||||
|
SERVICE_ANSWER_CALLBACK_QUERY: SERVICE_SCHEMA_ANSWER_CALLBACK_QUERY,
|
||||||
|
SERVICE_DELETE_MESSAGE: SERVICE_SCHEMA_DELETE_MESSAGE,
|
||||||
|
SERVICE_LEAVE_CHAT: SERVICE_SCHEMA_LEAVE_CHAT,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def load_data(
|
||||||
|
hass,
|
||||||
|
url=None,
|
||||||
|
filepath=None,
|
||||||
|
username=None,
|
||||||
|
password=None,
|
||||||
|
authentication=None,
|
||||||
|
num_retries=5,
|
||||||
|
verify_ssl=None,
|
||||||
|
):
|
||||||
|
"""Load data into ByteIO/File container from a source."""
|
||||||
|
try:
|
||||||
|
if url is not None:
|
||||||
|
# Load data from URL
|
||||||
|
params = {"timeout": 15}
|
||||||
|
if authentication == HTTP_BEARER_AUTHENTICATION and password is not None:
|
||||||
|
params["headers"] = {"Authorization": f"Bearer {password}"}
|
||||||
|
elif username is not None and password is not None:
|
||||||
|
if authentication == HTTP_DIGEST_AUTHENTICATION:
|
||||||
|
params["auth"] = HTTPDigestAuth(username, password)
|
||||||
|
else:
|
||||||
|
params["auth"] = HTTPBasicAuth(username, password)
|
||||||
|
if verify_ssl is not None:
|
||||||
|
params["verify"] = verify_ssl
|
||||||
|
retry_num = 0
|
||||||
|
while retry_num < num_retries:
|
||||||
|
req = requests.get(url, **params)
|
||||||
|
if not req.ok:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Status code %s (retry #%s) loading %s",
|
||||||
|
req.status_code,
|
||||||
|
retry_num + 1,
|
||||||
|
url,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
data = io.BytesIO(req.content)
|
||||||
|
if data.read():
|
||||||
|
data.seek(0)
|
||||||
|
data.name = url
|
||||||
|
return data
|
||||||
|
_LOGGER.warning("Empty data (retry #%s) in %s)", retry_num + 1, url)
|
||||||
|
retry_num += 1
|
||||||
|
_LOGGER.warning("Can't load data in %s after %s retries", url, retry_num)
|
||||||
|
elif filepath is not None:
|
||||||
|
if hass.config.is_allowed_path(filepath):
|
||||||
|
return open(filepath, "rb")
|
||||||
|
|
||||||
|
_LOGGER.warning("'%s' are not secure to load data from!", filepath)
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Can't load data. No data found in params!")
|
||||||
|
|
||||||
|
except (OSError, TypeError) as error:
|
||||||
|
_LOGGER.error("Can't load data into ByteIO: %s", error)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
|
||||||
|
"""Set up the Telegram bot component."""
|
||||||
|
if not config[DOMAIN]:
|
||||||
|
return False
|
||||||
|
|
||||||
|
for p_config in config[DOMAIN]:
|
||||||
|
|
||||||
|
p_type = p_config.get(CONF_PLATFORM)
|
||||||
|
|
||||||
|
platform = importlib.import_module(f".{p_config[CONF_PLATFORM]}", __name__)
|
||||||
|
|
||||||
|
_LOGGER.info("Setting up %s.%s", DOMAIN, p_type)
|
||||||
|
try:
|
||||||
|
receiver_service = await platform.async_setup_platform(hass, p_config)
|
||||||
|
if receiver_service is False:
|
||||||
|
_LOGGER.error("Failed to initialize Telegram bot %s", p_type)
|
||||||
|
return False
|
||||||
|
|
||||||
|
except Exception: # pylint: disable=broad-except
|
||||||
|
_LOGGER.exception("Error setting up platform %s", p_type)
|
||||||
|
return False
|
||||||
|
|
||||||
|
bot = initialize_bot(p_config)
|
||||||
|
notify_service = TelegramNotificationService(
|
||||||
|
hass, bot, p_config.get(CONF_ALLOWED_CHAT_IDS), p_config.get(ATTR_PARSER)
|
||||||
|
)
|
||||||
|
|
||||||
|
async def async_send_telegram_message(service: ServiceCall) -> None:
|
||||||
|
"""Handle sending Telegram Bot message service calls."""
|
||||||
|
|
||||||
|
def _render_template_attr(data, attribute):
|
||||||
|
if attribute_templ := data.get(attribute):
|
||||||
|
if any(
|
||||||
|
isinstance(attribute_templ, vtype) for vtype in (float, int, str)
|
||||||
|
):
|
||||||
|
data[attribute] = attribute_templ
|
||||||
|
else:
|
||||||
|
attribute_templ.hass = hass
|
||||||
|
try:
|
||||||
|
data[attribute] = attribute_templ.async_render(
|
||||||
|
parse_result=False
|
||||||
|
)
|
||||||
|
except TemplateError as exc:
|
||||||
|
_LOGGER.error(
|
||||||
|
"TemplateError in %s: %s -> %s",
|
||||||
|
attribute,
|
||||||
|
attribute_templ.template,
|
||||||
|
exc,
|
||||||
|
)
|
||||||
|
data[attribute] = attribute_templ.template
|
||||||
|
|
||||||
|
msgtype = service.service
|
||||||
|
kwargs = dict(service.data)
|
||||||
|
for attribute in (
|
||||||
|
ATTR_MESSAGE,
|
||||||
|
ATTR_TITLE,
|
||||||
|
ATTR_URL,
|
||||||
|
ATTR_FILE,
|
||||||
|
ATTR_CAPTION,
|
||||||
|
ATTR_LONGITUDE,
|
||||||
|
ATTR_LATITUDE,
|
||||||
|
):
|
||||||
|
_render_template_attr(kwargs, attribute)
|
||||||
|
_LOGGER.debug("New telegram message %s: %s", msgtype, kwargs)
|
||||||
|
|
||||||
|
if msgtype == SERVICE_SEND_MESSAGE:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.send_message, **kwargs)
|
||||||
|
)
|
||||||
|
elif msgtype in [
|
||||||
|
SERVICE_SEND_PHOTO,
|
||||||
|
SERVICE_SEND_ANIMATION,
|
||||||
|
SERVICE_SEND_VIDEO,
|
||||||
|
SERVICE_SEND_VOICE,
|
||||||
|
SERVICE_SEND_DOCUMENT,
|
||||||
|
]:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.send_file, msgtype, **kwargs)
|
||||||
|
)
|
||||||
|
elif msgtype == SERVICE_SEND_STICKER:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.send_sticker, **kwargs)
|
||||||
|
)
|
||||||
|
elif msgtype == SERVICE_SEND_LOCATION:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.send_location, **kwargs)
|
||||||
|
)
|
||||||
|
elif msgtype == SERVICE_ANSWER_CALLBACK_QUERY:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.answer_callback_query, **kwargs)
|
||||||
|
)
|
||||||
|
elif msgtype == SERVICE_DELETE_MESSAGE:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.delete_message, **kwargs)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await hass.async_add_executor_job(
|
||||||
|
partial(notify_service.edit_message, msgtype, **kwargs)
|
||||||
|
)
|
||||||
|
|
||||||
|
# Register notification services
|
||||||
|
for service_notif, schema in SERVICE_MAP.items():
|
||||||
|
hass.services.async_register(
|
||||||
|
DOMAIN, service_notif, async_send_telegram_message, schema=schema
|
||||||
|
)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def initialize_bot(p_config):
|
||||||
|
"""Initialize telegram bot with proxy support."""
|
||||||
|
|
||||||
|
api_key = p_config.get(CONF_API_KEY)
|
||||||
|
proxy_url = p_config.get(CONF_PROXY_URL)
|
||||||
|
proxy_params = p_config.get(CONF_PROXY_PARAMS)
|
||||||
|
|
||||||
|
if proxy_url is not None:
|
||||||
|
request = Request(
|
||||||
|
con_pool_size=8, proxy_url=proxy_url, urllib3_proxy_kwargs=proxy_params
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
request = Request(con_pool_size=8)
|
||||||
|
return Bot(token=api_key, request=request)
|
||||||
|
|
||||||
|
|
||||||
|
class TelegramNotificationService:
|
||||||
|
"""Implement the notification services for the Telegram Bot domain."""
|
||||||
|
|
||||||
|
def __init__(self, hass, bot, allowed_chat_ids, parser):
|
||||||
|
"""Initialize the service."""
|
||||||
|
|
||||||
|
self.allowed_chat_ids = allowed_chat_ids
|
||||||
|
self._default_user = self.allowed_chat_ids[0]
|
||||||
|
self._last_message_id = {user: None for user in self.allowed_chat_ids}
|
||||||
|
self._parsers = {PARSER_HTML: ParseMode.HTML, PARSER_MD: ParseMode.MARKDOWN}
|
||||||
|
self._parse_mode = self._parsers.get(parser)
|
||||||
|
self.bot = bot
|
||||||
|
self.hass = hass
|
||||||
|
|
||||||
|
def _get_msg_ids(self, msg_data, chat_id):
|
||||||
|
"""Get the message id to edit.
|
||||||
|
|
||||||
|
This can be one of (message_id, inline_message_id) from a msg dict,
|
||||||
|
returning a tuple.
|
||||||
|
**You can use 'last' as message_id** to edit
|
||||||
|
the message last sent in the chat_id.
|
||||||
|
"""
|
||||||
|
message_id = inline_message_id = None
|
||||||
|
if ATTR_MESSAGEID in msg_data:
|
||||||
|
message_id = msg_data[ATTR_MESSAGEID]
|
||||||
|
if (
|
||||||
|
isinstance(message_id, str)
|
||||||
|
and (message_id == "last")
|
||||||
|
and (self._last_message_id[chat_id] is not None)
|
||||||
|
):
|
||||||
|
message_id = self._last_message_id[chat_id]
|
||||||
|
else:
|
||||||
|
inline_message_id = msg_data["inline_message_id"]
|
||||||
|
return message_id, inline_message_id
|
||||||
|
|
||||||
|
def _get_target_chat_ids(self, target):
|
||||||
|
"""Validate chat_id targets or return default target (first).
|
||||||
|
|
||||||
|
:param target: optional list of integers ([12234, -12345])
|
||||||
|
:return list of chat_id targets (integers)
|
||||||
|
"""
|
||||||
|
if target is not None:
|
||||||
|
if isinstance(target, int):
|
||||||
|
target = [target]
|
||||||
|
chat_ids = [t for t in target if t in self.allowed_chat_ids]
|
||||||
|
if chat_ids:
|
||||||
|
return chat_ids
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Disallowed targets: %s, using default: %s", target, self._default_user
|
||||||
|
)
|
||||||
|
return [self._default_user]
|
||||||
|
|
||||||
|
def _get_msg_kwargs(self, data):
|
||||||
|
"""Get parameters in message data kwargs."""
|
||||||
|
|
||||||
|
def _make_row_inline_keyboard(row_keyboard):
|
||||||
|
"""Make a list of InlineKeyboardButtons.
|
||||||
|
|
||||||
|
It can accept:
|
||||||
|
- a list of tuples like:
|
||||||
|
`[(text_b1, data_callback_b1),
|
||||||
|
(text_b2, data_callback_b2), ...]
|
||||||
|
- a string like: `/cmd1, /cmd2, /cmd3`
|
||||||
|
- or a string like: `text_b1:/cmd1, text_b2:/cmd2`
|
||||||
|
"""
|
||||||
|
|
||||||
|
buttons = []
|
||||||
|
if isinstance(row_keyboard, str):
|
||||||
|
for key in row_keyboard.split(","):
|
||||||
|
if ":/" in key:
|
||||||
|
# commands like: 'Label:/cmd' become ('Label', '/cmd')
|
||||||
|
label = key.split(":/")[0]
|
||||||
|
command = key[len(label) + 1 :]
|
||||||
|
buttons.append(
|
||||||
|
InlineKeyboardButton(label, callback_data=command)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# commands like: '/cmd' become ('CMD', '/cmd')
|
||||||
|
label = key.strip()[1:].upper()
|
||||||
|
buttons.append(InlineKeyboardButton(label, callback_data=key))
|
||||||
|
elif isinstance(row_keyboard, list):
|
||||||
|
for entry in row_keyboard:
|
||||||
|
text_btn, data_btn = entry
|
||||||
|
buttons.append(
|
||||||
|
InlineKeyboardButton(text_btn, callback_data=data_btn)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError(str(row_keyboard))
|
||||||
|
return buttons
|
||||||
|
|
||||||
|
# Defaults
|
||||||
|
params = {
|
||||||
|
ATTR_PARSER: self._parse_mode,
|
||||||
|
ATTR_DISABLE_NOTIF: False,
|
||||||
|
ATTR_DISABLE_WEB_PREV: None,
|
||||||
|
ATTR_REPLY_TO_MSGID: None,
|
||||||
|
ATTR_REPLYMARKUP: None,
|
||||||
|
ATTR_TIMEOUT: None,
|
||||||
|
ATTR_MESSAGE_TAG: None,
|
||||||
|
}
|
||||||
|
if data is not None:
|
||||||
|
if ATTR_PARSER in data:
|
||||||
|
params[ATTR_PARSER] = self._parsers.get(
|
||||||
|
data[ATTR_PARSER], self._parse_mode
|
||||||
|
)
|
||||||
|
if ATTR_TIMEOUT in data:
|
||||||
|
params[ATTR_TIMEOUT] = data[ATTR_TIMEOUT]
|
||||||
|
if ATTR_DISABLE_NOTIF in data:
|
||||||
|
params[ATTR_DISABLE_NOTIF] = data[ATTR_DISABLE_NOTIF]
|
||||||
|
if ATTR_DISABLE_WEB_PREV in data:
|
||||||
|
params[ATTR_DISABLE_WEB_PREV] = data[ATTR_DISABLE_WEB_PREV]
|
||||||
|
if ATTR_REPLY_TO_MSGID in data:
|
||||||
|
params[ATTR_REPLY_TO_MSGID] = data[ATTR_REPLY_TO_MSGID]
|
||||||
|
if ATTR_MESSAGE_TAG in data:
|
||||||
|
params[ATTR_MESSAGE_TAG] = data[ATTR_MESSAGE_TAG]
|
||||||
|
# Keyboards:
|
||||||
|
if ATTR_KEYBOARD in data:
|
||||||
|
keys = data.get(ATTR_KEYBOARD)
|
||||||
|
keys = keys if isinstance(keys, list) else [keys]
|
||||||
|
if keys:
|
||||||
|
params[ATTR_REPLYMARKUP] = ReplyKeyboardMarkup(
|
||||||
|
[[key.strip() for key in row.split(",")] for row in keys]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
params[ATTR_REPLYMARKUP] = ReplyKeyboardRemove(True)
|
||||||
|
|
||||||
|
elif ATTR_KEYBOARD_INLINE in data:
|
||||||
|
keys = data.get(ATTR_KEYBOARD_INLINE)
|
||||||
|
keys = keys if isinstance(keys, list) else [keys]
|
||||||
|
params[ATTR_REPLYMARKUP] = InlineKeyboardMarkup(
|
||||||
|
[_make_row_inline_keyboard(row) for row in keys]
|
||||||
|
)
|
||||||
|
return params
|
||||||
|
|
||||||
|
def _send_msg(self, func_send, msg_error, message_tag, *args_msg, **kwargs_msg):
|
||||||
|
"""Send one message."""
|
||||||
|
|
||||||
|
try:
|
||||||
|
out = func_send(*args_msg, **kwargs_msg)
|
||||||
|
if not isinstance(out, bool) and hasattr(out, ATTR_MESSAGEID):
|
||||||
|
chat_id = out.chat_id
|
||||||
|
message_id = out[ATTR_MESSAGEID]
|
||||||
|
self._last_message_id[chat_id] = message_id
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Last message ID: %s (from chat_id %s)",
|
||||||
|
self._last_message_id,
|
||||||
|
chat_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
event_data = {
|
||||||
|
ATTR_CHAT_ID: chat_id,
|
||||||
|
ATTR_MESSAGEID: message_id,
|
||||||
|
}
|
||||||
|
if message_tag is not None:
|
||||||
|
event_data[ATTR_MESSAGE_TAG] = message_tag
|
||||||
|
self.hass.bus.fire(EVENT_TELEGRAM_SENT, event_data)
|
||||||
|
elif not isinstance(out, bool):
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Update last message: out_type:%s, out=%s", type(out), out
|
||||||
|
)
|
||||||
|
return out
|
||||||
|
except TelegramError as exc:
|
||||||
|
_LOGGER.error(
|
||||||
|
"%s: %s. Args: %s, kwargs: %s", msg_error, exc, args_msg, kwargs_msg
|
||||||
|
)
|
||||||
|
|
||||||
|
def send_message(self, message="", target=None, **kwargs):
|
||||||
|
"""Send a message to one or multiple pre-allowed chat IDs."""
|
||||||
|
title = kwargs.get(ATTR_TITLE)
|
||||||
|
text = f"{title}\n{message}" if title else message
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
for chat_id in self._get_target_chat_ids(target):
|
||||||
|
_LOGGER.debug("Send message in chat ID %s with params: %s", chat_id, params)
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_message,
|
||||||
|
"Error sending message",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id,
|
||||||
|
text,
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
disable_web_page_preview=params[ATTR_DISABLE_WEB_PREV],
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_to_message_id=params[ATTR_REPLY_TO_MSGID],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
|
||||||
|
def delete_message(self, chat_id=None, **kwargs):
|
||||||
|
"""Delete a previously sent message."""
|
||||||
|
chat_id = self._get_target_chat_ids(chat_id)[0]
|
||||||
|
message_id, _ = self._get_msg_ids(kwargs, chat_id)
|
||||||
|
_LOGGER.debug("Delete message %s in chat ID %s", message_id, chat_id)
|
||||||
|
deleted = self._send_msg(
|
||||||
|
self.bot.delete_message, "Error deleting message", None, chat_id, message_id
|
||||||
|
)
|
||||||
|
# reduce message_id anyway:
|
||||||
|
if self._last_message_id[chat_id] is not None:
|
||||||
|
# change last msg_id for deque(n_msgs)?
|
||||||
|
self._last_message_id[chat_id] -= 1
|
||||||
|
return deleted
|
||||||
|
|
||||||
|
def edit_message(self, type_edit, chat_id=None, **kwargs):
|
||||||
|
"""Edit a previously sent message."""
|
||||||
|
chat_id = self._get_target_chat_ids(chat_id)[0]
|
||||||
|
message_id, inline_message_id = self._get_msg_ids(kwargs, chat_id)
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Edit message %s in chat ID %s with params: %s",
|
||||||
|
message_id or inline_message_id,
|
||||||
|
chat_id,
|
||||||
|
params,
|
||||||
|
)
|
||||||
|
if type_edit == SERVICE_EDIT_MESSAGE:
|
||||||
|
message = kwargs.get(ATTR_MESSAGE)
|
||||||
|
title = kwargs.get(ATTR_TITLE)
|
||||||
|
text = f"{title}\n{message}" if title else message
|
||||||
|
_LOGGER.debug("Editing message with ID %s", message_id or inline_message_id)
|
||||||
|
return self._send_msg(
|
||||||
|
self.bot.edit_message_text,
|
||||||
|
"Error editing text message",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
text,
|
||||||
|
chat_id=chat_id,
|
||||||
|
message_id=message_id,
|
||||||
|
inline_message_id=inline_message_id,
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
disable_web_page_preview=params[ATTR_DISABLE_WEB_PREV],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
if type_edit == SERVICE_EDIT_CAPTION:
|
||||||
|
return self._send_msg(
|
||||||
|
self.bot.edit_message_caption,
|
||||||
|
"Error editing message attributes",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
message_id=message_id,
|
||||||
|
inline_message_id=inline_message_id,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
)
|
||||||
|
|
||||||
|
return self._send_msg(
|
||||||
|
self.bot.edit_message_reply_markup,
|
||||||
|
"Error editing message attributes",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
message_id=message_id,
|
||||||
|
inline_message_id=inline_message_id,
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
|
||||||
|
def answer_callback_query(
|
||||||
|
self, message, callback_query_id, show_alert=False, **kwargs
|
||||||
|
):
|
||||||
|
"""Answer a callback originated with a press in an inline keyboard."""
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Answer callback query with callback ID %s: %s, alert: %s",
|
||||||
|
callback_query_id,
|
||||||
|
message,
|
||||||
|
show_alert,
|
||||||
|
)
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.answer_callback_query,
|
||||||
|
"Error sending answer callback query",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
callback_query_id,
|
||||||
|
text=message,
|
||||||
|
show_alert=show_alert,
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
|
||||||
|
def send_file(self, file_type=SERVICE_SEND_PHOTO, target=None, **kwargs):
|
||||||
|
"""Send a photo, sticker, video, or document."""
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
file_content = load_data(
|
||||||
|
self.hass,
|
||||||
|
url=kwargs.get(ATTR_URL),
|
||||||
|
filepath=kwargs.get(ATTR_FILE),
|
||||||
|
username=kwargs.get(ATTR_USERNAME),
|
||||||
|
password=kwargs.get(ATTR_PASSWORD),
|
||||||
|
authentication=kwargs.get(ATTR_AUTHENTICATION),
|
||||||
|
verify_ssl=kwargs.get(ATTR_VERIFY_SSL),
|
||||||
|
)
|
||||||
|
|
||||||
|
if file_content:
|
||||||
|
for chat_id in self._get_target_chat_ids(target):
|
||||||
|
_LOGGER.debug("Sending file to chat ID %s", chat_id)
|
||||||
|
|
||||||
|
if file_type == SERVICE_SEND_PHOTO:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_photo,
|
||||||
|
"Error sending photo",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
photo=file_content,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
)
|
||||||
|
|
||||||
|
elif file_type == SERVICE_SEND_STICKER:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_sticker,
|
||||||
|
"Error sending sticker",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
sticker=file_content,
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
|
||||||
|
elif file_type == SERVICE_SEND_VIDEO:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_video,
|
||||||
|
"Error sending video",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
video=file_content,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
)
|
||||||
|
elif file_type == SERVICE_SEND_DOCUMENT:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_document,
|
||||||
|
"Error sending document",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
document=file_content,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
)
|
||||||
|
elif file_type == SERVICE_SEND_VOICE:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_voice,
|
||||||
|
"Error sending voice",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
voice=file_content,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
elif file_type == SERVICE_SEND_ANIMATION:
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_animation,
|
||||||
|
"Error sending animation",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
animation=file_content,
|
||||||
|
caption=kwargs.get(ATTR_CAPTION),
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
parse_mode=params[ATTR_PARSER],
|
||||||
|
)
|
||||||
|
|
||||||
|
file_content.seek(0)
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Can't send file with kwargs: %s", kwargs)
|
||||||
|
|
||||||
|
def send_sticker(self, target=None, **kwargs):
|
||||||
|
"""Send a sticker from a telegram sticker pack."""
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
stickerid = kwargs.get(ATTR_STICKER_ID)
|
||||||
|
if stickerid:
|
||||||
|
for chat_id in self._get_target_chat_ids(target):
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_sticker,
|
||||||
|
"Error sending sticker",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
sticker=stickerid,
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
reply_markup=params[ATTR_REPLYMARKUP],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.send_file(SERVICE_SEND_STICKER, target, **kwargs)
|
||||||
|
|
||||||
|
def send_location(self, latitude, longitude, target=None, **kwargs):
|
||||||
|
"""Send a location."""
|
||||||
|
latitude = float(latitude)
|
||||||
|
longitude = float(longitude)
|
||||||
|
params = self._get_msg_kwargs(kwargs)
|
||||||
|
for chat_id in self._get_target_chat_ids(target):
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Send location %s/%s to chat ID %s", latitude, longitude, chat_id
|
||||||
|
)
|
||||||
|
self._send_msg(
|
||||||
|
self.bot.send_location,
|
||||||
|
"Error sending location",
|
||||||
|
params[ATTR_MESSAGE_TAG],
|
||||||
|
chat_id=chat_id,
|
||||||
|
latitude=latitude,
|
||||||
|
longitude=longitude,
|
||||||
|
disable_notification=params[ATTR_DISABLE_NOTIF],
|
||||||
|
timeout=params[ATTR_TIMEOUT],
|
||||||
|
)
|
||||||
|
|
||||||
|
def leave_chat(self, chat_id=None):
|
||||||
|
"""Remove bot from chat."""
|
||||||
|
chat_id = self._get_target_chat_ids(chat_id)[0]
|
||||||
|
_LOGGER.debug("Leave from chat ID %s", chat_id)
|
||||||
|
leaved = self._send_msg(
|
||||||
|
self.bot.leave_chat, "Error leaving chat", None, chat_id
|
||||||
|
)
|
||||||
|
return leaved
|
||||||
|
|
||||||
|
|
||||||
|
class BaseTelegramBotEntity:
|
||||||
|
"""The base class for the telegram bot."""
|
||||||
|
|
||||||
|
def __init__(self, hass, allowed_chat_ids):
|
||||||
|
"""Initialize the bot base class."""
|
||||||
|
self.allowed_chat_ids = allowed_chat_ids
|
||||||
|
self.hass = hass
|
||||||
|
|
||||||
|
def _get_message_data(self, msg_data):
|
||||||
|
"""Return boolean msg_data_is_ok and dict msg_data."""
|
||||||
|
if not msg_data:
|
||||||
|
return False, None
|
||||||
|
bad_fields = (
|
||||||
|
"text" not in msg_data and "data" not in msg_data and "chat" not in msg_data
|
||||||
|
)
|
||||||
|
if bad_fields or "from" not in msg_data:
|
||||||
|
# Message is not correct.
|
||||||
|
_LOGGER.error("Incoming message does not have required data (%s)", msg_data)
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
if (
|
||||||
|
msg_data["from"].get("id") not in self.allowed_chat_ids
|
||||||
|
and msg_data["chat"].get("id") not in self.allowed_chat_ids
|
||||||
|
# and msg_data["message"]["chat"].get("id") not in self.allowed_chat_ids
|
||||||
|
):
|
||||||
|
# Neither from id nor chat id was in allowed_chat_ids,
|
||||||
|
# origin is not allowed.
|
||||||
|
_LOGGER.error("Incoming message is not allowed (%s)", msg_data)
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
data = {
|
||||||
|
ATTR_USER_ID: msg_data["from"]["id"],
|
||||||
|
ATTR_FROM_FIRST: msg_data["from"]["first_name"],
|
||||||
|
}
|
||||||
|
if "message_id" in msg_data:
|
||||||
|
data[ATTR_MSGID] = msg_data["message_id"]
|
||||||
|
if "last_name" in msg_data["from"]:
|
||||||
|
data[ATTR_FROM_LAST] = msg_data["from"]["last_name"]
|
||||||
|
if "chat" in msg_data:
|
||||||
|
data[ATTR_CHAT_ID] = msg_data["chat"]["id"]
|
||||||
|
elif ATTR_MESSAGE in msg_data and "chat" in msg_data[ATTR_MESSAGE]:
|
||||||
|
data[ATTR_CHAT_ID] = msg_data[ATTR_MESSAGE]["chat"]["id"]
|
||||||
|
|
||||||
|
return True, data
|
||||||
|
|
||||||
|
def _get_channel_post_data(self, msg_data):
|
||||||
|
"""Return boolean msg_data_is_ok and dict msg_data."""
|
||||||
|
if not msg_data:
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
if "sender_chat" in msg_data and "chat" in msg_data and "text" in msg_data:
|
||||||
|
if (
|
||||||
|
msg_data["sender_chat"].get("id") not in self.allowed_chat_ids
|
||||||
|
and msg_data["chat"].get("id") not in self.allowed_chat_ids
|
||||||
|
):
|
||||||
|
# Neither sender_chat id nor chat id was in allowed_chat_ids,
|
||||||
|
# origin is not allowed.
|
||||||
|
_LOGGER.error("Incoming message is not allowed (%s)", msg_data)
|
||||||
|
return True, None
|
||||||
|
|
||||||
|
data = {
|
||||||
|
ATTR_MSGID: msg_data["message_id"],
|
||||||
|
ATTR_CHAT_ID: msg_data["chat"]["id"],
|
||||||
|
ATTR_TEXT: msg_data["text"],
|
||||||
|
}
|
||||||
|
return True, data
|
||||||
|
|
||||||
|
_LOGGER.error("Incoming message does not have required data (%s)", msg_data)
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
def process_message(self, data):
|
||||||
|
"""Check for basic message rules and fire an event if message is ok."""
|
||||||
|
if ATTR_MSG in data or ATTR_EDITED_MSG in data:
|
||||||
|
event = EVENT_TELEGRAM_COMMAND
|
||||||
|
if ATTR_MSG in data:
|
||||||
|
data = data.get(ATTR_MSG)
|
||||||
|
else:
|
||||||
|
data = data.get(ATTR_EDITED_MSG)
|
||||||
|
message_ok, event_data = self._get_message_data(data)
|
||||||
|
if event_data is None:
|
||||||
|
return message_ok
|
||||||
|
|
||||||
|
if ATTR_MSGID in data:
|
||||||
|
event_data[ATTR_MSGID] = data[ATTR_MSGID]
|
||||||
|
|
||||||
|
if "text" in data:
|
||||||
|
if data["text"][0] == "/":
|
||||||
|
pieces = data["text"].split(" ")
|
||||||
|
event_data[ATTR_COMMAND] = pieces[0]
|
||||||
|
event_data[ATTR_ARGS] = pieces[1:]
|
||||||
|
else:
|
||||||
|
event_data[ATTR_TEXT] = data["text"]
|
||||||
|
event = EVENT_TELEGRAM_TEXT
|
||||||
|
else:
|
||||||
|
_LOGGER.warning("Message without text data received: %s", data)
|
||||||
|
event_data[ATTR_TEXT] = str(data)
|
||||||
|
event = EVENT_TELEGRAM_TEXT
|
||||||
|
|
||||||
|
self.hass.bus.async_fire(event, event_data)
|
||||||
|
return True
|
||||||
|
if ATTR_CALLBACK_QUERY in data:
|
||||||
|
event = EVENT_TELEGRAM_CALLBACK
|
||||||
|
data = data.get(ATTR_CALLBACK_QUERY)
|
||||||
|
message_ok, event_data = self._get_message_data(data)
|
||||||
|
if event_data is None:
|
||||||
|
return message_ok
|
||||||
|
|
||||||
|
query_data = event_data[ATTR_DATA] = data[ATTR_DATA]
|
||||||
|
|
||||||
|
if query_data[0] == "/":
|
||||||
|
pieces = query_data.split(" ")
|
||||||
|
event_data[ATTR_COMMAND] = pieces[0]
|
||||||
|
event_data[ATTR_ARGS] = pieces[1:]
|
||||||
|
|
||||||
|
event_data[ATTR_MSG] = data[ATTR_MSG]
|
||||||
|
event_data[ATTR_CHAT_INSTANCE] = data[ATTR_CHAT_INSTANCE]
|
||||||
|
event_data[ATTR_MSGID] = data[ATTR_MSGID]
|
||||||
|
|
||||||
|
self.hass.bus.async_fire(event, event_data)
|
||||||
|
return True
|
||||||
|
if ATTR_CHANNEL_POST in data:
|
||||||
|
event = EVENT_TELEGRAM_TEXT
|
||||||
|
data = data.get(ATTR_CHANNEL_POST)
|
||||||
|
message_ok, event_data = self._get_channel_post_data(data)
|
||||||
|
if event_data is None:
|
||||||
|
return message_ok
|
||||||
|
|
||||||
|
self.hass.bus.async_fire(event, event_data)
|
||||||
|
return True
|
||||||
|
|
||||||
|
_LOGGER.warning("Message with unknown data received: %s", data)
|
||||||
|
return True
|
|
@ -0,0 +1,17 @@
|
||||||
|
"""Support for Telegram bot to send messages only."""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from . import initialize_bot
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config):
|
||||||
|
"""Set up the Telegram broadcast platform."""
|
||||||
|
bot = initialize_bot(config)
|
||||||
|
|
||||||
|
bot_config = await hass.async_add_executor_job(bot.getMe)
|
||||||
|
_LOGGER.debug(
|
||||||
|
"Telegram broadcast platform setup with bot %s", bot_config["username"]
|
||||||
|
)
|
||||||
|
return True
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"domain": "telegram_bot",
|
||||||
|
"name": "Telegram bot",
|
||||||
|
"version": "1.0",
|
||||||
|
"documentation": "https://www.home-assistant.io/integrations/telegram_bot",
|
||||||
|
"requirements": ["python-telegram-bot==13.1", "PySocks==1.7.1"],
|
||||||
|
"dependencies": ["http"],
|
||||||
|
"codeowners": [],
|
||||||
|
"iot_class": "cloud_push",
|
||||||
|
"loggers": ["telegram"]
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
"""Support for Telegram bot using polling."""
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from telegram import Update
|
||||||
|
from telegram.error import NetworkError, RetryAfter, TelegramError, TimedOut
|
||||||
|
from telegram.ext import CallbackContext, Dispatcher, Handler, Updater
|
||||||
|
from telegram.utils.types import HandlerArg
|
||||||
|
|
||||||
|
from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP
|
||||||
|
|
||||||
|
from . import CONF_ALLOWED_CHAT_IDS, BaseTelegramBotEntity, initialize_bot
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config):
|
||||||
|
"""Set up the Telegram polling platform."""
|
||||||
|
bot = initialize_bot(config)
|
||||||
|
pol = TelegramPoll(bot, hass, config[CONF_ALLOWED_CHAT_IDS])
|
||||||
|
|
||||||
|
def _start_bot(_event):
|
||||||
|
"""Start the bot."""
|
||||||
|
pol.start_polling()
|
||||||
|
|
||||||
|
def _stop_bot(_event):
|
||||||
|
"""Stop the bot."""
|
||||||
|
pol.stop_polling()
|
||||||
|
|
||||||
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_START, _start_bot)
|
||||||
|
hass.bus.async_listen_once(EVENT_HOMEASSISTANT_STOP, _stop_bot)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def process_error(update: Update, context: CallbackContext):
|
||||||
|
"""Telegram bot error handler."""
|
||||||
|
try:
|
||||||
|
raise context.error
|
||||||
|
except (TimedOut, NetworkError, RetryAfter):
|
||||||
|
# Long polling timeout or connection problem. Nothing serious.
|
||||||
|
pass
|
||||||
|
except TelegramError:
|
||||||
|
_LOGGER.error('Update "%s" caused error: "%s"', update, context.error)
|
||||||
|
|
||||||
|
|
||||||
|
def message_handler(handler):
|
||||||
|
"""Create messages handler."""
|
||||||
|
|
||||||
|
class MessageHandler(Handler):
|
||||||
|
"""Telegram bot message handler."""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Initialize the messages handler instance."""
|
||||||
|
super().__init__(handler)
|
||||||
|
|
||||||
|
def check_update(self, update):
|
||||||
|
"""Check is update valid."""
|
||||||
|
return isinstance(update, Update)
|
||||||
|
|
||||||
|
def handle_update(
|
||||||
|
self,
|
||||||
|
update: HandlerArg,
|
||||||
|
dispatcher: Dispatcher,
|
||||||
|
check_result: object,
|
||||||
|
context: CallbackContext = None,
|
||||||
|
):
|
||||||
|
"""Handle update."""
|
||||||
|
optional_args = self.collect_optional_args(dispatcher, update)
|
||||||
|
context.args = optional_args
|
||||||
|
return self.callback(update, context)
|
||||||
|
|
||||||
|
return MessageHandler()
|
||||||
|
|
||||||
|
|
||||||
|
class TelegramPoll(BaseTelegramBotEntity):
|
||||||
|
"""Asyncio telegram incoming message handler."""
|
||||||
|
|
||||||
|
def __init__(self, bot, hass, allowed_chat_ids):
|
||||||
|
"""Initialize the polling instance."""
|
||||||
|
|
||||||
|
BaseTelegramBotEntity.__init__(self, hass, allowed_chat_ids)
|
||||||
|
|
||||||
|
self.updater = Updater(bot=bot, workers=4)
|
||||||
|
self.dispatcher = self.updater.dispatcher
|
||||||
|
|
||||||
|
self.dispatcher.add_handler(message_handler(self.process_update))
|
||||||
|
self.dispatcher.add_error_handler(process_error)
|
||||||
|
|
||||||
|
def start_polling(self):
|
||||||
|
"""Start the polling task."""
|
||||||
|
self.updater.start_polling()
|
||||||
|
|
||||||
|
def stop_polling(self):
|
||||||
|
"""Stop the polling task."""
|
||||||
|
self.updater.stop()
|
||||||
|
|
||||||
|
def process_update(self, update: HandlerArg, context: CallbackContext):
|
||||||
|
"""Process incoming message."""
|
||||||
|
self.process_message(update.to_dict())
|
|
@ -0,0 +1,840 @@
|
||||||
|
# Describes the format for available Telegram bot services
|
||||||
|
|
||||||
|
send_message:
|
||||||
|
name: Send message
|
||||||
|
description: Send a notification.
|
||||||
|
fields:
|
||||||
|
message:
|
||||||
|
name: Message
|
||||||
|
description: Message body of the notification.
|
||||||
|
required: true
|
||||||
|
example: The garage door has been open for 10 minutes.
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
title:
|
||||||
|
name: Title
|
||||||
|
description: Optional title for your notification. Will be composed as '%title\n%message'
|
||||||
|
example: "Your Garage Door Friend"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the notification to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
disable_web_page_preview:
|
||||||
|
name: Disable web page preview
|
||||||
|
description: Disables link previews for links in the message.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send message. Will help with timeout errors (poor internet connection, etc)s
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard. Empty list clears a previously set keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or ["Text button1:/button1, Text button2:/button2", "Text button3:/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_photo:
|
||||||
|
name: Send photo
|
||||||
|
description: Send a photo.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to an image.
|
||||||
|
example: "http://example.org/path/to/the/image.png"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to an image.
|
||||||
|
example: "/path/to/the/image.png"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: The title of the image.
|
||||||
|
example: "My image"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send photo. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_sticker:
|
||||||
|
name: Send sticker
|
||||||
|
description: Send a sticker.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to a static .webp or animated .tgs sticker.
|
||||||
|
example: "http://example.org/path/to/the/sticker.webp"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to a static .webp or animated .tgs sticker.
|
||||||
|
example: "/path/to/the/sticker.webp"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
sticker_id:
|
||||||
|
name: Sticker ID
|
||||||
|
description: ID of a sticker that exists on telegram servers
|
||||||
|
example: CAACAgIAAxkBAAEDDldhZD-hqWclr6krLq-FWSfCrGNmOQAC9gAD9HsZAAFeYY-ltPYnrCEE
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send sticker. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_animation:
|
||||||
|
name: Send animation
|
||||||
|
description: Send an anmiation.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to a GIF or H.264/MPEG-4 AVC video without sound.
|
||||||
|
example: "http://example.org/path/to/the/animation.gif"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to a GIF or H.264/MPEG-4 AVC video without sound.
|
||||||
|
example: "/path/to/the/animation.gif"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: The title of the animation.
|
||||||
|
example: "My animation"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse Mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send sticker. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
|
||||||
|
send_video:
|
||||||
|
name: Send video
|
||||||
|
description: Send a video.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to a video.
|
||||||
|
example: "http://example.org/path/to/the/video.mp4"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to a video.
|
||||||
|
example: "/path/to/the/video.mp4"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: The title of the video.
|
||||||
|
example: "My video"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send video. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_voice:
|
||||||
|
name: Send voice
|
||||||
|
description: Send a voice message.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to a voice message.
|
||||||
|
example: "http://example.org/path/to/the/voice.opus"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to a voice message.
|
||||||
|
example: "/path/to/the/voice.opus"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: The title of the voice message.
|
||||||
|
example: "My microphone recording"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send voice. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_document:
|
||||||
|
name: Send document
|
||||||
|
description: Send a document.
|
||||||
|
fields:
|
||||||
|
url:
|
||||||
|
name: URL
|
||||||
|
description: Remote path to a document.
|
||||||
|
example: "http://example.org/path/to/the/document.odf"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
file:
|
||||||
|
name: File
|
||||||
|
description: Local path to a document.
|
||||||
|
example: "/tmp/whatever.odf"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: The title of the document.
|
||||||
|
example: Document Title xy
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
username:
|
||||||
|
name: Username
|
||||||
|
description: Username for a URL which require HTTP authentication.
|
||||||
|
example: myuser
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
password:
|
||||||
|
name: Password
|
||||||
|
description: Password (or bearer token) for a URL which require HTTP authentication.
|
||||||
|
example: myuser_pwd
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
authentication:
|
||||||
|
name: Authentication method
|
||||||
|
description: Define which authentication method to use. Set to `digest` to use HTTP digest authentication, or `bearer_token` for OAuth 2.0 bearer token authentication. Defaults to `basic`.
|
||||||
|
default: digest
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "digest"
|
||||||
|
- "bearer_token"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the document to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
verify_ssl:
|
||||||
|
name: Verify SSL
|
||||||
|
description: Enable or disable SSL certificate verification. Set to false if you're downloading the file from a URL and you don't want to validate the SSL certificate of the server.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send document. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
send_location:
|
||||||
|
name: Send location
|
||||||
|
description: Send a location.
|
||||||
|
fields:
|
||||||
|
latitude:
|
||||||
|
name: Latitude
|
||||||
|
description: The latitude to send.
|
||||||
|
required: true
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -90
|
||||||
|
max: 90
|
||||||
|
step: 0.001
|
||||||
|
unit_of_measurement: "°"
|
||||||
|
longitude:
|
||||||
|
name: Longitude
|
||||||
|
description: The longitude to send.
|
||||||
|
required: true
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: -180
|
||||||
|
max: 180
|
||||||
|
step: 0.001
|
||||||
|
unit_of_measurement: "°"
|
||||||
|
target:
|
||||||
|
name: Target
|
||||||
|
description: An array of pre-authorized chat_ids to send the location to. If not present, first allowed chat_id is the default.
|
||||||
|
example: "[12345, 67890] or 12345"
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
disable_notification:
|
||||||
|
name: Disable notification
|
||||||
|
description: Sends the message silently. iOS users and Web users will not receive a notification, Android users will receive a notification with no sound.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for send photo. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
keyboard:
|
||||||
|
name: Keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom keyboard.
|
||||||
|
example: '["/command1, /command2", "/command3"]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
message_tag:
|
||||||
|
name: Message tag
|
||||||
|
description: "Tag for sent message. In telegram_sent event data: {{trigger.event.data.message_tag}}"
|
||||||
|
example: "msg_to_edit"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
|
||||||
|
edit_message:
|
||||||
|
name: Edit message
|
||||||
|
description: Edit a previously sent message.
|
||||||
|
fields:
|
||||||
|
message_id:
|
||||||
|
name: Message ID
|
||||||
|
description: id of the message to edit.
|
||||||
|
required: true
|
||||||
|
example: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
chat_id:
|
||||||
|
name: Chat ID
|
||||||
|
description: The chat_id where to edit the message.
|
||||||
|
required: true
|
||||||
|
example: 12345
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
message:
|
||||||
|
name: Message
|
||||||
|
description: Message body of the notification.
|
||||||
|
example: The garage door has been open for 10 minutes.
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
title:
|
||||||
|
name: Title
|
||||||
|
description: Optional title for your notification. Will be composed as '%title\n%message'
|
||||||
|
example: "Your Garage Door Friend"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
parse_mode:
|
||||||
|
name: Parse mode
|
||||||
|
description: "Parser for the message text."
|
||||||
|
selector:
|
||||||
|
select:
|
||||||
|
options:
|
||||||
|
- "html"
|
||||||
|
- "markdown"
|
||||||
|
- "markdown2"
|
||||||
|
disable_web_page_preview:
|
||||||
|
name: Disable web page preview
|
||||||
|
description: Disables link previews for links in the message.
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
|
||||||
|
edit_caption:
|
||||||
|
name: Edit caption
|
||||||
|
description: Edit the caption of a previously sent message.
|
||||||
|
fields:
|
||||||
|
message_id:
|
||||||
|
name: Message ID
|
||||||
|
description: id of the message to edit.
|
||||||
|
required: true
|
||||||
|
example: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
chat_id:
|
||||||
|
name: Chat ID
|
||||||
|
description: The chat_id where to edit the caption.
|
||||||
|
required: true
|
||||||
|
example: 12345
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
caption:
|
||||||
|
name: Caption
|
||||||
|
description: Message body of the notification.
|
||||||
|
required: true
|
||||||
|
example: The garage door has been open for 10 minutes.
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
|
||||||
|
edit_replymarkup:
|
||||||
|
name: Edit reply markup
|
||||||
|
description: Edit the inline keyboard of a previously sent message.
|
||||||
|
fields:
|
||||||
|
message_id:
|
||||||
|
name: Message ID
|
||||||
|
description: id of the message to edit.
|
||||||
|
required: true
|
||||||
|
example: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
chat_id:
|
||||||
|
name: Chat ID
|
||||||
|
description: The chat_id where to edit the reply_markup.
|
||||||
|
required: true
|
||||||
|
example: 12345
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
inline_keyboard:
|
||||||
|
name: Inline keyboard
|
||||||
|
description: List of rows of commands, comma-separated, to make a custom inline keyboard with buttons with associated callback data.
|
||||||
|
required: true
|
||||||
|
example: '["/button1, /button2", "/button3"] or [[["Text button1", "/button1"], ["Text button2", "/button2"]], [["Text button3", "/button3"]]]'
|
||||||
|
selector:
|
||||||
|
object:
|
||||||
|
|
||||||
|
answer_callback_query:
|
||||||
|
name: Answer callback query
|
||||||
|
description: Respond to a callback query originated by clicking on an online keyboard button. The answer will be displayed to the user as a notification at the top of the chat screen or as an alert.
|
||||||
|
fields:
|
||||||
|
message:
|
||||||
|
name: Message
|
||||||
|
description: Unformatted text message body of the notification.
|
||||||
|
required: true
|
||||||
|
example: "OK, I'm listening"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
callback_query_id:
|
||||||
|
name: Callback query ID
|
||||||
|
description: Unique id of the callback response.
|
||||||
|
required: true
|
||||||
|
example: "{{ trigger.event.data.id }}"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
show_alert:
|
||||||
|
name: Show alert
|
||||||
|
description: Show a permanent notification.
|
||||||
|
required: true
|
||||||
|
selector:
|
||||||
|
boolean:
|
||||||
|
timeout:
|
||||||
|
name: Timeout
|
||||||
|
description: Timeout for sending the answer. Will help with timeout errors (poor internet connection, etc)
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 3600
|
||||||
|
unit_of_measurement: seconds
|
||||||
|
|
||||||
|
delete_message:
|
||||||
|
name: Delete message
|
||||||
|
description: Delete a previously sent message.
|
||||||
|
fields:
|
||||||
|
message_id:
|
||||||
|
name: Message ID
|
||||||
|
description: id of the message to delete.
|
||||||
|
required: true
|
||||||
|
example: "{{ trigger.event.data.message.message_id }}"
|
||||||
|
selector:
|
||||||
|
text:
|
||||||
|
chat_id:
|
||||||
|
name: Chat ID
|
||||||
|
description: The chat_id where to delete the message.
|
||||||
|
required: true
|
||||||
|
example: 12345
|
||||||
|
selector:
|
||||||
|
text:
|
|
@ -0,0 +1,107 @@
|
||||||
|
"""Support for Telegram bots using webhooks."""
|
||||||
|
import datetime as dt
|
||||||
|
from http import HTTPStatus
|
||||||
|
from ipaddress import ip_address
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from telegram.error import TimedOut
|
||||||
|
|
||||||
|
from homeassistant.components.http import HomeAssistantView
|
||||||
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||||
|
from homeassistant.helpers.network import get_url
|
||||||
|
|
||||||
|
from . import (
|
||||||
|
CONF_ALLOWED_CHAT_IDS,
|
||||||
|
CONF_TRUSTED_NETWORKS,
|
||||||
|
CONF_URL,
|
||||||
|
BaseTelegramBotEntity,
|
||||||
|
initialize_bot,
|
||||||
|
)
|
||||||
|
|
||||||
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
TELEGRAM_HANDLER_URL = "/api/telegram_webhooks"
|
||||||
|
REMOVE_HANDLER_URL = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def async_setup_platform(hass, config):
|
||||||
|
"""Set up the Telegram webhooks platform."""
|
||||||
|
|
||||||
|
bot = initialize_bot(config)
|
||||||
|
|
||||||
|
current_status = await hass.async_add_executor_job(bot.getWebhookInfo)
|
||||||
|
if not (base_url := config.get(CONF_URL)):
|
||||||
|
base_url = get_url(hass, require_ssl=True, allow_internal=False)
|
||||||
|
|
||||||
|
# Some logging of Bot current status:
|
||||||
|
last_error_date = getattr(current_status, "last_error_date", None)
|
||||||
|
if (last_error_date is not None) and (isinstance(last_error_date, int)):
|
||||||
|
last_error_date = dt.datetime.fromtimestamp(last_error_date)
|
||||||
|
_LOGGER.info(
|
||||||
|
"Telegram webhook last_error_date: %s. Status: %s",
|
||||||
|
last_error_date,
|
||||||
|
current_status,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
_LOGGER.debug("telegram webhook Status: %s", current_status)
|
||||||
|
|
||||||
|
handler_url = f"{base_url}{TELEGRAM_HANDLER_URL}"
|
||||||
|
if not handler_url.startswith("https"):
|
||||||
|
_LOGGER.error("Invalid telegram webhook %s must be https", handler_url)
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _try_to_set_webhook():
|
||||||
|
retry_num = 0
|
||||||
|
while retry_num < 3:
|
||||||
|
try:
|
||||||
|
return bot.setWebhook(handler_url, timeout=5)
|
||||||
|
except TimedOut:
|
||||||
|
retry_num += 1
|
||||||
|
_LOGGER.warning("Timeout trying to set webhook (retry #%d)", retry_num)
|
||||||
|
|
||||||
|
if current_status and current_status["url"] != handler_url:
|
||||||
|
result = await hass.async_add_executor_job(_try_to_set_webhook)
|
||||||
|
if result:
|
||||||
|
_LOGGER.info("Set new telegram webhook %s", handler_url)
|
||||||
|
else:
|
||||||
|
_LOGGER.error("Set telegram webhook failed %s", handler_url)
|
||||||
|
return False
|
||||||
|
|
||||||
|
hass.bus.async_listen_once(
|
||||||
|
EVENT_HOMEASSISTANT_STOP, lambda event: bot.setWebhook(REMOVE_HANDLER_URL)
|
||||||
|
)
|
||||||
|
hass.http.register_view(
|
||||||
|
BotPushReceiver(
|
||||||
|
hass, config[CONF_ALLOWED_CHAT_IDS], config[CONF_TRUSTED_NETWORKS]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
class BotPushReceiver(HomeAssistantView, BaseTelegramBotEntity):
|
||||||
|
"""Handle pushes from Telegram."""
|
||||||
|
|
||||||
|
requires_auth = False
|
||||||
|
url = TELEGRAM_HANDLER_URL
|
||||||
|
name = "telegram_webhooks"
|
||||||
|
|
||||||
|
def __init__(self, hass, allowed_chat_ids, trusted_networks):
|
||||||
|
"""Initialize the class."""
|
||||||
|
BaseTelegramBotEntity.__init__(self, hass, allowed_chat_ids)
|
||||||
|
self.trusted_networks = trusted_networks
|
||||||
|
|
||||||
|
async def post(self, request):
|
||||||
|
"""Accept the POST from telegram."""
|
||||||
|
real_ip = ip_address(request.remote)
|
||||||
|
if not any(real_ip in net for net in self.trusted_networks):
|
||||||
|
_LOGGER.warning("Access denied from %s", real_ip)
|
||||||
|
return self.json_message("Access denied", HTTPStatus.UNAUTHORIZED)
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = await request.json()
|
||||||
|
except ValueError:
|
||||||
|
return self.json_message("Invalid JSON", HTTPStatus.BAD_REQUEST)
|
||||||
|
|
||||||
|
if not self.process_message(data):
|
||||||
|
return self.json_message("Invalid message", HTTPStatus.BAD_REQUEST)
|
||||||
|
return None
|
|
@ -1,141 +0,0 @@
|
||||||
"""
|
|
||||||
Custom Component, written by @skalavala - based on the existing TCP component.
|
|
||||||
|
|
||||||
Support for UDP socket based sensors.
|
|
||||||
|
|
||||||
For more details about this platform, please refer to the documentation at
|
|
||||||
https://home-assistant.io/components/sensor.udp/
|
|
||||||
"""
|
|
||||||
import logging
|
|
||||||
import socket
|
|
||||||
import select
|
|
||||||
|
|
||||||
import voluptuous as vol
|
|
||||||
|
|
||||||
from homeassistant.components.sensor import PLATFORM_SCHEMA
|
|
||||||
from homeassistant.const import (
|
|
||||||
CONF_NAME, CONF_HOST, CONF_PORT, CONF_PAYLOAD, CONF_TIMEOUT,
|
|
||||||
CONF_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE)
|
|
||||||
from homeassistant.exceptions import TemplateError
|
|
||||||
from homeassistant.helpers.entity import Entity
|
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
CONF_BUFFER_SIZE = 'buffer_size'
|
|
||||||
CONF_VALUE_ON = 'value_on'
|
|
||||||
|
|
||||||
DEFAULT_BUFFER_SIZE = 1024
|
|
||||||
DEFAULT_NAME = 'UDP Sensor'
|
|
||||||
DEFAULT_TIMEOUT = 10
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
|
|
||||||
vol.Required(CONF_HOST): cv.string,
|
|
||||||
vol.Required(CONF_PORT): cv.port,
|
|
||||||
vol.Required(CONF_PAYLOAD): cv.string,
|
|
||||||
vol.Optional(CONF_BUFFER_SIZE, default=DEFAULT_BUFFER_SIZE):
|
|
||||||
cv.positive_int,
|
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
|
||||||
vol.Optional(CONF_TIMEOUT, default=DEFAULT_TIMEOUT): cv.positive_int,
|
|
||||||
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
|
|
||||||
vol.Optional(CONF_VALUE_ON): cv.string,
|
|
||||||
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
def setup_platform(hass, config, add_entities, discovery_info=None):
|
|
||||||
"""Set up the UDP Sensor."""
|
|
||||||
add_entities([UdpSensor(hass, config)])
|
|
||||||
|
|
||||||
|
|
||||||
class UdpSensor(Entity):
|
|
||||||
"""Implementation of a UDP socket based sensor."""
|
|
||||||
|
|
||||||
required = tuple()
|
|
||||||
|
|
||||||
def __init__(self, hass, config):
|
|
||||||
"""Set all the config values if they exist and get initial state."""
|
|
||||||
value_template = config.get(CONF_VALUE_TEMPLATE)
|
|
||||||
|
|
||||||
if value_template is not None:
|
|
||||||
value_template.hass = hass
|
|
||||||
|
|
||||||
self._hass = hass
|
|
||||||
self._config = {
|
|
||||||
CONF_NAME: config.get(CONF_NAME),
|
|
||||||
CONF_HOST: config.get(CONF_HOST),
|
|
||||||
CONF_PORT: config.get(CONF_PORT),
|
|
||||||
CONF_TIMEOUT: config.get(CONF_TIMEOUT),
|
|
||||||
CONF_PAYLOAD: config.get(CONF_PAYLOAD),
|
|
||||||
CONF_UNIT_OF_MEASUREMENT: config.get(CONF_UNIT_OF_MEASUREMENT),
|
|
||||||
CONF_VALUE_TEMPLATE: value_template,
|
|
||||||
CONF_VALUE_ON: config.get(CONF_VALUE_ON),
|
|
||||||
CONF_BUFFER_SIZE: config.get(CONF_BUFFER_SIZE),
|
|
||||||
}
|
|
||||||
self._state = None
|
|
||||||
self.update()
|
|
||||||
|
|
||||||
@property
|
|
||||||
def name(self):
|
|
||||||
"""Return the name of this sensor."""
|
|
||||||
name = self._config[CONF_NAME]
|
|
||||||
if name is not None:
|
|
||||||
return name
|
|
||||||
return super(UdpSensor, self).name
|
|
||||||
|
|
||||||
@property
|
|
||||||
def state(self):
|
|
||||||
"""Return the state of the device."""
|
|
||||||
return self._state
|
|
||||||
|
|
||||||
@property
|
|
||||||
def unit_of_measurement(self):
|
|
||||||
"""Return the unit of measurement of this entity."""
|
|
||||||
return self._config[CONF_UNIT_OF_MEASUREMENT]
|
|
||||||
|
|
||||||
def update(self):
|
|
||||||
"""Get the latest value for this sensor."""
|
|
||||||
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock:
|
|
||||||
sock.settimeout(self._config[CONF_TIMEOUT])
|
|
||||||
try:
|
|
||||||
sock.connect(
|
|
||||||
(self._config[CONF_HOST], self._config[CONF_PORT]))
|
|
||||||
except socket.error as err:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Unable to connect to %s on port %s: %s",
|
|
||||||
self._config[CONF_HOST], self._config[CONF_PORT], err)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
|
||||||
sock.send(self._config[CONF_PAYLOAD].encode())
|
|
||||||
except socket.error as err:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Unable to send payload %r to %s on port %s: %s",
|
|
||||||
self._config[CONF_PAYLOAD], self._config[CONF_HOST],
|
|
||||||
self._config[CONF_PORT], err)
|
|
||||||
return
|
|
||||||
|
|
||||||
readable, _, _ = select.select(
|
|
||||||
[sock], [], [], self._config[CONF_TIMEOUT])
|
|
||||||
if not readable:
|
|
||||||
_LOGGER.warning(
|
|
||||||
"Timeout (%s second(s)) waiting for a response after "
|
|
||||||
"sending %r to %s on port %s.",
|
|
||||||
self._config[CONF_TIMEOUT], self._config[CONF_PAYLOAD],
|
|
||||||
self._config[CONF_HOST], self._config[CONF_PORT])
|
|
||||||
return
|
|
||||||
|
|
||||||
value = sock.recv(self._config[CONF_BUFFER_SIZE]).decode()
|
|
||||||
|
|
||||||
if self._config[CONF_VALUE_TEMPLATE] is not None:
|
|
||||||
try:
|
|
||||||
self._state = self._config[CONF_VALUE_TEMPLATE].render(
|
|
||||||
value=value)
|
|
||||||
return
|
|
||||||
except TemplateError:
|
|
||||||
_LOGGER.error(
|
|
||||||
"Unable to render template of %r with value: %r",
|
|
||||||
self._config[CONF_VALUE_TEMPLATE], value)
|
|
||||||
return
|
|
||||||
|
|
||||||
self._state = value
|
|
|
@ -1,16 +1,14 @@
|
||||||
default: warning
|
default: warning
|
||||||
logs:
|
logs:
|
||||||
gsp: critical
|
|
||||||
root: warning
|
root: warning
|
||||||
pyhap: warning
|
pyhap: warning
|
||||||
openzwave: warning
|
|
||||||
py.warnings: warning
|
py.warnings: warning
|
||||||
pywemo.ssdp: warning
|
pywemo.ssdp: warning
|
||||||
libopenzwave: warning
|
|
||||||
simplipy.api: warning
|
simplipy.api: warning
|
||||||
netdisco.ssdp: warning
|
netdisco.ssdp: warning
|
||||||
aiohttp.server: warning
|
aiohttp.server: warning
|
||||||
aiohttp.websocket: error
|
aiohttp.websocket: error
|
||||||
|
pywemo.subscribe: error
|
||||||
homeassistant.core: critical
|
homeassistant.core: critical
|
||||||
homeassistant.setup: warning
|
homeassistant.setup: warning
|
||||||
homeassistant.loader: warning # hide custom_component warnings
|
homeassistant.loader: warning # hide custom_component warnings
|
||||||
|
@ -19,9 +17,9 @@ logs:
|
||||||
homeassistant.helpers.entity: warning
|
homeassistant.helpers.entity: warning
|
||||||
homeassistant.helpers.template: critical
|
homeassistant.helpers.template: critical
|
||||||
homeassistant.components.wemo: critical
|
homeassistant.components.wemo: critical
|
||||||
|
homeassistant.components.light: error
|
||||||
homeassistant.components.sensor: critical
|
homeassistant.components.sensor: critical
|
||||||
homeassistant.components.cloud.iot: warning
|
homeassistant.components.cloud.iot: warning
|
||||||
# homeassistant.components.http: warning
|
|
||||||
homeassistant.components.camera: warning
|
homeassistant.components.camera: warning
|
||||||
homeassistant.components.zwave: critical
|
homeassistant.components.zwave: critical
|
||||||
homeassistant.components.image_processing: warning
|
homeassistant.components.image_processing: warning
|
||||||
|
@ -39,4 +37,3 @@ logs:
|
||||||
homeassistant.components.emulated_hue: warning
|
homeassistant.components.emulated_hue: warning
|
||||||
homeassistant.components.device_tracker: warning
|
homeassistant.components.device_tracker: warning
|
||||||
homeassistant.components.camera.generic: warning
|
homeassistant.components.camera.generic: warning
|
||||||
homeassistant.components.automation.update_zwave_battery_levels: critical
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
title: My Home
|
title: My Home
|
||||||
icon: mdi:home
|
icon: mdi:home
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
- type: alarm-panel
|
||||||
cards:
|
|
||||||
- type: "custom:button-card"
|
|
||||||
entity: alarm_control_panel.home
|
entity: alarm_control_panel.home
|
||||||
icon: mdi:security
|
icon: mdi:security
|
||||||
color_type: card
|
color_type: card
|
||||||
show_state: true
|
show_state: true
|
||||||
|
name: Security
|
||||||
|
size: 20%
|
||||||
style:
|
style:
|
||||||
|
- height: 75px
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(255, 255, 255)
|
- color: rgb(255, 255, 255)
|
||||||
state:
|
state:
|
||||||
|
@ -20,12 +21,17 @@ cards:
|
||||||
color: rgb(0, 0, 255)
|
color: rgb(0, 0, 255)
|
||||||
action: more_info
|
action: more_info
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: horizontal-stack
|
||||||
|
cards:
|
||||||
|
- type: button
|
||||||
entity: climate.dining_room
|
entity: climate.dining_room
|
||||||
icon: mdi:thermometer-lines
|
icon: mdi:thermometer-lines
|
||||||
|
name: Nest
|
||||||
color_type: card
|
color_type: card
|
||||||
show_state: true
|
show_state: "on"
|
||||||
|
size: 20%
|
||||||
style:
|
style:
|
||||||
|
- height: 75px
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(255, 255, 255)
|
- color: rgb(255, 255, 255)
|
||||||
state:
|
state:
|
||||||
|
@ -40,67 +46,58 @@ cards:
|
||||||
domain: script
|
domain: script
|
||||||
action: toggle_climate
|
action: toggle_climate
|
||||||
|
|
||||||
|
- type: button
|
||||||
|
entity: binary_sensor.door_window_sensor_158d000424a6d6
|
||||||
|
icon: mdi:door
|
||||||
|
name: Front Door
|
||||||
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 20%
|
||||||
|
style:
|
||||||
|
- height: 75px
|
||||||
|
- font-weight: bold
|
||||||
|
- color: rgb(255, 255, 255)
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
color: rgb(255,0,0)
|
||||||
|
- value: "off"
|
||||||
|
color: rgb(0, 128, 0)
|
||||||
|
|
||||||
|
- type: button
|
||||||
|
entity: binary_sensor.door_window_sensor_158d00040ad8fc
|
||||||
|
icon: mdi:door
|
||||||
|
name: Back Door
|
||||||
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 20%
|
||||||
|
style:
|
||||||
|
- height: 75px
|
||||||
|
- font-weight: bold
|
||||||
|
- color: rgb(255, 255, 255)
|
||||||
|
state:
|
||||||
|
- value: "on"
|
||||||
|
color: rgb(255,0,0)
|
||||||
|
- value: "off"
|
||||||
|
color: rgb(0, 128, 0)
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Kalavala Family
|
title: Kalavala Family
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- entity: device_tracker.life360_suresh
|
- entity: device_tracker.mallika
|
||||||
name: Suresh
|
name: Mallika's Location
|
||||||
- entity: device_tracker.life360_mallika
|
- entity: device_tracker.suresh
|
||||||
name: Mallika
|
name: Suresh's Location
|
||||||
- entity: device_tracker.life360_srinika
|
- entity: device_tracker.srinika
|
||||||
name: Srinika
|
name: Srinika's Location
|
||||||
- entity: device_tracker.life360_hasika
|
- entity: device_tracker.hasika
|
||||||
name: Hasika
|
name: Hasika's Location
|
||||||
- entity: sensor.yo_mama_geocoded_location
|
- entity: input_boolean.home_mode_away
|
||||||
name: Suresh
|
name: Home Away Status
|
||||||
- entity: sensor.mallika_geocoded_location
|
|
||||||
name: Mallika
|
|
||||||
card:
|
card:
|
||||||
type: glance
|
type: glance
|
||||||
title: Kalavala Family
|
title: Kalavala Family
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: Pill Reminder
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- input_datetime.pill_reminder_time
|
|
||||||
- input_boolean.pill_on_vacation
|
|
||||||
- input_boolean.pill_taken
|
|
||||||
- input_boolean.pill_voice_notification
|
|
||||||
- binary_sensor.door_window_sensor_158d00040ad8ec
|
|
||||||
- input_label.pill_taken_at
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: 3D Printer
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- binary_sensor.octoprint_printing
|
|
||||||
- binary_sensor.octoprint_printing_error
|
|
||||||
- sensor.octoprint_current_state
|
|
||||||
- sensor.octoprint_job_percentage
|
|
||||||
- sensor.octoprint_time_elapsed
|
|
||||||
- sensor.octoprint_time_remaining
|
|
||||||
|
|
||||||
- type: glance
|
|
||||||
show_icon: true
|
|
||||||
show_name: true
|
|
||||||
show_state: true
|
|
||||||
title: Fitness
|
|
||||||
entities:
|
|
||||||
- entity: sensor.yo_mama_steps
|
|
||||||
icon: "mdi:run"
|
|
||||||
name: Suresh Steps
|
|
||||||
- entity: sensor.yo_mama_floors_ascended
|
|
||||||
icon: "mdi:run"
|
|
||||||
name: Suresh Floors Ascended
|
|
||||||
- entity: sensor.mallika_steps
|
|
||||||
icon: "mdi:run"
|
|
||||||
name: Mallika Steps
|
|
||||||
- entity: sensor.mallika_floors_ascended
|
|
||||||
icon: "mdi:run"
|
|
||||||
name: Mallika Floors Ascended
|
|
||||||
|
|
||||||
- type: entity-filter
|
- type: entity-filter
|
||||||
title: For Your Information
|
title: For Your Information
|
||||||
show_empty: false
|
show_empty: false
|
||||||
|
@ -135,6 +132,35 @@ cards:
|
||||||
type: glance
|
type: glance
|
||||||
title: FYI
|
title: FYI
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Pill Reminder
|
||||||
|
show_header_toggle: false
|
||||||
|
entities:
|
||||||
|
- input_datetime.pill_reminder_time
|
||||||
|
- input_boolean.pill_taken
|
||||||
|
- input_boolean.pill_voice_notification
|
||||||
|
- binary_sensor.door_window_sensor_158d00040ad8ec
|
||||||
|
- input_label.pill_taken_at
|
||||||
|
|
||||||
|
- type: glance
|
||||||
|
show_icon: true
|
||||||
|
show_name: true
|
||||||
|
show_state: true
|
||||||
|
title: Fitness
|
||||||
|
entities:
|
||||||
|
- entity: sensor.yo_mama_steps
|
||||||
|
icon: "mdi:run"
|
||||||
|
name: Suresh Steps
|
||||||
|
- entity: sensor.yo_mama_floors_ascended
|
||||||
|
icon: "mdi:run"
|
||||||
|
name: Suresh Floors Ascended
|
||||||
|
- entity: sensor.mallika_steps
|
||||||
|
icon: "mdi:run"
|
||||||
|
name: Mallika Steps
|
||||||
|
- entity: sensor.mallika_floors_ascended
|
||||||
|
icon: "mdi:run"
|
||||||
|
name: Mallika Floors Ascended
|
||||||
|
|
||||||
- type: conditional
|
- type: conditional
|
||||||
conditions:
|
conditions:
|
||||||
- entity: input_boolean.emergency_mode
|
- entity: input_boolean.emergency_mode
|
||||||
|
@ -180,6 +206,10 @@ cards:
|
||||||
name: Single Car Garage Door
|
name: Single Car Garage Door
|
||||||
- entity: binary_sensor.two_car_garage_door_tilt_sensor_sensor
|
- entity: binary_sensor.two_car_garage_door_tilt_sensor_sensor
|
||||||
name: Double Car Garage Door
|
name: Double Car Garage Door
|
||||||
|
- entity: binary_sensor.door_window_sensor_158d00044e5cb3
|
||||||
|
name: Master Bathroom Toilet Door Sensor
|
||||||
|
- entity: binary_sensor.door_window_sensor_158d00045ab168
|
||||||
|
name: Guest Bathroom Door Sensor
|
||||||
state_filter:
|
state_filter:
|
||||||
- "on"
|
- "on"
|
||||||
- "opened"
|
- "opened"
|
||||||
|
@ -188,22 +218,9 @@ cards:
|
||||||
type: glance
|
type: glance
|
||||||
title: Doors
|
title: Doors
|
||||||
|
|
||||||
- type: weather-forecast
|
- type: tile
|
||||||
entity: weather.dark_sky
|
entity: weather.dark_sky
|
||||||
|
|
||||||
- type: conditional
|
|
||||||
conditions:
|
|
||||||
- entity: sensor.usps_mail
|
|
||||||
state_not: "0"
|
|
||||||
card:
|
|
||||||
type: picture-entity
|
|
||||||
id: camera_usps_mail_pictures
|
|
||||||
title: USPS Mail Pictures
|
|
||||||
entity: camera.usps_mail_pictures
|
|
||||||
camera_image: camera.usps_mail_pictures
|
|
||||||
show_info: true
|
|
||||||
tap_action:
|
|
||||||
action: more-info
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Xiaomi Motion Sensors
|
title: Xiaomi Motion Sensors
|
||||||
|
@ -240,6 +257,10 @@ cards:
|
||||||
name: Two Car Garage Door
|
name: Two Car Garage Door
|
||||||
- entity: binary_sensor.door_window_sensor_158d0004248d5b
|
- entity: binary_sensor.door_window_sensor_158d0004248d5b
|
||||||
name: Single Car Garage Door
|
name: Single Car Garage Door
|
||||||
|
- entity: binary_sensor.door_window_sensor_158d00044e5cb3
|
||||||
|
name: Master Bathroom Toilet Door Sensor
|
||||||
|
- entity: binary_sensor.door_window_sensor_158d00045ab168
|
||||||
|
name: Guest Bathroom Door Sensor
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Plex
|
title: Plex
|
||||||
|
@ -312,18 +333,14 @@ cards:
|
||||||
- binary_sensor.driveway_camera_motion
|
- binary_sensor.driveway_camera_motion
|
||||||
- binary_sensor.audio_detector_sensor
|
- binary_sensor.audio_detector_sensor
|
||||||
- binary_sensor.basement_door_sensor_sensor
|
- binary_sensor.basement_door_sensor_sensor
|
||||||
- binary_sensor.downstairs_multi_sensor_sensor
|
|
||||||
- binary_sensor.front_room_multi_sensor_sensor
|
|
||||||
- binary_sensor.door_window_sensor_158d000424a6d6
|
- binary_sensor.door_window_sensor_158d000424a6d6
|
||||||
- binary_sensor.garage_door_sensor_sensor
|
- binary_sensor.garage_door_sensor_sensor
|
||||||
- binary_sensor.kitchen_motion_sensor_sensor
|
- binary_sensor.kitchen_motion_sensor_sensor
|
||||||
- binary_sensor.door_window_sensor_158d00040ad8fc # back door
|
- binary_sensor.door_window_sensor_158d00040ad8fc # back door
|
||||||
- binary_sensor.door_window_sensor_158d0004880f30 # Garage Entry Door
|
- binary_sensor.door_window_sensor_158d0004880f30 # Garage Entry Door
|
||||||
- binary_sensor.stairs_motion_sensor_sensor
|
- binary_sensor.stairs_motion_sensor_sensor
|
||||||
- binary_sensor.tv_multi_sensor_sensor
|
|
||||||
- binary_sensor.door_window_sensor_158d0004248d5b
|
- binary_sensor.door_window_sensor_158d0004248d5b
|
||||||
- binary_sensor.two_car_garage_door_tilt_sensor_sensor
|
- binary_sensor.two_car_garage_door_tilt_sensor_sensor
|
||||||
- binary_sensor.upstairs_multi_sensor_sensor
|
|
||||||
state_filter:
|
state_filter:
|
||||||
- "on"
|
- "on"
|
||||||
- "detected"
|
- "detected"
|
||||||
|
@ -334,52 +351,6 @@ cards:
|
||||||
title: Motion Sensors
|
title: Motion Sensors
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
||||||
- type: conditional
|
|
||||||
conditions:
|
|
||||||
- entity: sensor.season
|
|
||||||
state: "spring"
|
|
||||||
card:
|
|
||||||
type: vertical-stack
|
|
||||||
cards:
|
|
||||||
- type: horizontal-stack
|
|
||||||
cards:
|
|
||||||
- type: gauge
|
|
||||||
name: Pollen Today
|
|
||||||
unit: "%"
|
|
||||||
entity: sensor.allergy_index_today
|
|
||||||
max: 12.0
|
|
||||||
severity:
|
|
||||||
green: 0
|
|
||||||
yellow: 4
|
|
||||||
red: 7
|
|
||||||
- type: gauge
|
|
||||||
name: Pollen Tomorrow
|
|
||||||
unit: "%"
|
|
||||||
entity: sensor.allergy_index_tomorrow
|
|
||||||
max: 12.0
|
|
||||||
severity:
|
|
||||||
green: 0
|
|
||||||
yellow: 4
|
|
||||||
red: 7
|
|
||||||
- type: horizontal-stack
|
|
||||||
cards:
|
|
||||||
- type: gauge
|
|
||||||
name: Asthma Today
|
|
||||||
unit: "%"
|
|
||||||
entity: sensor.asthma_index_forecasted_average
|
|
||||||
severity:
|
|
||||||
green: 0
|
|
||||||
yellow: 4
|
|
||||||
red: 7
|
|
||||||
- type: gauge
|
|
||||||
name: Asthma Tomorrow
|
|
||||||
unit: "%"
|
|
||||||
entity: sensor.asthma_index_tomorrow
|
|
||||||
severity:
|
|
||||||
green: 0
|
|
||||||
yellow: 4
|
|
||||||
red: 7
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Motion Counters
|
title: Motion Counters
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
|
@ -2,22 +2,28 @@ title: Lights
|
||||||
icon: mdi:lightbulb-on
|
icon: mdi:lightbulb-on
|
||||||
cards:
|
cards:
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Upstairs
|
title: Master Bedroom
|
||||||
show_header_toggle: true
|
show_header_toggle: true
|
||||||
entities:
|
entities:
|
||||||
- light.master_bedroom_lights
|
# - light.master_bedroom_lights
|
||||||
|
- switch.master_bedroom_fan
|
||||||
|
- switch.master_bedroom_lights
|
||||||
- entity: light.master_bedroom_1
|
- entity: light.master_bedroom_1
|
||||||
name: Suresh's Bedside Light
|
name: Suresh's Bedside Light
|
||||||
- entity: light.master_bedroom_2
|
- entity: light.master_bedroom_2
|
||||||
name: Mallika's Bedside Light
|
name: Mallika's Bedside Light
|
||||||
- entity: switch.kids_bedroom
|
|
||||||
name: Hasika's Bedroom
|
# header:
|
||||||
- entity: switch.kids_bed_accent
|
# type: picture
|
||||||
name: Hasika's Bed Accent Lights
|
# image: "https://www.home-assistant.io/images/lovelace/header-footer/balloons-header.png"
|
||||||
- entity: switch.guest_bedroom
|
|
||||||
name: Srinika's Bedroom
|
- type: entities
|
||||||
- entity: switch.prayer_room
|
title: Master Bathroom
|
||||||
name: Study Room
|
show_header_toggle: true
|
||||||
|
entities:
|
||||||
|
- switch.master_bathroom_toilet_light
|
||||||
|
- switch.master_bathroom_toilet_exhaust
|
||||||
|
- switch.master_bathroom_shower_exhaust
|
||||||
- entity: light.master_bathroom_lights
|
- entity: light.master_bathroom_lights
|
||||||
name: Master Bathroom Lights
|
name: Master Bathroom Lights
|
||||||
|
|
||||||
|
@ -29,11 +35,49 @@ cards:
|
||||||
- entity: switch.wemoswitch1
|
- entity: switch.wemoswitch1
|
||||||
name: Office Room Accent Lights
|
name: Office Room Accent Lights
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Srinika Room
|
||||||
|
show_header_toggle: true
|
||||||
|
entities:
|
||||||
|
- switch.srinika_bedroom
|
||||||
|
- switch.srinika_bedroom_fan
|
||||||
|
- switch.srinika_bedroom_fan_light
|
||||||
|
- light.srinika_led_dimmer_switch
|
||||||
|
- switch.srinika_bedroom_closet
|
||||||
|
- switch.srinika_bedroom_accent_lights
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Hasika Room
|
||||||
|
show_header_toggle: true
|
||||||
|
entities:
|
||||||
|
- switch.hasika_bedroom
|
||||||
|
- switch.hasika_bedroom_fan
|
||||||
|
- switch.hasika_bedroom_fan_light
|
||||||
|
- light.hasika_led_dimmer_switch
|
||||||
|
- switch.hasika_bedroom_closet
|
||||||
|
- switch.hasika_bed_accent
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Guest Room
|
||||||
|
show_header_toggle: true
|
||||||
|
entities:
|
||||||
|
- switch.guest_room
|
||||||
|
- switch.guest_bedroom_fan
|
||||||
|
- switch.guest_bedroom_fan_light
|
||||||
|
- light.guest_bedroom_led_dimmer_switch
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Guest/Kids Bathroom
|
||||||
|
show_header_toggle: true
|
||||||
|
entities:
|
||||||
|
- switch.guest_bathroom_exhaust
|
||||||
|
- switch.guest_bathroom_lights
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Family Room
|
title: Family Room
|
||||||
show_header_toggle: true
|
show_header_toggle: true
|
||||||
entities:
|
entities:
|
||||||
- switch.kitchen
|
- switch.kitchen_switch
|
||||||
- light.family_room_lights
|
- light.family_room_lights
|
||||||
- light.hue_color_lamp_1
|
- light.hue_color_lamp_1
|
||||||
- light.hue_color_lamp_2
|
- light.hue_color_lamp_2
|
||||||
|
@ -57,11 +101,11 @@ cards:
|
||||||
title: TV Power Strip
|
title: TV Power Strip
|
||||||
show_header_toggle: true
|
show_header_toggle: true
|
||||||
entities:
|
entities:
|
||||||
- entity: switch.plug_1
|
- entity: switch.chromecast_monitor
|
||||||
name: Monitor
|
name: Monitor
|
||||||
- entity: switch.plug_2
|
- entity: switch.sharp_tv
|
||||||
name: Sharp TV
|
name: Sharp TV
|
||||||
- entity: switch.plug_3
|
- entity: switch.bose_audio
|
||||||
name: Bose Audio
|
name: Bose Audio
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
|
@ -82,13 +126,6 @@ cards:
|
||||||
- entity: switch.tasmota_outlet_2
|
- entity: switch.tasmota_outlet_2
|
||||||
name: Tasmota Outlet 2
|
name: Tasmota Outlet 2
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: Fragrance Outlets
|
|
||||||
show_header_toggle: true
|
|
||||||
entities:
|
|
||||||
- switch.downstairs_fragrance
|
|
||||||
- switch.upstairs_fragrance
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Garage
|
title: Garage
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
@ -102,3 +139,44 @@ cards:
|
||||||
entities:
|
entities:
|
||||||
- switch.frontyard_light
|
- switch.frontyard_light
|
||||||
- switch.backyard_light
|
- switch.backyard_light
|
||||||
|
|
||||||
|
# - type: entities
|
||||||
|
# title: LED Indicators
|
||||||
|
# show_header_toggle: false
|
||||||
|
# entities:
|
||||||
|
# - switch.3d_printer_led
|
||||||
|
# - switch.basement_left_led
|
||||||
|
# - switch.basement_right_led
|
||||||
|
# - switch.front_room_led
|
||||||
|
# - switch.garage_led
|
||||||
|
# - switch.garage_shop_lights_led
|
||||||
|
# - switch.guest_bathroom_exhaust_led
|
||||||
|
# - switch.guest_bathroom_lights_led
|
||||||
|
# - switch.guest_bedroom_fan_led
|
||||||
|
# - switch.guest_bedroom_fan_light_led
|
||||||
|
# - switch.guest_bedroom_lamp_led
|
||||||
|
# - switch.guest_bedroom_led_dimmer_switch_led
|
||||||
|
# - switch.hasika_bed_accent_lights_led
|
||||||
|
# - switch.hasika_bedroom_closet_led
|
||||||
|
# - switch.hasika_bedroom_fan_led
|
||||||
|
# - switch.hasika_bedroom_fan_light_led
|
||||||
|
# - switch.hasika_bedroom_lamp_led
|
||||||
|
# - switch.hasika_led_dimmer_switch_led
|
||||||
|
# - switch.kitchen_switch_led
|
||||||
|
# - switch.master_bathroom_lights
|
||||||
|
# - switch.master_bathroom_shower_exhaust_led
|
||||||
|
# - switch.master_bathroom_toilet_exhaust_led
|
||||||
|
# - switch.master_bathroom_toilet_light_led
|
||||||
|
# - switch.master_bedroom_accent_lights_led
|
||||||
|
# - switch.master_bedroom_fan_led
|
||||||
|
# - switch.master_bedroom_lights_led
|
||||||
|
# - switch.office_room_led
|
||||||
|
# - switch.srinika_bed_accent_lights_led
|
||||||
|
# - switch.srinika_bedroom_closet_led
|
||||||
|
# - switch.srinika_bedroom_fan_led
|
||||||
|
# - switch.srinika_bedroom_fan_light_led
|
||||||
|
# - switch.srinika_bedroom_lamp_led
|
||||||
|
# - switch.srinika_led_dimmer_switch_led
|
||||||
|
# - switch.tp_link_power_strip_b5e2_led
|
||||||
|
# - switch.tp_link_smart_plug_25ba_led
|
||||||
|
# - switch.upstairs_fragrance_led
|
|
@ -1,110 +1,95 @@
|
||||||
title: Camera Live
|
title: Camera Live
|
||||||
icon: mdi:cctv
|
icon: mdi:cctv
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
- type: vertical-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Porch
|
name: RESET CAMERA
|
||||||
entity: input_label.current_stream
|
entity: input_label.current_stream
|
||||||
icon: mdi:cctv
|
icon: mdi:cctv
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: false
|
||||||
|
size: 5%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
state:
|
state:
|
||||||
- value: "frontyard"
|
- value: "frontyard"
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
action: service
|
tap_action:
|
||||||
service:
|
action: call-service
|
||||||
domain: script
|
service: script.reset_camera_stream
|
||||||
action: stream_frontdoor_camera_to_chromecast
|
- type: horizontal-stack
|
||||||
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Driveway
|
|
||||||
entity: input_label.current_stream
|
|
||||||
icon: mdi:cctv
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: rgb(0, 0, 5)
|
|
||||||
state:
|
|
||||||
- value: "driveway"
|
|
||||||
color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: stream_driveway_camera_to_chromecast
|
|
||||||
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Patio
|
|
||||||
entity: input_label.current_stream
|
|
||||||
icon: mdi:cctv
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: rgb(0, 0, 5)
|
|
||||||
state:
|
|
||||||
- value: "patio"
|
|
||||||
color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: stream_patio_camera_to_chromecast
|
|
||||||
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Porch
|
name: Porch
|
||||||
entity: input_label.current_stream
|
entity: input_label.current_stream
|
||||||
icon: mdi:cctv
|
icon: mdi:cctv
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: false
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
state:
|
state:
|
||||||
- value: "porch"
|
- value: "porch"
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
|
tap_action:
|
||||||
action: service
|
action: service
|
||||||
service:
|
service: script.stream_porch_camera_to_chromecast
|
||||||
domain: script
|
|
||||||
action: stream_porch_camera_to_chromecast
|
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
|
name: Driveway
|
||||||
|
entity: input_label.current_stream
|
||||||
|
icon: mdi:cctv
|
||||||
|
color_type: card
|
||||||
|
show_state: false
|
||||||
|
style:
|
||||||
|
- font-weight: bold
|
||||||
|
- color: rgb(0, 0, 5)
|
||||||
|
state:
|
||||||
|
- value: "driveway"
|
||||||
|
color: var(--primary-color)
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: script.stream_driveway_camera_to_chromecast
|
||||||
|
|
||||||
|
- type: button
|
||||||
|
name: Patio
|
||||||
|
entity: input_label.current_stream
|
||||||
|
icon: mdi:cctv
|
||||||
|
color_type: card
|
||||||
|
show_state: false
|
||||||
|
style:
|
||||||
|
- font-weight: bold
|
||||||
|
- color: rgb(0, 0, 5)
|
||||||
|
state:
|
||||||
|
- value: "patio"
|
||||||
|
color: var(--primary-color)
|
||||||
|
tap_action:
|
||||||
|
action: call-service
|
||||||
|
service: script.stream_patio_camera_to_chromecast
|
||||||
|
|
||||||
|
- type: button
|
||||||
name: Playarea
|
name: Playarea
|
||||||
entity: input_label.current_stream
|
entity: input_label.current_stream
|
||||||
icon: mdi:cctv
|
icon: mdi:cctv
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: false
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
state:
|
state:
|
||||||
- value: "playarea"
|
- value: "playarea"
|
||||||
color: var(--primary-color)
|
color: var(--primary-color)
|
||||||
action: service
|
tap_action:
|
||||||
service:
|
action: call-service
|
||||||
domain: script
|
service: script.stream_playarea_camera_to_chromecast
|
||||||
action: stream_playarea_camera_to_chromecast
|
|
||||||
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: RESET CAMERA
|
|
||||||
entity: input_label.current_stream
|
|
||||||
icon: mdi:cctv
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: rgb(0, 0, 5)
|
|
||||||
state:
|
|
||||||
- value: "frontyard"
|
|
||||||
color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: reset_camera_stream
|
|
||||||
|
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
id: camera_frontdoor_camera
|
id: camera_frontdoor_camera
|
||||||
title: Frontdoor Camera
|
title: Frontdoor Camera
|
||||||
entity: camera.frontdoor_camera
|
entity: camera.frontdoor_camera
|
||||||
camera_image: camera.frontdoor_camera
|
camera_image: camera.frontdoor_camera
|
||||||
# camera_view: live
|
|
||||||
show_info: true
|
show_info: true
|
||||||
tap_action:
|
tap_action:
|
||||||
action: more-info
|
action: more-info
|
||||||
|
@ -148,28 +133,27 @@ cards:
|
||||||
- switch.backyard_light
|
- switch.backyard_light
|
||||||
- binary_sensor.playarea_camera_motion
|
- binary_sensor.playarea_camera_motion
|
||||||
|
|
||||||
- type: picture-glance
|
# - type: picture-glance
|
||||||
id: camera_garage_camera
|
# id: camera_garage_camera
|
||||||
title: Garage Camera
|
# title: Garage Camera
|
||||||
entity: camera.garage_camera
|
# entity: camera.garage_camera
|
||||||
camera_image: camera.garage_camera
|
# camera_image: camera.garage_camera
|
||||||
show_info: true
|
# show_info: true
|
||||||
tap_action:
|
# tap_action:
|
||||||
action: more-info
|
# action: more-info
|
||||||
entities:
|
# entities:
|
||||||
- switch.garage
|
# - switch.garage
|
||||||
|
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
id: camera_3dprinter_camera
|
id: camera_front_camera
|
||||||
title: 3D Printer Camera
|
title: Front Camera
|
||||||
entity: camera.3d_printer_camera
|
entity: camera.amcrest_camera
|
||||||
camera_image: camera.3d_printer_camera
|
camera_image: camera.amcrest_camera
|
||||||
show_info: true
|
show_info: true
|
||||||
tap_action:
|
tap_action:
|
||||||
action: more-info
|
action: more-info
|
||||||
entities:
|
entities:
|
||||||
- binary_sensor.motion_sensor_158d00016c2d0e
|
- switch.basement_left
|
||||||
- binary_sensor.octoprint_printing
|
|
||||||
|
|
||||||
- type: picture-glance
|
- type: picture-glance
|
||||||
id: porch_camera
|
id: porch_camera
|
||||||
|
@ -182,3 +166,15 @@ cards:
|
||||||
entities:
|
entities:
|
||||||
- binary_sensor.porch_motion
|
- binary_sensor.porch_motion
|
||||||
- switch.frontyard_light
|
- switch.frontyard_light
|
||||||
|
|
||||||
|
- type: picture-glance
|
||||||
|
id: garage_camera
|
||||||
|
title: Garage Camera
|
||||||
|
entity: camera.garage
|
||||||
|
camera_image: camera.garage
|
||||||
|
show_info: true
|
||||||
|
tap_action:
|
||||||
|
action: more-info
|
||||||
|
entities:
|
||||||
|
- switch.garage
|
||||||
|
- switch.garage_shop_lights
|
||||||
|
|
|
@ -68,17 +68,17 @@ cards:
|
||||||
title: Image Processing
|
title: Image Processing
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- entity: image_processing.tensorflow_frontdoor_camera
|
- entity: image_processing.doods_frontdoor_camera
|
||||||
name: Front Door Camera
|
name: Front Door Camera
|
||||||
- entity: image_processing.tensorflow_driveway_camera
|
- entity: image_processing.doods_driveway_camera
|
||||||
name: Driveway Camera
|
name: Driveway Camera
|
||||||
- entity: image_processing.tensorflow_garage_camera
|
- entity: image_processing.doods_garage
|
||||||
name: Garage Camera
|
name: Garage Camera
|
||||||
- entity: image_processing.tensorflow_patio_camera
|
- entity: image_processing.doods_patio_camera
|
||||||
name: Patio Camera
|
name: Patio Camera
|
||||||
- entity: image_processing.tensorflow_playarea_camera
|
- entity: image_processing.doods_playarea_camera
|
||||||
name: Playarea Camera
|
name: Playarea Camera
|
||||||
- entity: image_processing.tensorflow_3d_printer_camera
|
- entity: image_processing.doods_3d_printer_camera
|
||||||
name: 3D Printer Camera
|
name: 3D Printer Camera
|
||||||
- entity: image_processing.tensorflow_porch_camera
|
- entity: image_processing.doods_porch_camera
|
||||||
name: Porch Camera
|
name: Porch Camera
|
||||||
|
|
|
@ -40,7 +40,7 @@ cards:
|
||||||
title: Tesla Car
|
title: Tesla Car
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- device_tracker.mahasri_tesla_location_tracker
|
# - device_tracker.mahasri_tesla_location_tracker
|
||||||
- binary_sensor.mahasri_tesla_online_sensor
|
- binary_sensor.mahasri_tesla_online_sensor
|
||||||
- binary_sensor.mahasri_tesla_parking_brake_sensor
|
- binary_sensor.mahasri_tesla_parking_brake_sensor
|
||||||
- lock.mahasri_tesla_door_lock
|
- lock.mahasri_tesla_door_lock
|
||||||
|
|
|
@ -63,12 +63,12 @@ cards:
|
||||||
- sensor.esxi_total_ram
|
- sensor.esxi_total_ram
|
||||||
- sensor.esxi_used_ram
|
- sensor.esxi_used_ram
|
||||||
|
|
||||||
- type: entities
|
# - type: entities
|
||||||
title: Windows Server
|
# title: Windows Server
|
||||||
show_header_toggle: false
|
# show_header_toggle: false
|
||||||
entities:
|
# entities:
|
||||||
- sensor.windows_server
|
# - sensor.windows_server
|
||||||
- sensor.windows_server_cpu_usage
|
# - sensor.windows_server_cpu_usage
|
||||||
- sensor.windows_server_idle_time
|
# - sensor.windows_server_idle_time
|
||||||
- sensor.windows_server_memory_available
|
# - sensor.windows_server_memory_available
|
||||||
- sensor.windows_server_memory_used
|
# - sensor.windows_server_memory_used
|
||||||
|
|
|
@ -1,21 +1,6 @@
|
||||||
title: Multi Room Audio & TTS
|
title: Multi Room Audio & TTS
|
||||||
icon: mdi:television
|
icon: mdi:television
|
||||||
cards:
|
cards:
|
||||||
# - type: entities
|
|
||||||
# title: Snapcast Server Commands
|
|
||||||
# show_header_toggle: false
|
|
||||||
# entities:
|
|
||||||
# - entity: input_select.snapcast_server
|
|
||||||
# name: Snapcast Server Command
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: Raspberry Pi Commands
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- entity: input_select.raspberry_pis
|
|
||||||
name: Select a Raspberry Pi
|
|
||||||
- entity: input_select.rpi_commands
|
|
||||||
name: Select Command To Execute
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Raspberry Pi Scripts
|
title: Raspberry Pi Scripts
|
||||||
|
@ -42,13 +27,10 @@ cards:
|
||||||
title: Media Players
|
title: Media Players
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
# - media_player.denon_avr_x2400h
|
|
||||||
# - media_player.gstreamer
|
|
||||||
# - media_player.mpd
|
|
||||||
- media_player.attic_tv
|
- media_player.attic_tv
|
||||||
- media_player.living_room
|
- media_player.living_room # sonos
|
||||||
- media_player.upstairs
|
- media_player.upstairs # sonos
|
||||||
# - media_player.my_denon_receiver
|
- media_player.smart_tv
|
||||||
|
|
||||||
- type: vertical-stack
|
- type: vertical-stack
|
||||||
cards:
|
cards:
|
||||||
|
@ -56,26 +38,8 @@ cards:
|
||||||
entity: media_player.living_room
|
entity: media_player.living_room
|
||||||
- type: media-control
|
- type: media-control
|
||||||
entity: media_player.upstairs
|
entity: media_player.upstairs
|
||||||
|
|
||||||
# - type: media-control
|
|
||||||
# entity: media_player.denon_avr_x2400h
|
|
||||||
|
|
||||||
# - type: media-control
|
|
||||||
# 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
|
|
||||||
# entity: media_player.my_denon_receiver
|
|
||||||
# - type: entities
|
|
||||||
# title: Snapcast Clients
|
|
||||||
# show_header_toggle: false
|
|
||||||
# entities:
|
|
||||||
# - media_player.snapcast_client_b827eb011e00
|
|
||||||
# - media_player.snapcast_client_b827eb4445b1
|
|
||||||
# - media_player.snapcast_client_b827eb505e2d
|
|
||||||
# - media_player.snapcast_client_b827eba8e7ef
|
|
||||||
# - media_player.snapcast_client_b827ebaa08f7
|
|
||||||
|
|
|
@ -5,11 +5,13 @@ cards:
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Automatic Lights
|
name: Automatic Lights
|
||||||
entity: input_boolean.light_automations
|
entity: input_boolean.light_automations
|
||||||
icon: mdi:lightbulb-on
|
icon: mdi:lightbulb-on
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -21,11 +23,13 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: light_automations
|
action: light_automations
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Do Not Disturb
|
name: Do Not Disturb
|
||||||
entity: input_boolean.do_not_disturb
|
entity: input_boolean.do_not_disturb
|
||||||
icon: mdi:do-not-disturb
|
icon: mdi:minus-circle
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -37,11 +41,15 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: do_not_disturb
|
action: do_not_disturb
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: horizontal-stack
|
||||||
|
cards:
|
||||||
|
- type: button
|
||||||
name: Home Sounds
|
name: Home Sounds
|
||||||
entity: input_boolean.voice_notifications
|
entity: input_boolean.voice_notifications
|
||||||
icon: mdi:volume-high
|
icon: mdi:volume-high
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -53,11 +61,13 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: voice_notifications
|
action: voice_notifications
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Location Alerts
|
name: Location Alerts
|
||||||
entity: input_boolean.zone_alerts
|
entity: input_boolean.zone_alerts
|
||||||
icon: mdi:map-marker
|
icon: mdi:map-marker
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -71,11 +81,13 @@ cards:
|
||||||
|
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Family Movie
|
name: Family Movie
|
||||||
entity: input_boolean.movie_time
|
entity: input_boolean.movie_time
|
||||||
icon: mdi:filmstrip
|
icon: mdi:filmstrip
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -87,11 +99,13 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: movie_time
|
action: movie_time
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Hourly Report
|
name: Hourly Report
|
||||||
entity: input_boolean.hourly_report
|
entity: input_boolean.hourly_report
|
||||||
icon: mdi:timer-sand
|
icon: mdi:timer-sand
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -103,11 +117,15 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: hourly_report
|
action: hourly_report
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: horizontal-stack
|
||||||
|
cards:
|
||||||
|
- type: button
|
||||||
name: Nightly Report
|
name: Nightly Report
|
||||||
entity: input_boolean.nightly_report
|
entity: input_boolean.nightly_report
|
||||||
icon: mdi:weather-night
|
icon: mdi:weather-night
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -119,11 +137,13 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: nightly_report
|
action: nightly_report
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Good Weather
|
name: Go Outside
|
||||||
entity: input_boolean.enjoyable_weather_reminders
|
entity: input_boolean.enjoyable_weather_reminders
|
||||||
icon: mdi:weather-windy-variant
|
icon: mdi:weather-windy-variant
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -137,11 +157,13 @@ cards:
|
||||||
|
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Working in Office
|
name: Working in Office
|
||||||
entity: input_boolean.working_in_office_room
|
entity: input_boolean.working_in_office_room
|
||||||
icon: mdi:office-building
|
icon: mdi:office-building
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -153,11 +175,13 @@ cards:
|
||||||
domain: input_boolean
|
domain: input_boolean
|
||||||
action: working_in_office_room
|
action: working_in_office_room
|
||||||
|
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Working in Garage
|
name: Working in Garage
|
||||||
entity: input_boolean.working_in_garage
|
entity: input_boolean.working_in_garage
|
||||||
icon: mdi:garage-alert
|
icon: mdi:garage-alert
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 10%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -171,11 +195,13 @@ cards:
|
||||||
|
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
name: Stream Cameras To Chromecast
|
name: Stream Cameras To Chromecast
|
||||||
entity: input_boolean.stream_camera2chromecast
|
entity: input_boolean.stream_camera2chromecast
|
||||||
icon: mdi:cctv
|
icon: mdi:cctv
|
||||||
color_type: card
|
color_type: card
|
||||||
|
show_state: "on"
|
||||||
|
size: 5%
|
||||||
style:
|
style:
|
||||||
- font-weight: bold
|
- font-weight: bold
|
||||||
- color: rgb(0, 0, 5)
|
- color: rgb(0, 0, 5)
|
||||||
|
@ -194,6 +220,36 @@ cards:
|
||||||
- input_number.calendar_remind_before_days
|
- input_number.calendar_remind_before_days
|
||||||
- input_number.battery_alert_threshold
|
- input_number.battery_alert_threshold
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Garage Timers
|
||||||
|
show_header_toggle: false
|
||||||
|
entities:
|
||||||
|
- input_number.garage_lights
|
||||||
|
- input_number.garage_shop_lights
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Master Suite Timers
|
||||||
|
show_header_toggle: false
|
||||||
|
entities:
|
||||||
|
- input_number.master_bathroom_lights
|
||||||
|
- input_number.master_bathroom_toilet_lights
|
||||||
|
- input_number.master_bathroom_shower_exhaust_timer_duration
|
||||||
|
- input_number.master_bathroom_toilet_exhaust_timer_duration
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Kids Bathroom Timers
|
||||||
|
show_header_toggle: false
|
||||||
|
entities:
|
||||||
|
- input_number.guest_bathroom_lights
|
||||||
|
- input_number.guest_bathroom_exhaust_timer_duration
|
||||||
|
|
||||||
|
- type: entities
|
||||||
|
title: Kids Bedroom Closet Timers
|
||||||
|
show_header_toggle: false
|
||||||
|
entities:
|
||||||
|
- input_number.srinika_bedroom_closet_lights
|
||||||
|
- input_number.hasika_bedroom_closet_lights
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Alerts & Notifications
|
title: Alerts & Notifications
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
title: Raspberry PI
|
|
||||||
icon: mdi:pig
|
|
||||||
cards:
|
|
||||||
- type: horizontal-stack
|
|
||||||
cards:
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Query Wifi
|
|
||||||
entity: inout_boolean.dummy
|
|
||||||
icon: mdi:wifi
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: query_wifi_info
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Query Disk
|
|
||||||
entity: inout_boolean.dummy
|
|
||||||
icon: mdi:harddisk
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: query_disk_info
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: Raspberry Pi Commands
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- input_select.raspberry_pis
|
|
||||||
- input_select.rpi_commands
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: WiFi Signal Strength
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- sensor.kitchen_pi_signal_level
|
|
||||||
- sensor.family_room_pi_signal_level
|
|
||||||
- sensor.front_room_pi_signal_level
|
|
||||||
- sensor.garage_pi_signal_level
|
|
||||||
- sensor.guest_1_pi_signal_level
|
|
||||||
- sensor.guest_2_pi_signal_level
|
|
||||||
- sensor.master_bedroom_pi_signal_level
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: WiFi Link Quality
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- sensor.kitchen_pi_link_quality
|
|
||||||
- sensor.family_room_pi_link_quality
|
|
||||||
- sensor.front_room_pi_link_quality
|
|
||||||
- sensor.garage_pi_link_quality
|
|
||||||
- sensor.guest_1_pi_link_quality
|
|
||||||
- sensor.guest_2_pi_link_quality
|
|
||||||
- sensor.master_bedroom_pi_link_quality
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: RPi Disk Available
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- sensor.kitchen_pi_available_disk
|
|
||||||
- sensor.family_room_pi_available_disk
|
|
||||||
- sensor.front_room_pi_available_disk
|
|
||||||
- sensor.garage_pi_available_disk
|
|
||||||
- sensor.guest_1_pi_available_disk
|
|
||||||
- sensor.guest_2_pi_available_disk
|
|
||||||
- sensor.master_bedroom_pi_available_disk
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: RPi Disk Used
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- sensor.kitchen_pi_disk_used
|
|
||||||
- sensor.family_room_pi_disk_used
|
|
||||||
- sensor.front_room_pi_disk_used
|
|
||||||
- sensor.garage_pi_disk_used
|
|
||||||
- sensor.guest_1_pi_disk_used
|
|
||||||
- sensor.guest_2_pi_disk_used
|
|
||||||
- sensor.master_bedroom_pi_disk_used
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: RPi Scripts
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- script.query_disk_info
|
|
||||||
- script.query_wifi_info
|
|
||||||
- script.restart_all_raspberrypis
|
|
||||||
- script.restart_all_snapclients
|
|
||||||
- script.shutdown_all_raspberrypis
|
|
|
@ -1,34 +1,6 @@
|
||||||
title: Scripts
|
title: Scripts
|
||||||
icon: mdi:script
|
icon: mdi:script
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
|
||||||
cards:
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Update HASS
|
|
||||||
entity: inout_boolean.dummy
|
|
||||||
icon: mdi:home-assistant
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: update_hass
|
|
||||||
|
|
||||||
- type: "custom:button-card"
|
|
||||||
name: Restart HASS
|
|
||||||
entity: inout_boolean.dummy
|
|
||||||
icon: mdi:home-assistant
|
|
||||||
color_type: card
|
|
||||||
style:
|
|
||||||
- font-weight: bold
|
|
||||||
- color: var(--primary-color)
|
|
||||||
action: service
|
|
||||||
service:
|
|
||||||
domain: script
|
|
||||||
action: restart_hass
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Notification Scripts
|
title: Notification Scripts
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
|
@ -27,10 +27,7 @@ cards:
|
||||||
title: Zone Based Alerts
|
title: Zone Based Alerts
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- automation.alert_private_zone_enter
|
|
||||||
- automation.alert_private_zone_leaves
|
|
||||||
- automation.alert_when_everyone_is_away
|
- automation.alert_when_everyone_is_away
|
||||||
- automation.alert_when_moving
|
|
||||||
- automation.alert_when_someone_enters_a_zone
|
- automation.alert_when_someone_enters_a_zone
|
||||||
- automation.alert_when_someone_leaves_a_zone
|
- automation.alert_when_someone_leaves_a_zone
|
||||||
- automation.send_a_message_as_i_get_closer_to_home
|
- automation.send_a_message_as_i_get_closer_to_home
|
||||||
|
@ -40,21 +37,14 @@ cards:
|
||||||
title: Misc. Notifications
|
title: Misc. Notifications
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- automation.notify_charger_switch_state
|
|
||||||
- automation.notify_charging_status
|
|
||||||
- automation.notify_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_thermostat_state_change
|
- automation.notify_thermostat_state_change
|
||||||
- automation.notify_usps_mail
|
|
||||||
- automation.notify_usps_packages
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Timer Automations
|
title: Timer Automations
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- automation.cancel_wfh_timer_when_suresh_leaves_home
|
|
||||||
- automation.family_room_motion_timer
|
- automation.family_room_motion_timer
|
||||||
- automation.family_room_timer_elapsed
|
- automation.family_room_timer_elapsed
|
||||||
- automation.frontroom_motion_timer
|
- automation.frontroom_motion_timer
|
||||||
|
@ -64,22 +54,6 @@ cards:
|
||||||
- automation.master_bedroom_timer_elapsed
|
- automation.master_bedroom_timer_elapsed
|
||||||
- automation.officeroom_motion_timer
|
- automation.officeroom_motion_timer
|
||||||
- automation.officeroom_timer_elapsed
|
- automation.officeroom_timer_elapsed
|
||||||
- automation.timer_elapsed_take_a_walk
|
|
||||||
- automation.upstairs_aroma_timer_elapsed
|
|
||||||
- automation.upstairs_aroma_timer_finish
|
|
||||||
- automation.upstairs_aroma_timer_start
|
|
||||||
- automation.wfh_timer_start
|
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: 3D Printer Automations
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- automation.3d_print_send_telegram_pictures
|
|
||||||
- automation.3d_print_job_finished
|
|
||||||
- automation.3d_print_progress_update
|
|
||||||
- automation.3d_print_state_changed
|
|
||||||
- automation.3d_print_notify_printer_state
|
|
||||||
- automation.3d_print_notify_printer_error
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Garage Automations
|
title: Garage Automations
|
||||||
|
@ -121,7 +95,6 @@ cards:
|
||||||
title: Light Automations
|
title: Light Automations
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- automation.restore_familyroom_lights
|
|
||||||
- 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
|
||||||
|
@ -197,17 +170,8 @@ cards:
|
||||||
- automation.notify_home_status_when_away
|
- automation.notify_home_status_when_away
|
||||||
- automation.home_mode_away_on
|
- automation.home_mode_away_on
|
||||||
- automation.hourly_report_during_day_time
|
- automation.hourly_report_during_day_time
|
||||||
- automation.check_wi_fi_status_of_iphones_at_home
|
|
||||||
- automation.night_bedtime_report
|
- automation.night_bedtime_report
|
||||||
|
|
||||||
- type: entities
|
|
||||||
title: Raspberry Pi Automations
|
|
||||||
show_header_toggle: false
|
|
||||||
entities:
|
|
||||||
- automation.query_rpi_disk_data
|
|
||||||
- automation.query_rpi_wifi_data
|
|
||||||
- automation.raspberry_pi_command
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: Media Player Automations
|
title: Media Player Automations
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
|
|
|
@ -6,7 +6,7 @@ cards:
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.kalavala_nas_smart_status_drive_0_1
|
entity: sensor.kalavala_nas_smart_status_drive_0_1
|
||||||
name: Drive 1
|
name: Drive 1
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -20,7 +20,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.kalavala_nas_smart_status_drive_0_2
|
entity: sensor.kalavala_nas_smart_status_drive_0_2
|
||||||
name: Drive 2
|
name: Drive 2
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -34,7 +34,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.kalavala_nas_smart_status_drive_0_3
|
entity: sensor.kalavala_nas_smart_status_drive_0_3
|
||||||
name: Drive 3
|
name: Drive 3
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -48,7 +48,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.kalavala_nas_smart_status_drive_0_4
|
entity: sensor.kalavala_nas_smart_status_drive_0_4
|
||||||
name: Drive 4
|
name: Drive 4
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -115,7 +115,7 @@ cards:
|
||||||
cards:
|
cards:
|
||||||
- type: horizontal-stack
|
- type: horizontal-stack
|
||||||
cards:
|
cards:
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.mahasri_nas_smart_status_drive_0_1
|
entity: sensor.mahasri_nas_smart_status_drive_0_1
|
||||||
name: Drive 1
|
name: Drive 1
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -129,7 +129,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.mahasri_nas_smart_status_drive_0_2
|
entity: sensor.mahasri_nas_smart_status_drive_0_2
|
||||||
name: Drive 2
|
name: Drive 2
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -143,7 +143,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.mahasri_nas_smart_status_drive_0_3
|
entity: sensor.mahasri_nas_smart_status_drive_0_3
|
||||||
name: Drive 3
|
name: Drive 3
|
||||||
color_type: card
|
color_type: card
|
||||||
|
@ -157,7 +157,7 @@ cards:
|
||||||
- value: "FAIL"
|
- value: "FAIL"
|
||||||
color: rgb(255, 0, 0)
|
color: rgb(255, 0, 0)
|
||||||
action: more_info
|
action: more_info
|
||||||
- type: "custom:button-card"
|
- type: button
|
||||||
entity: sensor.mahasri_nas_smart_status_drive_0_4
|
entity: sensor.mahasri_nas_smart_status_drive_0_4
|
||||||
name: Drive 4
|
name: Drive 4
|
||||||
color_type: card
|
color_type: card
|
||||||
|
|
|
@ -42,12 +42,10 @@ cards:
|
||||||
title: Print Times
|
title: Print Times
|
||||||
show_header_toggle: false
|
show_header_toggle: false
|
||||||
entities:
|
entities:
|
||||||
- entity: sensor.time_elapsed
|
- entity: sensor.octoprint_print_start
|
||||||
name: Elapsed
|
name: Print Started
|
||||||
- entity: sensor.time_estimated
|
- entity: sensor.octoprint_print_end_eta
|
||||||
name: Estimated
|
name: Completed ETA
|
||||||
- entity: sensor.print_completion
|
|
||||||
name: Print Completion
|
|
||||||
|
|
||||||
- type: entities
|
- type: entities
|
||||||
title: 3D Printer Settings
|
title: 3D Printer Settings
|
||||||
|
|
82
mos_sub.py
82
mos_sub.py
|
@ -1,82 +0,0 @@
|
||||||
import mosquitto
|
|
||||||
import os
|
|
||||||
import urlparse
|
|
||||||
|
|
||||||
# External module imports
|
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
import time
|
|
||||||
|
|
||||||
led = 12
|
|
||||||
MQTT_SERVER = "x.x.x.xxx"
|
|
||||||
MQTT_SERVER_PORT = xxx
|
|
||||||
MQTT_TOPIC = "/home/tv/backlight"
|
|
||||||
MQTT_USERNAME = "mosquitto"
|
|
||||||
MQTT_PASSWORD = "xxx"
|
|
||||||
|
|
||||||
# Pin Setup:
|
|
||||||
GPIO.setmode(GPIO.BOARD)
|
|
||||||
GPIO.setwarnings(False)
|
|
||||||
GPIO.setup(led, GPIO.OUT)
|
|
||||||
|
|
||||||
# Define event callbacks
|
|
||||||
def on_connect(mosq, obj, rc):
|
|
||||||
print("Return Code On Connect: " + str(rc))
|
|
||||||
|
|
||||||
def on_message(mosq, obj, msg):
|
|
||||||
print(msg.topic + " " + str(msg.qos) + " " + str(msg.payload))
|
|
||||||
if (str(msg.payload) == "on" or str(msg.payload) == "ON"):
|
|
||||||
#os.system('python on.py')
|
|
||||||
GPIO.output(led, GPIO.LOW)
|
|
||||||
time.sleep(1)
|
|
||||||
else:
|
|
||||||
if (str(msg.payload) == "off" or str(msg.payload) == "OFF"):
|
|
||||||
#os.system('python off.py')
|
|
||||||
GPIO.output(led, GPIO.HIGH)
|
|
||||||
time.sleep(1)
|
|
||||||
else:
|
|
||||||
if (str(msg.payload) == "FLICKER_TV_OFF"):
|
|
||||||
for x in range(0, 3):
|
|
||||||
GPIO.output(led, GPIO.HIGH)
|
|
||||||
time.sleep(0.25)
|
|
||||||
GPIO.output(led, GPIO.LOW)
|
|
||||||
time.sleep(0.25)
|
|
||||||
else:
|
|
||||||
if (str(msg.payload) == "FLICKER"):
|
|
||||||
for x in range(0, 3):
|
|
||||||
GPIO.output(led, GPIO.LOW)
|
|
||||||
time.sleep(0.25)
|
|
||||||
GPIO.output(led, GPIO.HIGH)
|
|
||||||
time.sleep(0.25)
|
|
||||||
time.sleep(1.00)
|
|
||||||
else:
|
|
||||||
print("Unknown command")
|
|
||||||
|
|
||||||
|
|
||||||
def on_subscribe(mosq, obj, mid, granted_qos):
|
|
||||||
print("Subscribed: " + str(mid) + " " + str(granted_qos))
|
|
||||||
|
|
||||||
def on_log(mosq, obj, level, string):
|
|
||||||
print(string)
|
|
||||||
|
|
||||||
mqttc = mosquitto.Mosquitto()
|
|
||||||
|
|
||||||
# Assign event callbacks
|
|
||||||
mqttc.on_message = on_message
|
|
||||||
mqttc.on_connect = on_connect
|
|
||||||
mqttc.on_subscribe = on_subscribe
|
|
||||||
|
|
||||||
# Uncomment to enable debug messages
|
|
||||||
#mqttc.on_log = on_log
|
|
||||||
|
|
||||||
# Connect
|
|
||||||
mqttc.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
|
|
||||||
mqttc.connect(MQTT_SERVER, MQTT_SERVER_PORT)
|
|
||||||
|
|
||||||
# Start subscribe, with QoS level 0
|
|
||||||
mqttc.subscribe(MQTT_TOPIC, 0)
|
|
||||||
|
|
||||||
# Continue the network loop, exit when an error occurs
|
|
||||||
rc = 0
|
|
||||||
while rc == 0:
|
|
||||||
rc = mqttc.loop()
|
|
||||||
print("MQTT Return Code: " + str(rc))
|
|
|
@ -1,31 +0,0 @@
|
||||||
import os
|
|
||||||
import time
|
|
||||||
import paho.mqtt.client as mqtt
|
|
||||||
|
|
||||||
MQTT_SERVER = "192.168.xxx.xxx"
|
|
||||||
MQTT_SERVER_PORT = 1883
|
|
||||||
MQTT_TOPIC = "/garage/motion"
|
|
||||||
MQTT_USERNAME = "xxx"
|
|
||||||
MQTT_PASSWORD = "xxx"
|
|
||||||
|
|
||||||
# Define event callbacks
|
|
||||||
def on_connect(mosq, obj, rc):
|
|
||||||
print("Return Code On Connect: " + str(rc))
|
|
||||||
|
|
||||||
def on_log(mosq, obj, level, string):
|
|
||||||
print(string)
|
|
||||||
|
|
||||||
mqttc = mqtt.Mosquitto()
|
|
||||||
|
|
||||||
# Assign event callbacks
|
|
||||||
mqttc.on_connect = on_connect
|
|
||||||
|
|
||||||
# Uncomment to enable debug messages
|
|
||||||
#mqttc.on_log = on_log
|
|
||||||
|
|
||||||
# Connect
|
|
||||||
mqttc.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
|
|
||||||
mqttc.connect(MQTT_SERVER, MQTT_SERVER_PORT)
|
|
||||||
|
|
||||||
# publish the message
|
|
||||||
mqttc.publish(MQTT_TOPIC, 'on')
|
|
|
@ -1,274 +1,274 @@
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
# @author : Mahasri Kalavala
|
# # @author : Mahasri Kalavala
|
||||||
# @date : 09/04/2020
|
# # @date : 09/04/2020
|
||||||
# @package : 3D Printer
|
# # @package : 3D Printer
|
||||||
# @description : 3D Printer Automations
|
# # @description : 3D Printer Automations
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
homeassistant:
|
# homeassistant:
|
||||||
customize:
|
# customize:
|
||||||
automation.3d_print:
|
# automation.3d_print:
|
||||||
icon: mdi:printer
|
# icon: mdi:printer
|
||||||
|
|
||||||
input_boolean:
|
# input_boolean:
|
||||||
twenty_five_percent:
|
# twenty_five_percent:
|
||||||
name: "25%"
|
# name: "25%"
|
||||||
icon: mdi:radiobox-blank
|
# icon: mdi:radiobox-blank
|
||||||
|
|
||||||
fifty_percent:
|
# fifty_percent:
|
||||||
name: "50%"
|
# name: "50%"
|
||||||
icon: mdi:brightness-3
|
# icon: mdi:brightness-3
|
||||||
|
|
||||||
seventy_five_percent:
|
# seventy_five_percent:
|
||||||
name: "75%"
|
# name: "75%"
|
||||||
icon: mdi:brightness-2
|
# icon: mdi:brightness-2
|
||||||
|
|
||||||
hundred_percent:
|
# hundred_percent:
|
||||||
name: "100%"
|
# name: "100%"
|
||||||
icon: mdi:brightness-1
|
# icon: mdi:brightness-1
|
||||||
|
|
||||||
power_off_when_complete:
|
# power_off_when_complete:
|
||||||
name: Auto Shutoff When Done
|
# name: Auto Shutoff When Done
|
||||||
icon: mdi:toggle-switch-off
|
# icon: mdi:toggle-switch-off
|
||||||
|
|
||||||
send_progress_pictures:
|
# send_progress_pictures:
|
||||||
name: Send Telegram Pictures
|
# name: Send Telegram Pictures
|
||||||
icon: mdi:toggle-switch-off
|
# icon: mdi:toggle-switch-off
|
||||||
|
|
||||||
#
|
# #
|
||||||
# Octoprint Camera URL in the format
|
# # Octoprint Camera URL in the format
|
||||||
# still_image_url: "http://192.xxx.xxx.xxx/webcam/?action=snapshot"
|
# # still_image_url: "http://192.xxx.xxx.xxx/webcam/?action=snapshot"
|
||||||
# mjpeg_url: "http://192.xxx.xxx.xxx/webcam/?action=stream"
|
# # mjpeg_url: "http://192.xxx.xxx.xxx/webcam/?action=stream"
|
||||||
#
|
# #
|
||||||
camera:
|
# camera:
|
||||||
- platform: mjpeg
|
# - platform: mjpeg
|
||||||
name: 3D Printer Camera
|
# name: 3D Printer Camera
|
||||||
still_image_url: !secret octoprint_cam_snapshot
|
# still_image_url: !secret octoprint_cam_snapshot
|
||||||
mjpeg_url: !secret octoprint_cam_stream
|
# mjpeg_url: !secret octoprint_cam_stream
|
||||||
|
|
||||||
#
|
# #
|
||||||
# A couple of template sensors to show the elapsed and estimated time in readable format
|
# # A couple of template sensors to show the elapsed and estimated time in readable format
|
||||||
# instead of # of seconds (default)
|
# # instead of # of seconds (default)
|
||||||
#
|
# #
|
||||||
sensor:
|
# sensor:
|
||||||
- platform: template
|
# # - platform: template
|
||||||
sensors:
|
# # sensors:
|
||||||
time_elapsed:
|
# # time_elapsed:
|
||||||
value_template: >
|
# # value_template: >
|
||||||
{%- macro secondsToReadableString(seconds) %}
|
# # {%- macro secondsToReadableString(seconds) %}
|
||||||
{%- set map = {'week': (seconds / 604800) % 604800,
|
# # {%- set map = {'week': (seconds / 604800) % 604800,
|
||||||
'day': (seconds / 86400) % 7, 'hour': (seconds / 3600) % 24,
|
# # 'day': (seconds / 86400) % 7, 'hour': (seconds / 3600) % 24,
|
||||||
'minute': (seconds / 60) % 60} -%}
|
# # 'minute': (seconds / 60) % 60} -%}
|
||||||
{%- for item in map if map[item] | int > 0 -%}
|
# # {%- for item in map if map[item] | int > 0 -%}
|
||||||
{%- if loop.first %}{% elif loop.last %}, and {% else %}, {% endif -%}
|
# # {%- if loop.first %}{% elif loop.last %}, and {% else %}, {% endif -%}
|
||||||
{{- map[item]|int }} {{ item -}} {{- 's' if map[item]|int > 1 -}}
|
# # {{- map[item]|int }} {{ item -}} {{- 's' if map[item]|int > 1 -}}
|
||||||
{%- endfor -%}
|
# # {%- endfor -%}
|
||||||
{% endmacro %}
|
# # {% endmacro %}
|
||||||
{{ secondsToReadableString(states('sensor.octoprint_time_elapsed') |int) }}
|
# # {{ secondsToReadableString(states('sensor.octoprint_time_elapsed') |int) }}
|
||||||
|
|
||||||
- platform: template
|
# # - platform: template
|
||||||
sensors:
|
# # sensors:
|
||||||
time_estimated:
|
# # time_estimated:
|
||||||
value_template: >
|
# # value_template: >
|
||||||
{%- macro secondsToReadableString(seconds) %}
|
# # {%- macro secondsToReadableString(seconds) %}
|
||||||
{%- set map = {'week': (seconds / 604800) % 604800,
|
# # {%- set map = {'week': (seconds / 604800) % 604800,
|
||||||
'day': (seconds / 86400) % 7, 'hour': (seconds / 3600) % 24,
|
# # 'day': (seconds / 86400) % 7, 'hour': (seconds / 3600) % 24,
|
||||||
'minute': (seconds / 60) % 60 } -%}
|
# # 'minute': (seconds / 60) % 60 } -%}
|
||||||
{%- for item in map if map[item] | int > 0 -%}
|
# # {%- for item in map if map[item] | int > 0 -%}
|
||||||
{%- if loop.first %}{% elif loop.last %}, and {% else %}, {% endif -%}
|
# # {%- if loop.first %}{% elif loop.last %}, and {% else %}, {% endif -%}
|
||||||
{{- map[item]|int }} {{ item -}} {{- 's' if map[item]|int > 1 -}}
|
# # {{- map[item]|int }} {{ item -}} {{- 's' if map[item]|int > 1 -}}
|
||||||
{%- endfor -%}
|
# # {%- endfor -%}
|
||||||
{% endmacro %}
|
# # {% endmacro %}
|
||||||
{{ secondsToReadableString(states('sensor.octoprint_time_remaining') |int) }}
|
# # {{ secondsToReadableString(states('sensor.octoprint_time_remaining') |int) }}
|
||||||
|
|
||||||
- platform: template
|
# # - platform: template
|
||||||
sensors:
|
# # sensors:
|
||||||
print_completion:
|
# # print_completion:
|
||||||
value_template: >
|
# # value_template: >
|
||||||
{% set seconds = states('sensor.octoprint_time_remaining')|int %}
|
# # {% set seconds = states('sensor.octoprint_time_remaining')|int %}
|
||||||
{% if utcnow().strftime('%s')|int | timestamp_custom("%A %D") == (utcnow().strftime('%s') |int + seconds) | timestamp_custom("%A %D") %}
|
# # {% if utcnow().strftime('%s')|int | timestamp_custom("%A %D") == (utcnow().strftime('%s') |int + seconds) | timestamp_custom("%A %D") %}
|
||||||
Today at {{ (utcnow().strftime('%s')|int + seconds) | timestamp_custom("%I:%M %p") }}
|
# # Today at {{ (utcnow().strftime('%s')|int + seconds) | timestamp_custom("%I:%M %p") }}
|
||||||
{% else %}
|
# # {% else %}
|
||||||
{{ (utcnow().strftime('%s') |int + seconds) | timestamp_custom("%A %D %I:%M %p") }}
|
# # {{ (utcnow().strftime('%s') |int + seconds) | timestamp_custom("%A %D %I:%M %p") }}
|
||||||
{% endif %}
|
# # {% endif %}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
octoprint_actual_bed_temp_c:
|
# octoprint_actual_bed_temp_c:
|
||||||
unit_of_measurement: "C"
|
# unit_of_measurement: "C"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{%- macro F2C(temperature) -%}
|
# {%- macro F2C(temperature) -%}
|
||||||
{% set tmp = (((temperature - 32) *5)/9) %}
|
# {% set tmp = (((temperature - 32) *5)/9) %}
|
||||||
{{- " %0.2f" % tmp }}
|
# {{- " %0.2f" % tmp }}
|
||||||
{%- endmacro -%}
|
# {%- endmacro -%}
|
||||||
{{ F2C(states('sensor.octoprint_actual_bed_temp') |int ) |int }}
|
# {{ F2C(states('sensor.octoprint_actual_bed_temp') |int ) |int }}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
octoprint_actual_tool0_temp_c:
|
# octoprint_actual_tool0_temp_c:
|
||||||
unit_of_measurement: "C"
|
# unit_of_measurement: "C"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{%- macro F2C(temperature) -%}
|
# {%- macro F2C(temperature) -%}
|
||||||
{% set tmp = (((temperature - 32) *5)/9) %}
|
# {% set tmp = (((temperature - 32) *5)/9) %}
|
||||||
{{- " %0.2f" % tmp }}
|
# {{- " %0.2f" % tmp }}
|
||||||
{%- endmacro -%}
|
# {%- endmacro -%}
|
||||||
{{ F2C(states('sensor.octoprint_actual_tool0_temp') |int ) |int }}
|
# {{ F2C(states('sensor.octoprint_actual_tool0_temp') |int ) |int }}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
octoprint_target_bed_temp_c:
|
# octoprint_target_bed_temp_c:
|
||||||
unit_of_measurement: "C"
|
# unit_of_measurement: "C"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{%- macro F2C(temperature) -%}
|
# {%- macro F2C(temperature) -%}
|
||||||
{% set tmp = (((temperature - 32) *5)/9) %}
|
# {% set tmp = (((temperature - 32) *5)/9) %}
|
||||||
{{- " %0.2f" % tmp }}
|
# {{- " %0.2f" % tmp }}
|
||||||
{%- endmacro -%}
|
# {%- endmacro -%}
|
||||||
{{ F2C(states('sensor.octoprint_target_bed_temp') |int ) |int }}
|
# {{ F2C(states('sensor.octoprint_target_bed_temp') |int ) |int }}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
octoprint_target_tool0_temp_c:
|
# octoprint_target_tool0_temp_c:
|
||||||
unit_of_measurement: "C"
|
# unit_of_measurement: "C"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{%- macro F2C(temperature) -%}
|
# {%- macro F2C(temperature) -%}
|
||||||
{% set tmp = (((temperature - 32) *5)/9) %}
|
# {% set tmp = (((temperature - 32) *5)/9) %}
|
||||||
{{- " %0.2f" % tmp }}
|
# {{- " %0.2f" % tmp }}
|
||||||
{%- endmacro -%}
|
# {%- endmacro -%}
|
||||||
{{ F2C(states('sensor.octoprint_target_tool0_temp') |int ) |int }}
|
# {{ F2C(states('sensor.octoprint_target_tool0_temp') |int ) |int }}
|
||||||
|
|
||||||
automation:
|
# - platform: template
|
||||||
#
|
# sensors:
|
||||||
# Notify when the printer status changed from "Prnting" to anything.
|
# octoprint_print_start:
|
||||||
# Use this later to determine if you want to turn off printer or not
|
# value_template: "{{ as_timestamp(states('sensor.octoprint_start_time'))| timestamp_custom('%m/%d/%Y, %H:%M:%S %p') }}"
|
||||||
#
|
|
||||||
- alias: "3D Print State Changed"
|
|
||||||
trigger:
|
|
||||||
platform: state
|
|
||||||
entity_id: "sensor.octoprint_current_state"
|
|
||||||
from: "Printing"
|
|
||||||
action:
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "3D Printer Status Changed from 'Printing' to '{{ trigger.to_state.state }}'."
|
|
||||||
|
|
||||||
#
|
# - platform: template
|
||||||
# Updates on the Printer Status
|
# sensors:
|
||||||
#
|
# octoprint_print_end_eta:
|
||||||
- alias: "3D Print Notify Printer State"
|
# value_template: "{{ as_timestamp(states('sensor.octoprint_estimated_finish_time'))| timestamp_custom('%m/%d/%Y, %H:%M:%S %p') }}"
|
||||||
trigger:
|
|
||||||
platform: state
|
|
||||||
entity_id: "binary_sensor.octoprint_printing"
|
|
||||||
action:
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "3D Printer Status changed from '{{ trigger.from_state.state }}' to '{{ trigger.to_state.state }}'."
|
|
||||||
|
|
||||||
#
|
# automation:
|
||||||
# Notifies when the printer errors out
|
# #
|
||||||
#
|
# # Notify when the printer status changed from "Prnting" to anything.
|
||||||
- alias: "3D Print Notify Printer Error"
|
# # Use this later to determine if you want to turn off printer or not
|
||||||
trigger:
|
# #
|
||||||
platform: state
|
# - alias: "3D Print State Changed"
|
||||||
entity_id: binary_sensor.octoprint_printing_error
|
# trigger:
|
||||||
to: "on"
|
# platform: state
|
||||||
action:
|
# entity_id: "sensor.octoprint_current_state"
|
||||||
- service: script.notify_me
|
# from: "Printing"
|
||||||
data_template:
|
# action:
|
||||||
message: "3D Printer Status changed to 'ERROR'. Please check the printer!"
|
# - service: script.notify_me
|
||||||
|
# data_template:
|
||||||
|
# message: "3D Printer Status Changed from 'Printing' to '{{ trigger.to_state.state }}'."
|
||||||
|
|
||||||
#
|
# #
|
||||||
# Updates appropriate input booleans based on percentage complete
|
# # Updates on the Printer Status
|
||||||
#
|
# #
|
||||||
- alias: "3D Print Update Percentage Booleans"
|
# - alias: "3D Print Notify Printer State"
|
||||||
trigger:
|
# trigger:
|
||||||
platform: state
|
# platform: state
|
||||||
entity_id: sensor.octoprint_job_percentage
|
# entity_id: "binary_sensor.octoprint_printing"
|
||||||
action:
|
# action:
|
||||||
- service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 25 else 'off' }}"
|
# - service: script.notify_me
|
||||||
entity_id: input_boolean.twenty_five_percent
|
# data_template:
|
||||||
- service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 50 else 'off' }}"
|
# message: "3D Printer Status changed from '{{ trigger.from_state.state }}' to '{{ trigger.to_state.state }}'."
|
||||||
entity_id: input_boolean.fifty_percent
|
|
||||||
- service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 75 else 'off' }}"
|
|
||||||
entity_id: input_boolean.seventy_five_percent
|
|
||||||
- service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int == 100 else 'off' }}"
|
|
||||||
entity_id: input_boolean.hundred_percent
|
|
||||||
|
|
||||||
#
|
# #
|
||||||
# Provides update at frequent intervals - 25%, 50%, 75%, and 100%!
|
# # Notifies when the printer errors out
|
||||||
#
|
# #
|
||||||
- alias: "3D Print Progress Update"
|
# - alias: "3D Print Notify Printer Error"
|
||||||
trigger:
|
# trigger:
|
||||||
platform: state
|
# platform: state
|
||||||
entity_id: input_boolean.twenty_five_percent, input_boolean.fifty_percent, input_boolean.seventy_five_percent, input_boolean.hundred_percent
|
# entity_id: binary_sensor.octoprint_printing_error
|
||||||
to: "on"
|
# to: "on"
|
||||||
from: "off"
|
# action:
|
||||||
action:
|
# - service: script.notify_me
|
||||||
- service: script.notify_me
|
# data_template:
|
||||||
data_template:
|
# message: "3D Printer Status changed to 'ERROR'. Please check the printer!"
|
||||||
message: >-
|
|
||||||
{%- macro secondsToReadableString(seconds) %}
|
|
||||||
{%- set map = {'week': (seconds / 604800) % 604800,
|
|
||||||
'day': (seconds / 86400) % 7, 'hour': (seconds / 3600) % 24,
|
|
||||||
'minute': (seconds / 60) % 60 } -%}
|
|
||||||
{%- for item in map if map[item] | int > 0 -%}
|
|
||||||
{%- if loop.first %}{% elif loop.last %}, and {% else %}, {% endif -%}
|
|
||||||
{{- map[item]|int }} {{ item -}} {{- 's' if map[item]|int > 1 -}}
|
|
||||||
{%- endfor -%}
|
|
||||||
{% endmacro %}
|
|
||||||
3D Printer job is now {{ trigger.to_state.attributes.friendly_name }} complete. {% if trigger.entity_id != 'input_boolean.hundred_percent' %} Will be done in {{ secondsToReadableString(states('sensor.octoprint_time_remaining') |int) }}.
|
|
||||||
{%- endif -%}
|
|
||||||
|
|
||||||
#
|
# #
|
||||||
# When the printing is complete (100%), it waits for 2 minutes and turns off the printer.
|
# # Updates appropriate input booleans based on percentage complete
|
||||||
# It also resets all the input booleans, so that it starts fresh next time.
|
# #
|
||||||
# Resetting input boleans is not necessary as they get updated automatically when
|
# - alias: "3D Print Update Percentage Booleans"
|
||||||
# octoprint job percentage value chaanges... but why not?
|
# trigger:
|
||||||
#
|
# platform: state
|
||||||
- alias: "3d Print Job Finished"
|
# entity_id: sensor.octoprint_job_percentage
|
||||||
trigger:
|
# action:
|
||||||
platform: state
|
# - service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 25 else 'off' }}"
|
||||||
entity_id: input_boolean.hundred_percent
|
# entity_id: input_boolean.twenty_five_percent
|
||||||
to: "on"
|
# - service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 50 else 'off' }}"
|
||||||
action:
|
# entity_id: input_boolean.fifty_percent
|
||||||
- condition: template
|
# - service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int >= 75 else 'off' }}"
|
||||||
value_template: "{{ states('input_boolean.power_off_when_complete') == 'on' }}"
|
# entity_id: input_boolean.seventy_five_percent
|
||||||
- delay: "00:02:00"
|
# - service_template: "input_boolean.turn_{{- 'on' if states('sensor.octoprint_job_percentage') | int == 100 else 'off' }}"
|
||||||
- service: switch.turn_off
|
# entity_id: input_boolean.hundred_percent
|
||||||
entity_id: switch.3d_printer
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "3D Printer is now switched off!"
|
|
||||||
- service_template: input_boolean.turn_off
|
|
||||||
entity_id: input_boolean.twenty_five_percent
|
|
||||||
- service_template: input_boolean.turn_off
|
|
||||||
entity_id: input_boolean.fifty_percent
|
|
||||||
- service_template: input_boolean.turn_off
|
|
||||||
entity_id: input_boolean.seventy_five_percent
|
|
||||||
- service_template: input_boolean.turn_off
|
|
||||||
entity_id: input_boolean.hundred_percent
|
|
||||||
|
|
||||||
#
|
# #
|
||||||
# If the printer is ON and is "Printing", it will send a snapshot/picture every 30 minutes
|
# # Provides update at frequent intervals - 25%, 50%, 75%, and 100%!
|
||||||
#
|
# #
|
||||||
- alias: "3D Print Send Telegram Pictures"
|
# - alias: "3D Print Progress Update"
|
||||||
trigger:
|
# trigger:
|
||||||
platform: time_pattern
|
# platform: state
|
||||||
minutes: "/30"
|
# entity_id: input_boolean.twenty_five_percent, input_boolean.fifty_percent, input_boolean.seventy_five_percent, input_boolean.hundred_percent
|
||||||
seconds: 00
|
# to: "on"
|
||||||
condition:
|
# from: "off"
|
||||||
- condition: template
|
# action:
|
||||||
value_template: "{{ states('input_boolean.send_progress_pictures') == 'on' }}"
|
# - service: script.notify_me
|
||||||
- condition: template
|
# data_template:
|
||||||
value_template: "{{ states('sensor.octoprint_current_state') | lower == 'printing' }}"
|
# message: >-
|
||||||
action:
|
# 3D Printer job is now {{ trigger.to_state.attributes.friendly_name }} complete.
|
||||||
- service: camera.snapshot
|
|
||||||
data:
|
# #
|
||||||
entity_id: camera.3d_printer_camera
|
# # When the printing is complete (100%), it waits for 2 minutes and turns off the printer.
|
||||||
filename: "/config/www/downloads/camera/3dprinter/print_latest.jpg"
|
# # It also resets all the input booleans, so that it starts fresh next time.
|
||||||
- service: notify.telegram
|
# # Resetting input boleans is not necessary as they get updated automatically when
|
||||||
data_template:
|
# # octoprint job percentage value chaanges... but why not?
|
||||||
title: "3D Printer"
|
# #
|
||||||
message: "Print Progress"
|
# - alias: "3d Print Job Finished"
|
||||||
data:
|
# trigger:
|
||||||
photo:
|
# platform: state
|
||||||
- file: "/config/www/downloads/camera/3dprinter/print_latest.jpg"
|
# entity_id: input_boolean.hundred_percent
|
||||||
caption: "3D Print Progress at {{ states('sensor.octoprint_job_percentage') }}%"
|
# to: "on"
|
||||||
|
# action:
|
||||||
|
# - condition: template
|
||||||
|
# value_template: "{{ states('input_boolean.power_off_when_complete') == 'on' }}"
|
||||||
|
# - delay: "00:02:00"
|
||||||
|
# - service: switch.turn_off
|
||||||
|
# entity_id: switch.3d_printer
|
||||||
|
# - service: script.notify_me
|
||||||
|
# data_template:
|
||||||
|
# message: "3D Printer is now switched off!"
|
||||||
|
# - service_template: input_boolean.turn_off
|
||||||
|
# entity_id: input_boolean.twenty_five_percent
|
||||||
|
# - service_template: input_boolean.turn_off
|
||||||
|
# entity_id: input_boolean.fifty_percent
|
||||||
|
# - service_template: input_boolean.turn_off
|
||||||
|
# entity_id: input_boolean.seventy_five_percent
|
||||||
|
# - service_template: input_boolean.turn_off
|
||||||
|
# entity_id: input_boolean.hundred_percent
|
||||||
|
|
||||||
|
# #
|
||||||
|
# # If the printer is ON and is "Printing", it will send a snapshot/picture every 30 minutes
|
||||||
|
# #
|
||||||
|
# - alias: "3D Print Send Telegram Pictures"
|
||||||
|
# trigger:
|
||||||
|
# platform: time_pattern
|
||||||
|
# minutes: "/30"
|
||||||
|
# seconds: 00
|
||||||
|
# condition:
|
||||||
|
# - condition: template
|
||||||
|
# value_template: "{{ states('input_boolean.send_progress_pictures') == 'on' }}"
|
||||||
|
# - condition: template
|
||||||
|
# value_template: "{{ states('sensor.octoprint_current_state') | lower == 'printing' }}"
|
||||||
|
# action:
|
||||||
|
# - service: camera.snapshot
|
||||||
|
# data:
|
||||||
|
# entity_id: camera.3d_printer_camera
|
||||||
|
# filename: "/config/www/downloads/camera/3dprinter/print_latest.jpg"
|
||||||
|
# - service: notify.telegram
|
||||||
|
# data_template:
|
||||||
|
# title: "3D Printer"
|
||||||
|
# message: "Print Progress"
|
||||||
|
# data:
|
||||||
|
# photo:
|
||||||
|
# - file: "/config/www/downloads/camera/3dprinter/print_latest.jpg"
|
||||||
|
# caption: "3D Print Progress at {{ states('sensor.octoprint_job_percentage') }}%"
|
||||||
|
|
|
@ -1,113 +0,0 @@
|
||||||
homeassistant:
|
|
||||||
customize:
|
|
||||||
timer.timer_downstairs_aroma:
|
|
||||||
hidden: true
|
|
||||||
timer.timer_upstairs_aroma:
|
|
||||||
hidden: true
|
|
||||||
|
|
||||||
timer:
|
|
||||||
timer_downstairs_aroma:
|
|
||||||
duration: "01:00:00"
|
|
||||||
timer_upstairs_aroma:
|
|
||||||
duration: "01:00:00"
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# _ _ _
|
|
||||||
# /\ | | | | (_)
|
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
automation:
|
|
||||||
- alias: Downstairs Aroma Timer Start
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: switch.downstairs_fragrance
|
|
||||||
from: "off"
|
|
||||||
to: "on"
|
|
||||||
action:
|
|
||||||
- service: timer.start
|
|
||||||
entity_id: timer.timer_downstairs_aroma
|
|
||||||
|
|
||||||
- alias: Downstairs Aroma Timer Finish
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: switch.downstairs_fragrance
|
|
||||||
from: "on"
|
|
||||||
to: "off"
|
|
||||||
action:
|
|
||||||
- service: timer.finish
|
|
||||||
entity_id: timer.timer_downstairs_aroma
|
|
||||||
|
|
||||||
- alias: Upstairs Aroma Timer Start
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: switch.upstairs_fragrance
|
|
||||||
from: "off"
|
|
||||||
to: "on"
|
|
||||||
action:
|
|
||||||
- service: timer.start
|
|
||||||
entity_id: timer.timer_upstairs_aroma
|
|
||||||
|
|
||||||
- alias: Upstairs Aroma Timer Finish
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: switch.upstairs_fragrance
|
|
||||||
from: "on"
|
|
||||||
to: "off"
|
|
||||||
action:
|
|
||||||
- service: timer.finish
|
|
||||||
entity_id: timer.timer_upstairs_aroma
|
|
||||||
|
|
||||||
#
|
|
||||||
# Timer Elapsed Events
|
|
||||||
#
|
|
||||||
- alias: Downstairs Aroma Timer Elapsed
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: event
|
|
||||||
event_type: timer.finished
|
|
||||||
event_data:
|
|
||||||
entity_id: timer.timer_downstairs_aroma
|
|
||||||
action:
|
|
||||||
- service: switch.turn_off
|
|
||||||
entity_id: switch.downstairs_fragrance
|
|
||||||
|
|
||||||
- alias: Upstairs Aroma Timer Elapsed
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: event
|
|
||||||
event_type: timer.finished
|
|
||||||
event_data:
|
|
||||||
entity_id: timer.timer_upstairs_aroma
|
|
||||||
action:
|
|
||||||
- service: switch.turn_off
|
|
||||||
entity_id: switch.upstairs_fragrance
|
|
||||||
|
|
||||||
#
|
|
||||||
# Turn ON fragrance outlets automatically at specific times of the day
|
|
||||||
#
|
|
||||||
- alias: Turn On Upstairs Aroma
|
|
||||||
trigger:
|
|
||||||
- platform: time
|
|
||||||
at: "08:00:00"
|
|
||||||
- platform: time
|
|
||||||
at: "20:00:00"
|
|
||||||
action:
|
|
||||||
- service: switch.turn_on
|
|
||||||
entity_id: switch.upstairs_fragrance
|
|
||||||
|
|
||||||
- alias: Turn On Downstairs Aroma
|
|
||||||
trigger:
|
|
||||||
- platform: time
|
|
||||||
at: "17:00:00"
|
|
||||||
action:
|
|
||||||
- service: switch.turn_on
|
|
||||||
entity_id: switch.downstairs_fragrance
|
|
|
@ -1,473 +1,473 @@
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
# @author : Mahasri Kalavala
|
# # @author : Mahasri Kalavala
|
||||||
# @date : 04/15/2017
|
# # @date : 04/15/2017
|
||||||
# @package : Batteries
|
# # @package : Batteries
|
||||||
# @description : Status about various baterries (iphones, sensors...etc)
|
# # @description : Status about various baterries (iphones, sensors...etc)
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
homeassistant:
|
# homeassistant:
|
||||||
customize:
|
# customize:
|
||||||
group.batteries:
|
# group.batteries:
|
||||||
order: 2
|
# order: 2
|
||||||
|
|
||||||
sensor.suresh_iphone_battery_state:
|
# sensor.suresh_iphone_battery_state:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.mallika_iphone_battery_state:
|
# sensor.mallika_iphone_battery_state:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.srinika_iphone_battery_state:
|
# sensor.srinika_iphone_battery_state:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.hasika_iphone_battery_state:
|
# sensor.hasika_iphone_battery_state:
|
||||||
hidden: true
|
# hidden: true
|
||||||
|
|
||||||
sensor.suresh_iphone_battery_ot:
|
# sensor.suresh_iphone_battery_ot:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.mallika_iphone_battery_ot:
|
# sensor.mallika_iphone_battery_ot:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.srinika_iphone_battery_ot:
|
# sensor.srinika_iphone_battery_ot:
|
||||||
hidden: true
|
# hidden: true
|
||||||
sensor.hasika_iphone_battery_ot:
|
# sensor.hasika_iphone_battery_ot:
|
||||||
hidden: true
|
# hidden: true
|
||||||
|
|
||||||
sensor.hasika_iphone_wifi_state:
|
# sensor.hasika_iphone_wifi_state:
|
||||||
friendly_name: Hasika Phone Wi-Fi Status
|
# friendly_name: Hasika Phone Wi-Fi Status
|
||||||
sensor.mallika_iphone_wifi_state:
|
# sensor.mallika_iphone_wifi_state:
|
||||||
friendly_name: Mallika Phone Wi-Fi Status
|
# friendly_name: Mallika Phone Wi-Fi Status
|
||||||
sensor.srinika_iphone_wifi_state:
|
# sensor.srinika_iphone_wifi_state:
|
||||||
friendly_name: Srinika Phone Wi-Fi Status
|
# friendly_name: Srinika Phone Wi-Fi Status
|
||||||
sensor.suresh_iphone_wifi_state:
|
# sensor.suresh_iphone_wifi_state:
|
||||||
friendly_name: Suresh Phone Wi-Fi Status
|
# friendly_name: Suresh Phone Wi-Fi Status
|
||||||
|
|
||||||
sensor:
|
# sensor:
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/mallika/mallika"
|
# state_topic: "owntracks/mallika/mallika"
|
||||||
name: "Mallika iPhone Battery (OT)"
|
# name: "Mallika iPhone Battery (OT)"
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ value_json.batt }}"
|
# value_template: "{{ value_json.batt }}"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/suresh/suresh"
|
# state_topic: "owntracks/suresh/suresh"
|
||||||
name: "Suresh iPhone Battery (OT)"
|
# name: "Suresh iPhone Battery (OT)"
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ value_json.batt }}"
|
# value_template: "{{ value_json.batt }}"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/srinika/srinika"
|
# state_topic: "owntracks/srinika/srinika"
|
||||||
name: "Srinika iPhone Battery (OT)"
|
# name: "Srinika iPhone Battery (OT)"
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ value_json.batt }}"
|
# value_template: "{{ value_json.batt }}"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/hasika/hasika"
|
# state_topic: "owntracks/hasika/hasika"
|
||||||
name: "Hasika iPhone Battery (OT)"
|
# name: "Hasika iPhone Battery (OT)"
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ value_json.batt }}"
|
# value_template: "{{ value_json.batt }}"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/mallika/mallika"
|
# state_topic: "owntracks/mallika/mallika"
|
||||||
name: "Mallika iPhone Battery State"
|
# name: "Mallika iPhone Battery State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.charging == 1 %}
|
# {% if value_json.charging == 1 %}
|
||||||
Charging
|
# Charging
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Charging
|
# Not Charging
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:battery-charging"
|
# icon: "mdi:battery-charging"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/suresh/suresh"
|
# state_topic: "owntracks/suresh/suresh"
|
||||||
name: "Suresh iPhone Battery State"
|
# name: "Suresh iPhone Battery State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.charging == 1 %}
|
# {% if value_json.charging == 1 %}
|
||||||
Charging
|
# Charging
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Charging
|
# Not Charging
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:battery-charging"
|
# icon: "mdi:battery-charging"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/srinika/srinika"
|
# state_topic: "owntracks/srinika/srinika"
|
||||||
name: "Srinika iPhone Battery State"
|
# name: "Srinika iPhone Battery State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.charging == 1 %}
|
# {% if value_json.charging == 1 %}
|
||||||
Charging
|
# Charging
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Charging
|
# Not Charging
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:battery-charging"
|
# icon: "mdi:battery-charging"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/hasika/hasika"
|
# state_topic: "owntracks/hasika/hasika"
|
||||||
name: "Hasika iPhone Battery State"
|
# name: "Hasika iPhone Battery State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.charging == 1 %}
|
# {% if value_json.charging == 1 %}
|
||||||
Charging
|
# Charging
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Charging
|
# Not Charging
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:battery-charging"
|
# icon: "mdi:battery-charging"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/mallika/mallika"
|
# state_topic: "owntracks/mallika/mallika"
|
||||||
name: "Mallika iPhone Wifi State"
|
# name: "Mallika iPhone Wifi State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.conn == "w" %}
|
# {% if value_json.conn == "w" %}
|
||||||
Connected
|
# Connected
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Connected
|
# Not Connected
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:wifi"
|
# icon: "mdi:wifi"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/suresh/suresh"
|
# state_topic: "owntracks/suresh/suresh"
|
||||||
name: "Suresh iPhone Wifi State"
|
# name: "Suresh iPhone Wifi State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.conn == "w" %}
|
# {% if value_json.conn == "w" %}
|
||||||
Connected
|
# Connected
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Connected
|
# Not Connected
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:wifi"
|
# icon: "mdi:wifi"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/srinika/srinika"
|
# state_topic: "owntracks/srinika/srinika"
|
||||||
name: "Srinika iPhone Wifi State"
|
# name: "Srinika iPhone Wifi State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.conn == "w" %}
|
# {% if value_json.conn == "w" %}
|
||||||
Connected
|
# Connected
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Connected
|
# Not Connected
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:wifi"
|
# icon: "mdi:wifi"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/hasika/hasika"
|
# state_topic: "owntracks/hasika/hasika"
|
||||||
name: "Hasika iPhone Wifi State"
|
# name: "Hasika iPhone Wifi State"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if value_json.conn == "w" %}
|
# {% if value_json.conn == "w" %}
|
||||||
Connected
|
# Connected
|
||||||
{% else %}
|
# {% else %}
|
||||||
Not Connected
|
# Not Connected
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon: "mdi:wifi"
|
# icon: "mdi:wifi"
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/mallika/mallika"
|
# state_topic: "owntracks/mallika/mallika"
|
||||||
name: "Mallika Driving Speed"
|
# name: "Mallika Driving Speed"
|
||||||
value_template: "{{ value_json.vel |int|round}}"
|
# value_template: "{{ value_json.vel |int|round}}"
|
||||||
unit_of_measurement: miles
|
# unit_of_measurement: miles
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/suresh/suresh"
|
# state_topic: "owntracks/suresh/suresh"
|
||||||
name: "Suresh Driving Speed"
|
# name: "Suresh Driving Speed"
|
||||||
value_template: "{{ value_json.vel |int|round}}"
|
# value_template: "{{ value_json.vel |int|round}}"
|
||||||
unit_of_measurement: miles
|
# unit_of_measurement: miles
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/srinika/srinika"
|
# state_topic: "owntracks/srinika/srinika"
|
||||||
name: "Srinika Driving Speed"
|
# name: "Srinika Driving Speed"
|
||||||
value_template: "{{ value_json.vel |int|round}}"
|
# value_template: "{{ value_json.vel |int|round}}"
|
||||||
unit_of_measurement: miles
|
# unit_of_measurement: miles
|
||||||
|
|
||||||
- platform: mqtt
|
# - platform: mqtt
|
||||||
state_topic: "owntracks/hasika/hasika"
|
# state_topic: "owntracks/hasika/hasika"
|
||||||
name: "Hasika Driving Speed"
|
# name: "Hasika Driving Speed"
|
||||||
value_template: "{{ value_json.vel |int|round}}"
|
# value_template: "{{ value_json.vel |int|round}}"
|
||||||
unit_of_measurement: miles
|
# unit_of_measurement: miles
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
suresh_iphone_battery_ot:
|
# suresh_iphone_battery_ot:
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: >
|
# value_template: >
|
||||||
{% if states('sensor.suresh_iphone_battery_ot') != "unknown" %}
|
# {% if states('sensor.suresh_iphone_battery_ot') != "unknown" %}
|
||||||
{{ states('sensor.suresh_iphone_battery_ot')| int }}
|
# {{ states('sensor.suresh_iphone_battery_ot')| int }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
0
|
# 0
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
icon_template: >-
|
# icon_template: >-
|
||||||
{% if states('sensor.suresh_iphone_battery_ot') != "unknown" %}
|
# {% if states('sensor.suresh_iphone_battery_ot') != "unknown" %}
|
||||||
{% set battery_level = states('sensor.suresh_iphone_battery_ot')|int (-1)%}
|
# {% set battery_level = states('sensor.suresh_iphone_battery_ot')|int (-1)%}
|
||||||
{% set battery_round = (battery_level|int / 10)|int * 10 %}
|
# {% set battery_round = (battery_level|int / 10)|int * 10 %}
|
||||||
{% if states('sensor.suresh_iphone_battery_state') | lower == "charging" %}
|
# {% if states('sensor.suresh_iphone_battery_state') | lower == "charging" %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery-charging-100
|
# mdi:battery-charging-100
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-charging-{{ battery_round }}
|
# mdi:battery-charging-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery
|
# mdi:battery
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-{{ battery_round }}
|
# mdi:battery-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
mallika_iphone_battery_ot:
|
# mallika_iphone_battery_ot:
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ states('sensor.mallika_iphone_battery_ot')|int(-1) }}"
|
# value_template: "{{ states('sensor.mallika_iphone_battery_ot')|int(-1) }}"
|
||||||
icon_template: >-
|
# icon_template: >-
|
||||||
{% if states('sensor.mallika_iphone_battery_ot') != "unknown" %}
|
# {% if states('sensor.mallika_iphone_battery_ot') != "unknown" %}
|
||||||
{% set battery_level = states('sensor.mallika_iphone_battery_ot')|int (-1)%}
|
# {% set battery_level = states('sensor.mallika_iphone_battery_ot')|int (-1)%}
|
||||||
{% set battery_round = (battery_level|int / 10)|int * 10 %}
|
# {% set battery_round = (battery_level|int / 10)|int * 10 %}
|
||||||
{% if states('sensor.mallika_iphone_battery_state') | lower == "charging" %}
|
# {% if states('sensor.mallika_iphone_battery_state') | lower == "charging" %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery-charging-100
|
# mdi:battery-charging-100
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-charging-{{ battery_round }}
|
# mdi:battery-charging-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery
|
# mdi:battery
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-{{ battery_round }}
|
# mdi:battery-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
srinika_iphone_battery_ot:
|
# srinika_iphone_battery_ot:
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ states('sensor.srinika_iphone_battery_ot')|int(-1) }}"
|
# value_template: "{{ states('sensor.srinika_iphone_battery_ot')|int(-1) }}"
|
||||||
icon_template: >-
|
# icon_template: >-
|
||||||
{% if states('sensor.srinika_iphone_battery_ot') != "unknown" %}
|
# {% if states('sensor.srinika_iphone_battery_ot') != "unknown" %}
|
||||||
{% set battery_level = states('sensor.srinika_iphone_battery_ot')|int (-1)%}
|
# {% set battery_level = states('sensor.srinika_iphone_battery_ot')|int (-1)%}
|
||||||
{% set battery_round = (battery_level|int / 10)|int * 10 %}
|
# {% set battery_round = (battery_level|int / 10)|int * 10 %}
|
||||||
{% if states('sensor.srinika_iphone_battery_state') | lower == "charging" %}
|
# {% if states('sensor.srinika_iphone_battery_state') | lower == "charging" %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery-charging-100
|
# mdi:battery-charging-100
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-charging-{{ battery_round }}
|
# mdi:battery-charging-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery
|
# mdi:battery
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-{{ battery_round }}
|
# mdi:battery-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
|
|
||||||
- platform: template
|
# - platform: template
|
||||||
sensors:
|
# sensors:
|
||||||
hasika_iphone_battery_ot:
|
# hasika_iphone_battery_ot:
|
||||||
unit_of_measurement: "%"
|
# unit_of_measurement: "%"
|
||||||
value_template: "{{ states('sensor.hasika_iphone_battery_ot')|int(-1) }}"
|
# value_template: "{{ states('sensor.hasika_iphone_battery_ot')|int(-1) }}"
|
||||||
icon_template: >-
|
# icon_template: >-
|
||||||
{% if states('sensor.hasika_iphone_battery_ot') != "unknown" %}
|
# {% if states('sensor.hasika_iphone_battery_ot') != "unknown" %}
|
||||||
{% set battery_level = states('sensor.hasika_iphone_battery_ot')|int (-1)%}
|
# {% set battery_level = states('sensor.hasika_iphone_battery_ot')|int (-1)%}
|
||||||
{% set battery_round = (battery_level|int / 10)|int * 10 %}
|
# {% set battery_round = (battery_level|int / 10)|int * 10 %}
|
||||||
{% if states('sensor.hasika_iphone_battery_state') | lower == "charging" %}
|
# {% if states('sensor.hasika_iphone_battery_state') | lower == "charging" %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery-charging-100
|
# mdi:battery-charging-100
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-charging-{{ battery_round }}
|
# mdi:battery-charging-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_level == -1 %}
|
# {% if battery_level == -1 %}
|
||||||
mdi:battery-unknown
|
# mdi:battery-unknown
|
||||||
{% else %}
|
# {% else %}
|
||||||
{% if battery_round >= 100 %}
|
# {% if battery_round >= 100 %}
|
||||||
mdi:battery
|
# mdi:battery
|
||||||
{% elif battery_round > 0 %}
|
# {% elif battery_round > 0 %}
|
||||||
mdi:battery-{{ battery_round }}
|
# mdi:battery-{{ battery_round }}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
{% else %}
|
# {% else %}
|
||||||
mdi:battery-alert
|
# mdi:battery-alert
|
||||||
{% endif %}
|
# {% endif %}
|
||||||
|
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
# _ _ _
|
# # _ _ _
|
||||||
# /\ | | | | (_)
|
# # /\ | | | | (_)
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
# # / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
# # / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
# # / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
# # /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
||||||
#
|
# #
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
|
|
||||||
automation:
|
# automation:
|
||||||
#
|
# #
|
||||||
# This automation alerts family members when they are "moving" - meaning either in driving from work,
|
# # This automation alerts family members when they are "moving" - meaning either in driving from work,
|
||||||
# kids got on the school bus, and bus is moving...etc
|
# # kids got on the school bus, and bus is moving...etc
|
||||||
# This will only announces/ alert when someone is at home.
|
# # This will only announces/ alert when someone is at home.
|
||||||
#
|
# #
|
||||||
- alias: Alert When Moving
|
# - alias: Alert When Moving
|
||||||
trigger:
|
# trigger:
|
||||||
platform: numeric_state
|
# platform: numeric_state
|
||||||
entity_id:
|
# entity_id:
|
||||||
- sensor.suresh_driving_speed
|
# - sensor.suresh_driving_speed
|
||||||
- sensor.mallika_driving_speed
|
# - sensor.mallika_driving_speed
|
||||||
- sensor.srinika_driving_speed
|
# - sensor.srinika_driving_speed
|
||||||
- sensor.hasika_driving_speed
|
# - sensor.hasika_driving_speed
|
||||||
above: 8
|
# above: 8
|
||||||
condition:
|
# condition:
|
||||||
- condition: template
|
# - condition: template
|
||||||
value_template: >
|
# value_template: >
|
||||||
{%- if state_attr('automation.alert_when_moving', 'last_triggered') -%}
|
# {%- if state_attr('automation.alert_when_moving', 'last_triggered') -%}
|
||||||
{{ (as_timestamp(now()) - as_timestamp(state_attr('automation.alert_when_moving', 'last_triggered'))) > 300 }}
|
# {{ (as_timestamp(now()) - as_timestamp(state_attr('automation.alert_when_moving', 'last_triggered'))) > 300 }}
|
||||||
{%- else -%}
|
# {%- else -%}
|
||||||
true
|
# true
|
||||||
{%- endif -%}
|
# {%- endif -%}
|
||||||
- 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.home') | 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:
|
||||||
message: >-
|
# message: >-
|
||||||
{% set apostrophe = "\'" %}
|
# {% set apostrophe = "\'" %}
|
||||||
{{ trigger.entity_id.split('.')[1].split('_')[0] |title ~ apostrophe ~ 's' }} vehicle is in motion.
|
# {{ trigger.entity_id.split('.')[1].split('_')[0] |title ~ apostrophe ~ 's' }} vehicle is in motion.
|
||||||
- service: script.notify_me
|
# - service: script.notify_me
|
||||||
data_template:
|
# data_template:
|
||||||
message: >-
|
# message: >-
|
||||||
{% set apostrophe = "\'" %}
|
# {% set apostrophe = "\'" %}
|
||||||
{{ trigger.entity_id.split('.')[1].split('_')[0] |title ~ apostrophe ~ 's' }} vehicle is going at {{ trigger.to_state.state |round *2 }} mph.
|
# {{ trigger.entity_id.split('.')[1].split('_')[0] |title ~ apostrophe ~ 's' }} vehicle is going at {{ trigger.to_state.state |round *2 }} mph.
|
||||||
|
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
# Automation: Notify of iPhone Low Battery
|
# # Automation: Notify of iPhone Low Battery
|
||||||
###############################################################################
|
# ###############################################################################
|
||||||
- alias: Notify Low battery
|
# - alias: Notify Low battery
|
||||||
initial_state: true
|
# initial_state: true
|
||||||
trigger:
|
# trigger:
|
||||||
platform: numeric_state
|
# platform: numeric_state
|
||||||
entity_id:
|
# entity_id:
|
||||||
- device_tracker.life360_suresh
|
# - device_tracker.suresh
|
||||||
- device_tracker.life360_mallika
|
# - device_tracker.mallika
|
||||||
- device_tracker.life360_srinika
|
# - device_tracker.srinika
|
||||||
- device_tracker.life360_hasika
|
# - device_tracker.hasika
|
||||||
value_template: "{{ state.attributes.battery }}"
|
# value_template: "{{ state.attributes.battery }}"
|
||||||
below: 25
|
# below: 25
|
||||||
condition:
|
# condition:
|
||||||
- condition: template
|
# - condition: template
|
||||||
value_template: "{{ states('input_boolean.battery_notifications') == 'on' }}"
|
# value_template: "{{ states('input_boolean.battery_notifications') == 'on' }}"
|
||||||
action:
|
# action:
|
||||||
- service: script.notify_me
|
# - service: script.notify_me
|
||||||
data_template:
|
# data_template:
|
||||||
message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] | title }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
# message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] | title }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
||||||
- service: script.voice_notify
|
# - service: script.voice_notify
|
||||||
data_template:
|
# data_template:
|
||||||
message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
# message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
||||||
- service: script.led_message
|
# - service: script.led_message
|
||||||
data_template:
|
# data_template:
|
||||||
message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
# message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
||||||
|
|
||||||
# - alias: Alert Low Battery
|
# # - alias: Alert Low Battery
|
||||||
# trigger:
|
# # trigger:
|
||||||
# - platform: template
|
# # - platform: template
|
||||||
# value_template: >
|
# # value_template: >
|
||||||
# {% set ns = namespace(lowBattery=false) %}
|
# # {% set ns = namespace(lowBattery=false) %}
|
||||||
# {%- for x in states if x.attributes and x.attributes.battery_level and x.attributes.battery_level |int <= 24 %}
|
# # {%- for x in states if x.attributes and x.attributes.battery_level and x.attributes.battery_level |int <= 24 %}
|
||||||
# {% set ns.lowBattery = true %}{% endfor %}
|
# # {% set ns.lowBattery = true %}{% endfor %}
|
||||||
# {{ ns.lowBattery }}
|
# # {{ ns.lowBattery }}
|
||||||
# condition:
|
# # condition:
|
||||||
# - condition: template
|
# # - condition: template
|
||||||
# value_template: "{{ ((trigger.to_state.state | int) < states('sensor.battery_alert_threshold') | int) }}"
|
# # value_template: "{{ ((trigger.to_state.state | int) < states('sensor.battery_alert_threshold') | int) }}"
|
||||||
# action:
|
# # action:
|
||||||
# - service: script.voice_notify
|
# # - service: script.voice_notify
|
||||||
# data_template:
|
# # data_template:
|
||||||
# message: >
|
# # message: >
|
||||||
# {% set ns = namespace(lowBattery="") %}
|
# # {% set ns = namespace(lowBattery="") %}
|
||||||
# {%- for x in states if x.attributes and x.attributes.battery_level and x.attributes.battery_level |int <= 24 %}
|
# # {%- for x in states if x.attributes and x.attributes.battery_level and x.attributes.battery_level |int <= 24 %}
|
||||||
# {%- if loop.first %}The {% elif loop.last %} and the {% else %}, the {% endif -%}
|
# # {%- if loop.first %}The {% elif loop.last %} and the {% else %}, the {% endif -%}
|
||||||
# {% set ns.lowBattery = ns.lowBattery ~ ',' ~ x.name %}
|
# # {% set ns.lowBattery = ns.lowBattery ~ ',' ~ x.name %}
|
||||||
# {%- endfor %}
|
# # {%- endfor %}
|
||||||
# {{ ns.lowBattery -}}
|
# # {{ ns.lowBattery -}}
|
||||||
# {{- ' battery is ' if ns.lowBattery.split(',')|count == 2 else ' batteries are ' -}} less than 25 percent.
|
# # {{- ' battery is ' if ns.lowBattery.split(',')|count == 2 else ' batteries are ' -}} less than 25 percent.
|
||||||
# - service: script.led_message
|
# # - service: script.led_message
|
||||||
# data_template:
|
# # data_template:
|
||||||
# message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
# # message: "{{ trigger.to_state.attributes.friendly_name.split(' ')[1] }}'s phone battery is : {{ trigger.to_state.attributes.battery }}%."
|
||||||
|
|
||||||
- alias: Check Wi-Fi Status of iPhones At Home
|
# - alias: Check Wi-Fi Status of iPhones At Home
|
||||||
initial_state: true
|
# initial_state: true
|
||||||
trigger:
|
# trigger:
|
||||||
- platform: state
|
# - platform: state
|
||||||
entity_id:
|
# entity_id:
|
||||||
- device_tracker.life360_mallika
|
# - device_tracker.mallika
|
||||||
- device_tracker.life360_suresh
|
# - device_tracker.suresh
|
||||||
- device_tracker.life360_srinika
|
# - device_tracker.srinika
|
||||||
- device_tracker.life360_hasika
|
# - device_tracker.hasika
|
||||||
from: "not_home"
|
# from: "not_home"
|
||||||
to: "home"
|
# to: "home"
|
||||||
for: "00:05:00"
|
# for: "00:05:00"
|
||||||
condition:
|
# condition:
|
||||||
condition: or
|
# condition: or
|
||||||
conditions:
|
# conditions:
|
||||||
- condition: state
|
# - condition: state
|
||||||
entity_id: sensor.hasika_iphone_wifi_state
|
# entity_id: sensor.hasika_iphone_wifi_state
|
||||||
state: "Not Connected"
|
# state: "Not Connected"
|
||||||
- condition: state
|
# - condition: state
|
||||||
entity_id: sensor.mallika_iphone_wifi_state
|
# entity_id: sensor.mallika_iphone_wifi_state
|
||||||
state: "Not Connected"
|
# state: "Not Connected"
|
||||||
- condition: state
|
# - condition: state
|
||||||
entity_id: sensor.srinika_iphone_wifi_state
|
# entity_id: sensor.srinika_iphone_wifi_state
|
||||||
state: "Not Connected"
|
# state: "Not Connected"
|
||||||
- condition: state
|
# - condition: state
|
||||||
entity_id: sensor.suresh_iphone_wifi_state
|
# entity_id: sensor.suresh_iphone_wifi_state
|
||||||
state: "Not Connected"
|
# state: "Not Connected"
|
||||||
action:
|
# action:
|
||||||
- service: script.notify_me
|
# - service: script.notify_me
|
||||||
data_template:
|
# data_template:
|
||||||
message: >
|
# message: >
|
||||||
{% set member = trigger.entity_id.split('.')[1].split('_')[0] %}
|
# {% set member = trigger.entity_id.split('.')[1].split('_')[0] %}
|
||||||
{{ member | title }}'s iPhone is not connected to Wi-Fi at home!
|
# {{ member | title }}'s iPhone is not connected to Wi-Fi at home!
|
||||||
- service: script.voice_notify
|
# - service: script.voice_notify
|
||||||
data_template:
|
# data_template:
|
||||||
message: >
|
# message: >
|
||||||
{% set member = trigger.entity_id.split('.')[1].split('_')[0] %}
|
# {% set member = trigger.entity_id.split('.')[1].split('_')[0] %}
|
||||||
{{ member | title }}'s iPhone is not connected to Wi-Fi at home!
|
# {{ member | title }}'s iPhone is not connected to Wi-Fi at home!
|
||||||
|
|
|
@ -13,6 +13,7 @@ homeassistant:
|
||||||
# frontdoor_camera_url: http://username:password@192.168.xxx.xxx/ISAPI/Streaming/channels/101/picture
|
# frontdoor_camera_url: http://username:password@192.168.xxx.xxx/ISAPI/Streaming/channels/101/picture
|
||||||
#
|
#
|
||||||
camera:
|
camera:
|
||||||
|
|
||||||
- platform: generic
|
- platform: generic
|
||||||
name: Frontdoor Camera
|
name: Frontdoor Camera
|
||||||
still_image_url: !secret frontdoor_camera_url
|
still_image_url: !secret frontdoor_camera_url
|
||||||
|
@ -58,9 +59,12 @@ camera:
|
||||||
# input: porch_camera_rtsp_url
|
# input: porch_camera_rtsp_url
|
||||||
# name: Porch Camera
|
# name: Porch Camera
|
||||||
|
|
||||||
- platform: mjpeg
|
# - platform: mjpeg
|
||||||
mjpeg_url: !secret garage_camera_url
|
# mjpeg_url: !secret garage_camera_url
|
||||||
name: Garage Camera
|
# name: Garage Camera
|
||||||
|
|
||||||
|
# add amcrest cameras
|
||||||
|
- platform: amcrest
|
||||||
|
|
||||||
- platform: local_file
|
- platform: local_file
|
||||||
name: Frontdoor Latest Scan
|
name: Frontdoor Latest Scan
|
||||||
|
@ -87,6 +91,16 @@ camera:
|
||||||
shell_command:
|
shell_command:
|
||||||
reset_camera_stream: !secret camera_stream_restart_docker_url
|
reset_camera_stream: !secret camera_stream_restart_docker_url
|
||||||
|
|
||||||
|
# Amcrest Camera Model IP8M-T2669EW-AI
|
||||||
|
amcrest:
|
||||||
|
- host: !secret amcrest_front_camera_ip
|
||||||
|
username: !secret amcrest_front_camera_username
|
||||||
|
password: !secret amcrest_front_camera_password
|
||||||
|
binary_sensors:
|
||||||
|
- motion_detected
|
||||||
|
- crossline_detected
|
||||||
|
- online
|
||||||
|
|
||||||
switch:
|
switch:
|
||||||
- platform: rest
|
- platform: rest
|
||||||
resource: !secret camera_stream_docker_url
|
resource: !secret camera_stream_docker_url
|
||||||
|
@ -132,22 +146,46 @@ binary_sensor:
|
||||||
payload_off: "OFF"
|
payload_off: "OFF"
|
||||||
value_template: "{{ value }}"
|
value_template: "{{ value }}"
|
||||||
|
|
||||||
|
# image_processing:
|
||||||
|
# - platform: tensorflow
|
||||||
|
# scan_interval: 10000
|
||||||
|
# source:
|
||||||
|
# - entity_id: camera.frontdoor_camera
|
||||||
|
# - entity_id: camera.driveway_camera
|
||||||
|
# - entity_id: camera.patio_camera
|
||||||
|
# - entity_id: camera.playarea_camera
|
||||||
|
# - entity_id: camera.garage_camera
|
||||||
|
# - entity_id: camera.3d_printer_camera
|
||||||
|
# - entity_id: camera.porch_camera
|
||||||
|
# file_out:
|
||||||
|
# - "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_latest.jpg"
|
||||||
|
# - "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg"
|
||||||
|
# model:
|
||||||
|
# graph: /config/tensorflow/models/efficientdet_d0_coco17_tpu-32/
|
||||||
|
|
||||||
image_processing:
|
image_processing:
|
||||||
- platform: tensorflow
|
- platform: doods
|
||||||
scan_interval: 10000
|
scan_interval: 10000
|
||||||
|
url: !secret doods_server_url
|
||||||
|
detector: tensorflow
|
||||||
source:
|
source:
|
||||||
- entity_id: camera.frontdoor_camera
|
- entity_id: camera.frontdoor_camera
|
||||||
- entity_id: camera.driveway_camera
|
- entity_id: camera.driveway_camera
|
||||||
- entity_id: camera.patio_camera
|
- entity_id: camera.patio_camera
|
||||||
- entity_id: camera.playarea_camera
|
- entity_id: camera.playarea_camera
|
||||||
- entity_id: camera.garage_camera
|
- entity_id: camera.garage
|
||||||
- entity_id: camera.3d_printer_camera
|
- entity_id: camera.3d_printer_camera
|
||||||
- entity_id: camera.porch_camera
|
- entity_id: camera.porch_camera
|
||||||
file_out:
|
file_out:
|
||||||
- "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_latest.jpg"
|
- "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_latest.jpg"
|
||||||
- "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg"
|
- "/config/www/downloads/camera/{{- camera_entity.split('.')[1].split('_')[0] -}}/{{ camera_entity.split('.')[1].split('_')[0] }}_{{ now().strftime('%Y%m%d_%H%M%S') }}.jpg"
|
||||||
model:
|
labels:
|
||||||
graph: /config/tensorflow/models/efficientdet_d0_coco17_tpu-32/
|
- name: person
|
||||||
|
confidence: 75
|
||||||
|
- name: car
|
||||||
|
confidence: 90
|
||||||
|
- name: truck
|
||||||
|
confidence: 90
|
||||||
|
|
||||||
input_label:
|
input_label:
|
||||||
current_stream:
|
current_stream:
|
||||||
|
@ -240,7 +278,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_porch_camera
|
entity_id: image_processing.doods_porch_camera
|
||||||
|
|
||||||
#
|
#
|
||||||
# Scan front door and driveway cameras when motion detected
|
# Scan front door and driveway cameras when motion detected
|
||||||
|
@ -261,14 +299,14 @@ automation:
|
||||||
value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == '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.doods_frontdoor_camera
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_driveway_camera
|
entity_id: image_processing.doods_driveway_camera
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{% if state_attr('image_processing.tensorflow_frontdoor_camera', 'summary') != None %}
|
{% if state_attr('image_processing.doods_frontdoor_camera', 'summary') != None %}
|
||||||
{% if state_attr('image_processing.tensorflow_frontdoor_camera', 'summary') |count > 0 %}
|
{% if state_attr('image_processing.doods_frontdoor_camera', 'summary') |count > 0 %}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
|
@ -280,7 +318,7 @@ automation:
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
message: >-
|
message: >-
|
||||||
{%- set e_id = "image_processing.tensorflow_frontdoor_camera" -%}
|
{%- set e_id = "image_processing.doods_frontdoor_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -295,7 +333,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: 'Front door motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
title: 'Front door motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_frontdoor_camera" -%}
|
{%- set e_id = "image_processing.doods_frontdoor_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -314,7 +352,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: "Front Door Motion"
|
title: "Front Door Motion"
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_frontdoor_camera" -%}
|
{%- set e_id = "image_processing.doods_frontdoor_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -338,7 +376,7 @@ automation:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_garage_camera
|
entity_id: image_processing.doods_garage
|
||||||
#
|
#
|
||||||
# Scan driveway and frontdoor cameras when motion detected
|
# Scan driveway and frontdoor cameras when motion detected
|
||||||
# if the garage doors are open, scan garage cameras as well
|
# if the garage doors are open, scan garage cameras as well
|
||||||
|
@ -361,14 +399,14 @@ automation:
|
||||||
value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == '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.doods_driveway_camera
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_frontdoor_camera
|
entity_id: image_processing.doods_frontdoor_camera
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{% if state_attr('image_processing.tensorflow_driveway_camera', 'summary') != None %}
|
{% if state_attr('image_processing.doods_driveway_camera', 'summary') != None %}
|
||||||
{% if state_attr('image_processing.tensorflow_driveway_camera', 'summary') |count > 0 %}
|
{% if state_attr('image_processing.doods_driveway_camera', 'summary') |count > 0 %}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
|
@ -380,7 +418,7 @@ automation:
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
message: >-
|
message: >-
|
||||||
{%- set e_id = "image_processing.tensorflow_driveway_camera" -%}
|
{%- set e_id = "image_processing.doods_driveway_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -394,7 +432,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: "Driveway Motion"
|
title: "Driveway Motion"
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_driveway_camera" -%}
|
{%- set e_id = "image_processing.doods_driveway_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -412,7 +450,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: 'Driveway motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
title: 'Driveway motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_driveway_camera" -%}
|
{%- set e_id = "image_processing.doods_driveway_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -438,7 +476,7 @@ automation:
|
||||||
|
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_garage_camera
|
entity_id: image_processing.doods_garage
|
||||||
|
|
||||||
#
|
#
|
||||||
# When motion detected in garage, scan garage camera
|
# When motion detected in garage, scan garage camera
|
||||||
|
@ -459,7 +497,7 @@ automation:
|
||||||
action:
|
action:
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_garage_camera
|
entity_id: image_processing.doods_garage
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >
|
value_template: >
|
||||||
{% if states('binary_sensor.door_window_sensor_158d0004248d5b') == "on" or
|
{% if states('binary_sensor.door_window_sensor_158d0004248d5b') == "on" or
|
||||||
|
@ -470,14 +508,14 @@ automation:
|
||||||
{% endif %}
|
{% endif %}
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_driveway_camera
|
entity_id: image_processing.doods_driveway_camera
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_frontdoor_camera
|
entity_id: image_processing.doods_frontdoor_camera
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{% if state_attr('image_processing.tensorflow_garage_camera', 'summary') != None %}
|
{% if state_attr('image_processing.doods_garage', 'summary') != None %}
|
||||||
{% if state_attr('image_processing.tensorflow_garage_camera', 'summary') |count > 0 %}
|
{% if state_attr('image_processing.doods_garage', 'summary') |count > 0 %}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
|
@ -489,7 +527,7 @@ automation:
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
message: >-
|
message: >-
|
||||||
{%- set e_id = "image_processing.tensorflow_garage_camera" -%}
|
{%- set e_id = "image_processing.doods_garage" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -503,7 +541,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: "Garage Motion"
|
title: "Garage Motion"
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_garage_camera" -%}
|
{%- set e_id = "image_processing.doods_garage" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -521,7 +559,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: 'Garage motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
title: 'Garage motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_garage_camera" -%}
|
{%- set e_id = "image_processing.doods_garage" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -556,14 +594,14 @@ automation:
|
||||||
value_template: "{{ states('alarm_control_panel.home') == 'armed_home' or states('alarm_control_panel.home') == '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.doods_patio_camera
|
||||||
- service: image_processing.scan
|
- service: image_processing.scan
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: image_processing.tensorflow_playarea_camera
|
entity_id: image_processing.doods_playarea_camera
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{% if state_attr('image_processing.tensorflow_patio_camera', 'summary') != None %}
|
{% if state_attr('image_processing.doods_patio_camera', 'summary') != None %}
|
||||||
{% if state_attr('image_processing.tensorflow_patio_camera', 'summary') |count > 0 %}
|
{% if state_attr('image_processing.doods_patio_camera', 'summary') |count > 0 %}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
|
@ -575,7 +613,7 @@ automation:
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
data_template:
|
data_template:
|
||||||
message: >-
|
message: >-
|
||||||
{%- set e_id = "image_processing.tensorflow_patio_camera" -%}
|
{%- set e_id = "image_processing.doods_patio_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -589,7 +627,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: "Backyardge Motion"
|
title: "Backyardge Motion"
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_patio_camera" -%}
|
{%- set e_id = "image_processing.doods_patio_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -607,7 +645,7 @@ automation:
|
||||||
data_template:
|
data_template:
|
||||||
title: 'Backyard motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
title: 'Backyard motion {{ now().strftime("%d %h %Y, %I:%M:%S %p") }}'
|
||||||
message: >
|
message: >
|
||||||
{%- set e_id = "image_processing.tensorflow_patio_camera" -%}
|
{%- set e_id = "image_processing.doods_patio_camera" -%}
|
||||||
{%- if state_attr(e_id, 'summary') -%}
|
{%- if state_attr(e_id, 'summary') -%}
|
||||||
{%- set count = state_attr(e_id, 'summary') | count -%}
|
{%- set count = state_attr(e_id, 'summary') | count -%}
|
||||||
{%- for x in state_attr(e_id, 'summary') | list -%}
|
{%- for x in state_attr(e_id, 'summary') | list -%}
|
||||||
|
@ -693,7 +731,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "camera.garage_camera"
|
entity_id: "camera.garage"
|
||||||
filename:
|
filename:
|
||||||
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
||||||
(states.binary_sensor.motion_sensor_158d00024ee084.last_updated ~ '').replace('-','_')
|
(states.binary_sensor.motion_sensor_158d00024ee084.last_updated ~ '').replace('-','_')
|
||||||
|
@ -742,7 +780,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('device_tracker.life360_suresh') == 'home' }}"
|
value_template: "{{ states('device_tracker.suresh') == 'home' }}"
|
||||||
|
|
||||||
- service: notify.ios_devices
|
- service: notify.ios_devices
|
||||||
data_template:
|
data_template:
|
||||||
|
@ -792,7 +830,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "camera.garage_camera"
|
entity_id: "camera.garage"
|
||||||
filename:
|
filename:
|
||||||
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
||||||
(states.binary_sensor.motion_sensor_158d00024e57fb.last_updated ~ '').replace('-','_')
|
(states.binary_sensor.motion_sensor_158d00024e57fb.last_updated ~ '').replace('-','_')
|
||||||
|
@ -834,7 +872,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('device_tracker.life360_suresh') == 'home' }}"
|
value_template: "{{ states('device_tracker.suresh') == 'home' }}"
|
||||||
- service: notify.ios_devices
|
- service: notify.ios_devices
|
||||||
data_template:
|
data_template:
|
||||||
message: "Check Driveway camera!"
|
message: "Check Driveway camera!"
|
||||||
|
@ -869,8 +907,8 @@ automation:
|
||||||
action:
|
action:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: >-
|
value_template: >-
|
||||||
{% if state_attr('image_processing.tensorflow_frontdoor_camera', 'summary') != None %}
|
{% if state_attr('image_processing.doods_frontdoor_camera', 'summary') != None %}
|
||||||
{% if state_attr('image_processing.tensorflow_frontdoor_camera', 'summary') |count > 0 %}
|
{% if state_attr('image_processing.doods_frontdoor_camera', 'summary') |count > 0 %}
|
||||||
true
|
true
|
||||||
{% else %}
|
{% else %}
|
||||||
false
|
false
|
||||||
|
@ -924,7 +962,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('device_tracker.life360_suresh') == 'home' }}"
|
value_template: "{{ states('device_tracker.suresh') == 'home' }}"
|
||||||
- service: notify.ios_devices
|
- service: notify.ios_devices
|
||||||
data_template:
|
data_template:
|
||||||
message: "Check Patio camera!"
|
message: "Check Patio camera!"
|
||||||
|
|
|
@ -1,409 +0,0 @@
|
||||||
# #
|
|
||||||
# # I COMMENTED OUT ALL THE TAGBOX RELATED STUFF AS I USE TENSORFLOW COMPONENT FOR IT.
|
|
||||||
# #
|
|
||||||
# homeassistant:
|
|
||||||
# customize:
|
|
||||||
# image_processing.facebox_frontdoor_camera:
|
|
||||||
# friendly_name: People @ Front Door
|
|
||||||
# image_processing.facebox_driveway_camera:
|
|
||||||
# friendly_name: People @ Driveway
|
|
||||||
# image_processing.facebox_patio_camera:
|
|
||||||
# friendly_name: People @ Patio
|
|
||||||
# image_processing.facebox_playarea_camera:
|
|
||||||
# friendly_name: People @ Playarea
|
|
||||||
# image_processing.facebox_garage_camera:
|
|
||||||
# friendly_name: People @ Garage
|
|
||||||
|
|
||||||
# image_processing.tagbox_frontdoor_camera:
|
|
||||||
# friendly_name: Frontdoor Tag
|
|
||||||
# image_processing.tagbox_driveway_camera:
|
|
||||||
# friendly_name: Driveway Tag
|
|
||||||
# image_processing.tagbox_playarea_camera:
|
|
||||||
# friendly_name: Playarea Tag
|
|
||||||
# image_processing.tagbox_patio_camera:
|
|
||||||
# friendly_name: Patio Tag
|
|
||||||
# image_processing.tagbox_garage_camera:
|
|
||||||
# friendly_name: Garage Tag
|
|
||||||
|
|
||||||
# sensor.frontdoor_camera_objects:
|
|
||||||
# friendly_name: Things At Front Door
|
|
||||||
# sensor.driveway_camera_objects:
|
|
||||||
# friendly_name: Things At Driveway
|
|
||||||
# sensor.playarea_camera_objects:
|
|
||||||
# friendly_name: Things At Playarea
|
|
||||||
# sensor.patio_camera_objects:
|
|
||||||
# friendly_name: Things At Patio
|
|
||||||
# sensor.garage_camera_objects:
|
|
||||||
# friendly_name: Things in Garage
|
|
||||||
# sensor.frontdoor_camera_people:
|
|
||||||
# friendly_name: People At Front Door
|
|
||||||
# sensor.driveway_camera_people:
|
|
||||||
# friendly_name: People Driveway
|
|
||||||
# sensor.playarea_camera_people:
|
|
||||||
# friendly_name: People Playarea
|
|
||||||
# sensor.patio_camera_people:
|
|
||||||
# friendly_name: People Patio
|
|
||||||
# sensor.garage_camera_people:
|
|
||||||
# friendly_name: Garage Patio
|
|
||||||
|
|
||||||
# image_processing:
|
|
||||||
# - platform: facebox
|
|
||||||
# ip_address: !secret ha_ip_address
|
|
||||||
# scan_interval: 360
|
|
||||||
# port: 8080
|
|
||||||
# source:
|
|
||||||
# - entity_id: camera.frontdoor_camera
|
|
||||||
# - entity_id: camera.driveway_camera
|
|
||||||
# - entity_id: camera.patio_camera
|
|
||||||
# - entity_id: camera.playarea_camera
|
|
||||||
# - entity_id: camera.garage_camera
|
|
||||||
# # - platform: tagbox
|
|
||||||
# # scan_interval: 10000 # Default 10
|
|
||||||
# # ip_address: !secret ha_ip_address
|
|
||||||
# # port: 8081
|
|
||||||
# # source:
|
|
||||||
# # - entity_id: camera.frontdoor_camera
|
|
||||||
# # - entity_id: camera.driveway_camera
|
|
||||||
# # - entity_id: camera.patio_camera
|
|
||||||
# # - entity_id: camera.playarea_camera
|
|
||||||
# # - entity_id: camera.garage_camera
|
|
||||||
|
|
||||||
# sensor:
|
|
||||||
|
|
||||||
# ##
|
|
||||||
# #Facebox related sensors
|
|
||||||
# ##
|
|
||||||
# - platform: template
|
|
||||||
# sensors:
|
|
||||||
# frontdoor_camera_people:
|
|
||||||
# value_template: >-
|
|
||||||
# {% set faces = state_attr('image_processing.facebox_frontdoor_camera', 'matched_faces') %}
|
|
||||||
# {% if None != faces %}
|
|
||||||
# {% if faces | list | count == 0 %}
|
|
||||||
# Clear
|
|
||||||
# {% else %}
|
|
||||||
# {%- for face in faces | list %}{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{ face }}{%- endfor %}
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# - platform: template
|
|
||||||
# sensors:
|
|
||||||
# driveway_camera_people:
|
|
||||||
# value_template: >-
|
|
||||||
# {% set faces = state_attr('image_processing.facebox_driveway_camera', 'matched_faces') %}
|
|
||||||
# {% if None != faces %}
|
|
||||||
# {% if faces | list | count == 0 %}
|
|
||||||
# Clear
|
|
||||||
# {% else %}
|
|
||||||
# {%- for face in faces | list %}{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{ face }}{%- endfor %}
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# - platform: template
|
|
||||||
# sensors:
|
|
||||||
# patio_camera_people:
|
|
||||||
# value_template: >-
|
|
||||||
# {% set faces = state_attr('image_processing.facebox_patio_camera', 'matched_faces') %}
|
|
||||||
# {% if None != faces %}
|
|
||||||
# {% if faces | list | count == 0 %}
|
|
||||||
# Clear
|
|
||||||
# {% else %}
|
|
||||||
# {%- for face in faces | list %}{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{ face }}{%- endfor %}
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# - platform: template
|
|
||||||
# sensors:
|
|
||||||
# playarea_camera_people:
|
|
||||||
# value_template: >-
|
|
||||||
# {% set faces = state_attr('image_processing.facebox_playarea_camera', 'matched_faces') %}
|
|
||||||
# {% if None != faces %}
|
|
||||||
# {% if faces | list | count == 0 %}
|
|
||||||
# Clear
|
|
||||||
# {% else %}
|
|
||||||
# {%- for face in faces | list %}{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{ face }}{%- endfor %}
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# - platform: template
|
|
||||||
# sensors:
|
|
||||||
# garage_camera_people:
|
|
||||||
# value_template: >-
|
|
||||||
# {% set faces = state_attr('image_processing.facebox_garage_camera', 'matched_faces') %}
|
|
||||||
# {% if None != faces %}
|
|
||||||
# {% if faces | list | count == 0 %}
|
|
||||||
# Clear
|
|
||||||
# {% else %}
|
|
||||||
# {%- for face in faces | list %}{%- if loop.first %}{% elif loop.last %} and {% else %}, {% endif -%}{{ face }}{%- endfor %}
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# # ###########################################################################################################################
|
|
||||||
# # # Tagbox related Sensors; Please don't go crazy looking at the code. Here is the simple explanation.
|
|
||||||
# # # The tagbox gives a bunch of tags for each picture, and I eliminate a bunch of unwanted tags by filtering them out
|
|
||||||
# # # The unwanted tags are something that I really don't care - like a Tree in the front yard.
|
|
||||||
# # # Then I do custom mapping of the tags that fits my needs. That way I can display what I want rather than what I was given.
|
|
||||||
# # # I have no control over what tagbox gives, I want to pick and choose tags irrespective of confidence level.
|
|
||||||
# # ###########################################################################################################################
|
|
||||||
|
|
||||||
# # - platform: template
|
|
||||||
# # sensors:
|
|
||||||
# # frontdoor_camera_objects:
|
|
||||||
# # value_template: >-
|
|
||||||
# # {% set attribs = state_attr('image_processing.tagbox_frontdoor_camera', 'tags') %}
|
|
||||||
# # {%- if None != attribs -%}
|
|
||||||
# # {%- set tag_map = {'Vehicle':'Car', 'Sedan':'Car', 'Luxury vehicle':'Car', 'Driving':'Car',
|
|
||||||
# # 'Wheel':'Car', 'Automotive design':'Car', 'Automotive exterior':'Car',
|
|
||||||
# # 'Transport':'Car', 'Sports car':'Car', 'Land vehicle':'Car', 'Supercar':'Car',
|
|
||||||
# # 'Waterway':'Rain', 'Super car': 'Car'
|
|
||||||
# # } -%}
|
|
||||||
# # {%- set unwanted_tags = ['Asphalt', 'Backyard', 'City', 'Estate', 'Flower', 'Garden', 'Grass', 'Tree', 'Car', 'Vehicle', 'Suburb', 'Street',
|
|
||||||
# # 'Highway', 'Infrastructure', 'Lane', 'Lawn', 'Neighbourhood', 'Public space', 'Super car', 'Snow', 'Winter', 'Supercar',
|
|
||||||
# # 'Residential area', 'Road', 'Road surface', 'Sidewalk', 'Tarmac', 'Race track', 'Sport venue', 'Soil', 'Outdoor structure', 'Cartoon', 'Poster', 'Illustration',
|
|
||||||
# # 'Transport', 'Walkway', 'Yard', 'Screenshot', 'Night', 'Lighting and Light', 'Drawing', 'Sketch', 'Stadium',
|
|
||||||
# # 'Black-and-white', 'Monochrome', 'Monochrome photography', 'Black and White', 'Parking lot', 'Parking',
|
|
||||||
# # 'Black', 'White', 'Darkness', 'Light', 'Text'] -%}
|
|
||||||
# # {%- macro filter_unwanted(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in unwanted_tags -%}{{- comma() -}}{{- item -}}{% endfor %}{%- endmacro -%}
|
|
||||||
# # {%- macro mapped_items(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in tag_map -%}{{- comma() -}}{{- item -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {%- for item in tags if item in tag_map -%}{{- comma() -}}{{- tag_map[item] -}}{%- endfor -%}
|
|
||||||
# # {%- endmacro -%}
|
|
||||||
# # {% macro get_final_output(output_list) %}
|
|
||||||
# # {%- for x in output_list if x != "" -%}
|
|
||||||
# # {%- if loop.first %}{% elif loop.last %},{% else %},{% endif -%}{{- x -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {% endmacro %}
|
|
||||||
# # {%- set result = filter_unwanted(attribs| map(attribute='name')|list).split(',') -%}
|
|
||||||
# # {%- set output = get_final_output(mapped_items(result).split(',') | unique|list) -%}
|
|
||||||
# # {{- "Clear" if output |trim == "" else output -}}
|
|
||||||
# # {% endif %}
|
|
||||||
# # icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# # - platform: template
|
|
||||||
# # sensors:
|
|
||||||
# # driveway_camera_objects:
|
|
||||||
# # value_template: >-
|
|
||||||
# # {%- set attribs = state_attr('image_processing.tagbox_driveway_camera', 'tags') -%}
|
|
||||||
# # {%- if None != attribs -%}
|
|
||||||
# # {%- set tag_map = {'Vehicle':'Car', 'Sedan':'Car', 'Luxury vehicle':'Car', 'Driving':'Car',
|
|
||||||
# # 'Wheel':'Car', 'Automotive design':'Car', 'Automotive exterior':'Car',
|
|
||||||
# # 'Transport':'Car', 'Sports car':'Car', 'Land vehicle':'Car','Supercar':'Car',
|
|
||||||
# # 'Waterway':'Rain', 'Super car': 'Car'
|
|
||||||
# # } -%}
|
|
||||||
# # {%- set unwanted_tags = ['Asphalt', 'Backyard', 'City', 'Estate', 'Flower', 'Garden', 'Grass', 'Tree', 'Car', 'Vehicle', 'Suburb', 'Street',
|
|
||||||
# # 'Highway', 'Infrastructure', 'Lane', 'Lawn', 'Neighbourhood', 'Public space', 'Super car', 'Sport venue', 'Supercar',
|
|
||||||
# # 'Residential area', 'Road', 'Road surface', 'Sidewalk', 'Tarmac', 'Race track', 'Snow', 'Winter', 'Soil', 'Outdoor structure', 'Cartoon', 'Poster', 'Illustration',
|
|
||||||
# # 'Transport', 'Walkway', 'Yard', 'Screenshot', 'Night', 'Lighting and Light', 'Drawing', 'Sketch', 'Stadium',
|
|
||||||
# # 'Black-and-white', 'Monochrome', 'Monochrome photography', 'Black and White',
|
|
||||||
# # 'Black', 'White', 'Darkness', 'Light', 'Text'] -%}
|
|
||||||
# # {%- macro filter_unwanted(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in unwanted_tags -%}{{- comma() -}}{{- item -}}{% endfor %}{%- endmacro -%}
|
|
||||||
# # {%- macro mapped_items(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in tag_map -%}{{- comma() -}}{{- item -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {%- for item in tags if item in tag_map -%}{{- comma() -}}{{- tag_map[item] -}}{%- endfor -%}
|
|
||||||
# # {%- endmacro -%}
|
|
||||||
# # {% macro get_final_output(output_list) %}
|
|
||||||
# # {%- for x in output_list if x != "" -%}
|
|
||||||
# # {%- if loop.first %}{% elif loop.last %},{% else %},{% endif -%}{{- x -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {% endmacro %}
|
|
||||||
# # {%- set result = filter_unwanted(attribs| map(attribute='name')|list).split(',') -%}
|
|
||||||
# # {%- set output = get_final_output(mapped_items(result).split(',') | unique|list) -%}
|
|
||||||
# # {{- "Clear" if output |trim == "" else output -}}
|
|
||||||
# # {% endif %}
|
|
||||||
# # icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# # - platform: template
|
|
||||||
# # sensors:
|
|
||||||
# # patio_camera_objects:
|
|
||||||
# # value_template: >-
|
|
||||||
# # {% set attribs = state_attr('image_processing.tagbox_patio_camera', 'tags') %}
|
|
||||||
# # {%- if None != attribs -%}
|
|
||||||
# # {%- set tag_map = {'Waterway':'Rain'} -%}
|
|
||||||
# # {%- set unwanted_tags = ['Asphalt', 'Backyard', 'City', 'Estate', 'Flower', 'Garden', 'Grass', 'Tree', 'Vehicle','Driving', 'Transport', 'Car', 'Vehicle', 'Suburb', 'Street',
|
|
||||||
# # 'Highway', 'Infrastructure', 'Lane', 'Lawn', 'Neighbourhood', 'Public space', 'Car', 'Wheel', 'Sports car','Super car', 'Sport venue', 'Outdoor structure', 'Cartoon', 'Poster', 'Illustration',
|
|
||||||
# # 'Residential area', 'Road', 'Road surface', 'Sidewalk', 'Tarmac', 'Race track', 'Sedan', 'Automotive design', 'Snow', 'Winter', 'Soil', 'Stadium',
|
|
||||||
# # 'Transport', 'Walkway', 'Yard', 'Screenshot', 'Night', 'Lighting and Light', 'Luxury vehicle', 'Automotive exterior', 'Drawing', 'Sketch',
|
|
||||||
# # 'Black-and-white', 'Monochrome', 'Monochrome photography', 'Black and White', 'Black', 'White', 'Light', 'Text'] -%}
|
|
||||||
# # {%- macro filter_unwanted(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in unwanted_tags -%}{{- comma() -}}{{- item -}}{% endfor %}{%- endmacro -%}
|
|
||||||
# # {%- macro mapped_items(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in tag_map -%}{{- comma() -}}{{- item -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {%- for item in tags if item in tag_map -%}{{- comma() -}}{{- tag_map[item] -}}{%- endfor -%}
|
|
||||||
# # {%- endmacro -%}
|
|
||||||
# # {% macro get_final_output(output_list) %}
|
|
||||||
# # {%- for x in output_list if x != "" -%}
|
|
||||||
# # {%- if loop.first %}{% elif loop.last %},{% else %},{% endif -%}{{- x -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {% endmacro %}
|
|
||||||
# # {%- set result = filter_unwanted(attribs| map(attribute='name')|list).split(',') -%}
|
|
||||||
# # {%- set output = get_final_output(mapped_items(result).split(',') | unique|list) -%}
|
|
||||||
# # {{- "Clear" if output |trim == "" else output -}}
|
|
||||||
# # {% endif %}
|
|
||||||
# # icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# # - platform: template
|
|
||||||
# # sensors:
|
|
||||||
# # playarea_camera_objects:
|
|
||||||
# # value_template: >-
|
|
||||||
# # {% set attribs = state_attr('image_processing.tagbox_playarea_camera', 'tags') %}
|
|
||||||
# # {%- if None != attribs -%}
|
|
||||||
# # {%- set tag_map = {'Waterway':'Rain'} -%}
|
|
||||||
# # {%- set unwanted_tags = ['Asphalt', 'Backyard', 'City', 'Estate', 'Flower', 'Garden', 'Grass', 'Tree', 'Vehicle','Driving', 'Transport', 'Car', 'Vehicle', 'Suburb', 'Street',
|
|
||||||
# # 'Highway', 'Infrastructure', 'Lane', 'Lawn', 'Neighbourhood', 'Public space', 'Car', 'Wheel', 'Sports car', 'Super car', 'Winter', 'Soil', 'Stadium',
|
|
||||||
# # 'Residential area', 'Road', 'Road surface', 'Sidewalk', 'Tarmac', 'Race track', 'Sedan', 'Automotive design', 'Snow', 'Sport venue', 'Outdoor structure', 'Cartoon', 'Poster', 'Illustration',
|
|
||||||
# # 'Transport', 'Walkway', 'Yard', 'Screenshot', 'Night', 'Lighting and Light', 'Luxury vehicle', 'Automotive exterior', 'Drawing', 'Sketch',
|
|
||||||
# # 'Black-and-white', 'Monochrome', 'Monochrome photography', 'Black and White', 'Black', 'White', 'Light', 'Text'] -%}
|
|
||||||
# # {%- macro filter_unwanted(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in unwanted_tags -%}{{- comma() -}}{{- item -}}{% endfor %}{%- endmacro -%}
|
|
||||||
# # {%- macro mapped_items(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in tag_map -%}{{- comma() -}}{{- item -}}{%- endfor -%}
|
|
||||||
# # {%- for item in tags if item in tag_map -%}{{- comma() -}}{{- tag_map[item] -}}{%- endfor -%}
|
|
||||||
# # {%- endmacro -%}
|
|
||||||
# # {% macro get_final_output(output_list) %}
|
|
||||||
# # {%- for x in output_list if x != "" -%}
|
|
||||||
# # {%- if loop.first %}{% elif loop.last %},{% else %},{% endif -%}{{- x -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {% endmacro %}
|
|
||||||
# # {%- set result = filter_unwanted(attribs| map(attribute='name')|list).split(',') -%}
|
|
||||||
# # {%- set output = get_final_output(mapped_items(result).split(',') | unique|list) -%}
|
|
||||||
# # {{- "Clear" if output |trim == "" else output -}}
|
|
||||||
# # {% endif %}
|
|
||||||
# # icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# # - platform: template
|
|
||||||
# # sensors:
|
|
||||||
# # garage_camera_objects:
|
|
||||||
# # value_template: >-
|
|
||||||
# # {% set attribs = state_attr('image_processing.tagbox_garage_camera', 'tags') %}
|
|
||||||
# # {%- if None != attribs -%}
|
|
||||||
# # {%- set tag_map = {'Waterway':'Rain'} -%}
|
|
||||||
# # {%- set unwanted_tags = ['Asphalt', 'Backyard', 'City', 'Estate', 'Flower', 'Garden', 'Grass', 'Tree', 'Driving', 'Transport', 'Suburb', 'Street',
|
|
||||||
# # 'Highway', 'Infrastructure', 'Lane', 'Lawn', 'Neighbourhood', 'Public space', 'Winter', 'Soil', 'Stadium',
|
|
||||||
# # 'Residential area', 'Road', 'Road surface', 'Sidewalk', 'Tarmac', 'Race track', 'Sedan', 'Automotive design', 'Snow', 'Sport venue', 'Outdoor structure', 'Cartoon', 'Poster', 'Illustration',
|
|
||||||
# # 'Transport', 'Walkway', 'Yard', 'Screenshot', 'Night', 'Lighting and Light', 'Luxury vehicle', 'Automotive exterior', 'Drawing', 'Sketch',
|
|
||||||
# # 'Black-and-white', 'Monochrome', 'Monochrome photography', 'Black and White', 'Black', 'White', 'Light', 'Text'] -%}
|
|
||||||
# # {%- macro filter_unwanted(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in unwanted_tags -%}{{- comma() -}}{{- item -}}{% endfor %}{%- endmacro -%}
|
|
||||||
# # {%- macro mapped_items(tags) -%}
|
|
||||||
# # {%- set comma = joiner(',') -%}
|
|
||||||
# # {%- for item in tags if item not in tag_map -%}{{- comma() -}}{{- item -}}{%- endfor -%}
|
|
||||||
# # {%- for item in tags if item in tag_map -%}{{- comma() -}}{{- tag_map[item] -}}{%- endfor -%}
|
|
||||||
# # {%- endmacro -%}
|
|
||||||
# # {% macro get_final_output(output_list) %}
|
|
||||||
# # {%- for x in output_list if x != "" -%}
|
|
||||||
# # {%- if loop.first %}{% elif loop.last %},{% else %},{% endif -%}{{- x -}}
|
|
||||||
# # {%- endfor -%}
|
|
||||||
# # {% endmacro %}
|
|
||||||
# # {%- set result = filter_unwanted(attribs| map(attribute='name')|list).split(',') -%}
|
|
||||||
# # {%- set output = get_final_output(mapped_items(result).split(',') | unique|list) -%}
|
|
||||||
# # {{- "Clear" if output |trim == "" else output -}}
|
|
||||||
# # {% endif %}
|
|
||||||
# # icon_template: mdi:cctv
|
|
||||||
|
|
||||||
# automation:
|
|
||||||
|
|
||||||
# - alias: Alert Family Member Activity
|
|
||||||
# trigger:
|
|
||||||
# - platform: state
|
|
||||||
# entity_id:
|
|
||||||
# - sensor.frontdoor_camera_people
|
|
||||||
# - sensor.driveway_camera_people
|
|
||||||
# - sensor.patio_camera_people
|
|
||||||
# - sensor.playarea_camera_people
|
|
||||||
# - sensor.garage_camera_people
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: '{{ trigger.to_state.state | trim != "" and
|
|
||||||
# trigger.to_state.state | lower | trim != "unknown" and
|
|
||||||
# trigger.to_state.state | lower | trim != "clear" }}'
|
|
||||||
# action:
|
|
||||||
# - service: script.notify_me
|
|
||||||
# data_template:
|
|
||||||
# message: >-
|
|
||||||
# {% set camera_name = states['camera'][trigger.entity_id.split('.')[1].split('_')[0] ~ '_camera'].attributes.friendly_name %}
|
|
||||||
# {{ trigger.to_state.state }} is at the {{ camera_name }}.
|
|
||||||
|
|
||||||
# # - alias: Alert Object Activity
|
|
||||||
# # trigger:
|
|
||||||
# # - platform: state
|
|
||||||
# # entity_id:
|
|
||||||
# # - sensor.frontdoor_camera_objects
|
|
||||||
# # - sensor.driveway_camera_objects
|
|
||||||
# # - sensor.patio_camera_objects
|
|
||||||
# # - sensor.playarea_camera_objects
|
|
||||||
# # - sensor.garage_camera_objects
|
|
||||||
# # condition:
|
|
||||||
# # - condition: template
|
|
||||||
# # value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
|
||||||
# # - condition: template
|
|
||||||
# # value_template: '{{ trigger.to_state.state | trim != "" and
|
|
||||||
# # trigger.to_state.state | lower | trim != "unknown" and
|
|
||||||
# # trigger.to_state.state | lower | trim != "clear" }}'
|
|
||||||
# # action:
|
|
||||||
# # - service: script.notify_me
|
|
||||||
# # data_template:
|
|
||||||
# # message: >-
|
|
||||||
# # {% set camera_name = states['camera'][trigger.entity_id.split('.')[1].split('_')[0] ~ '_camera'].attributes.friendly_name %}
|
|
||||||
# # {{ trigger.to_state.state }} detected at the {{ camera_name }}.
|
|
||||||
|
|
||||||
# #
|
|
||||||
# # This automation basically scans image and keeps a count of people from each camera view and notifies using iOS notification
|
|
||||||
# # There is another automation that alerts in the house (using TTS) based on the data
|
|
||||||
# #
|
|
||||||
# - alias: Scan People and Objects
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# - platform: state
|
|
||||||
# entity_id:
|
|
||||||
# - binary_sensor.frontdoor_camera_motion
|
|
||||||
# - binary_sensor.driveway_camera_motion
|
|
||||||
# - binary_sensor.patio_camera_motion
|
|
||||||
# - binary_sensor.playarea_camera_motion
|
|
||||||
# - binary_sensor.frontdoor_camera_field_detection
|
|
||||||
# - binary_sensor.driveway_camera_field_detection
|
|
||||||
# - binary_sensor.patio_camera_field_detection
|
|
||||||
# - binary_sensor.playarea_camera_field_detection
|
|
||||||
# - binary_sensor.frontdoor_camera_line_crossing
|
|
||||||
# - binary_sensor.driveway_camera_line_crossing
|
|
||||||
# - binary_sensor.patio_camera_line_crossing
|
|
||||||
# - binary_sensor.playarea_camera_line_crossing
|
|
||||||
# - binary_sensor.garage_motion
|
|
||||||
# to: 'on'
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ states('input_boolean.notify_camera_alerts') == 'on' }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: >
|
|
||||||
# {% macro last_triggered(entity) %}
|
|
||||||
# {% set time_in_seconds = 30 %}
|
|
||||||
# {{ ( (as_timestamp(now()) - as_timestamp(states["binary_sensor"][entity].attributes.last_tripped_time)))|round|abs < time_in_seconds }}
|
|
||||||
# {% endmacro %}
|
|
||||||
# {{ last_triggered(trigger.entity_id.split('.')[1].split('_')[0] ~ '_camera_motion')}}
|
|
||||||
# action:
|
|
||||||
# - service: image_processing.scan
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "image_processing.facebox_{{- trigger.entity_id.split('.')[1].split('_')[0] -}}_camera"
|
|
||||||
# # - service: image_processing.scan
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "image_processing.tagbox_{{- trigger.entity_id.split('.')[1].split('_')[0] -}}_camera"
|
|
|
@ -40,7 +40,7 @@ automation:
|
||||||
action:
|
action:
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
data:
|
data:
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Turn ON Master Bedroom lights ON in the morning
|
# Turn ON Master Bedroom lights ON in the morning
|
||||||
|
@ -70,6 +70,9 @@ automation:
|
||||||
transition: 15
|
transition: 15
|
||||||
brightness: 25
|
brightness: 25
|
||||||
color_temp: 154
|
color_temp: 154
|
||||||
|
- service: switch.turn_on
|
||||||
|
data:
|
||||||
|
entity_id: switch.chromecast_monitor
|
||||||
|
|
||||||
- alias: Morning Master Bedroom Lights OFF (Mallika)
|
- alias: Morning Master Bedroom Lights OFF (Mallika)
|
||||||
initial_state: true
|
initial_state: true
|
||||||
|
@ -134,7 +137,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: switch.turn_off
|
- service: switch.turn_off
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
- service: switch.turn_off
|
- service: switch.turn_off
|
||||||
entity_id: switch.front_room
|
entity_id: switch.front_room
|
||||||
|
|
||||||
|
@ -153,7 +156,7 @@ automation:
|
||||||
# Turn outdoor lights on 15 minutes before sunset
|
# Turn outdoor lights on 15 minutes before sunset
|
||||||
###############################################################################
|
###############################################################################
|
||||||
- alias: Evening Outdoor Lights ON (At Sunset)
|
- alias: Evening Outdoor Lights ON (At Sunset)
|
||||||
initial_state: true
|
# initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: sun
|
platform: sun
|
||||||
event: sunset
|
event: sunset
|
||||||
|
@ -187,23 +190,23 @@ automation:
|
||||||
action:
|
action:
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
data:
|
data:
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
entity_id: light.hue_color_lamp_1
|
entity_id: light.hue_color_lamp_1
|
||||||
transition: 15
|
transition: 3000
|
||||||
brightness: 255
|
brightness: 255
|
||||||
color_temp: 154
|
color_temp: 154
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
entity_id: light.hue_color_lamp_2
|
entity_id: light.hue_color_lamp_2
|
||||||
transition: 15
|
transition: 3000
|
||||||
brightness: 255
|
brightness: 255
|
||||||
color_temp: 154
|
color_temp: 154
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
data:
|
data:
|
||||||
entity_id: light.hue_color_lamp_3
|
entity_id: light.hue_color_lamp_3
|
||||||
transition: 15
|
transition: 3000
|
||||||
brightness: 255
|
brightness: 255
|
||||||
color_temp: 154
|
color_temp: 154
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
|
@ -217,7 +220,7 @@ automation:
|
||||||
brightness: 25
|
brightness: 25
|
||||||
color_temp: 366
|
color_temp: 366
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
entity_id: switch.kids_bed_accent
|
entity_id: switch.hasika_bed_accent
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
entity_id: switch.front_room
|
entity_id: switch.front_room
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
|
@ -281,9 +284,9 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: script.all_indoor_lights_off
|
- service: script.all_indoor_lights_off
|
||||||
- service: script.notify_me
|
# - service: script.notify_me
|
||||||
data:
|
# data:
|
||||||
message: "It is bed time, turned lights off!"
|
# message: "It is bed time, turned lights off!"
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Provide Bed time Report via TTS
|
# Provide Bed time Report via TTS
|
||||||
|
|
|
@ -157,7 +157,7 @@ automation:
|
||||||
- delay: "00:00:05"
|
- delay: "00:00:05"
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "camera.garage_camera"
|
entity_id: "camera.garage"
|
||||||
filename:
|
filename:
|
||||||
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
||||||
((state_attr('automation.notify_garage_door_status', 'last_triggered') |string).replace('-','_')
|
((state_attr('automation.notify_garage_door_status', 'last_triggered') |string).replace('-','_')
|
||||||
|
@ -290,7 +290,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('sun.sun') == 'below_horizon' }}"
|
value_template: "{{ states('sun.sun') == 'below_horizon' }}"
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
# When I open the garage door
|
# When I open the garage door
|
||||||
|
@ -324,6 +324,9 @@ automation:
|
||||||
- service: timer.start
|
- service: timer.start
|
||||||
entity_id: timer.timer_garage
|
entity_id: timer.timer_garage
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# MASTER BATHROOM AUTOMATIONS
|
||||||
|
###############################################################################
|
||||||
#
|
#
|
||||||
# Only turn ON lights at 25% at night
|
# Only turn ON lights at 25% at night
|
||||||
#
|
#
|
||||||
|
@ -335,7 +338,7 @@ automation:
|
||||||
to: "on"
|
to: "on"
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{states.sun.sun.state == "below_horizon"}}'
|
value_template: '{{states("sun.sun") == "below_horizon"}}'
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_boolean.light_automations
|
entity_id: input_boolean.light_automations
|
||||||
state: "on"
|
state: "on"
|
||||||
|
@ -354,7 +357,7 @@ automation:
|
||||||
to: "on"
|
to: "on"
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{states.sun.sun.state == "above_horizon"}}'
|
value_template: '{{states("sun.sun") == "above_horizon"}}'
|
||||||
- condition: state
|
- condition: state
|
||||||
entity_id: input_boolean.light_automations
|
entity_id: input_boolean.light_automations
|
||||||
state: "on"
|
state: "on"
|
||||||
|
@ -362,5 +365,54 @@ automation:
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
entity_id: light.master_bathroom_lights
|
entity_id: light.master_bathroom_lights
|
||||||
data:
|
data:
|
||||||
brightness: 255 # 100% of brightness
|
brightness: 254 # 100% of brightness
|
||||||
transition: 10
|
transition: 5
|
||||||
|
|
||||||
|
- alias: Master Bathroom Toilet Door Opened
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
platform: state
|
||||||
|
entity_id: binary_sensor.door_window_sensor_158d00044e5cb3
|
||||||
|
to: "on"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.master_bathroom_toilet_light
|
||||||
|
|
||||||
|
- alias: Turn off Master Bathroom Toilet if the door is open for too long
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id: binary_sensor.door_window_sensor_158d00044e5cb3
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: 3
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: switch.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: switch.master_bathroom_toilet_light
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# GUEST BATHROOM AUTOMATIONS
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
- alias: Guest Bathroom Door Opened
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
platform: state
|
||||||
|
entity_id: binary_sensor.door_window_sensor_158d00045ab168
|
||||||
|
to: "on"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.guest_bathroom_lights
|
|
@ -1,39 +0,0 @@
|
||||||
# sudo usermod -a -G video homeassistant
|
|
||||||
# ln -s /usr/local/lib/python3.4/dist-packages/cec /srv/homeassistant/lib/python3.4/site-packages
|
|
||||||
|
|
||||||
# echo scan | cec-client -s -d 1
|
|
||||||
|
|
||||||
# opening a connection to the CEC adapter...
|
|
||||||
# requesting CEC bus information ...
|
|
||||||
# CEC bus information
|
|
||||||
# ===================
|
|
||||||
# device #0: TV
|
|
||||||
# address: 0.0.0.0
|
|
||||||
# active source: no
|
|
||||||
# vendor: Vizio
|
|
||||||
# osd string: TV
|
|
||||||
# CEC version: 1.4
|
|
||||||
# power status: on
|
|
||||||
# language: eng
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# device #1: Recorder 1
|
|
||||||
# address: 2.0.0.0
|
|
||||||
# active source: no
|
|
||||||
# vendor: Pulse Eight
|
|
||||||
# osd string: CECTester
|
|
||||||
# CEC version: 1.4
|
|
||||||
# power status: on
|
|
||||||
# language: eng
|
|
||||||
|
|
||||||
# currently active source: unknown (-1)
|
|
||||||
|
|
||||||
|
|
||||||
# Edit /boot/config.txt and include the line to prevent turning TV on when you restart Raspberry Pi
|
|
||||||
# hdmi_ignore_cec_init=1
|
|
||||||
|
|
||||||
|
|
||||||
hdmi_cec:
|
|
||||||
devices:
|
|
||||||
TV: 0.0.0.0
|
|
||||||
PI: 2.0.0.0
|
|
|
@ -6,28 +6,7 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
homeassistant:
|
homeassistant:
|
||||||
|
|
||||||
shell_command:
|
|
||||||
stop_hass: >-
|
|
||||||
hassctl stop
|
|
||||||
|
|
||||||
restart_hass: >-
|
|
||||||
hassctl restart
|
|
||||||
|
|
||||||
update_hass: >-
|
|
||||||
hassctl update-hass && hassctl config && hassctl restart
|
|
||||||
|
|
||||||
speedtestdotnet:
|
|
||||||
scan_interval:
|
|
||||||
hours: 1
|
|
||||||
monitored_conditions:
|
|
||||||
- ping
|
|
||||||
- download
|
|
||||||
- upload
|
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: uptime
|
|
||||||
name: Home Assistant Up Time
|
|
||||||
|
|
||||||
- platform: rest
|
- platform: rest
|
||||||
resource: http://icanhazip.com
|
resource: http://icanhazip.com
|
||||||
name: external_ip
|
name: external_ip
|
||||||
|
@ -43,28 +22,3 @@ sensor:
|
||||||
- type: ipv4_address
|
- type: ipv4_address
|
||||||
arg: ens160
|
arg: ens160
|
||||||
- type: last_boot
|
- type: last_boot
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "iotlink/domain/winsvr2016/lwt"
|
|
||||||
name: "Windows Server"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "iotlink/domain/winsvr2016/windows-monitor/stats/cpu/usage"
|
|
||||||
name: "Windows Server CPU Usage"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "iotlink/domain/winsvr2016/windows-monitor/stats/memory/used"
|
|
||||||
name: "Windows Server Memory Used"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "iotlink/domain/winsvr2016/windows-monitor/stats/memory/available"
|
|
||||||
name: "Windows Server Memory Available"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "iotlink/domain/winsvr2016/windows-monitor/stats/system/idle-time"
|
|
||||||
name: "Windows Server Idle Time"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
|
@ -16,11 +16,6 @@ homeassistant:
|
||||||
friendly_name: Home Security System
|
friendly_name: Home Security System
|
||||||
icon: mdi:security
|
icon: mdi:security
|
||||||
|
|
||||||
# simplisafe:
|
|
||||||
# accounts:
|
|
||||||
# - username: !secret simplisafe_username
|
|
||||||
# password: !secret simplisafe_password
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# _ _ _
|
# _ _ _
|
||||||
# /\ | | | | (_)
|
# /\ | | | | (_)
|
||||||
|
@ -111,7 +106,7 @@ automation:
|
||||||
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "camera.garage_camera"
|
entity_id: "camera.garage"
|
||||||
filename:
|
filename:
|
||||||
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
"{{ '/config/www/downloads/camera/garage/garage_' ~
|
||||||
(states.binary_sensor.motion_sensor_158d00024ee084.last_updated ~ '').replace('-','_')
|
(states.binary_sensor.motion_sensor_158d00024ee084.last_updated ~ '').replace('-','_')
|
||||||
|
@ -265,33 +260,33 @@ automation:
|
||||||
entity_id: climate.dining_room
|
entity_id: climate.dining_room
|
||||||
away_mode: "false"
|
away_mode: "false"
|
||||||
|
|
||||||
# ###############################################################################
|
###############################################################################
|
||||||
# # TURN HOME SECURITY SYSTEM ON AT BED TIME
|
# TURN HOME SECURITY SYSTEM ON AT BED TIME
|
||||||
# ###############################################################################
|
###############################################################################
|
||||||
# - alias: Night HomeSecurity On
|
- alias: Night HomeSecurity On
|
||||||
# initial_state: true
|
initial_state: true
|
||||||
# trigger:
|
trigger:
|
||||||
# platform: time_pattern
|
platform: time_pattern
|
||||||
# minutes: "/5"
|
minutes: "/5"
|
||||||
# seconds: 00
|
seconds: 00
|
||||||
# condition:
|
condition:
|
||||||
# - condition: template
|
- condition: template
|
||||||
# value_template: "{{ states('sensor.bedtime_hour')|int == now().hour|int }}"
|
value_template: "{{ states('sensor.bedtime_hour')|int == now().hour|int }}"
|
||||||
# - 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.home') != 'away' }}"
|
value_template: "{{ states('alarm_control_panel.home') != 'away' }}"
|
||||||
# - condition: template
|
- condition: template
|
||||||
# value_template: "{{ states('alarm_control_panel.home') == '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.home
|
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."
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Check for Garage Door Status when Home Security System State changes
|
# Check for Garage Door Status when Home Security System State changes
|
||||||
|
@ -324,7 +319,7 @@ automation:
|
||||||
|
|
||||||
- service: camera.snapshot
|
- service: camera.snapshot
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "camera.garage_camera"
|
entity_id: "camera.garage"
|
||||||
filename: "{{ '/config/www/downloads/camera/garage/garage_' ~ (state_attr('automation.home_security_system_and_garage_door_check','last_updated') ~ '').replace('-','_').replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
filename: "{{ '/config/www/downloads/camera/garage/garage_' ~ (state_attr('automation.home_security_system_and_garage_door_check','last_updated') ~ '').replace('-','_').replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
|
||||||
- service: notify.telegram
|
- service: notify.telegram
|
||||||
|
|
|
@ -60,10 +60,10 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- device_tracker.life360_mallika
|
- device_tracker.mallika
|
||||||
- device_tracker.life360_suresh
|
- device_tracker.suresh
|
||||||
- device_tracker.life360_srinika
|
- device_tracker.srinika
|
||||||
- device_tracker.life360_hasika
|
- device_tracker.hasika
|
||||||
from: "not_home"
|
from: "not_home"
|
||||||
to: "home"
|
to: "home"
|
||||||
for: "00:02:00"
|
for: "00:02:00"
|
||||||
|
@ -77,16 +77,12 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: zone
|
- platform: zone
|
||||||
entity_id:
|
entity_id:
|
||||||
- device_tracker.life360_hasika
|
- device_tracker.hasika
|
||||||
- device_tracker.life360_mallika
|
- device_tracker.mallika
|
||||||
- device_tracker.life360_srinika
|
- device_tracker.srinika
|
||||||
- device_tracker.life360_suresh
|
- device_tracker.suresh
|
||||||
zone: zone.home
|
zone: zone.home
|
||||||
event: enter
|
event: enter
|
||||||
- platform: zone
|
|
||||||
entity_id: device_tracker.life360_suresh
|
|
||||||
zone: zone.work
|
|
||||||
event: enter
|
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
||||||
|
|
|
@ -24,22 +24,6 @@ homeassistant:
|
||||||
emulated_hue_name: Backyard Lights
|
emulated_hue_name: Backyard Lights
|
||||||
homebridge_name: Backyard Lights
|
homebridge_name: Backyard Lights
|
||||||
|
|
||||||
switch.guest_bedroom:
|
|
||||||
icon: mdi:lightbulb
|
|
||||||
friendly_name: Guest Bedroom 1
|
|
||||||
emulated_hue_name: Guest Bedroom 1
|
|
||||||
homebridge_name: Guest Bedroom 1
|
|
||||||
|
|
||||||
switch.prayer_room:
|
|
||||||
icon: mdi:lightbulb
|
|
||||||
friendly_name: Guest Bedroom 2
|
|
||||||
emulated_hue_name: Guest Bedroom 2
|
|
||||||
homebridge_name: Guest Bedroom 2
|
|
||||||
|
|
||||||
switch.kids_bed_accent:
|
|
||||||
friendly_name: Hasika's Bed Accent Lights
|
|
||||||
assumed_state: false
|
|
||||||
icon: mdi:lightbulb
|
|
||||||
switch.front_room:
|
switch.front_room:
|
||||||
friendly_name: Front Room Light
|
friendly_name: Front Room Light
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
|
@ -52,7 +36,7 @@ homeassistant:
|
||||||
friendly_name: Basement Right Side Lights
|
friendly_name: Basement Right Side Lights
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
switch.kitchen:
|
switch.kitchen_switch:
|
||||||
friendly_name: Kitchen Light
|
friendly_name: Kitchen Light
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
|
@ -60,9 +44,6 @@ homeassistant:
|
||||||
friendly_name: Office Room Lights
|
friendly_name: Office Room Lights
|
||||||
assumed_state: false
|
assumed_state: false
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
switch.kids_bedroom:
|
|
||||||
friendly_name: Kids Bedroom
|
|
||||||
icon: mdi:lightbulb
|
|
||||||
switch.garage:
|
switch.garage:
|
||||||
friendly_name: Garage Lights
|
friendly_name: Garage Lights
|
||||||
icon: mdi:lightbulb
|
icon: mdi:lightbulb
|
||||||
|
@ -82,55 +63,14 @@ homeassistant:
|
||||||
input_boolean.long_flash:
|
input_boolean.long_flash:
|
||||||
icon: mdi:flash
|
icon: mdi:flash
|
||||||
friendly_name: Long Flash
|
friendly_name: Long Flash
|
||||||
input_boolean.animate_downstairs_lights:
|
|
||||||
icon: mdi:flash-outline
|
|
||||||
friendly_name: Animate Family Room Lights
|
|
||||||
input_boolean.animate_upstairs_lights:
|
input_boolean.animate_upstairs_lights:
|
||||||
icon: mdi:flash-outline
|
icon: mdi:flash-outline
|
||||||
friendly_name: Animate Master Bedroom Lights
|
friendly_name: Animate Master Bedroom Lights
|
||||||
|
|
||||||
tplink:
|
|
||||||
discovery: false
|
|
||||||
switch:
|
|
||||||
# In-wall switches
|
|
||||||
- host: !secret tplink_hasika_bedroom
|
|
||||||
- host: !secret tplink_srinika_bedroom
|
|
||||||
- host: !secret tplink_guest_bedroom
|
|
||||||
- host: !secret tplink_garage
|
|
||||||
- host: !secret tplink_garage_shoplights
|
|
||||||
- host: !secret tplink_basement_left
|
|
||||||
- host: !secret tplink_basement_right
|
|
||||||
- host: !secret tplink_kitchen
|
|
||||||
- host: !secret tplink_office_room
|
|
||||||
- host: !secret tplink_front_room
|
|
||||||
# Smart Outlets
|
|
||||||
- host: !secret tplink_smart_outlet1
|
|
||||||
#name: Downstairs Fragrance Outlet
|
|
||||||
- host: !secret tplink_smart_outlet3
|
|
||||||
#name: Upstairs Fragrance Outlet
|
|
||||||
- host: !secret tplink_kids_bed_accent_light
|
|
||||||
#name: Kids Bed Accent Light
|
|
||||||
- host: !secret tplink_3d_printer
|
|
||||||
dimmer:
|
|
||||||
- host: !secret tplink_bathroom_lights
|
|
||||||
strip:
|
|
||||||
- host: !secret tplink_smart_strip
|
|
||||||
- host: !secret tplink_outdoor_plug
|
|
||||||
|
|
||||||
wemo:
|
|
||||||
discovery: false
|
|
||||||
static:
|
|
||||||
- !secret wemo_switch_1
|
|
||||||
- !secret wemo_switch_2
|
|
||||||
- !secret wemo_switch_3
|
|
||||||
|
|
||||||
input_boolean:
|
input_boolean:
|
||||||
animate_upstairs_lights:
|
animate_upstairs_lights:
|
||||||
name: Animate Master Bedroom Lights
|
name: Animate Master Bedroom Lights
|
||||||
initial: off
|
initial: off
|
||||||
animate_downstairs_lights:
|
|
||||||
name: Animate Family Room Lights
|
|
||||||
initial: off
|
|
||||||
long_flash:
|
long_flash:
|
||||||
name: Long Flash Lights
|
name: Long Flash Lights
|
||||||
initial: off
|
initial: off
|
||||||
|
|
|
@ -6,18 +6,12 @@ homeassistant:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.basement_door_sensor_sensor:
|
input_label.basement_door_sensor_sensor:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.downstairs_multi_sensor_sensor:
|
|
||||||
unit_of_measurement: "count"
|
|
||||||
input_label.front_room_multi_sensor_sensor:
|
|
||||||
unit_of_measurement: "count"
|
|
||||||
input_label.front_room_window_sensor_sensor:
|
input_label.front_room_window_sensor_sensor:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.garage_door_sensor_sensor:
|
input_label.garage_door_sensor_sensor:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.garage_motion:
|
input_label.garage_motion:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.guest_bedroom_multi_sensor_sensor:
|
|
||||||
unit_of_measurement: "count"
|
|
||||||
input_label.kitchen_motion_sensor_sensor:
|
input_label.kitchen_motion_sensor_sensor:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.motion_sensor_158d00016c2d0e:
|
input_label.motion_sensor_158d00016c2d0e:
|
||||||
|
@ -50,8 +44,6 @@ homeassistant:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.two_car_garage_door_tilt_sensor_sensor:
|
input_label.two_car_garage_door_tilt_sensor_sensor:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.upstairs_multi_sensor_sensor:
|
|
||||||
unit_of_measurement: "count"
|
|
||||||
input_label.door_window_sensor_158d0004231f7b:
|
input_label.door_window_sensor_158d0004231f7b:
|
||||||
unit_of_measurement: "count"
|
unit_of_measurement: "count"
|
||||||
input_label.door_window_sensor_158d0004248d5b:
|
input_label.door_window_sensor_158d0004248d5b:
|
||||||
|
@ -80,21 +72,12 @@ input_label:
|
||||||
name: Garage Door
|
name: Garage Door
|
||||||
icon: mdi:run-fast
|
icon: mdi:run-fast
|
||||||
|
|
||||||
downstairs_multi_sensor_sensor:
|
|
||||||
name: TV Room Multi Sensor
|
|
||||||
icon: mdi:run-fast
|
|
||||||
front_room_multi_sensor_sensor:
|
|
||||||
name: Front Room Multi Sensor
|
|
||||||
icon: mdi:run-fast
|
|
||||||
front_room_window_sensor_sensor:
|
front_room_window_sensor_sensor:
|
||||||
name: Front Room Sensor
|
name: Front Room Sensor
|
||||||
icon: mdi:run-fast
|
icon: mdi:run-fast
|
||||||
garage_motion:
|
garage_motion:
|
||||||
name: Garage Motion
|
name: Garage Motion
|
||||||
icon: mdi:run-fast
|
icon: mdi:run-fast
|
||||||
guest_bedroom_multi_sensor_sensor:
|
|
||||||
name: Guest Bedroom Motion
|
|
||||||
icon: mdi:run-fast
|
|
||||||
kitchen_motion_sensor_sensor:
|
kitchen_motion_sensor_sensor:
|
||||||
name: Kitchen Motion
|
name: Kitchen Motion
|
||||||
icon: mdi:run-fast
|
icon: mdi:run-fast
|
||||||
|
@ -145,9 +128,6 @@ input_label:
|
||||||
stairs_motion_sensor_sensor:
|
stairs_motion_sensor_sensor:
|
||||||
name: Stairs Motion
|
name: Stairs Motion
|
||||||
icon: mdi:run-fast
|
icon: mdi:run-fast
|
||||||
upstairs_multi_sensor_sensor:
|
|
||||||
name: Upstairs Motion Sensor
|
|
||||||
icon: mdi:run-fast
|
|
||||||
|
|
||||||
automation:
|
automation:
|
||||||
- alias: Count Motions
|
- alias: Count Motions
|
||||||
|
@ -159,12 +139,9 @@ automation:
|
||||||
- binary_sensor.door_window_sensor_158d00040ad8fc
|
- binary_sensor.door_window_sensor_158d00040ad8fc
|
||||||
- binary_sensor.door_window_sensor_158d0004880f30 # garage entry door
|
- binary_sensor.door_window_sensor_158d0004880f30 # garage entry door
|
||||||
- binary_sensor.basement_door_sensor_sensor
|
- binary_sensor.basement_door_sensor_sensor
|
||||||
- binary_sensor.downstairs_multi_sensor_sensor
|
|
||||||
- binary_sensor.front_room_multi_sensor_sensor
|
|
||||||
- binary_sensor.front_room_window_sensor_sensor
|
- binary_sensor.front_room_window_sensor_sensor
|
||||||
- binary_sensor.garage_door_sensor_sensor
|
- binary_sensor.garage_door_sensor_sensor
|
||||||
- binary_sensor.garage_motion
|
- binary_sensor.garage_motion
|
||||||
- binary_sensor.guest_bedroom_multi_sensor_sensor
|
|
||||||
- binary_sensor.kitchen_motion_sensor_sensor
|
- binary_sensor.kitchen_motion_sensor_sensor
|
||||||
- binary_sensor.motion_sensor_158d00016c2d0e
|
- binary_sensor.motion_sensor_158d00016c2d0e
|
||||||
- binary_sensor.motion_sensor_158d00016db6d2
|
- binary_sensor.motion_sensor_158d00016db6d2
|
||||||
|
@ -181,7 +158,6 @@ automation:
|
||||||
- binary_sensor.stairs_motion_sensor_sensor
|
- binary_sensor.stairs_motion_sensor_sensor
|
||||||
- binary_sensor.door_window_sensor_158d0004248d5b # Single Car Garage
|
- binary_sensor.door_window_sensor_158d0004248d5b # Single Car Garage
|
||||||
- binary_sensor.door_window_sensor_158d0004231f7b # Double Car Garage
|
- binary_sensor.door_window_sensor_158d0004231f7b # Double Car Garage
|
||||||
- binary_sensor.upstairs_multi_sensor_sensor
|
|
||||||
action:
|
action:
|
||||||
- service: input_label.set_value
|
- service: input_label.set_value
|
||||||
data_template:
|
data_template:
|
||||||
|
@ -200,12 +176,9 @@ automation:
|
||||||
value: 0
|
value: 0
|
||||||
entity_id:
|
entity_id:
|
||||||
- input_label.basement_door_sensor_sensor
|
- input_label.basement_door_sensor_sensor
|
||||||
- input_label.downstairs_multi_sensor_sensor
|
|
||||||
- input_label.front_room_multi_sensor_sensor
|
|
||||||
- input_label.front_room_window_sensor_sensor
|
- input_label.front_room_window_sensor_sensor
|
||||||
- input_label.garage_door_sensor_sensor
|
- input_label.garage_door_sensor_sensor
|
||||||
- input_label.garage_motion
|
- input_label.garage_motion
|
||||||
- input_label.guest_bedroom_multi_sensor_sensor
|
|
||||||
- input_label.kitchen_motion_sensor_sensor
|
- input_label.kitchen_motion_sensor_sensor
|
||||||
- input_label.motion_sensor_158d00016c2d0e
|
- input_label.motion_sensor_158d00016c2d0e
|
||||||
- input_label.motion_sensor_158d00016db6d2
|
- input_label.motion_sensor_158d00016db6d2
|
||||||
|
|
|
@ -70,6 +70,16 @@ automation:
|
||||||
entity_id: timer.timer_masterbathroom
|
entity_id: timer.timer_masterbathroom
|
||||||
- service: light.turn_on
|
- service: light.turn_on
|
||||||
entity_id: light.master_bathroom_lights
|
entity_id: light.master_bathroom_lights
|
||||||
|
data:
|
||||||
|
brightness: 64 # 25% of brightness
|
||||||
|
transition: 5
|
||||||
|
- condition: template
|
||||||
|
value_template: '{{states("sun.sun") == "above_horizon"}}'
|
||||||
|
- service: light.turn_on
|
||||||
|
entity_id: light.master_bathroom_lights
|
||||||
|
data:
|
||||||
|
brightness: 254 # 100% of brightness
|
||||||
|
transition: 5
|
||||||
|
|
||||||
- alias: Master Bathroom Timer Elapsed
|
- alias: Master Bathroom Timer Elapsed
|
||||||
initial_state: true
|
initial_state: true
|
||||||
|
@ -171,7 +181,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: switch.turn_on
|
- service: switch.turn_on
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
- service: timer.start
|
- service: timer.start
|
||||||
entity_id: timer.timer_kitchen
|
entity_id: timer.timer_kitchen
|
||||||
# Kitchen:
|
# Kitchen:
|
||||||
|
@ -199,7 +209,7 @@ automation:
|
||||||
{% else %}
|
{% else %}
|
||||||
switch.turn_on
|
switch.turn_on
|
||||||
{% endif %}
|
{% endif %}
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
# Family Room:
|
# Family Room:
|
||||||
# Motion Detected - When TV is OFF, turn ON the light 100% and extend timer
|
# Motion Detected - When TV is OFF, turn ON the light 100% and extend timer
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
###############################################################################
|
###############################################################################
|
||||||
homeassistant:
|
homeassistant:
|
||||||
|
|
||||||
ifttt:
|
|
||||||
key: !secret ifttt_key
|
|
||||||
|
|
||||||
notify:
|
notify:
|
||||||
- name: ios_devices
|
- name: ios_devices
|
||||||
platform: group
|
platform: group
|
||||||
|
|
|
@ -1,218 +0,0 @@
|
||||||
# ###############################################################################
|
|
||||||
# # AUTHOR : Suresh Kalavala
|
|
||||||
# # DATE : 03/04/2018
|
|
||||||
# # PACKAGE : PALO ALTO APPLANCE/DEVICE SENSOR
|
|
||||||
# # Description : Package to monitor PaloAlto device, logged-in users, vpn users
|
|
||||||
# # and other system information
|
|
||||||
# ###############################################################################
|
|
||||||
# homeassistant:
|
|
||||||
# customize:
|
|
||||||
|
|
||||||
# # Sensors from custom component
|
|
||||||
# sensor.paloalto_host_name:
|
|
||||||
# friendly_name: Palo Alto Host Name
|
|
||||||
# sensor.paloalto_operation_mode:
|
|
||||||
# friendly_name: Device Operation Mode
|
|
||||||
# sensor.paloalto_serial_number:
|
|
||||||
# friendly_name: Device Serial Number
|
|
||||||
# sensor.paloalto_global_protect_user_count:
|
|
||||||
# friendly_name: VPN Loggedin User Count
|
|
||||||
# sensor.paloalto_global_protect_users:
|
|
||||||
# friendly_name: VPN Loggedin Users
|
|
||||||
# sensor.paloalto_global_protect_version:
|
|
||||||
# friendly_name: VPN Software Version
|
|
||||||
# sensor.paloalto_logdb_version:
|
|
||||||
# friendly_name: Log Db Version
|
|
||||||
# sensor.paloalto_software_version:
|
|
||||||
# friendly_name: Device Software Version
|
|
||||||
# sensor.paloalto_core_temperature:
|
|
||||||
# friendly_name: Core Temperature
|
|
||||||
# sensor.paloalto_system_temperature:
|
|
||||||
# friendly_name: System Temperature
|
|
||||||
# sensor.paloalto_up_time:
|
|
||||||
# friendly_name: Up Time
|
|
||||||
|
|
||||||
# # Scripts
|
|
||||||
# script.paloalto_clear_traffic_logs:
|
|
||||||
# friendly_name: Clear Traffic Logs
|
|
||||||
# script.paloalto_clear_threat_logs:
|
|
||||||
# friendly_name: Clear Threat Logs
|
|
||||||
# script.paloalto_clear_alarm_logs:
|
|
||||||
# friendly_name: Clear Alarm Logs
|
|
||||||
# script.paloalto_clear_authentication_logs:
|
|
||||||
# friendly_name: Clear Authentication Logs
|
|
||||||
# script.paloalto_clear_config_logs:
|
|
||||||
# friendly_name: Clear Configuration Logs
|
|
||||||
# script.paloalto_clear_system_logs:
|
|
||||||
# friendly_name: Clear System Logs
|
|
||||||
# script.paloalto_shutdown:
|
|
||||||
# friendly_name: Shutdown Palo Alto Device
|
|
||||||
# icon: mdi:power
|
|
||||||
# script.paloalto_restart:
|
|
||||||
# friendly_name: Restart Palo Alto Device
|
|
||||||
# icon: mdi:restart
|
|
||||||
|
|
||||||
# sensor:
|
|
||||||
# - platform: paloalto
|
|
||||||
# api_key: !secret paloalto_authkey
|
|
||||||
# ip_address: !secret paloalto_hostip
|
|
||||||
# ssl: True
|
|
||||||
# verify_ssl: False
|
|
||||||
# scan_interval: 60
|
|
||||||
# monitored_conditions:
|
|
||||||
# - host_name
|
|
||||||
# - up_time
|
|
||||||
# - serial_no
|
|
||||||
# - sw_version
|
|
||||||
# - gp_version
|
|
||||||
# - logdb_version
|
|
||||||
# - operation_mode
|
|
||||||
# - core_temp
|
|
||||||
# - sys_temp
|
|
||||||
# - gp_users
|
|
||||||
# - gp_user_count
|
|
||||||
# - loggedin_user_count
|
|
||||||
# - loggedin_users
|
|
||||||
|
|
||||||
# #
|
|
||||||
# # All the URLs below use the following format
|
|
||||||
# # For ex: paloalto_clear_traffic_logs: "curl -k 'https://192.xxx.xxx.xxx/api/?type=op&cmd=<clear><log><traffic></traffic></log></clear>&key=YOUR_API_KEY'"
|
|
||||||
# # Check out secrets.example file for additional details about the commands
|
|
||||||
# # https://github.com/skalavala/mysmarthome/blob/master/secrets.example
|
|
||||||
# #
|
|
||||||
# shell_command:
|
|
||||||
# paloalto_clear_traffic_logs: !secret paloalto_clear_traffic_logs
|
|
||||||
# paloalto_clear_threat_logs: !secret paloalto_clear_threat_logs
|
|
||||||
# paloalto_clear_alarm_logs: !secret paloalto_clear_alarm_logs
|
|
||||||
# paloalto_clear_authentication_logs: !secret paloalto_clear_authentication_logs
|
|
||||||
# paloalto_clear_config_logs: !secret paloalto_clear_config_logs
|
|
||||||
# paloalto_clear_system_logs: !secret paloalto_clear_system_logs
|
|
||||||
# paloalto_shutdown: !secret paloalto_shutdown
|
|
||||||
# paloalto_restart: !secret paloalto_restart
|
|
||||||
|
|
||||||
# script:
|
|
||||||
# paloalto_clear_traffic_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_traffic_logs
|
|
||||||
# paloalto_clear_threat_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_threat_logs
|
|
||||||
# paloalto_clear_alarm_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_alarm_logs
|
|
||||||
# paloalto_clear_authentication_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_authentication_logs
|
|
||||||
# paloalto_clear_config_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_config_logs
|
|
||||||
# paloalto_clear_system_logs:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_clear_system_logs
|
|
||||||
# paloalto_shutdown:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_shutdown
|
|
||||||
# paloalto_restart:
|
|
||||||
# sequence:
|
|
||||||
# - service: shell_command.paloalto_restart
|
|
||||||
|
|
||||||
# automation:
|
|
||||||
# #
|
|
||||||
# # Alerts me when someone logs into my VPN network
|
|
||||||
# # This automation compares before and after state changes
|
|
||||||
# # and alerts when someone logged in/out of VPN
|
|
||||||
# #
|
|
||||||
# - alias: Alert When Someone Logged into VPN
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# - platform: state
|
|
||||||
# entity_id: sensor.paloalto_global_protect_users
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: '{{ trigger.from_state.state | lower != trigger.to_state.state | lower }}'
|
|
||||||
# action:
|
|
||||||
# - service: script.notify_me
|
|
||||||
# data_template:
|
|
||||||
# message: >-
|
|
||||||
# {% set before = trigger.from_state.state %}
|
|
||||||
# {% set after = trigger.to_state.state %}
|
|
||||||
# {% macro loggedIn(beforeList, afterList) %}
|
|
||||||
# {%- for user in afterList if user != 'None' and user not in beforeList%}
|
|
||||||
# {%- if loop.first %}{% elif loop.last %} and{% else %},{% endif -%}
|
|
||||||
# {{- user }}
|
|
||||||
# {%- endfor %}
|
|
||||||
# {%- endmacro %}
|
|
||||||
# {% macro loggedOut(beforeList, afterList) %}
|
|
||||||
# {%- for user in beforeList if user != 'None' and user not in afterList %}
|
|
||||||
# {%- if loop.first %}{% elif loop.last %} and{% else %},{% endif -%}
|
|
||||||
# {{- user }}
|
|
||||||
# {%- endfor %}
|
|
||||||
# {%- endmacro %}
|
|
||||||
# {%- macro checkUsers(beforeList, afterList) -%}
|
|
||||||
# {%- set loggedInUsers = loggedIn(beforeList, afterList) -%}
|
|
||||||
# {%- set loggedOutUsers = loggedOut(beforeList, afterList) -%}
|
|
||||||
# {%- if loggedInUsers | trim != "" -%}
|
|
||||||
# Alert! {{- loggedInUsers | title }} just logged into your Web VPN.
|
|
||||||
# {%- endif -%}
|
|
||||||
# {%- if loggedOutUsers | trim != "" %}
|
|
||||||
# {{- loggedOutUsers |title }} just logged out of your Web VPN.
|
|
||||||
# {% endif %}
|
|
||||||
# {%- endmacro -%}
|
|
||||||
# {{ checkUsers(before.split(','), after.split(',')) }}
|
|
||||||
|
|
||||||
# #
|
|
||||||
# # Alerts me when someone logs into my firewall.
|
|
||||||
# # This automation compares before and after state changes
|
|
||||||
# # and alerts when someone logged in/out of Firewall
|
|
||||||
# #
|
|
||||||
# - alias: Alert When Someone Logged into Firewall
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# - platform: state
|
|
||||||
# entity_id: sensor.paloalto_loggedin_users
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: '{{ trigger.from_state.state | lower != trigger.to_state.state | lower }}'
|
|
||||||
# action:
|
|
||||||
# - service: script.notify_me
|
|
||||||
# data_template:
|
|
||||||
# message: >-
|
|
||||||
# {% set before = trigger.from_state.state %}
|
|
||||||
# {% set after = trigger.to_state.state %}
|
|
||||||
# {% macro loggedIn(beforeList, afterList) %}
|
|
||||||
# {%- for user in afterList if user != 'None' and user not in beforeList%}
|
|
||||||
# {%- if loop.first %}{% elif loop.last %} and{% else %},{% endif -%}
|
|
||||||
# {{- user }}
|
|
||||||
# {%- endfor %}
|
|
||||||
# {%- endmacro %}
|
|
||||||
# {% macro loggedOut(beforeList, afterList) %}
|
|
||||||
# {%- for user in beforeList if user != 'None' and user not in afterList %}
|
|
||||||
# {%- if loop.first %}{% elif loop.last %} and{% else %},{% endif -%}
|
|
||||||
# {{- user }}
|
|
||||||
# {%- endfor %}
|
|
||||||
# {%- endmacro %}
|
|
||||||
# {%- macro checkUsers(beforeList, afterList) -%}
|
|
||||||
# {%- set loggedInUsers = loggedIn(beforeList, afterList) -%}
|
|
||||||
# {%- set loggedOutUsers = loggedOut(beforeList, afterList) -%}
|
|
||||||
# {%- if loggedInUsers | trim != "" -%}
|
|
||||||
# Alert! {{- loggedInUsers | title }} just logged into your Palo Alto Firewall.
|
|
||||||
# {%- endif -%}
|
|
||||||
# {%- if loggedOutUsers | trim != "" %}
|
|
||||||
# {{- loggedOutUsers |title }} just logged out of your Palo Alto Firewall.
|
|
||||||
# {% endif %}
|
|
||||||
# {%- endmacro -%}
|
|
||||||
# {{ checkUsers(before.split(','), after.split(',')) }}
|
|
||||||
|
|
||||||
# #
|
|
||||||
# # Palo Alto PA-200 device sucks ass in terms of its disk space!
|
|
||||||
# # A work around would be to clear traffic logs periodically
|
|
||||||
# # This automation runs every hour and clears traffic log/log files
|
|
||||||
# #
|
|
||||||
# - alias: Clear Traffic Logs
|
|
||||||
# initial_state: True
|
|
||||||
# trigger:
|
|
||||||
# - platform: time_pattern
|
|
||||||
# hours: '/1'
|
|
||||||
# minutes: 00
|
|
||||||
# action:
|
|
||||||
# - service: script.paloalto_clear_traffic_logs
|
|
|
@ -1,552 +0,0 @@
|
||||||
###############################################################################
|
|
||||||
# @author : Mahasri Kalavala
|
|
||||||
# @date : 12/27/2017
|
|
||||||
# @package : Pi Admin Package
|
|
||||||
# @description : Got way too many Raspberry Pi's and this package is to
|
|
||||||
# help me with managing them via Home Assistant.
|
|
||||||
#
|
|
||||||
# How Does It Work?
|
|
||||||
#
|
|
||||||
# Each Raspberry Pi runs a service (a python program) locally that listens for
|
|
||||||
# commands via MQTT on a pre-defined topic. This package publishes commands
|
|
||||||
# to MQTT requesting each Raspberry Pi to respond and or return data.
|
|
||||||
# When the responses are received (on a differet topic), the sensors gets
|
|
||||||
# updated automatically and are displayed.
|
|
||||||
#
|
|
||||||
################################################################################
|
|
||||||
|
|
||||||
homeassistant:
|
|
||||||
customize:
|
|
||||||
script.restart_all_raspberrypis:
|
|
||||||
friendly_name: Restart All Raspberry Pis
|
|
||||||
script.restart_all_snapclients:
|
|
||||||
friendly_name: Restart All Snapserver Clients
|
|
||||||
script.shutdown_all_raspberrypis:
|
|
||||||
friendly_name: Shutdown All Raspberry Pis
|
|
||||||
script.query_wifi_info:
|
|
||||||
friendly_name: Query WiFi Info
|
|
||||||
script.query_disk_info:
|
|
||||||
friendly_name: Query Disk Info
|
|
||||||
|
|
||||||
input_select:
|
|
||||||
raspberry_pis:
|
|
||||||
name: All Raspberry Pis
|
|
||||||
options:
|
|
||||||
- Select One
|
|
||||||
- pi_basement
|
|
||||||
- pi_theater
|
|
||||||
- pi_kitchen
|
|
||||||
- pi_familyroom
|
|
||||||
- pi_frontroom
|
|
||||||
- pi_garage
|
|
||||||
- pi_guest1
|
|
||||||
- pi_guest2
|
|
||||||
- pi_masterbedroom
|
|
||||||
initial: Select One
|
|
||||||
icon: mdi:pig
|
|
||||||
|
|
||||||
rpi_commands:
|
|
||||||
name: RPi Commands
|
|
||||||
options:
|
|
||||||
- Select One
|
|
||||||
- Restart Server
|
|
||||||
- Shutdown
|
|
||||||
- Restart Snapcast
|
|
||||||
initial: Select One
|
|
||||||
icon: mdi:pig
|
|
||||||
|
|
||||||
sensor:
|
|
||||||
## WiFi Information related sensors
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_basement"
|
|
||||||
name: Basement Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_basement"
|
|
||||||
name: Basement Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_theater"
|
|
||||||
name: Theater Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_theater"
|
|
||||||
name: Theater Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_kitchen"
|
|
||||||
name: Kitchen Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_kitchen"
|
|
||||||
name: Kitchen Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_familyroom"
|
|
||||||
name: Family Room Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_familyroom"
|
|
||||||
name: Family Room Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_frontroom"
|
|
||||||
name: Front Room Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_frontroom"
|
|
||||||
name: Front Room Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_garage"
|
|
||||||
name: Garage Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_garage"
|
|
||||||
name: Garage Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_guest1"
|
|
||||||
name: Guest 1 Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_guest1"
|
|
||||||
name: Guest 1 Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_guest2"
|
|
||||||
name: Guest 2 Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_guest2"
|
|
||||||
name: Guest 2 Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_masterbedroom"
|
|
||||||
name: master Bedroom Pi Signal Level
|
|
||||||
value_template: '{{ value_json["Signal Level"]}}'
|
|
||||||
unit_of_measurement: dBm
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/wifi/pi_masterbedroom"
|
|
||||||
name: Master Bedroom Pi Link Quality
|
|
||||||
value_template: '{{ value_json["Link Quality"]}}'
|
|
||||||
|
|
||||||
## Disk Information related Sensors
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_basement"
|
|
||||||
name: Basement Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_basement"
|
|
||||||
name: Basement Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_theater"
|
|
||||||
name: Theater Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_theater"
|
|
||||||
name: Theater Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_kitchen"
|
|
||||||
name: Kitchen Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_kitchen"
|
|
||||||
name: Kitchen Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_familyroom"
|
|
||||||
name: Family Room Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_familyroom"
|
|
||||||
name: Family Room Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_frontroom"
|
|
||||||
name: Front Room Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_frontroom"
|
|
||||||
name: Front Room Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_garage"
|
|
||||||
name: Garage Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_garage"
|
|
||||||
name: Garage Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_guest1"
|
|
||||||
name: Guest 1 Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_guest1"
|
|
||||||
name: Guest 1 Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_guest2"
|
|
||||||
name: Guest 2 Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_guest2"
|
|
||||||
name: Guest 2 Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_masterbedroom"
|
|
||||||
name: Master Bedroom Pi Available Disk
|
|
||||||
value_template: '{{ value_json["Available"]}}'
|
|
||||||
- platform: mqtt
|
|
||||||
state_topic: "/disk/pi_masterbedroom"
|
|
||||||
name: Master Bedroom Pi Disk Used
|
|
||||||
value_template: '{{ value_json["% Used"]}}'
|
|
||||||
|
|
||||||
script:
|
|
||||||
restart_all_raspberrypis:
|
|
||||||
sequence:
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_basement"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_theater"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_kitchen"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_familyroom"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_frontroom"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_garage"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest1"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest2"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_masterbedroom"
|
|
||||||
payload: CMD_REBOOT_PI
|
|
||||||
retain: false
|
|
||||||
|
|
||||||
restart_all_snapclients:
|
|
||||||
sequence:
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_basement"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_theater"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_kitchen"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_familyroom"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_frontroom"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_garage"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest1"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest2"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_masterbedroom"
|
|
||||||
payload: CMD_RESTART_SNAPCLIENT
|
|
||||||
retain: false
|
|
||||||
|
|
||||||
shutdown_all_raspberrypis:
|
|
||||||
sequence:
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_basement"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_theater"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_kitchen"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_familyroom"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_frontroom"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_garage"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest1"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_guest2"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
topic: "/server/pi_masterbedroom"
|
|
||||||
payload: CMD_SHUTDOWN_PI
|
|
||||||
retain: false
|
|
||||||
|
|
||||||
# Script to Query Disk Information - Publishes message 'CMD_REPORT_WIFI_DETAILS'
|
|
||||||
# to MQTT, so that the message gets received by individual Raspberry Pi
|
|
||||||
###############################################################################
|
|
||||||
query_wifi_info:
|
|
||||||
sequence:
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_basement
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_theater
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_kitchen
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_familyroom
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_frontroom
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_garage
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_guest1
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_guest2
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_masterbedroom
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pizero_green
|
|
||||||
payload: "CMD_REPORT_WIFI_DETAILS"
|
|
||||||
retain: false
|
|
||||||
|
|
||||||
# Script to Query Disk Information - Publishes message 'CMD_REPORT_DISK_DETAILS'
|
|
||||||
# to MQTT, so that the message gets received by individual Raspberry Pi
|
|
||||||
###############################################################################
|
|
||||||
query_disk_info:
|
|
||||||
sequence:
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_basement
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_theater
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_kitchen
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_familyroom
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_frontroom
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_garage
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_guest1
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_guest2
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pi_masterbedroom
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
- service: mqtt.publish
|
|
||||||
data:
|
|
||||||
topic: /server/pizero_green
|
|
||||||
payload: "CMD_REPORT_DISK_DETAILS"
|
|
||||||
retain: false
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# _ _ _
|
|
||||||
# /\ | | | | (_)
|
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
# Automations: Various automations to query and issue commands to Raspberry Pis
|
|
||||||
###############################################################################
|
|
||||||
automation:
|
|
||||||
# Queries WiFi Signal Level and Link Quality - it loads during startup, and
|
|
||||||
# updates once every 30 minutes
|
|
||||||
###############################################################################
|
|
||||||
- alias: Query RPi Wifi Data
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: time_pattern
|
|
||||||
minutes: "/30"
|
|
||||||
- platform: homeassistant
|
|
||||||
event: start
|
|
||||||
action:
|
|
||||||
- service: script.query_wifi_info
|
|
||||||
|
|
||||||
# Queries Disk Available and % Used - it loads during startup, and
|
|
||||||
# updates once every 30 minutes
|
|
||||||
###############################################################################
|
|
||||||
- alias: Query RPi Disk Data
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: time_pattern
|
|
||||||
minutes: "/30"
|
|
||||||
- platform: homeassistant
|
|
||||||
event: start
|
|
||||||
action:
|
|
||||||
- service: script.query_disk_info
|
|
||||||
|
|
||||||
# Issues commands to Raspberry Pi via MQTT - On Demand
|
|
||||||
###############################################################################
|
|
||||||
- alias: Raspberry Pi Command
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: input_select.rpi_commands
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('input_select.raspberry_pis') | lower != 'select one' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('input_select.rpi_commands') | lower != 'select one' }}"
|
|
||||||
action:
|
|
||||||
service: mqtt.publish
|
|
||||||
data_template:
|
|
||||||
retain: false
|
|
||||||
topic: "{{ '/server/' ~ states('input_select.raspberry_pis') }}"
|
|
||||||
payload: >-
|
|
||||||
{% if states('input_select.rpi_commands') | lower == "restart server" %}
|
|
||||||
CMD_REBOOT_PI
|
|
||||||
{% elif states('input_select.rpi_commands') | lower == "restart snapcast" %}
|
|
||||||
CMD_RESTART_SNAPCLIENT
|
|
||||||
{% else %}
|
|
||||||
CMD_SHUTDOWN_PI
|
|
||||||
{% endif %}
|
|
|
@ -27,11 +27,6 @@ input_boolean:
|
||||||
name: Pill Taken
|
name: Pill Taken
|
||||||
icon: mdi:pill
|
icon: mdi:pill
|
||||||
|
|
||||||
pill_on_vacation:
|
|
||||||
name: On Vacation
|
|
||||||
initial: off
|
|
||||||
icon: mdi:beach
|
|
||||||
|
|
||||||
pill_voice_notification:
|
pill_voice_notification:
|
||||||
name: Pill Voice Notification
|
name: Pill Voice Notification
|
||||||
icon: mdi:speaker
|
icon: mdi:speaker
|
||||||
|
@ -90,20 +85,6 @@ automation:
|
||||||
- service: input_boolean.turn_off
|
- service: input_boolean.turn_off
|
||||||
entity_id: input_boolean.pill_taken
|
entity_id: input_boolean.pill_taken
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Set the vacation mode automatically based on home security system state
|
|
||||||
# When travelling, make sure you add a reminder on your mobile phone
|
|
||||||
###############################################################################
|
|
||||||
- alias: Set Vacation Mode For Pills
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
platform: state
|
|
||||||
entity_id: alarm_control_panel.home
|
|
||||||
action:
|
|
||||||
- service_template: "input_boolean.turn_{{- 'on' if
|
|
||||||
states('alarm_control_panel.home') == 'armed_away' else 'off' }}"
|
|
||||||
entity_id: input_boolean.pill_on_vacation
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# Checks if the pills were taken - trigger on the pill reminder time
|
# Checks if the pills were taken - trigger on the pill reminder time
|
||||||
# Also, only remind if not on vacation or away from home
|
# Also, only remind if not on vacation or away from home
|
||||||
|
@ -120,7 +101,7 @@ automation:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.pill_taken') == 'off' }}"
|
value_template: "{{ states('input_boolean.pill_taken') == 'off' }}"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.pill_on_vacation') == 'off' }}"
|
value_template: "{{ states('input_boolean.home_mode_away') == 'off' }}"
|
||||||
action:
|
action:
|
||||||
- service: script.remind_pill
|
- service: script.remind_pill
|
||||||
|
|
||||||
|
|
|
@ -282,7 +282,7 @@ automation:
|
||||||
condition: and
|
condition: and
|
||||||
conditions:
|
conditions:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ states.input_boolean.trash_reminders.state == "on" }}'
|
value_template: "{{ states('input_boolean.trash_reminders') == 'on' }}"
|
||||||
- condition: or
|
- condition: or
|
||||||
conditions:
|
conditions:
|
||||||
- condition: state
|
- condition: state
|
||||||
|
|
|
@ -1,186 +0,0 @@
|
||||||
# NOTE: THIS CODE WORKS! I NO LONGER USE RPI FOR MY HA ANYMORE. HENCE THE CODE IS COMMENTED.
|
|
||||||
# PLEASE FEEL FREE TO COPY THE CODE AND UNCOMMENT IT, AND SHOULD WORK OUT OF THE BOX
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # @author : Mahasri Kalavala
|
|
||||||
# # @date : 04/15/2017
|
|
||||||
# # @package : RF Outlets
|
|
||||||
# # @description : Etekcity RF Outlet Sensors and Automations
|
|
||||||
# ###############################################################################
|
|
||||||
# homeassistant:
|
|
||||||
# customize:
|
|
||||||
|
|
||||||
# group.etekcity_rf_switches:
|
|
||||||
# order: 13
|
|
||||||
|
|
||||||
# switch.switch_one:
|
|
||||||
# friendly_name: Switch One
|
|
||||||
# switch.switch_two:
|
|
||||||
# friendly_name: Switch Two
|
|
||||||
# switch.switch_three:
|
|
||||||
# friendly_name: Switch Three
|
|
||||||
# switch.switch_four:
|
|
||||||
# friendly_name: Switch Four
|
|
||||||
# switch.switch_five:
|
|
||||||
# friendly_name: Switch Five
|
|
||||||
|
|
||||||
# sensor.rf_switch_one:
|
|
||||||
# hidden: true
|
|
||||||
# sensor.rf_switch_two:
|
|
||||||
# hidden: true
|
|
||||||
# sensor.rf_switch_three:
|
|
||||||
# hidden: true
|
|
||||||
# sensor.rf_switch_four:
|
|
||||||
# hidden: true
|
|
||||||
# sensor.rf_switch_five:
|
|
||||||
# hidden: true
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # RF Switches
|
|
||||||
# ###############################################################################
|
|
||||||
# switch:
|
|
||||||
# - platform: rpi_rf
|
|
||||||
# gpio: 17
|
|
||||||
# switches:
|
|
||||||
# switch_one:
|
|
||||||
# code_on: !secret rf_switch_1_code_on
|
|
||||||
# code_off: !secret rf_switch_1_code_off
|
|
||||||
# pulselength: !secret rf_switch_1_pulselength
|
|
||||||
# switch_two:
|
|
||||||
# code_on: !secret rf_switch_2_code_on
|
|
||||||
# code_off: !secret rf_switch_2_code_off
|
|
||||||
# pulselength: !secret rf_switch_2_pulselength
|
|
||||||
# switch_three:
|
|
||||||
# code_on: !secret rf_switch_3_code_on
|
|
||||||
# code_off: !secret rf_switch_3_code_off
|
|
||||||
# pulselength: !secret rf_switch_3_pulselength
|
|
||||||
# switch_four:
|
|
||||||
# code_on: !secret rf_switch_4_code_on
|
|
||||||
# code_off: !secret rf_switch_4_code_off
|
|
||||||
# pulselength: !secret rf_switch_4_pulselength
|
|
||||||
# switch_five:
|
|
||||||
# code_on: !secret rf_switch_5_code_on
|
|
||||||
# code_off: !secret rf_switch_5_code_off
|
|
||||||
# pulselength: !secret rf_switch_5_pulselength
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # Sensor Definitions
|
|
||||||
# ###############################################################################
|
|
||||||
# sensor:
|
|
||||||
# - platform: mqtt
|
|
||||||
# state_topic: "/home/rfswitches/switch_one"
|
|
||||||
# name: "RF Switch One"
|
|
||||||
# value_template: "{{ value }}"
|
|
||||||
|
|
||||||
# - platform: mqtt
|
|
||||||
# state_topic: "/home/rfswitches/switch_two"
|
|
||||||
# name: "RF Switch Two"
|
|
||||||
# value_template: "{{ value }}"
|
|
||||||
|
|
||||||
# - platform: mqtt
|
|
||||||
# state_topic: "/home/rfswitches/switch_three"
|
|
||||||
# name: "RF Switch Three"
|
|
||||||
# value_template: "{{ value }}"
|
|
||||||
|
|
||||||
# - platform: mqtt
|
|
||||||
# state_topic: "/home/rfswitches/switch_four"
|
|
||||||
# name: "RF Switch Four"
|
|
||||||
# value_template: "{{ value }}"
|
|
||||||
|
|
||||||
# - platform: mqtt
|
|
||||||
# state_topic: "/home/rfswitches/switch_five"
|
|
||||||
# name: "RF Switch Five"
|
|
||||||
# value_template: "{{ value }}"
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # Automation - Saves Switch State to MQTT
|
|
||||||
# ###############################################################################
|
|
||||||
# automation:
|
|
||||||
|
|
||||||
# # When the switch state changes (programatically or by UI), save the state to MQTT
|
|
||||||
# - alias: Save RF Switch State
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# platform: state
|
|
||||||
# entity_id:
|
|
||||||
# - switch.switch_one
|
|
||||||
# - switch.switch_two
|
|
||||||
# - switch.switch_three
|
|
||||||
# - switch.switch_four
|
|
||||||
# - switch.switch_five
|
|
||||||
# action:
|
|
||||||
# service: mqtt.publish
|
|
||||||
# data_template:
|
|
||||||
# topic: "/home/rfswitches/{{ trigger.entity_id.split('.')[1] }}"
|
|
||||||
# retain: true
|
|
||||||
# qos: 1
|
|
||||||
# payload: '{{ trigger.to_state.state }}'
|
|
||||||
|
|
||||||
# # When the switch state is updated in MQTT (for remove integration), reload the Switch to that state
|
|
||||||
# - alias: Sync MQTT and Switch States
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# platform: state
|
|
||||||
# entity_id:
|
|
||||||
# - sensor.rf_switch_one
|
|
||||||
# - sensor.rf_switch_two
|
|
||||||
# - sensor.rf_switch_three
|
|
||||||
# - sensor.rf_switch_four
|
|
||||||
# - sensor.rf_switch_five
|
|
||||||
# action:
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if trigger.to_state.state | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# data_template:
|
|
||||||
# entity_id: 'switch.switch_{{ trigger.entity_id.split(".")[1].split("_")[2]}}'
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # Startup event - restores states of dropdowns, and RF Switches...etc
|
|
||||||
# ###############################################################################
|
|
||||||
# - alias: Restore RF Switch Status on Startup
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# platform: homeassistant
|
|
||||||
# event: start
|
|
||||||
# action:
|
|
||||||
# - delay:
|
|
||||||
# minutes: 1
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if states('sensor.rf_switch_one') | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# entity_id: switch.switch_one
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if states('sensor.rf_switch_two') | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# entity_id: switch.switch_two
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if states('sensor.rf_switch_three') | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# entity_id: switch.switch_three
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if states('sensor.rf_switch_four') | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# entity_id: switch.switch_four
|
|
||||||
# - service_template: >
|
|
||||||
# {%- if states('sensor.rf_switch_five') | lower == "on" -%}
|
|
||||||
# homeassistant.turn_on
|
|
||||||
# {%- else -%}
|
|
||||||
# homeassistant.turn_off
|
|
||||||
# {%- endif -%}
|
|
||||||
# data:
|
|
||||||
# entity_id: switch.switch_five
|
|
|
@ -80,14 +80,13 @@ script:
|
||||||
- service: script.all_indoor_lights_off
|
- service: script.all_indoor_lights_off
|
||||||
- service: input_boolean.turn_on
|
- service: input_boolean.turn_on
|
||||||
entity_id: input_boolean.notify_camera_alerts
|
entity_id: input_boolean.notify_camera_alerts
|
||||||
- service: climate.set_away_mode
|
- service: alarm_control_panel.alarm_arm_away
|
||||||
data:
|
data:
|
||||||
entity_id: climate.dining_room
|
entity_id: alarm_control_panel.home
|
||||||
away_mode: "true"
|
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data:
|
data:
|
||||||
message: >
|
message: >
|
||||||
No one is at home. Cameras rolling, Indoor lights OFF, Thermostat is set to 'away' and your home is secured!
|
No one is at home. Cameras rolling, Indoor lights are OFF. Your home security system is turned ON!
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# The following script runs when no one is home. It excludes some lights
|
# The following script runs when no one is home. It excludes some lights
|
||||||
|
@ -111,28 +110,18 @@ script:
|
||||||
entity_id:
|
entity_id:
|
||||||
- switch.basement_left
|
- switch.basement_left
|
||||||
- switch.basement_right
|
- switch.basement_right
|
||||||
- switch.downstairs_fragrance
|
|
||||||
- switch.front_room
|
- switch.front_room
|
||||||
- switch.garage
|
- switch.garage
|
||||||
- switch.garage_shop_lights
|
- switch.garage_shop_lights
|
||||||
- switch.guest_bedroom
|
- switch.srinika_bedroom
|
||||||
- switch.kids_bed_accent
|
- switch.hasika_bed_accent
|
||||||
- switch.kids_bedroom
|
- switch.hasika_bedroom
|
||||||
- switch.kitchen
|
- switch.kitchen_switch
|
||||||
- switch.office_room
|
- switch.office_room
|
||||||
- switch.prayer_room
|
- switch.guest_room
|
||||||
- switch.upstairs_fragrance
|
|
||||||
- switch.officeroom_accent_lights
|
- switch.officeroom_accent_lights
|
||||||
|
- switch.chromecast_monitor
|
||||||
stop_hass:
|
- switch.master_bathroom_lights
|
||||||
sequence:
|
|
||||||
- service: shell_command.stop_hass
|
|
||||||
update_hass:
|
|
||||||
sequence:
|
|
||||||
- service: shell_command.update_hass
|
|
||||||
restart_hass:
|
|
||||||
sequence:
|
|
||||||
- service: shell_command.restart_hass
|
|
||||||
|
|
||||||
xiaomi_red:
|
xiaomi_red:
|
||||||
sequence:
|
sequence:
|
||||||
|
@ -186,8 +175,8 @@ script:
|
||||||
state: "on"
|
state: "on"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{- message | trim != "" -}}'
|
value_template: '{{- message | trim != "" -}}'
|
||||||
- service: notify.telegram
|
- service: telegram_bot.send_message
|
||||||
data_template:
|
data:
|
||||||
title: "{{- title -}}"
|
title: "{{- title -}}"
|
||||||
message: "{{- message -}}"
|
message: "{{- message -}}"
|
||||||
data:
|
data:
|
||||||
|
@ -202,9 +191,15 @@ script:
|
||||||
state: "on"
|
state: "on"
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: '{{ message | trim != "" }}'
|
value_template: '{{ message | trim != "" }}'
|
||||||
- service: notify.telegram
|
- service: telegram_bot.send_message
|
||||||
data_template:
|
data:
|
||||||
message: "{{ message }}"
|
message: "{{ message }}"
|
||||||
|
- service: notify.android_tv_fire_tv
|
||||||
|
data:
|
||||||
|
message: "{{ message }}"
|
||||||
|
title: "Hello!"
|
||||||
|
data:
|
||||||
|
color: red
|
||||||
|
|
||||||
good_night_tts:
|
good_night_tts:
|
||||||
sequence:
|
sequence:
|
||||||
|
@ -363,8 +358,12 @@ script:
|
||||||
- service: input_boolean.turn_on
|
- service: input_boolean.turn_on
|
||||||
entity_id: input_boolean.pill_taken
|
entity_id: input_boolean.pill_taken
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data:
|
data_template:
|
||||||
message: "Thank you for taking tablets on time!"
|
message: >
|
||||||
|
Thank you for taking tablets.
|
||||||
|
{%- if state_attr('sensor.allergy_index_today', 'rating') != None %}
|
||||||
|
{{- " Today's pollen level is : " ~ state_attr('sensor.allergy_index_today', 'rating') }}.
|
||||||
|
{%- endif -%}
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.pill_voice_notification') == 'on' }}"
|
value_template: "{{ states('input_boolean.pill_voice_notification') == 'on' }}"
|
||||||
- service: script.voice_notify
|
- service: script.voice_notify
|
||||||
|
|
|
@ -10,10 +10,6 @@
|
||||||
|
|
||||||
homeassistant:
|
homeassistant:
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: season
|
|
||||||
type: astronomical
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# _ _ _
|
# _ _ _
|
||||||
# /\ | | | | (_)
|
# /\ | | | | (_)
|
||||||
|
|
|
@ -56,18 +56,79 @@ input_datetime:
|
||||||
input_number:
|
input_number:
|
||||||
calendar_remind_before_days:
|
calendar_remind_before_days:
|
||||||
name: Calendar Remind Before Days
|
name: Calendar Remind Before Days
|
||||||
initial: 2
|
|
||||||
min: 1
|
min: 1
|
||||||
max: 15
|
max: 15
|
||||||
step: 1
|
step: 1
|
||||||
mode: box
|
mode: box
|
||||||
battery_alert_threshold:
|
battery_alert_threshold:
|
||||||
name: Notify Low Battery if goes below
|
name: Notify Low Battery if goes below
|
||||||
initial: 4
|
|
||||||
min: 1
|
min: 1
|
||||||
max: 100
|
max: 100
|
||||||
step: 1
|
step: 1
|
||||||
mode: box
|
mode: box
|
||||||
|
guest_bathroom_exhaust_timer_duration:
|
||||||
|
name: Guest Bathroom Shower Exhaust Timer Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
master_bathroom_shower_exhaust_timer_duration:
|
||||||
|
name: Master Bathroom Shower Exhaust Timer Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
master_bathroom_toilet_exhaust_timer_duration:
|
||||||
|
name: Master Bathroom Toilet Exhaust Timer Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
master_bathroom_toilet_lights:
|
||||||
|
name: Master Bathroom Toilet Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
|
||||||
|
guest_bathroom_lights:
|
||||||
|
name: Guest Bathroom Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
master_bathroom_lights:
|
||||||
|
name: Master Bathroom Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
garage_lights:
|
||||||
|
name: Garage Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
garage_shop_lights:
|
||||||
|
name: Garage Shop Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 240
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
|
||||||
|
######################### CLOSET LIGHTS
|
||||||
|
hasika_bedroom_closet_lights:
|
||||||
|
name: Hasika Closet Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 120
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
srinika_bedroom_closet_lights:
|
||||||
|
name: Srinika Closet Lights Duration
|
||||||
|
min: 5
|
||||||
|
max: 120
|
||||||
|
step: 5
|
||||||
|
mode: box
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: template
|
- platform: template
|
||||||
|
@ -202,11 +263,6 @@ input_boolean:
|
||||||
name: Battery Notifications
|
name: Battery Notifications
|
||||||
icon: mdi:battery
|
icon: mdi:battery
|
||||||
|
|
||||||
sharp_tv:
|
|
||||||
name: TV
|
|
||||||
initial: on
|
|
||||||
icon: mdi:television-classic
|
|
||||||
|
|
||||||
dummy:
|
dummy:
|
||||||
name: "Dummy Input Boolean!"
|
name: "Dummy Input Boolean!"
|
||||||
icon: mdi:sticker-emoji
|
icon: mdi:sticker-emoji
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
homeassistant:
|
|
||||||
# customize:
|
|
||||||
|
|
||||||
# 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
|
|
||||||
# 10 miles per day (or 3% battery use) on an average. Use this setting carefully!
|
|
||||||
|
|
||||||
tesla:
|
|
||||||
username: !secret tesla_username
|
|
||||||
password: !secret tesla_password
|
|
||||||
scan_interval: 21600
|
|
||||||
###############################################################################
|
|
||||||
# _ _ _
|
|
||||||
# /\ | | | | (_)
|
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
automation:
|
|
||||||
- alias: Notify Charging Status
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: binary_sensor.tesla_model_3_charger_sensor
|
|
||||||
action:
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "Tesla Car Charge Status changed to: {{ trigger.to_state.state| upper }}"
|
|
||||||
|
|
||||||
- alias: Notify Door Status
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: lock.tesla_model_3_door_lock
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
|
||||||
action:
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "Tesla Door is now: {{ trigger.to_state.state | upper }}"
|
|
||||||
|
|
||||||
- alias: Notify Charger Switch State
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: switch.tesla_model_3_charger_switch
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: '{{ trigger.from_state.state | lower != "unknown" }}'
|
|
||||||
action:
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "Tesla Door is now: {{ trigger.to_state.state| upper }}"
|
|
|
@ -12,13 +12,6 @@ binary_sensor:
|
||||||
payload_off: "off"
|
payload_off: "off"
|
||||||
value_template: "{{ value }}"
|
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 }}"
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# _ _ _
|
# _ _ _
|
||||||
# /\ | | | | (_)
|
# /\ | | | | (_)
|
||||||
|
@ -29,26 +22,33 @@ binary_sensor:
|
||||||
#
|
#
|
||||||
###############################################################################
|
###############################################################################
|
||||||
automation:
|
automation:
|
||||||
# Restore Familyroom Lights
|
|
||||||
###############################################################################
|
- alias: TV Status ON
|
||||||
- alias: Restore Familyroom Lights
|
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: state
|
platform: state
|
||||||
entity_id: input_boolean.animate_downstairs_lights
|
entity_id: remote.streaming_stick_4k
|
||||||
to: "off"
|
to: "on"
|
||||||
condition:
|
|
||||||
- condition: state
|
|
||||||
entity_id: input_boolean.light_automations
|
|
||||||
state: "on"
|
|
||||||
action:
|
action:
|
||||||
- service: light.turn_on
|
- service: mqtt.publish
|
||||||
data:
|
data_template:
|
||||||
entity_id: group.family_room_lights
|
topic: "/home/sharptv"
|
||||||
transition: 5
|
payload: "on"
|
||||||
rgb_color: [255, 251, 245]
|
retain: true
|
||||||
brightness: 255
|
|
||||||
color_temp: 162
|
- alias: TV Status OFF
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
platform: state
|
||||||
|
entity_id: remote.streaming_stick_4k
|
||||||
|
to: "unavailable"
|
||||||
|
action:
|
||||||
|
- service: mqtt.publish
|
||||||
|
data_template:
|
||||||
|
topic: "/home/sharptv"
|
||||||
|
payload: "off"
|
||||||
|
retain: true
|
||||||
|
|
||||||
|
|
||||||
# Dim Family Room Lights When TV is Turned ON
|
# Dim Family Room Lights When TV is Turned ON
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
###############################################################################
|
|
||||||
# @Author : Mahasri Kalavala
|
|
||||||
# @Date : 01/27/2018
|
|
||||||
# @Package : USPS Package - notifies me of mails and packages.
|
|
||||||
###############################################################################
|
|
||||||
homeassistant:
|
|
||||||
customize:
|
|
||||||
sensor.usps_mail:
|
|
||||||
friendly_name: USPS Mail
|
|
||||||
icon: mdi:email-outline
|
|
||||||
sensor.usps_packages:
|
|
||||||
friendly_name: USPS Packages
|
|
||||||
icon: mdi:package-variant
|
|
||||||
|
|
||||||
sensor:
|
|
||||||
- platform: mqtt
|
|
||||||
name: "USPS Mail"
|
|
||||||
state_topic: "/usps/mails"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
- platform: mqtt
|
|
||||||
name: USPS Packages
|
|
||||||
state_topic: "/usps/packages"
|
|
||||||
value_template: "{{ value }}"
|
|
||||||
|
|
||||||
camera:
|
|
||||||
- platform: generic
|
|
||||||
name: USPS Mail Pictures
|
|
||||||
still_image_url: !secret usps_camera_url
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# _ _ _
|
|
||||||
# /\ | | | | (_)
|
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
automation:
|
|
||||||
# Notify USPS mails via TTS, and iOS notification with attachment
|
|
||||||
###############################################################################
|
|
||||||
- alias: Notify USPS Mail
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: sensor.usps_mail
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('sensor.usps_mail') != 'unknown' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('sensor.usps_mail') | int > 0 }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ ((now().hour | int) > 7) and ((now().hour | int) < 16) }}"
|
|
||||||
action:
|
|
||||||
- service: script.voice_notify
|
|
||||||
data_template:
|
|
||||||
message: >
|
|
||||||
{%- if states('sensor.usps_mail') | int == 1 -%}
|
|
||||||
Attention: USPS is delivering {{ states('sensor.usps_mail') }} mail today.
|
|
||||||
{%- else -%}
|
|
||||||
Attention: USPS is delivering {{ states('sensor.usps_mail') }} mails today.
|
|
||||||
{%- endif -%}
|
|
||||||
- service: script.led_message
|
|
||||||
data_template:
|
|
||||||
message: >
|
|
||||||
{%- if states('sensor.usps_mail') | int == 1 -%}
|
|
||||||
USPS is delivering {{ states('sensor.usps_mail') }} mail today.
|
|
||||||
{%- else -%}
|
|
||||||
USPS is delivering {{ states('sensor.usps_mail') }} mails today.
|
|
||||||
{%- endif -%}
|
|
||||||
- service: notify.ios_devices
|
|
||||||
data_template:
|
|
||||||
message: "USPS will be delivering {{ states('sensor.usps_mail') }} mail(s) today."
|
|
||||||
data:
|
|
||||||
push:
|
|
||||||
category: camera
|
|
||||||
entity_id: "camera.usps_mail_pictures"
|
|
||||||
attachment:
|
|
||||||
url: "{{ state_attr('camera.usps_mail_pictures', 'entity_picture') }}"
|
|
||||||
content-type: jpg
|
|
||||||
|
|
||||||
# Notify USPS packages via TTS. Usually there are no pictures for packages
|
|
||||||
###############################################################################
|
|
||||||
- alias: Notify USPS Packages
|
|
||||||
initial_state: true
|
|
||||||
trigger:
|
|
||||||
- platform: state
|
|
||||||
entity_id: sensor.usps_packages
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('sensor.usps_packages') != 'unknown' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('sensor.usps_packages') | int > 0 }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ ((now().hour | int) > 7) and ((now().hour | int) < 16) }}"
|
|
||||||
action:
|
|
||||||
- service: script.voice_notify
|
|
||||||
data_template:
|
|
||||||
message: >
|
|
||||||
{%- if states('sensor.usps_packages') | int == 1 -%}
|
|
||||||
Attention: USPS is delivering {{ states('sensor.usps_packages') }} package today.
|
|
||||||
{%- else -%}
|
|
||||||
Attention: USPS is delivering {{ states('sensor.usps_packages') }} packages today.
|
|
||||||
{%- endif -%}
|
|
|
@ -106,7 +106,7 @@ automation:
|
||||||
# General Watch Dog automation:
|
# General Watch Dog automation:
|
||||||
# Keeps and eye on the lights & switches, turns off after 10 PM if they are on.
|
# Keeps and eye on the lights & switches, turns off after 10 PM if they are on.
|
||||||
###############################################################################
|
###############################################################################
|
||||||
- alias: Lights And Switches WatchDog
|
- alias: Lights And Switches WatchDog 10 Min
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
|
@ -114,12 +114,11 @@ automation:
|
||||||
- switch.basement_left
|
- switch.basement_left
|
||||||
- switch.basement_right
|
- switch.basement_right
|
||||||
- switch.front_room
|
- switch.front_room
|
||||||
- switch.guest_bedroom
|
- switch.srinika_bedroom
|
||||||
- switch.kids_bed_accent
|
- switch.hasika_bed_accent
|
||||||
- switch.kids_bedroom
|
- switch.hasika_bedroom
|
||||||
- switch.kitchen
|
- switch.kitchen_switch
|
||||||
- switch.prayer_room
|
- switch.study_room
|
||||||
- switch.upstairs_fragrance
|
|
||||||
- light.hue_color_lamp_1
|
- light.hue_color_lamp_1
|
||||||
- light.hue_color_lamp_2
|
- light.hue_color_lamp_2
|
||||||
- light.hue_color_lamp_3
|
- light.hue_color_lamp_3
|
||||||
|
@ -139,3 +138,281 @@ automation:
|
||||||
- service: homeassistant.turn_off
|
- service: homeassistant.turn_off
|
||||||
data_template:
|
data_template:
|
||||||
entity_id: "{{ trigger.entity_id }}"
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Guest Bathroom Lights WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.guest_bathroom_lights
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.guest_bathroom_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Master Bathroom Lights WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- light.master_bathroom_lights
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.master_bathroom_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Garage Lights WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.garage
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.garage_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Garage Shop Lights WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.garage_shop_lights
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.garage_shop_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Guest Bathroom Exhaust WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.guest_bathroom_exhaust
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.guest_bathroom_exhaust_timer_duration')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Master Bathroom Shower Exhaust WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.master_bathroom_shower_exhaust
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.master_bathroom_shower_exhaust_timer_duration')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Master Bathroom Toilet Exhaust WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.master_bathroom_toilet_exhaust
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.master_bathroom_toilet_exhaust_timer_duration')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# CLOSET LIGHTS WATCH DOG
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
- alias: Srinika Bedroom Closet WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.srinika_bedroom_closet
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.srinika_bedroom_closet_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Hasika Bedroom Closet WatchDog
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- switch.hasika_bedroom_closet
|
||||||
|
to: "on"
|
||||||
|
for:
|
||||||
|
minutes: "{{ states('input_number.hasika_bedroom_closet_lights')|int }}"
|
||||||
|
condition:
|
||||||
|
- condition: state
|
||||||
|
entity_id: input_boolean.light_automations
|
||||||
|
state: "on"
|
||||||
|
action:
|
||||||
|
- service: homeassistant.turn_off
|
||||||
|
data_template:
|
||||||
|
entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
- alias: Notify Plex User Status
|
||||||
|
initial_state: true
|
||||||
|
trigger:
|
||||||
|
# - platform: numeric_state
|
||||||
|
# entity_id: sensor.plex_mahasri_nas
|
||||||
|
# above: 0
|
||||||
|
# for:
|
||||||
|
# minutes: 2
|
||||||
|
- platform: state
|
||||||
|
entity_id:
|
||||||
|
- media_player.plex_adi_bh_plex_for_roku_roku3
|
||||||
|
- media_player.plex_adi_bh_plex_for_roku_rokuultra
|
||||||
|
- media_player.plex_prade5_plex_for_roku_roku_express
|
||||||
|
to: 'playing'
|
||||||
|
for:
|
||||||
|
minutes: 2
|
||||||
|
action:
|
||||||
|
- service: script.notify_me
|
||||||
|
data_template:
|
||||||
|
message: >-
|
||||||
|
{%- set tag_map = {'adi.bh':'Adi', 'prade5':'Pradeep'} -%}
|
||||||
|
{% for item in states.media_player if item.state == 'playing' and state_attr(item.entity_id, 'media_title') != None
|
||||||
|
and state_attr(item.entity_id, 'username') != 'kalavala'
|
||||||
|
and tag_map[state_attr(item.entity_id, 'username')] |trim != '' %}
|
||||||
|
|
||||||
|
{{ tag_map[state_attr(item.entity_id, 'username')] }} is watching {% if state_attr(item.entity_id, 'media_content_type') == "movie" -%}
|
||||||
|
{{ "a movie, " + state_attr(item.entity_id, 'media_title') |title }}
|
||||||
|
{% endif %}
|
||||||
|
{%- if state_attr(item.entity_id, 'media_content_type') == "tvshow" %}
|
||||||
|
TV Show - {{ state_attr(item.entity_id, 'media_series_title') }}
|
||||||
|
Season: {{ state_attr(item.entity_id, 'media_season') }}, Episode: {{ state_attr(item.entity_id, 'media_episode') }} ({{ state_attr(item.entity_id, 'media_title') }})
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# - alias: Lights And Switches WatchDog 10 Min
|
||||||
|
# initial_state: true
|
||||||
|
# trigger:
|
||||||
|
# - platform: state
|
||||||
|
# entity_id:
|
||||||
|
# - switch.guest_bathroom_exhaust
|
||||||
|
# - switch.master_bathroom_toilet_exhaust
|
||||||
|
# to: "on"
|
||||||
|
# for:
|
||||||
|
# minutes: 10
|
||||||
|
# condition:
|
||||||
|
# - condition: state
|
||||||
|
# entity_id: input_boolean.light_automations
|
||||||
|
# state: "on"
|
||||||
|
# action:
|
||||||
|
# - service: homeassistant.turn_off
|
||||||
|
# data_template:
|
||||||
|
# entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Main master Bathoom has more CFM to vent out... keep it for 20 minutes
|
||||||
|
#
|
||||||
|
# - alias: Lights And Switches WatchDog 20 Min
|
||||||
|
# initial_state: true
|
||||||
|
# trigger:
|
||||||
|
# - platform: state
|
||||||
|
# entity_id:
|
||||||
|
# - switch.master_bathroom_shower_exhaust
|
||||||
|
# to: "on"
|
||||||
|
# for:
|
||||||
|
# minutes: 20
|
||||||
|
# condition:
|
||||||
|
# - condition: state
|
||||||
|
# entity_id: input_boolean.light_automations
|
||||||
|
# state: "on"
|
||||||
|
# action:
|
||||||
|
# - service: homeassistant.turn_off
|
||||||
|
# data_template:
|
||||||
|
# entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
# - alias: Lights And Switches WatchDog 30 Min
|
||||||
|
# initial_state: true
|
||||||
|
# trigger:
|
||||||
|
# - platform: state
|
||||||
|
# entity_id:
|
||||||
|
# - switch.guest_bathroom_lights
|
||||||
|
# - switch.master_bathroom_toilet_light
|
||||||
|
# to: "on"
|
||||||
|
# for:
|
||||||
|
# minutes: 30
|
||||||
|
# condition:
|
||||||
|
# - condition: state
|
||||||
|
# entity_id: input_boolean.light_automations
|
||||||
|
# state: "on"
|
||||||
|
# action:
|
||||||
|
# - service: homeassistant.turn_off
|
||||||
|
# data_template:
|
||||||
|
# entity_id: "{{ trigger.entity_id }}"
|
||||||
|
|
||||||
|
# - alias: Lights And Switches WatchDog 45 Min
|
||||||
|
# initial_state: true
|
||||||
|
# trigger:
|
||||||
|
# - platform: state
|
||||||
|
# entity_id:
|
||||||
|
# - switch.garage_shop_lights
|
||||||
|
# to: "on"
|
||||||
|
# for:
|
||||||
|
# minutes: 45
|
||||||
|
# condition:
|
||||||
|
# - condition: state
|
||||||
|
# entity_id: input_boolean.light_automations
|
||||||
|
# state: "on"
|
||||||
|
# action:
|
||||||
|
# - service: homeassistant.turn_off
|
||||||
|
# data_template:
|
||||||
|
# entity_id: "{{ trigger.entity_id }}"
|
|
@ -115,6 +115,7 @@ binary_sensor:
|
||||||
weather:
|
weather:
|
||||||
- platform: darksky
|
- platform: darksky
|
||||||
api_key: !secret darksky_api_key
|
api_key: !secret darksky_api_key
|
||||||
|
mode: daily
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: darksky
|
- platform: darksky
|
||||||
|
|
|
@ -1,87 +0,0 @@
|
||||||
###############################################################################
|
|
||||||
# @author : Mahasri Kalavala
|
|
||||||
# @date : 11/07/2017
|
|
||||||
# @package : Work From Home (wfh)
|
|
||||||
# @description : Reminds me to Get Up and Walk around the house once
|
|
||||||
# every 30 minutes during Work From Home days
|
|
||||||
###############################################################################
|
|
||||||
homeassistant:
|
|
||||||
customize:
|
|
||||||
timer.wfh_timer:
|
|
||||||
hidden: true
|
|
||||||
|
|
||||||
timer:
|
|
||||||
wfh_timer:
|
|
||||||
duration: "00:30:00"
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# _ _ _
|
|
||||||
# /\ | | | | (_)
|
|
||||||
# / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
#
|
|
||||||
###############################################################################
|
|
||||||
|
|
||||||
automation:
|
|
||||||
# Start WFH timer if Suresh is HOME during weekdays between 10 AM and 5 PM
|
|
||||||
###############################################################################
|
|
||||||
- alias: WFH Timer Start
|
|
||||||
initial_state: false
|
|
||||||
trigger:
|
|
||||||
- platform: time_pattern
|
|
||||||
minutes: "/5"
|
|
||||||
seconds: 00
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('binary_sensor.workday_sensor') == 'on' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ now().hour|int >= 10 and now().hour|int < 17 }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('timer.wfh_timer') == 'idle' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('device_tracker.life360_suresh') == 'home' }}"
|
|
||||||
action:
|
|
||||||
- service: timer.start
|
|
||||||
entity_id: timer.wfh_timer
|
|
||||||
|
|
||||||
# Timer elapsed... Remind Suresh to take a quick walk
|
|
||||||
# Restart the timer ONLY if the time is betwen office hours (10 AM and 5 PM)
|
|
||||||
###############################################################################
|
|
||||||
- alias: Timer Elapsed - Take a walk
|
|
||||||
initial_state: false
|
|
||||||
trigger:
|
|
||||||
- platform: event
|
|
||||||
event_type: timer.finished
|
|
||||||
event_data:
|
|
||||||
entity_id: timer.wfh_timer
|
|
||||||
action:
|
|
||||||
- service_template: >
|
|
||||||
{% if now().hour | int >= 10 and now().hour | int < 17 %}
|
|
||||||
timer.start
|
|
||||||
{% else %}
|
|
||||||
timer.cancel
|
|
||||||
{% endif %}
|
|
||||||
entity_id: timer.wfh_timer
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ now().hour|int >= 10 and now().hour|int < 17 }}"
|
|
||||||
- service: script.voice_notify
|
|
||||||
data_template:
|
|
||||||
message: "It is time to stand up and walk around!"
|
|
||||||
|
|
||||||
# Cancel timer (if active) When Suresh left home
|
|
||||||
###############################################################################
|
|
||||||
- alias: Cancel WFH Timer When Suresh Leaves Home
|
|
||||||
initial_state: false
|
|
||||||
trigger:
|
|
||||||
- platform: zone
|
|
||||||
entity_id: device_tracker.life360_suresh
|
|
||||||
zone: zone.home
|
|
||||||
event: leave
|
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('timer.wfh_timer') == 'active' }}"
|
|
||||||
action:
|
|
||||||
- service: timer.cancel
|
|
||||||
entity_id: timer.wfh_timer
|
|
|
@ -75,7 +75,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: switch.toggle
|
- service: switch.toggle
|
||||||
entity_id: switch.kitchen
|
entity_id: switch.kitchen_switch
|
||||||
|
|
||||||
# Double Tap: Turn OFF Downstairs Lights
|
# Double Tap: Turn OFF Downstairs Lights
|
||||||
- alias: Family Room Cube Event Tap Twice
|
- alias: Family Room Cube Event Tap Twice
|
||||||
|
@ -186,7 +186,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service_template: switch.toggle
|
- service_template: switch.toggle
|
||||||
entity_id: switch.guest_bedroom
|
entity_id: switch.srinika_bedroom
|
||||||
|
|
||||||
# Shake: Toggle Do Not Disturb Mode
|
# Shake: Toggle Do Not Disturb Mode
|
||||||
- alias: Srinika Room Cube Event Shake
|
- alias: Srinika Room Cube Event Shake
|
||||||
|
@ -227,7 +227,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service_template: switch.toggle
|
- service_template: switch.toggle
|
||||||
entity_id: switch.kids_bedroom
|
entity_id: switch.hasika_bedroom
|
||||||
|
|
||||||
# Shake: Toggle Do Not Disturb Mode
|
# Shake: Toggle Do Not Disturb Mode
|
||||||
- alias: Hasika Room Cube Event Shake
|
- alias: Hasika Room Cube Event Shake
|
||||||
|
@ -270,7 +270,7 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: switch.toggle
|
- service: switch.toggle
|
||||||
entity_id: switch.prayer_room
|
entity_id: switch.study_room
|
||||||
|
|
||||||
# Shake: Toggle Do Not Disturb Mode
|
# Shake: Toggle Do Not Disturb Mode
|
||||||
- alias: Study Room Cube Event Shake
|
- alias: Study Room Cube Event Shake
|
||||||
|
@ -311,8 +311,10 @@ automation:
|
||||||
state: "on"
|
state: "on"
|
||||||
action:
|
action:
|
||||||
- service: homeassistant.turn_off
|
- service: homeassistant.turn_off
|
||||||
|
data:
|
||||||
entity_id: group.downstairs_lights
|
entity_id: group.downstairs_lights
|
||||||
- service: homeassistant.turn_off
|
- service: homeassistant.turn_off
|
||||||
|
data:
|
||||||
entity_id: group.upstairs_lights
|
entity_id: group.upstairs_lights
|
||||||
|
|
||||||
# Flip 180: Toggle Lights
|
# Flip 180: Toggle Lights
|
||||||
|
@ -428,6 +430,7 @@ automation:
|
||||||
{% else %}
|
{% else %}
|
||||||
script.play_dog_sounds
|
script.play_dog_sounds
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
- service: script.doorbell_camera_pics
|
||||||
|
|
||||||
- alias: Doorbell Double Press
|
- alias: Doorbell Double Press
|
||||||
initial_state: true
|
initial_state: true
|
||||||
|
@ -444,6 +447,7 @@ automation:
|
||||||
{% else %}
|
{% else %}
|
||||||
script.play_dog_sounds
|
script.play_dog_sounds
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
- service: script.doorbell_camera_pics
|
||||||
|
|
||||||
- alias: Doorbell Long Press
|
- alias: Doorbell Long Press
|
||||||
initial_state: true
|
initial_state: true
|
||||||
|
@ -460,3 +464,43 @@ automation:
|
||||||
{% else %}
|
{% else %}
|
||||||
script.play_dog_sounds
|
script.play_dog_sounds
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
- service: script.doorbell_camera_pics
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# Script for sending camera snapshots when doorbell is pressed
|
||||||
|
################################################################################
|
||||||
|
script:
|
||||||
|
|
||||||
|
doorbell_camera_pics:
|
||||||
|
sequence:
|
||||||
|
- service: script.notify_me
|
||||||
|
data:
|
||||||
|
message: "ALERT! Someone is at the front door!"
|
||||||
|
- service: camera.snapshot
|
||||||
|
data_template:
|
||||||
|
entity_id: "camera.frontdoor_camera"
|
||||||
|
filename:
|
||||||
|
"{{ '/config/www/downloads/camera/frontdoor/frontdoor_' ~
|
||||||
|
(state_attr('script.doorbell_camera_pics', 'last_triggered') ~ '').replace('-','_')
|
||||||
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
- service: camera.snapshot
|
||||||
|
data_template:
|
||||||
|
entity_id: "camera.driveway_camera"
|
||||||
|
filename:
|
||||||
|
"{{ '/config/www/downloads/camera/driveway/driveway_' ~
|
||||||
|
(state_attr('script.doorbell_camera_pics', 'last_triggered') ~ '').replace('-','_')
|
||||||
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
- service: notify.telegram
|
||||||
|
data_template:
|
||||||
|
title: "Door Bell"
|
||||||
|
message: "Someone rang door bell!"
|
||||||
|
data:
|
||||||
|
photo:
|
||||||
|
- file: "{{ '/config/www/downloads/camera/frontdoor/frontdoor_' ~
|
||||||
|
(state_attr('script.doorbell_camera_pics', 'last_triggered') ~ '').replace('-','_')
|
||||||
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
caption: "Someone rang door bell!"
|
||||||
|
- file: "{{ '/config/www/downloads/camera/driveway/driveway_' ~
|
||||||
|
(state_attr('script.doorbell_camera_pics', 'last_triggered') ~ '').replace('-','_')
|
||||||
|
.replace(' ', '_').replace(':','_').replace('.','_').replace('+','_') ~ '.jpg' }}"
|
||||||
|
caption: "Someone rang door bell!"
|
|
@ -10,18 +10,9 @@ homeassistant:
|
||||||
friendly_name: Away Mode
|
friendly_name: Away Mode
|
||||||
zone.home:
|
zone.home:
|
||||||
friendly_name: Home
|
friendly_name: Home
|
||||||
zone.work:
|
|
||||||
friendly_name: Office
|
|
||||||
group.zone_alerts:
|
group.zone_alerts:
|
||||||
order: 40
|
order: 40
|
||||||
|
|
||||||
zone:
|
|
||||||
- name: work
|
|
||||||
latitude: !secret work_latitude
|
|
||||||
longitude: !secret work_longitude
|
|
||||||
radius: 200
|
|
||||||
icon: mdi:briefcase
|
|
||||||
|
|
||||||
input_boolean:
|
input_boolean:
|
||||||
home_mode_away:
|
home_mode_away:
|
||||||
name: Away
|
name: Away
|
||||||
|
@ -29,11 +20,7 @@ input_boolean:
|
||||||
|
|
||||||
proximity:
|
proximity:
|
||||||
home:
|
home:
|
||||||
devices: device_tracker.life360_suresh
|
devices: device_tracker.suresh
|
||||||
tolerance: 50
|
|
||||||
unit_of_measurement: mi
|
|
||||||
work:
|
|
||||||
devices: device_tracker.life360_suresh
|
|
||||||
tolerance: 50
|
tolerance: 50
|
||||||
unit_of_measurement: mi
|
unit_of_measurement: mi
|
||||||
|
|
||||||
|
@ -56,16 +43,12 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: zone
|
- platform: zone
|
||||||
entity_id:
|
entity_id:
|
||||||
- device_tracker.life360_hasika
|
- device_tracker.hasika
|
||||||
- device_tracker.life360_mallika
|
- device_tracker.mallika
|
||||||
- device_tracker.life360_srinika
|
- device_tracker.srinika
|
||||||
- device_tracker.life360_suresh
|
- device_tracker.suresh
|
||||||
zone: zone.home
|
zone: zone.home
|
||||||
event: enter
|
event: enter
|
||||||
- platform: zone
|
|
||||||
entity_id: device_tracker.life360_suresh
|
|
||||||
zone: zone.work
|
|
||||||
event: enter
|
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
||||||
|
@ -85,16 +68,12 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: zone
|
- platform: zone
|
||||||
entity_id:
|
entity_id:
|
||||||
- device_tracker.life360_hasika
|
- device_tracker.hasika
|
||||||
- device_tracker.life360_mallika
|
- device_tracker.mallika
|
||||||
- device_tracker.life360_srinika
|
- device_tracker.srinika
|
||||||
- device_tracker.life360_suresh
|
- device_tracker.suresh
|
||||||
zone: zone.home
|
zone: zone.home
|
||||||
event: leave
|
event: leave
|
||||||
- platform: zone
|
|
||||||
entity_id: device_tracker.life360_suresh
|
|
||||||
zone: zone.work
|
|
||||||
event: leave
|
|
||||||
condition:
|
condition:
|
||||||
- condition: template
|
- condition: template
|
||||||
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
value_template: "{{ states('input_boolean.zone_alerts') == 'on' }}"
|
||||||
|
@ -119,10 +98,10 @@ automation:
|
||||||
trigger:
|
trigger:
|
||||||
- platform: state
|
- platform: state
|
||||||
entity_id:
|
entity_id:
|
||||||
- device_tracker.life360_mallika
|
- device_tracker.mallika
|
||||||
- device_tracker.life360_suresh
|
- device_tracker.suresh
|
||||||
- device_tracker.life360_srinika
|
- device_tracker.srinika
|
||||||
- device_tracker.life360_hasika
|
- device_tracker.hasika
|
||||||
from: "not_home"
|
from: "not_home"
|
||||||
to: "home"
|
to: "home"
|
||||||
for: "00:02:00"
|
for: "00:02:00"
|
||||||
|
@ -142,32 +121,25 @@ automation:
|
||||||
greeting: "no"
|
greeting: "no"
|
||||||
- service: input_boolean.turn_off
|
- service: input_boolean.turn_off
|
||||||
entity_id: input_boolean.home_mode_away
|
entity_id: input_boolean.home_mode_away
|
||||||
|
- service: switch.turn_on
|
||||||
|
entity_id: switch.chromecast_monitor
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
# Alert when every one is away
|
# Alert when every one is away
|
||||||
##############################################################################
|
##############################################################################
|
||||||
- alias: Alert when everyone is AWAY
|
- alias: Poll Home Away Mode
|
||||||
initial_state: true
|
initial_state: true
|
||||||
trigger:
|
trigger:
|
||||||
platform: time_pattern
|
platform: time_pattern
|
||||||
minutes: 00
|
minutes: 00
|
||||||
seconds: "/30"
|
seconds: "/30"
|
||||||
condition:
|
|
||||||
- condition: template
|
|
||||||
value_template: "{{ states('input_boolean.home_mode_away') == 'off' }}"
|
|
||||||
- condition: template
|
|
||||||
value_template: >
|
|
||||||
{% set suresh = states('device_tracker.life360_suresh') %}
|
|
||||||
{% set mallika = states('device_tracker.life360_mallika') %}
|
|
||||||
{% set srinika = states('device_tracker.life360_srinika') %}
|
|
||||||
{% set hasika = states('device_tracker.life360_hasika') %}
|
|
||||||
{% if suresh != "home" and mallika != "home" and srinika != "home" and hasika != "home" %}
|
|
||||||
True
|
|
||||||
{% else %}
|
|
||||||
False
|
|
||||||
{% endif %}
|
|
||||||
action:
|
action:
|
||||||
- service: input_boolean.turn_on
|
- service_template: >-
|
||||||
|
{%- set suresh = states('device_tracker.suresh') -%}
|
||||||
|
{%- set mallika = states('device_tracker.mallika') -%}
|
||||||
|
{%- set srinika = states('device_tracker.srinika') -%}
|
||||||
|
{%- set hasika = states('device_tracker.hasika') -%}
|
||||||
|
{{ 'input_boolean.turn_on' if suresh != "home" and mallika != "home" and srinika != "home" and hasika != "home" else 'input_boolean.turn_off' }}
|
||||||
entity_id: input_boolean.home_mode_away
|
entity_id: input_boolean.home_mode_away
|
||||||
|
|
||||||
- alias: Home Mode Away ON
|
- alias: Home Mode Away ON
|
||||||
|
@ -196,21 +168,3 @@ automation:
|
||||||
- service: script.notify_me
|
- service: script.notify_me
|
||||||
data_template:
|
data_template:
|
||||||
message: "Suresh is on his way home, he is within the 5 miles range. Should be home soon!"
|
message: "Suresh is on his way home, he is within the 5 miles range. Should be home soon!"
|
||||||
- condition: template
|
|
||||||
value_template: >
|
|
||||||
{% set suresh = states('device_tracker.life360_suresh') %}
|
|
||||||
{% set mallika = states('device_tracker.life360_mallika') %}
|
|
||||||
{% set srinika = states('device_tracker.life360_srinika') %}
|
|
||||||
{% set hasika = states('device_tracker.life360_hasika') %}
|
|
||||||
{% if suresh != "home" and mallika != "home" and srinika != "home" and hasika != "home" %}
|
|
||||||
True
|
|
||||||
{% else %}
|
|
||||||
False
|
|
||||||
{% endif %}
|
|
||||||
- service: climate.set_away_mode
|
|
||||||
data:
|
|
||||||
entity_id: climate.dining_room
|
|
||||||
away_mode: "false"
|
|
||||||
- service: script.notify_me
|
|
||||||
data_template:
|
|
||||||
message: "Your Nest thermostat is set to HOME mode. Thank you!"
|
|
||||||
|
|
|
@ -1,222 +0,0 @@
|
||||||
# ###############################################################################
|
|
||||||
# # @author : Mahasri Kalavala
|
|
||||||
# # @date : 04/20/2018
|
|
||||||
# # @package : zwave batteries
|
|
||||||
# # @description : Zwave batteries using input_label & MQTT
|
|
||||||
# ###############################################################################
|
|
||||||
|
|
||||||
# input_label:
|
|
||||||
# audio_detector:
|
|
||||||
# back_door_sensor:
|
|
||||||
# basement_door_sensor:
|
|
||||||
# downstairs_multi_sensor:
|
|
||||||
# zwave_front_door_sensor:
|
|
||||||
# front_room_multi_sensor:
|
|
||||||
# garage_door_sensor:
|
|
||||||
# guest_bedroom_multi_sensor:
|
|
||||||
# kitchen_motion_sensor:
|
|
||||||
# single_car_garage_door_tilt_sensor:
|
|
||||||
# stairs_motion_sensor:
|
|
||||||
# tv_multi_sensor:
|
|
||||||
# two_car_garage_door_tilt_sensor:
|
|
||||||
# upstairs_multi_sensor:
|
|
||||||
# wallmote:
|
|
||||||
# ecolink_motion_detector:
|
|
||||||
# ecolink_firefighter:
|
|
||||||
# ecolink_door_window_sensor_2:
|
|
||||||
# aeon_labs_zw100_multisensor_6_2:
|
|
||||||
# aeon_labs_zw100_multisensor_6:
|
|
||||||
# ecolink_door_window_sensor:
|
|
||||||
# ecolink_garage_door_tilt_sensor:
|
|
||||||
|
|
||||||
# suresh_battery:
|
|
||||||
# mallika_battery:
|
|
||||||
# srinika_battery:
|
|
||||||
# hasika_battery:
|
|
||||||
|
|
||||||
# suresh_charging:
|
|
||||||
# mallika_charging:
|
|
||||||
# srinika_charging:
|
|
||||||
# hasika_charging:
|
|
||||||
|
|
||||||
# suresh_wifi:
|
|
||||||
# mallika_wifi:
|
|
||||||
# srinika_wifi:
|
|
||||||
# hasika_wifi:
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # _ _ _
|
|
||||||
# # /\ | | | | (_)
|
|
||||||
# # / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# # / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# # / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# # /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
# #
|
|
||||||
# ###############################################################################
|
|
||||||
|
|
||||||
# automation:
|
|
||||||
# - alias: Update ZWave Battery Levels
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: state_changed
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.entity_id is not none }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.entity_id.split('.')[0] == 'zwave' }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.new_state.attributes.battery_level | trim != '' }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.new_state.attributes.battery_level | default(999) | int != 999 }}"
|
|
||||||
# action:
|
|
||||||
# - service: input_label.set_value
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1] -}}"
|
|
||||||
# value: "{{ trigger.event.data.new_state.attributes.battery_level }}"
|
|
||||||
# - service: input_label.set_name
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1] -}}"
|
|
||||||
# value: "{{ trigger.event.data.new_state.attributes.friendly_name }}'s Battery"
|
|
||||||
# - service: input_label.set_icon
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1] -}}"
|
|
||||||
# value: >
|
|
||||||
# {% set battery_level = trigger.event.data.new_state.attributes.battery_level | int %}
|
|
||||||
# {% set battery_round = (battery_level / 10)|int * 10 %}
|
|
||||||
# {% if battery_round >= 100 %}
|
|
||||||
# mdi:battery
|
|
||||||
# {% elif battery_round > 0 %}
|
|
||||||
# mdi:battery-{{ battery_round }}
|
|
||||||
# {% else %}
|
|
||||||
# mdi:battery-alert
|
|
||||||
# {% endif %}
|
|
||||||
|
|
||||||
# # - alias: Update Phone Battery Levels
|
|
||||||
# # initial_state: true
|
|
||||||
# # trigger:
|
|
||||||
# # platform: mqtt
|
|
||||||
# # topic: "owntracks/+/+"
|
|
||||||
# # action:
|
|
||||||
# # - service: input_label.set_value
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_wifi"
|
|
||||||
# # value: "{{ 'Yes' if trigger.payload_json.conn == 'w' else 'No' }}"
|
|
||||||
# # - service: input_label.set_icon
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_wifi"
|
|
||||||
# # value: "{{ 'mdi:wifi' if trigger.payload_json.conn == 'w' else 'mdi:wifi-off' }}"
|
|
||||||
# # - service: input_label.set_name
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_wifi"
|
|
||||||
# # value: "{{trigger.topic.split('/')[-1] | title }}'s phone wifi enabled?"
|
|
||||||
|
|
||||||
# # - service: input_label.set_value
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_battery"
|
|
||||||
# # value: "{{ trigger.payload_json.batt | int }}"
|
|
||||||
# # - service: input_label.set_name
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_battery"
|
|
||||||
# # value: "{{trigger.topic.split('/')[-1] | title }}'s Battery"
|
|
||||||
# # - service: input_label.set_icon
|
|
||||||
# # data_template:
|
|
||||||
# # entity_id: "input_label.{{trigger.topic.split('/')[-1]}}_battery"
|
|
||||||
# # value: >
|
|
||||||
# # {% set battery_level = trigger.payload_json.batt | int %}
|
|
||||||
# # {% set battery_round = (battery_level / 10)|int * 10 %}
|
|
||||||
# # {% if trigger.payload_json.charging == 1 %}
|
|
||||||
# # {% if battery_round >= 100 %}
|
|
||||||
# # mdi:battery-charging-100
|
|
||||||
# # {% elif battery_round > 0 %}
|
|
||||||
# # mdi:battery-charging-{{ battery_round }}
|
|
||||||
# # {% else %}
|
|
||||||
# # mdi:battery-alert
|
|
||||||
# # {% endif %}
|
|
||||||
# # {% else %}
|
|
||||||
# # {% if battery_round >= 100 %}
|
|
||||||
# # mdi:battery
|
|
||||||
# # {% elif battery_round > 0 %}
|
|
||||||
# # mdi:battery-{{ battery_round }}
|
|
||||||
# # {% else %}
|
|
||||||
# # mdi:battery-alert
|
|
||||||
# # {% endif %}
|
|
||||||
# # {% endif %}
|
|
||||||
|
|
||||||
# - alias: Update Phone Battery Levels From Life360
|
|
||||||
# initial_state: true
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: state_changed
|
|
||||||
# condition:
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.entity_id is not none }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ 'life360_' in trigger.event.data.entity_id }}"
|
|
||||||
# - condition: template
|
|
||||||
# value_template: "{{ trigger.event.data.new_state.attributes is not none }}"
|
|
||||||
# action:
|
|
||||||
# - service: input_label.set_name
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_battery"
|
|
||||||
# value: "{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] |title -}}'s Battery"
|
|
||||||
# - service: input_label.set_value
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_battery"
|
|
||||||
# value: "{{ trigger.event.data.new_state.attributes.battery }}"
|
|
||||||
# - service: input_label.set_icon
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_battery"
|
|
||||||
# value: >
|
|
||||||
# {% set battery_level = trigger.event.data.new_state.attributes.battery | int %}
|
|
||||||
# {% set battery_round = (battery_level / 10)|int * 10 %}
|
|
||||||
# {% if trigger.event.data.new_state.attributes.battery_charging == "true" %}
|
|
||||||
# {% if battery_round >= 100 %}
|
|
||||||
# mdi:battery-charging-100
|
|
||||||
# {% elif battery_round > 0 %}
|
|
||||||
# mdi:battery-charging-{{ battery_round }}
|
|
||||||
# {% else %}
|
|
||||||
# mdi:battery-alert
|
|
||||||
# {% endif %}
|
|
||||||
# {% else %}
|
|
||||||
# {% if battery_round >= 100 %}
|
|
||||||
# mdi:battery
|
|
||||||
# {% elif battery_round > 0 %}
|
|
||||||
# mdi:battery-{{ battery_round }}
|
|
||||||
# {% else %}
|
|
||||||
# mdi:battery-alert
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
||||||
# - service: input_label.set_value
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_wifi"
|
|
||||||
# value: "{{ 'WiFi' if trigger.event.data.new_state.attributes.wifi_on |string |lower == 'true' else 'LTE' }}"
|
|
||||||
# - service: input_label.set_value
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_charging"
|
|
||||||
# value: "{{ 'Charging' if trigger.event.data.new_state.attributes.battery_charging |string |lower == 'true' else 'Not Charging' }}"
|
|
||||||
# - service: input_label.set_icon
|
|
||||||
# data_template:
|
|
||||||
# entity_id: "input_label.{{- trigger.event.data.entity_id.split('.')[1].split('_')[1] -}}_charging"
|
|
||||||
# value: >
|
|
||||||
# {% set battery_level = trigger.event.data.new_state.attributes.battery | int %}
|
|
||||||
# {% set battery_round = (battery_level / 10)|int * 10 %}
|
|
||||||
# {% if trigger.event.data.new_state.attributes.battery_charging == "true" %}
|
|
||||||
# {% if battery_round >= 100 %}
|
|
||||||
# mdi:battery-charging-100
|
|
||||||
# {% elif battery_round > 0 %}
|
|
||||||
# mdi:battery-charging-{{ battery_round }}
|
|
||||||
# {% else %}
|
|
||||||
# mdi:battery-alert
|
|
||||||
# {% endif %}
|
|
||||||
# {% else %}
|
|
||||||
# {% if battery_round >= 100 %}
|
|
||||||
# mdi:battery
|
|
||||||
# {% elif battery_round > 0 %}
|
|
||||||
# mdi:battery-{{ battery_round }}
|
|
||||||
# {% else %}
|
|
||||||
# mdi:battery-alert
|
|
||||||
# {% endif %}
|
|
||||||
# {% endif %}
|
|
|
@ -1,318 +0,0 @@
|
||||||
# #################################################################
|
|
||||||
# # @author : Mahasri Kalavala
|
|
||||||
# # @date : 09/18/17
|
|
||||||
# # @package : Z-Wave package
|
|
||||||
# # @description : Z-Wave Still and it's configuration stuff
|
|
||||||
# #
|
|
||||||
# # This entire page is auto generated by the script (link below):
|
|
||||||
# # https://github.com/skalavala/mysmarthome/blob/master/jinja_helpers/zwave_auto_gen.md
|
|
||||||
# #################################################################
|
|
||||||
|
|
||||||
# homeassistant:
|
|
||||||
# customize:
|
|
||||||
# # ZWave Binary Sensors
|
|
||||||
# binary_sensor.audio_detector_sensor:
|
|
||||||
# friendly_name: Audio Detector Sensor
|
|
||||||
# binary_sensor.basement_door_sensor_sensor:
|
|
||||||
# friendly_name: Basement Door Sensor
|
|
||||||
# binary_sensor.downstairs_multi_sensor_sensor:
|
|
||||||
# friendly_name: Downstairs Multi Sensor
|
|
||||||
# binary_sensor.front_door_sensor_sensor:
|
|
||||||
# friendly_name: Front Door Sensor
|
|
||||||
# binary_sensor.front_room_multi_sensor_sensor:
|
|
||||||
# friendly_name: Front Room Multi Sensor
|
|
||||||
# binary_sensor.garage_door_sensor_sensor:
|
|
||||||
# friendly_name: Garage Door Sensor
|
|
||||||
# binary_sensor.guest_bedroom_multi_sensor_sensor:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor
|
|
||||||
# binary_sensor.kitchen_motion_sensor_sensor:
|
|
||||||
# friendly_name: Kitchen Motion Sensor
|
|
||||||
# binary_sensor.door_window_sensor_158d0004248d5b:
|
|
||||||
# friendly_name: Single Car Garage Door
|
|
||||||
# binary_sensor.stairs_motion_sensor_sensor:
|
|
||||||
# friendly_name: Stairs Motion Sensor
|
|
||||||
# binary_sensor.tv_multi_sensor_sensor:
|
|
||||||
# friendly_name: TV Multi Sensor
|
|
||||||
# binary_sensor.door_window_sensor_158d0004231f7b:
|
|
||||||
# friendly_name: Double Car Garage Door
|
|
||||||
# binary_sensor.upstairs_multi_sensor_sensor:
|
|
||||||
# friendly_name: Upstairs Multi Sensor
|
|
||||||
|
|
||||||
# # ZWave Sensors
|
|
||||||
# sensor.audio_detector_alarm_level:
|
|
||||||
# friendly_name: Audio Detector Alarm Level
|
|
||||||
# sensor.audio_detector_alarm_type:
|
|
||||||
# friendly_name: Audio Detector Alarm Type
|
|
||||||
# sensor.audio_detector_burglar:
|
|
||||||
# friendly_name: Audio Detector Burglar
|
|
||||||
# sensor.audio_detector_carbon_monoxide:
|
|
||||||
# friendly_name: Audio Detector Carbon Monoxide
|
|
||||||
# sensor.audio_detector_power_management:
|
|
||||||
# friendly_name: Audio Detector Power Management
|
|
||||||
# sensor.audio_detector_smoke:
|
|
||||||
# friendly_name: Audio Detector Smoke
|
|
||||||
# sensor.audio_detector_sourcenodeid:
|
|
||||||
# friendly_name: Audio Detector SourceNodeId
|
|
||||||
# sensor.audio_detector_temperature:
|
|
||||||
# friendly_name: Audio Detector Temperature
|
|
||||||
# sensor.back_door_sensor_access_control:
|
|
||||||
# friendly_name: Back Door Sensor Access Control
|
|
||||||
# sensor.back_door_sensor_alarm_level:
|
|
||||||
# friendly_name: Back Door Sensor Alarm Level
|
|
||||||
# sensor.back_door_sensor_alarm_type:
|
|
||||||
# friendly_name: Back Door Sensor Alarm Type
|
|
||||||
# sensor.back_door_sensor_burglar:
|
|
||||||
# friendly_name: Back Door Sensor Burglar
|
|
||||||
# sensor.back_door_sensor_power_management:
|
|
||||||
# friendly_name: Back Door Sensor Power Management
|
|
||||||
# sensor.back_door_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Back Door Sensor SourceNodeId
|
|
||||||
# sensor.basement_door_sensor_access_control:
|
|
||||||
# friendly_name: Basement Door Sensor Access Control
|
|
||||||
# sensor.basement_door_sensor_alarm_level:
|
|
||||||
# friendly_name: Basement Door Sensor Alarm Level
|
|
||||||
# sensor.basement_door_sensor_alarm_type:
|
|
||||||
# friendly_name: Basement Door Sensor Alarm Type
|
|
||||||
# sensor.basement_door_sensor_burglar:
|
|
||||||
# friendly_name: Basement Door Sensor Burglar
|
|
||||||
# sensor.basement_door_sensor_power_management:
|
|
||||||
# friendly_name: Basement Door Sensor Power Management
|
|
||||||
# sensor.basement_door_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Basement Door Sensor SourceNodeId
|
|
||||||
# sensor.downstairs_multi_sensor_alarm_level:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Alarm Level
|
|
||||||
# sensor.downstairs_multi_sensor_alarm_type:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Alarm Type
|
|
||||||
# sensor.downstairs_multi_sensor_burglar:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Burglar
|
|
||||||
# sensor.downstairs_multi_sensor_luminance:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Luminance
|
|
||||||
# sensor.downstairs_multi_sensor_power:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Power
|
|
||||||
# sensor.downstairs_multi_sensor_relative_humidity:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Relative Humidity
|
|
||||||
# sensor.downstairs_multi_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Downstairs Multi Sensor SourceNodeId
|
|
||||||
# sensor.downstairs_multi_sensor_temperature:
|
|
||||||
# friendly_name: Downstairs Multi Sensor Temperature
|
|
||||||
# sensor.front_room_multi_sensor_alarm_level:
|
|
||||||
# friendly_name: Front Room Multi Sensor Alarm Level
|
|
||||||
# sensor.front_room_multi_sensor_alarm_type:
|
|
||||||
# friendly_name: Front Room Multi Sensor Alarm Type
|
|
||||||
# sensor.front_room_multi_sensor_burglar:
|
|
||||||
# friendly_name: Front Room Multi Sensor Burglar
|
|
||||||
# sensor.front_room_multi_sensor_luminance:
|
|
||||||
# friendly_name: Front Room Multi Sensor Luminance
|
|
||||||
# sensor.front_room_multi_sensor_relative_humidity:
|
|
||||||
# friendly_name: Front Room Multi Sensor Relative Humidity
|
|
||||||
# sensor.front_room_multi_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Front Room Multi Sensor SourceNodeId
|
|
||||||
# sensor.front_room_multi_sensor_temperature:
|
|
||||||
# friendly_name: Front Room Multi Sensor Temperature
|
|
||||||
# sensor.front_room_multi_sensor_ultraviolet:
|
|
||||||
# friendly_name: Front Room Multi Sensor Ultraviolet
|
|
||||||
# sensor.garage_door_sensor_access_control:
|
|
||||||
# friendly_name: Garage Door Sensor Access Control
|
|
||||||
# sensor.garage_door_sensor_alarm_level:
|
|
||||||
# friendly_name: Garage Door Sensor Alarm Level
|
|
||||||
# sensor.garage_door_sensor_alarm_type:
|
|
||||||
# friendly_name: Garage Door Sensor Alarm Type
|
|
||||||
# sensor.garage_door_sensor_burglar:
|
|
||||||
# friendly_name: Garage Door Sensor Burglar
|
|
||||||
# sensor.garage_door_sensor_power_management:
|
|
||||||
# friendly_name: Garage Door Sensor Power Management
|
|
||||||
# sensor.garage_door_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Garage Door Sensor SourceNodeId
|
|
||||||
# sensor.single_car_garage_door_sensor_status:
|
|
||||||
# friendly_name: Single Car Garage Door Sensor Status
|
|
||||||
# sensor.two_car_garage_door_sensor_status:
|
|
||||||
# friendly_name: Double Car Garage Door Sensor Status
|
|
||||||
# sensor.guest_bedroom_multi_sensor_alarm_level:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Alarm Level
|
|
||||||
# sensor.guest_bedroom_multi_sensor_alarm_type:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Alarm Type
|
|
||||||
# sensor.guest_bedroom_multi_sensor_burglar:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Burglar
|
|
||||||
# sensor.guest_bedroom_multi_sensor_luminance:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Luminance
|
|
||||||
# sensor.guest_bedroom_multi_sensor_relative_humidity:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Relative Humidity
|
|
||||||
# sensor.guest_bedroom_multi_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor SourceNodeId
|
|
||||||
# sensor.guest_bedroom_multi_sensor_temperature:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Temperature
|
|
||||||
# sensor.guest_bedroom_multi_sensor_ultraviolet:
|
|
||||||
# friendly_name: Guest Bedroom Multi Sensor Ultraviolet
|
|
||||||
# sensor.kitchen_motion_sensor_alarm_level:
|
|
||||||
# friendly_name: Kitchen Motion Sensor Alarm Level
|
|
||||||
# sensor.kitchen_motion_sensor_alarm_type:
|
|
||||||
# friendly_name: Kitchen Motion Sensor Alarm Type
|
|
||||||
# sensor.kitchen_motion_sensor_burglar:
|
|
||||||
# friendly_name: Kitchen Motion Sensor Burglar
|
|
||||||
# sensor.kitchen_motion_sensor_power_management:
|
|
||||||
# friendly_name: Kitchen Motion Sensor Power Management
|
|
||||||
# sensor.kitchen_motion_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Kitchen Motion Sensor SourceNodeId
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_access_control:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor Access Control
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_alarm_level:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor Alarm Level
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_alarm_type:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor Alarm Type
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_burglar:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor Burglar
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_power_management:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor Power Management
|
|
||||||
# sensor.single_car_garage_door_tilt_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Single Car Garage Door Tilt Sensor SourceNodeId
|
|
||||||
# sensor.stairs_motion_sensor_alarm_level:
|
|
||||||
# friendly_name: Stairs Motion Sensor Alarm Level
|
|
||||||
# sensor.stairs_motion_sensor_alarm_type:
|
|
||||||
# friendly_name: Stairs Motion Sensor Alarm Type
|
|
||||||
# sensor.stairs_motion_sensor_burglar:
|
|
||||||
# friendly_name: Stairs Motion Sensor Burglar
|
|
||||||
# sensor.stairs_motion_sensor_power_management:
|
|
||||||
# friendly_name: Stairs Motion Sensor Power Management
|
|
||||||
# sensor.stairs_motion_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Stairs Motion Sensor SourceNodeId
|
|
||||||
# sensor.tv_multi_sensor_alarm_level:
|
|
||||||
# friendly_name: TV Multi Sensor Alarm Level
|
|
||||||
# sensor.tv_multi_sensor_alarm_type:
|
|
||||||
# friendly_name: TV Multi Sensor Alarm Type
|
|
||||||
# sensor.tv_multi_sensor_burglar:
|
|
||||||
# friendly_name: TV Multi Sensor Burglar
|
|
||||||
# sensor.tv_multi_sensor_luminance:
|
|
||||||
# friendly_name: TV Multi Sensor Luminance
|
|
||||||
# sensor.tv_multi_sensor_relative_humidity:
|
|
||||||
# friendly_name: TV Multi Sensor Relative Humidity
|
|
||||||
# sensor.tv_multi_sensor_sourcenodeid:
|
|
||||||
# friendly_name: TV Multi Sensor SourceNodeId
|
|
||||||
# sensor.tv_multi_sensor_temperature:
|
|
||||||
# friendly_name: TV Multi Sensor Temperature
|
|
||||||
# sensor.tv_multi_sensor_ultraviolet:
|
|
||||||
# friendly_name: TV Multi Sensor Ultraviolet
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_access_control:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor Access Control
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_alarm_level:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor Alarm Level
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_alarm_type:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor Alarm Type
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_burglar:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor Burglar
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_power_management:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor Power Management
|
|
||||||
# sensor.two_car_garage_door_tilt_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Two Car Garage Door Tilt Sensor SourceNodeId
|
|
||||||
# sensor.upstairs_multi_sensor_alarm_level:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Alarm Level
|
|
||||||
# sensor.upstairs_multi_sensor_alarm_type:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Alarm Type
|
|
||||||
# sensor.upstairs_multi_sensor_burglar:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Burglar
|
|
||||||
# sensor.upstairs_multi_sensor_luminance:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Luminance
|
|
||||||
# sensor.upstairs_multi_sensor_relative_humidity:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Relative Humidity
|
|
||||||
# sensor.upstairs_multi_sensor_sourcenodeid:
|
|
||||||
# friendly_name: Upstairs Multi Sensor SourceNodeId
|
|
||||||
# sensor.upstairs_multi_sensor_temperature:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Temperature
|
|
||||||
# sensor.upstairs_multi_sensor_ultraviolet:
|
|
||||||
# friendly_name: Upstairs Multi Sensor Ultraviolet
|
|
||||||
# sensor.wallmote_alarm_level:
|
|
||||||
# friendly_name: Wallmote Alarm Level
|
|
||||||
# sensor.wallmote_alarm_type:
|
|
||||||
# friendly_name: Wallmote Alarm Type
|
|
||||||
# sensor.wallmote_power_management:
|
|
||||||
# friendly_name: Wallmote Power Management
|
|
||||||
# sensor.wallmote_sourcenodeid:
|
|
||||||
# friendly_name: Wallmote SourceNodeId
|
|
||||||
# sensor.zwave_smart_switch_current:
|
|
||||||
# friendly_name: ZWave Smart Switch Current
|
|
||||||
# sensor.zwave_smart_switch_energy:
|
|
||||||
# friendly_name: ZWave Smart Switch Energy
|
|
||||||
# sensor.zwave_smart_switch_power:
|
|
||||||
# friendly_name: ZWave Smart Switch Power
|
|
||||||
# sensor.zwave_smart_switch_previous_reading:
|
|
||||||
# friendly_name: ZWave Smart Switch Previous Reading
|
|
||||||
# sensor.zwave_smart_switch_voltage:
|
|
||||||
# friendly_name: ZWave Smart Switch Voltage
|
|
||||||
|
|
||||||
# # ZWave Switches
|
|
||||||
|
|
||||||
# switch.kitchen_siren_switch:
|
|
||||||
# friendly_name: Kitchen Siren Switch 1
|
|
||||||
# switch.kitchen_siren_switch_2:
|
|
||||||
# friendly_name: Kitchen Siren Switch 2
|
|
||||||
# switch.kitchen_siren_switch_3:
|
|
||||||
# friendly_name: Kitchen Siren Switch 3
|
|
||||||
# switch.kitchen_siren_switch_4:
|
|
||||||
# friendly_name: Kitchen Siren Switch 4
|
|
||||||
# switch.kitchen_siren_switch_5:
|
|
||||||
# friendly_name: Kitchen Siren Switch 5
|
|
||||||
# switch.wallmote_switch:
|
|
||||||
# friendly_name: Wallmote Switch
|
|
||||||
|
|
||||||
# zwave:
|
|
||||||
# usb_path: /dev/ttyACM0
|
|
||||||
# network_key: !secret zwave_network_key
|
|
||||||
|
|
||||||
# ###############################################################################
|
|
||||||
# # _ _ _
|
|
||||||
# # /\ | | | | (_)
|
|
||||||
# # / \ _ _| |_ ___ _ __ ___ __ _| |_ _ ___ _ __ ___
|
|
||||||
# # / /\ \| | | | __/ _ \| '_ ` _ \ / _` | __| |/ _ \| '_ \/ __|
|
|
||||||
# # / ____ \ |_| | || (_) | | | | | | (_| | |_| | (_) | | | \__ \
|
|
||||||
# # /_/ \_\__,_|\__\___/|_| |_| |_|\__,_|\__|_|\___/|_| |_|___/
|
|
||||||
# #
|
|
||||||
# ###############################################################################
|
|
||||||
# automation:
|
|
||||||
# - alias: WallMote Button 1 Pressed
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: zwave.scene_activated
|
|
||||||
# event_data:
|
|
||||||
# entity_id: zwave.wallmote
|
|
||||||
# scene_id: 1
|
|
||||||
# action:
|
|
||||||
# - service: light.toggle
|
|
||||||
# entity_id: light.master_bedroom_1
|
|
||||||
# - service: light.toggle
|
|
||||||
# entity_id: light.master_bedroom_2
|
|
||||||
|
|
||||||
# - alias: WallMote Button 2 Pressed
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: zwave.scene_activated
|
|
||||||
# event_data:
|
|
||||||
# entity_id: zwave.wallmote
|
|
||||||
# scene_id: 2
|
|
||||||
# action:
|
|
||||||
# - service: homeassistant.turn_off
|
|
||||||
# entity_id: group.upstairs_lights
|
|
||||||
|
|
||||||
# - alias: WallMote Button 3 Pressed
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: zwave.scene_activated
|
|
||||||
# event_data:
|
|
||||||
# entity_id: zwave.wallmote
|
|
||||||
# scene_id: 3
|
|
||||||
# action:
|
|
||||||
# - service: climate.set_away_mode
|
|
||||||
# data_template:
|
|
||||||
# entity_id: climate.dining_room
|
|
||||||
# away_mode: "false"
|
|
||||||
|
|
||||||
# - alias: WallMote Button 4 Pressed
|
|
||||||
# trigger:
|
|
||||||
# - platform: event
|
|
||||||
# event_type: zwave.scene_activated
|
|
||||||
# event_data:
|
|
||||||
# entity_id: zwave.wallmote
|
|
||||||
# scene_id: 4
|
|
||||||
# action:
|
|
||||||
# - service: climate.set_away_mode
|
|
||||||
# data_template:
|
|
||||||
# entity_id: climate.dining_room
|
|
||||||
# away_mode: "true"
|
|
298
readme.md
298
readme.md
|
@ -1,301 +1,3 @@
|
||||||
## skalavala's Home Automation/Smart Home
|
## skalavala's Home Automation/Smart Home
|
||||||
|
|
||||||
skalavala's Home Automation
|
skalavala's Home Automation
|
||||||
|
|
||||||
<!-- Here you will find a bunch of scripts that I use to automate my home.
|
|
||||||
|
|
||||||
I have a bunch of Raspberry Pi's, and Pi Zeros at home along with a bunch of "smart" devices of various brands. All these smart devices work great independently but not together. My goal is to bring all of them together and have them talk to each other with a little bit of programming and make them really smarter as a whole! I also want to be able to run all the software on Raspberry Pi's only.
|
|
||||||
|
|
||||||
The primary Home Automation software/platform that I use is [Home Assistant](https://home-assistant.io/) (HA). It is an open-source home automation platform written by a bunch of smart individuals. HA allows you to track and control devices easily with simple configuration and with a little bit of scripting, you can do wonders. It is also a perfect piece of software to run entirely on a single Raspberry Pi.
|
|
||||||
|
|
||||||
The following picture shows high level architecture of my home network, and what I use for basic automation stuff.
|
|
||||||
![My Home Automation Setup](https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/smart-home.jpg)
|
|
||||||
|
|
||||||
Please feel free to let me know if you find any issues with my code, and/or have any suggestions. Thank you!
|
|
||||||
|
|
||||||
## My Smart Devices
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The following are some of the smart devices that I use for my current Smart Home setup. Please feel free to reach out to me or check my repository on how to configure them.
|
|
||||||
</p>
|
|
||||||
<h2>Smart Lights & Switches</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pTWaNm"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/lifx-bulb.jpg" alt="Lifx Light Bulb" /></a><br/>
|
|
||||||
Lifx Light Bulb
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DI7i4P"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/lifx-led-strip.jpg" alt="Lifx LED Strip" /></a><br/>
|
|
||||||
Lifx LED Strip
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DLfuBi"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/philips-hue-bulbs.jpg" alt="Philips Hue Bulbs" /></a><br/>
|
|
||||||
Philips Hue Bulbs
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2mH7bi8"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/philips-hue-hub.jpg" alt="Philips Hue Hub & Bulbs" /></a><br/>
|
|
||||||
Philips Hue Hub & Bulbs
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2qeilPx"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/tplink-smart-switches.jpg" alt="TP-Link Smart Switches" /></a><br/>
|
|
||||||
TP-Link Smart Switches
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pairYc"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/wemo-light-switches.jpg" alt="Wemo Switches" /></a><br/>
|
|
||||||
Wemo Switches
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DK11G5"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/wall-mote.jpg" alt="ZWave Wallmotes" /></a><br/>
|
|
||||||
ZWave Wallmotes
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Smart Outlets</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2FKtegl"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/aeltec-smart-outlet.jpg" alt="Aeotec Smart Outlet" /></a><br/>
|
|
||||||
Aeotec Smart Outlet
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pTIDFA"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/eteccity-rf-outlets.jpg" alt="Eteckcity RF Outlets" /></a><br/>
|
|
||||||
Eteckcity RF Outlets
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2qe8PMo"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/rf-transeivers.jpg" alt="RF Transmitters & Receivers" /></a><br/>
|
|
||||||
RF Transmitters & Receivers
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Home Securty System</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pVmS6y"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/ring-doorbell-pro.jpg" alt="Ring Doorbell Pro" /></a><br/>
|
|
||||||
Ring Doorbell Pro
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pTIpyv"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/simplisafe-home-security.jpg" alt="SimpliSafe Home Security System" /></a><br/>
|
|
||||||
SimpliSafe Home Security System
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2uOJxSX"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/ubiquity-poe-switch.jpg" alt="Ubiquity 8-port PoE Switch" /></a><br/>
|
|
||||||
Ubiquity 8-port PoE Switch
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2suiPhT"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/hikvision-bullet-cameras.jpg" alt="HikVision Bullet IP Cameras" /></a><br/>
|
|
||||||
HikVision Bullet IP Cameras
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2papVuj"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/leeo-smoke-alert.jpg" alt="Leeo Smoke Alert" /></a><br/>
|
|
||||||
Leeo Smoke Alert
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Motion Sensors</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pV6SkH"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/in-wall-motion-sensors.jpg" alt="In Wall Motion Sensors" /></a><br/>
|
|
||||||
In Wall Motion Sensors
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DI5TeJ"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/ecolink-motion-sensors.jpg" alt="Ecolink Motion Sensor" /></a><br/>
|
|
||||||
Ecolink Motion Sensor
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DKO7aN"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/xiaomi-motion-sensor.jpg" alt="Xiaomi Motion Sensors" /></a><br/>
|
|
||||||
Xiaomi Motion Sensors
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>ZWave Devices</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pa9uhO"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/aeltec-zwave-stick.jpg" alt="Aeotec ZWave Gen5 Stick" /></a><br/>
|
|
||||||
Aeotec ZWave Gen5 Stick
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DKyxvU"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/aeotec-energy-meter.jpg" alt="Aeotec Energy Meter" /></a><br/>
|
|
||||||
Aeotec Energy Meter
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2qdYUqa"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/aeotec-multi-sensor.jpg" alt="Aeotec Multi Sensor 5" /></a><br/>
|
|
||||||
Aeotec Multi Sensor 5
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pV5yOT"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/aeotec-multi-sensor6.jpg" alt="Aeotec Multi Sensor 6" /></a><br/>
|
|
||||||
Aeotec Multi Sensor 6
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DKz7cK"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/range-extender.jpg" alt="Aeotec Range Extender" /></a><br/>
|
|
||||||
Aeotec Range Extender
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Door & Window Sensors</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DKYfjJ"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/door-sensors.jpg" alt="Ecolink Door Sensors" /></a><br/>
|
|
||||||
Ecolink Door Sensors
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DKzHHM"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/door-window-sensors.jpg" alt="Door & Window Sensors" /></a><br/>
|
|
||||||
Door & Window Sensors
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2FLRnTI"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/window-sensor.jpg" alt="Window Sensors" /></a><br/>
|
|
||||||
Window Sensors
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Multimedia Stuff</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pU2V1Y"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/bluetooth-speaker.jpg" alt="Bluetooth Speakers" /></a><br/>
|
|
||||||
Bluetooth Speakers
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2tVYN4b"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/denon-receiver.jpg" alt="DENON Receiver" /></a><br/>
|
|
||||||
DENON Receiver
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2tVYN4b"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/denon-receiver.jpg" alt="ONKYO Receiver" /></a><br/>
|
|
||||||
ONKYO Receiver
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Garage Door Devices</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DHQNWu"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/garage-tilt-sensor.jpg" alt="Garage Door Tilt Sensors" /></a><br/>
|
|
||||||
Garage Door Tilt Sensors
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pV2wu1"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/garage-relay.jpg" alt="ZWave Garage Relay" /></a><br/>
|
|
||||||
ZWave Garage Relay
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Servers and Computers</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DMx2gN"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/apcups-1500va.jpg" alt="UPS Battery" /></a><br/>
|
|
||||||
UPS Battery
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2DI8Coj"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/qnap-nas.jpg" alt="NAS Storage" /></a><br/>
|
|
||||||
NAS Storage
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2p9RVhQ"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/raspberry-pi3.jpg" alt="Raspberry PI 3" /></a><br/>
|
|
||||||
Raspberry PI 3
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Smart Thermostat</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2FQCsaX"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/ecobee4-thermostat.jpg" alt="Ecobee Thermostat" /></a><br/>
|
|
||||||
Ecobee Thermostat
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2uuPAgl"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/ecobee-room-sensors.jpg" alt="Ecobee Room Sensors" /></a><br/>
|
|
||||||
Ecobee Room Sensors
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2Dgt3rv"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/nest-thermostat.jpg" alt="Nest Thermostat" /></a><br/>
|
|
||||||
Nest Thermostat
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2FQDgN1"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/xiaomi-temp-sensor.jpg" alt="Xiaomi Temperature Sensor" /></a><br/>
|
|
||||||
Xiaomi Temperature Sensor
|
|
||||||
</TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>DIY Stuff</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pTQ1kv"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/relay.jpg" alt="Relays" /></a><br/>
|
|
||||||
Relays
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2pV60wx"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/esp8266.jpg" alt="NodeMUC/ESP8266" /></a><br/>
|
|
||||||
NodeMUC/ESP8266
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2qe8PMo"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/rf-transeivers.jpg" alt="RF Transmitters & Receivers" /></a><br/>
|
|
||||||
RF Transmitters & Receivers
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
<h2>Smart Hubs</h2>
|
|
||||||
<TABLE>
|
|
||||||
<TR>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2FQmFsz"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/xiaomi-gateway-kit.jpg" alt="Xiaomi Aqara Gateway" /></a><br/>
|
|
||||||
Xiaomi Aqara Gateway
|
|
||||||
</TD>
|
|
||||||
<TD>
|
|
||||||
<a href="http://amzn.to/2mH7bi8"><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/philips-hue-hub.jpg" alt="Philips Hue Hub" /></a><br/>
|
|
||||||
Philips Hue Hub
|
|
||||||
</TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
<TD><img src="https://raw.githubusercontent.com/skalavala/skalavala.github.io/master/images/blank.jpg"/><br/> </TD>
|
|
||||||
</TR>
|
|
||||||
</TABLE>
|
|
||||||
|
|
||||||
## Here is a sample view of my dashboard
|
|
||||||
|
|
||||||
<img src="https://github.com/skalavala/mysmarthome/blob/master/images/skalavala-smarthome-dashboard.jpg" alt="Home Assistat" />
|
|
||||||
|
|
||||||
## Custom Components:
|
|
||||||
|
|
||||||
### Custom Variables:
|
|
||||||
|
|
||||||
I called it `input_label`, it is basically a `label` type component, where you can store any value you want, and can be used in automations, scripts and more. [check out the code here](https://github.com/skalavala/mysmarthome/blob/master/custom_components/input_label.py). Search for [input_label](https://github.com/skalavala/mysmarthome/search?utf8=%E2%9C%93&q=input_label) in my repo on how to use it.
|
|
||||||
|
|
||||||
### Life360 Custom Component:
|
|
||||||
|
|
||||||
The Life360 component uses Life360 API and retrieves information about the circle you created in the same format as OwnTracks. You just ned to setup OwnTracks, and drop-in the custom component, and you are all set!
|
|
||||||
|
|
||||||
[Click Here](https://github.com/skalavala/mysmarthome/blob/master/custom_components/sensor/life360.py) for the Life360 custom component code. Make sure you check out the [Packages](https://github.com/skalavala/mysmarthome/blob/master/packages/life360.yaml) section on how to use the Life360 Component.
|
|
||||||
|
|
||||||
### Palo Alto Component:
|
|
||||||
|
|
||||||
I wrote a Palo Alto component to keep an eye on who is logging into my firewall and VPN at home. Below is the screenshot and you can find the code in the `custom_components` folder and corresponding `Packages` folder.
|
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/skalavala/mysmarthome/master/images/paloalto.png"/>
|
|
||||||
|
|
||||||
### Tesla
|
|
||||||
|
|
||||||
<img src="https://raw.githubusercontent.com/skalavala/mysmarthome/master/images/Tesla.png" /> -->
|
|
||||||
|
|
|
@ -103,10 +103,6 @@ google_maps_geocoding_api: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
#Ecobee Credentials
|
#Ecobee Credentials
|
||||||
ecobee_api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
ecobee_api_key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
|
||||||
# Life 360 Credentials
|
|
||||||
life360_username: xxxx.xxxx@xxxx.com
|
|
||||||
life360_password: xxxxxxxxxxxxxxxxxxxx
|
|
||||||
|
|
||||||
# Google Calendar
|
# Google Calendar
|
||||||
google_client_id: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
google_client_id: xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
|
||||||
google_client_secret: xxxxxxxxxxxxxxxxxxxxxxxx
|
google_client_secret: xxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro alarm_status() -%}
|
{%- macro alarm_status() -%}
|
||||||
Your home is {{ "SECURED!" if states('alarm_control_panel.home') == "armed_away" or states('alarm_control_panel.home') == "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!" -}}
|
||||||
|
. Your Home Away Status is set to {{ states('input_boolean.home_mode_away') |upper }}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
||||||
{%- macro single_car_garage_door_status() -%}
|
{%- macro single_car_garage_door_status() -%}
|
||||||
|
@ -79,9 +80,9 @@
|
||||||
|
|
||||||
{%- macro light_switch_status() -%}
|
{%- macro light_switch_status() -%}
|
||||||
{% for item in states if item.domain =="light" or item.domain == "switch" -%}
|
{% for item in states if item.domain =="light" or item.domain == "switch" -%}
|
||||||
{%- if item.state == "on" -%}
|
{%- if item.state == "on" and not item.entity_id.endswith('led') and not item.attributes.friendly_name.endswith('LED') -%}
|
||||||
{%- set friendly_name = item.attributes.friendly_name -%}
|
{%- set friendly_name = item.attributes.friendly_name -%}
|
||||||
{{ friendly_name }} {{ 'are' if plural(friendly_name) == "true" else 'is' }} ON.
|
{{ item.domain }} {{ friendly_name }} {{ 'are' if plural(friendly_name) == "true" else 'is' }} ON.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
{%- endmacro -%}
|
{%- endmacro -%}
|
||||||
|
|
|
@ -22,11 +22,11 @@
|
||||||
"switch.basement_right",
|
"switch.basement_right",
|
||||||
"switch.frontyard_light",
|
"switch.frontyard_light",
|
||||||
"switch.garage",
|
"switch.garage",
|
||||||
"switch.guest_bedroom",
|
"switch.srinika_bedroom",
|
||||||
"switch.prayer_room",
|
"switch.guest_room",
|
||||||
"switch.kids_bed_accent",
|
"switch.hasika_bed_accent",
|
||||||
"switch.kids_bedroom",
|
"switch.hasika_bedroom",
|
||||||
"switch.kitchen",
|
"switch.kitchen_switch",
|
||||||
"switch.office_room",
|
"switch.office_room",
|
||||||
"switch.backyard_light"] %}
|
"switch.backyard_light"] %}
|
||||||
{%- for item in lights_switches -%}
|
{%- for item in lights_switches -%}
|
||||||
|
|
|
@ -164,7 +164,7 @@
|
||||||
{# Drone Flying Weather #}
|
{# Drone Flying Weather #}
|
||||||
{%- macro drone_weather() -%}
|
{%- macro drone_weather() -%}
|
||||||
{% if states('binary_sensor.good_weather_to_fly_drones')| lower == "on" and
|
{% if states('binary_sensor.good_weather_to_fly_drones')| lower == "on" and
|
||||||
states('device_tracker.life360_suresh') == "home" and
|
states('device_tracker.suresh') == "home" and
|
||||||
states('sun.sun') == "above_horizon" %}
|
states('sun.sun') == "above_horizon" %}
|
||||||
It is now a great weather to fly drone outside.
|
It is now a great weather to fly drone outside.
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -1,27 +1,15 @@
|
||||||
# This code is auto-generated using my Jinja lovelace migration script
|
|
||||||
# visit: https://github.com/skalavala/mysmarthome/blob/master/jinja_helpers/jinja_lovelace.md
|
|
||||||
# Or visit https://sharethelove.io/tools/jinja-magic-scripts
|
|
||||||
#
|
|
||||||
# I use custom:button card, for two button, credits to https://github.com/kuuji/button-card
|
|
||||||
#
|
|
||||||
title: Kalavala's Home
|
title: Kalavala's Home
|
||||||
# resources:
|
|
||||||
# - url: /local/button-card.js
|
|
||||||
# type: module
|
|
||||||
|
|
||||||
views:
|
views:
|
||||||
- !include lovelace/00_myhome_view.yaml
|
- !include lovelace/00_myhome_view.yaml
|
||||||
- !include lovelace/15_3d_printer.yaml
|
|
||||||
- !include lovelace/01_lights_view.yaml
|
- !include lovelace/01_lights_view.yaml
|
||||||
- !include lovelace/02_climate_view.yaml
|
- !include lovelace/02_climate_view.yaml
|
||||||
- !include lovelace/03_camera_view.yaml
|
- !include lovelace/03_camera_view.yaml
|
||||||
- !include lovelace/04_trash_view.yaml
|
- !include lovelace/04_trash_view.yaml
|
||||||
- !include lovelace/05_tensorflow_view.yaml
|
- !include lovelace/05_tensorflow_view.yaml
|
||||||
- !include lovelace/06_tesla_view.yaml
|
|
||||||
- !include lovelace/07_system_view.yaml
|
- !include lovelace/07_system_view.yaml
|
||||||
- !include lovelace/08_multimedia_view.yaml
|
- !include lovelace/08_multimedia_view.yaml
|
||||||
- !include lovelace/09_settings_view.yaml
|
- !include lovelace/09_settings_view.yaml
|
||||||
- !include lovelace/10_raspberrypi_view.yaml
|
|
||||||
- !include lovelace/11_scripts_view.yaml
|
- !include lovelace/11_scripts_view.yaml
|
||||||
- !include lovelace/12_automations_view.yaml
|
- !include lovelace/12_automations_view.yaml
|
||||||
- !include lovelace/13_qnap_view.yaml
|
- !include lovelace/13_qnap_view.yaml
|
24
wb_client.py
24
wb_client.py
|
@ -1,24 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import socket
|
|
||||||
|
|
||||||
UDP_SERVER_HOST = "192.168.xxx.xxx"
|
|
||||||
UDP_SERVER_PORT = 7090
|
|
||||||
|
|
||||||
def print_usage():
|
|
||||||
print("This program requires arguments to be passed. Possible arguments are: ")
|
|
||||||
print("['i', 'failsafe', 'curr', 'report 1', 'ena 1']")
|
|
||||||
print("\nUsage: python " + sys.argv[0] + " i\n")
|
|
||||||
exit()
|
|
||||||
|
|
||||||
args = len(sys.argv)
|
|
||||||
if args == 1:
|
|
||||||
print_usage()
|
|
||||||
|
|
||||||
serverAddressPort = (UDP_SERVER_HOST, UDP_SERVER_PORT)
|
|
||||||
UDPClientSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
|
|
||||||
bytesSent = UDPClientSock.sendto(str.encode(sys.argv[1]), serverAddressPort)
|
|
||||||
|
|
||||||
print ("Successfully sent '{}' ({} bytes) to the server!".format(sys.argv[1], str(bytesSent)))
|
|
49
wb_server.py
49
wb_server.py
|
@ -1,49 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
import socket
|
|
||||||
import asyncore
|
|
||||||
import paho.mqtt.client as mqtt
|
|
||||||
import paho.mqtt.publish as publish
|
|
||||||
|
|
||||||
MQTT_SERVER_HOST = "192.168.xxx.xxx"
|
|
||||||
MQTT_SERVER_PORT = 1883
|
|
||||||
MQTT_USERNAME = "username"
|
|
||||||
MQTT_PASSWORD = "letmein"
|
|
||||||
MQTT_TOPIC = "/wallbox/data"
|
|
||||||
|
|
||||||
UDP_SERVER_PORT = 7090
|
|
||||||
DEFAULT_RECV_BYTES = 2048
|
|
||||||
|
|
||||||
client = mqtt.Client("udp-server")
|
|
||||||
#client.tls_set('/home/pi/certs/ca-certificates.crt')
|
|
||||||
client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
|
|
||||||
client.connect(MQTT_SERVER_HOST, MQTT_SERVER_PORT)
|
|
||||||
client.loop_start()
|
|
||||||
|
|
||||||
class AsyncoreServerUDP(asyncore.dispatcher):
|
|
||||||
def __init__(self):
|
|
||||||
asyncore.dispatcher.__init__(self)
|
|
||||||
|
|
||||||
# Bind to port 7090 on all interfaces
|
|
||||||
self.create_socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
self.bind(('', UDP_SERVER_PORT))
|
|
||||||
|
|
||||||
# Even though UDP is connectionless this is called when it binds to a port
|
|
||||||
def handle_connect(self):
|
|
||||||
print("Server Started...")
|
|
||||||
|
|
||||||
# This is called everytime there is something to read
|
|
||||||
def handle_read(self):
|
|
||||||
data, addr = self.recvfrom(DEFAULT_RECV_BYTES)
|
|
||||||
client.publish(MQTT_TOPIC, data, retain=False)
|
|
||||||
print(str(addr) + " >> " + data)
|
|
||||||
|
|
||||||
|
|
||||||
# This is called all the time and causes errors if you leave it out.
|
|
||||||
def handle_write(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
AsyncoreServerUDP()
|
|
||||||
asyncore.loop()
|
|
||||||
|
|
||||||
print("continue")
|
|
1615
zwcfg_0xd89c4f0c.xml
1615
zwcfg_0xd89c4f0c.xml
File diff suppressed because it is too large
Load Diff
|
@ -1,2 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<Scenes xmlns="http://code.google.com/p/open-zwave/" version="1" />
|
|
Loading…
Reference in New Issue