Skip to content

Commit

Permalink
Alexa stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
aneisch committed Dec 22, 2020
1 parent af6d560 commit 0cad6cd
Show file tree
Hide file tree
Showing 16 changed files with 193 additions and 56 deletions.
3 changes: 2 additions & 1 deletion README.md
Expand Up @@ -55,7 +55,7 @@ Also using Grafana/Influx for graphing, both running in Docker containers on NUC
Description | value
-- | --
Lines of ESPHome YAML | 1552
Lines of Home Assistant YAML | 4977
Lines of Home Assistant YAML | 5060
[Integrations](https://www.home-assistant.io/integrations/) in use | 25
Zigbee devices in [`zha`](https://www.home-assistant.io/integrations/zha/) | 13

Expand Down Expand Up @@ -121,6 +121,7 @@ Entities in the [`zwave`](https://www.home-assistant.io/components/zwave) domain
[custom-cards/favicon-counter](https://github.com/custom-cards/favicon-counter)<br>
[dmulcahey/zha-network-visualization-card](https://github.com/dmulcahey/zha-network-visualization-card)<br>
[gadgetchnnel/lovelace-card-templater](https://github.com/gadgetchnnel/lovelace-card-templater)<br>
[gadgetchnnel/lovelace-text-input-row](https://github.com/gadgetchnnel/lovelace-text-input-row)<br>
[kalkih/mini-media-player](https://github.com/kalkih/mini-media-player)<br>
[maykar/custom-header](https://github.com/maykar/custom-header)<br>
[nervetattoo/simple-thermostat](https://github.com/nervetattoo/simple-thermostat)<br>
Expand Down
5 changes: 5 additions & 0 deletions configuration.yaml
Expand Up @@ -9,6 +9,7 @@ homeassistant:
time_zone: America/Chicago
customize: !include customize.yaml
packages:
alexa: !include packages/alexa.yaml
aarlo: !include packages/aarlo.yaml
compost: !include packages/compost.yaml
#door_unlock: !include packages/door_unlock.yaml
Expand Down Expand Up @@ -192,6 +193,8 @@ input_select: !include input_select.yaml

intent_script: !include intent_script.yaml

input_text: !include input_text.yaml

ios:
push:
categories:
Expand Down Expand Up @@ -293,6 +296,8 @@ lovelace:
type: module
- url: /hacsfiles/ozw-network-visualization-card/ozw-network-visualization-card.js
type: module
- url: /hacsfiles/lovelace-text-input-row/lovelace-text-input-row.js
type: module


map:
Expand Down
65 changes: 22 additions & 43 deletions custom_components/garbage_collection/calendar.py
@@ -1,7 +1,7 @@
"""Garbage collection calendar."""

import logging
from datetime import datetime, timedelta
from datetime import date, datetime, timedelta

from homeassistant.components.calendar import CalendarEventDevice
from homeassistant.util import Throttle
Expand Down Expand Up @@ -44,7 +44,7 @@ def name(self):

async def async_update(self):
"""Update all calendars."""
self.hass.data[DOMAIN][CALENDAR_PLATFORM].update()
await self.hass.data[DOMAIN][CALENDAR_PLATFORM].async_update()

async def async_get_events(self, hass, start_date, end_date):
"""Get all events in a specific time frame."""
Expand All @@ -58,7 +58,6 @@ def device_state_attributes(self):
if self.hass.data[DOMAIN][CALENDAR_PLATFORM].event is None:
# No tasks, we don't need to show anything.
return None

return {}


Expand Down Expand Up @@ -96,7 +95,7 @@ async def async_get_events(self, hass, start_datetime, end_datetime):
continue
garbage_collection = hass.data[DOMAIN][SENSOR_PLATFORM][entity]
await garbage_collection.async_load_holidays(start_date)
start = await garbage_collection.async_find_next_date(start_date)
start = await garbage_collection.async_find_next_date(start_date, True)
while start is not None and start >= start_date and start <= end_date:
try:
end = start + timedelta(days=1)
Expand All @@ -114,61 +113,41 @@ async def async_get_events(self, hass, start_datetime, end_datetime):
event = {
"uid": entity,
"summary": garbage_collection.name,
"start": {"date": start.strftime("%Y-%m-%d")},
"end": {"date": end.strftime("%Y-%m-%d")},
"allDay": True,
# "start": {"date": start.strftime("%Y-%m-%d %H:%M")},
# "end": {
# "date": datetime.combine(
# start, garbage_collection.expire_after
# ).strftime("%Y-%m-%d %H:%M")
# },
# "allDay": False,
"start": {"date": start.strftime("%Y-%m-%d %H:%M")},
"end": {
"date": datetime.combine(
start, garbage_collection.expire_after
).strftime("%Y-%m-%d %H:%M")
},
"allDay": False,
}
events.append(event)
start = await garbage_collection.async_find_next_date(
start + timedelta(days=1)
start + timedelta(days=1), True
)
return events

@Throttle(MIN_TIME_BETWEEN_UPDATES)
def update(self):
async def async_update(self):
"""Get the latest data."""
events = []
today = date.today()
for entity in self.entities:
state_object = self._hass.states.get(entity)
garbage_collection = self._hass.data[DOMAIN][SENSOR_PLATFORM][entity]
if state_object is None:
continue
start = state_object.attributes.get("next_date")
await garbage_collection.async_load_holidays(today)
start = await garbage_collection.async_find_next_date(today, True)
try:
end = start + timedelta(days=1)
except TypeError:
continue
if start is not None:
if garbage_collection.expire_after is None:
event = {
"uid": entity,
"summary": state_object.attributes.get("friendly_name"),
"start": {"date": start.strftime("%Y-%m-%d")},
"end": {"date": end.strftime("%Y-%m-%d")},
"allDay": True,
}
else:
event = {
"uid": entity,
"summary": state_object.attributes.get("friendly_name"),
"start": {"date": start.strftime("%Y-%m-%d")},
"end": {"date": end.strftime("%Y-%m-%d")},
"allDay": True,
# "start": {"date": start.strftime("%Y-%m-%d %H:%M")},
# "end": {
# "date": datetime.combine(
# start, garbage_collection.expire_after
# ).strftime("%Y-%m-%d %H:%M")
# },
# "allDay": False,
}
event = {
"uid": entity,
"summary": garbage_collection.name,
"start": {"date": start.strftime("%Y-%m-%d")},
"end": {"date": end.strftime("%Y-%m-%d")},
"allDay": True,
}
events.append(event)
events.sort(key=lambda x: x["start"]["date"])
if len(events) > 0:
Expand Down
18 changes: 12 additions & 6 deletions custom_components/garbage_collection/sensor.py
Expand Up @@ -498,7 +498,9 @@ async def _async_candidate_date_with_holidays(self, day1: date) -> date:
first_day -= relativedelta(days=look_back)
while True:
try:
next_date = await self._async_find_candidate_date(first_day)
next_date = await self._async_find_candidate_date(
first_day
) + relativedelta(days=self._offset)
except ValueError:
raise
if bool(self._holiday_in_week_move):
Expand Down Expand Up @@ -543,7 +545,9 @@ def _skip_holiday(self, day: date) -> date:
)
return day + relativedelta(days=skip_days)

async def _async_candidate_with_incl_excl(self, day1: date) -> date:
async def _async_candidate_with_incl_excl(
self, day1: date, ignore_today=False
) -> date:
"""Find the next date starting from day1."""
first_day = day1 - relativedelta(days=self._offset)
i = 0
Expand All @@ -561,7 +565,7 @@ async def _async_candidate_with_incl_excl(self, day1: date) -> date:
expiration = (
self.expire_after if self.expire_after is not None else time(23, 59, 59)
)
if next_date == now.date():
if next_date == now.date() and not ignore_today:
if (
self.last_collection is not None
and self.last_collection.date() == next_date
Expand All @@ -576,7 +580,7 @@ async def _async_candidate_with_incl_excl(self, day1: date) -> date:
_LOGGER.debug("(%s) Skipping exclude_date %s", self._name, next_date)
date_ok = False
if date_ok:
return next_date + relativedelta(days=self._offset)
return next_date
first_day = next_date + relativedelta(days=1)
i += 1
if i > 365:
Expand Down Expand Up @@ -620,13 +624,15 @@ async def _async_ready_for_update(self) -> bool:
pass
return ready_for_update

async def async_find_next_date(self, today: date) -> date:
async def async_find_next_date(self, today: date, ignore_today=False) -> date:
"""Get date within configured date range."""
year = today.year
month = today.month
if self.date_inside(today):
try:
next_date = await self._async_candidate_with_incl_excl(today)
next_date = await self._async_candidate_with_incl_excl(
today, ignore_today
)
except ValueError:
raise
_LOGGER.debug("(%s) Next date candidate (%s)", self._name, next_date)
Expand Down
3 changes: 1 addition & 2 deletions custom_components/samsungtv_tizen/media_player.py
@@ -1,7 +1,6 @@
"""Support for interface with an Samsung TV."""
import asyncio
from datetime import timedelta, datetime
from dateutil.parser import parse as parsedate
import logging
import socket
import json
Expand Down Expand Up @@ -624,7 +623,7 @@ def _ensure_latest_path_file(self):
if file_date < (datetime.now().astimezone()-timedelta(days=MEDIA_FILE_DAYS_BEFORE_UPDATE)):
try:
response = requests.head(MEDIA_IMAGE_BASE_URL + "logo_paths.json")
url_date = parsedate(response.headers.get("Last-Modified")).astimezone()
url_date = datetime.strptime(response.headers.get("Last-Modified"),'%a, %d %b %Y %X %Z').astimezone()
if url_date > file_date:
self._download_latest_path_file()
except:
Expand Down
4 changes: 2 additions & 2 deletions extras/appdaemon/apps/apps.yaml
Expand Up @@ -129,8 +129,8 @@ Occupancy Simulator:

# Ensure all off late
step_off_name: Off
step_off_start: '00:15:00'
step_off_stop: '00:30:00'
step_off_start: '11:30:00'
step_off_stop: '11:59:00'
step_off_off_1: light.master_bedroom_lamps
step_off_off_2: light.dining_room_light
step_off_off_3: light.kitchen_table_light
Expand Down
2 changes: 1 addition & 1 deletion extras/docker-compose/homeassistant/docker-compose.yml
Expand Up @@ -18,7 +18,7 @@ services:
environment:
- TZ=America/Chicago
healthcheck:
test: "curl -m 10 -sLf http://localhost:8123 || pkill -9 python3"
test: "curl -m 30 -sLf http://localhost:8123 || pkill -9 python3"
interval: 60s
timeout: 15s
retries: 2
Expand Down
2 changes: 1 addition & 1 deletion extras/docker-compose/unified/docker-compose.yml
Expand Up @@ -19,7 +19,7 @@ services:
environment:
- TZ=America/Chicago
healthcheck:
test: "curl -m 10 -sLf http://localhost:8123 || pkill -9 python3"
test: "curl -m 30 -sLf http://localhost:8123 || pkill -9 python3"
interval: 60s
timeout: 15s
retries: 2
Expand Down
Empty file added input_text.yaml
Empty file.
56 changes: 56 additions & 0 deletions packages/alexa.yaml
@@ -0,0 +1,56 @@
input_select:
target_echo:
name: Echo
icon: mdi:microphone
options:
- "Master"
- "Office"
- "Bethany Office"
- "Kitchen"
- "Living Room"

input_text:
alexa_cmd_text:
initial: ' '
max: 255
alexa_announcement_text:
initial: ' '
max: 255

group:
echos:
name: Echos
entities:
- media_player.master
- media_player.office
- media_player.bethany_office
- media_player.kitchen
- media_player.living_room

script:
send_alexa_command:
sequence:
- service: media_player.play_media
data:
entity_id: '{{ "media_player." + states("input_select.target_echo") }}'
media_content_id: '{{ states("input_text.alexa_cmd_text") }}'
media_content_type: custom

sensor:
- platform: template
sensors:
last_echo:
value_template: >
{{ expand(states.group.echos) | selectattr('attributes.last_called','eq',True) | map(attribute='entity_id') | first }}
automation:
- alias: "Change Alexa Input Select"
initial_state: on
trigger:
- platform: state
entity_id: sensor.last_echo
action:
- service: input_select.select_option
data:
entity_id: input_select.target_echo
option: '{{ states("sensor.last_echo") }}'
2 changes: 2 additions & 0 deletions sensors.yaml
@@ -1,5 +1,7 @@
- platform: moon

- platform: uptime

#- platform: arlo

#- platform: aarlo
Expand Down
25 changes: 25 additions & 0 deletions ui-lovelace/.cards/alexa.yaml
@@ -0,0 +1,25 @@
type: entities
entities:
- entity: input_select.target_echo
name: Select Alexa device
- entity: input_text.alexa_cmd_text
name: 'Type question/command here:'
type: 'custom:text-input-row'
- action_name: Run Command/Ask Question...
icon: 'mdi:voice'
name: ' '
service: script.send_alexa_command
type: call-service
- action_name: Stop Alexa
icon: 'mdi:voice'
name: ' '
service: script.stop_alexa_command
type: call-service
- entity: input_text.alexa_announcement_text
name: 'Type announcement text here:'
type: 'custom:text-input-row'
- type: call-service
name: ' '
icon: 'mdi:voice'
action_name: Announce It...
service: script.send_alexa_annoucement
1 change: 1 addition & 0 deletions ui-lovelace/01-home.yaml
Expand Up @@ -119,6 +119,7 @@ cards:
value: 20

- !include .cards/spotify.yaml
- !include .cards/alexa.yaml

- type: custom:vertical-stack-in-card
cards:
Expand Down
1 change: 1 addition & 0 deletions ui-lovelace/05-server.yaml
Expand Up @@ -158,6 +158,7 @@ cards:
title: Home Assistant
show_header_toggle: false
entities:
- sensor.uptime
- sensor.ha_version
- sensor.ha_github_version
- sensor.ha_docker_version_stable
Expand Down

0 comments on commit 0cad6cd

Please sign in to comment.