Compare commits

...

16 Commits

Author SHA1 Message Date
Pascal Vizeli
2d7208470e Merge pull request #28354 from home-assistant/rc
0.101.0
2019-10-30 21:20:32 +01:00
Pascal Vizeli
7eceedea10 Bump version 0.101.0 2019-10-30 19:50:48 +00:00
springstan
8aee92347f Fix KeyError in decora setup (#28279)
* Imported homeassistant.util and slugified address if no name is specified

* Added a custom validator function in case name is not set in config

* Removed logger.debug line only used for testing
2019-10-30 19:47:14 +00:00
Paulus Schoutsen
cf6d11db8d Bumped version to 0.101.0b4 2019-10-29 16:17:34 -07:00
Bram Kragten
c104efc18d Updated frontend to 20191025.1 (#28327) 2019-10-29 16:16:41 -07:00
Pascal Vizeli
f021e5832a Cleanup not needed websocket flags for ingress (#28295) 2019-10-29 16:16:10 -07:00
Paulus Schoutsen
070790ccc9 Bumped version to 0.101.0b3 2019-10-28 11:28:45 -07:00
jjlawren
0e2b55e60e Bump library to 0.0.3 (#28294) 2019-10-28 11:28:40 -07:00
Erik Montnemery
4a25bab1b3 Fix broken deconz trigger (#28211) 2019-10-28 11:28:39 -07:00
Erik Montnemery
3cedee3fea Add above and below to sensor condition extra_fields (#27364)
* Add above and below to sensor condition extra_fields

* Change unit_of_measurement to suffix in extra_fields

* Check if sensor has unit when getting capabilities

* Improve tests
2019-10-28 11:28:39 -07:00
michaeldavie
82ed84ba43 Bump env_canada to 0.0.27 (#28239) 2019-10-26 22:27:21 +02:00
Paulus Schoutsen
c456b725fd Bumped version to 0.101.0b2 2019-10-25 10:49:42 -07:00
Bram Kragten
524f5a7264 Updated frontend to 20191025.0 (#28208) 2019-10-25 10:49:36 -07:00
gngj
637a16799f Fix microsoft tts (#28199)
* Update pycsspeechtts

From 1.0.2 to 1.0.3 as the old one is using an api that doesn't work

* Give a option to choose region

Api is now region dependent, so gave it a config
2019-10-25 10:49:35 -07:00
SukramJ
4df6b3c76a Partially revert tensorflow import move (#28184)
* Revert "Refactor imports for tensorflow (#27617)"

This reverts commit 5a83a92390.

* move only some imports to top

* fix lint

* add comments
2019-10-25 10:49:35 -07:00
jjlawren
05ee15c28c Update Plex via websockets (#28158)
* Save client identifier from auth for future use

* Use websocket events to update Plex

* Handle websocket disconnections

* Use aiohttp, shut down socket cleanly

* Bad rebase fix

* Don't connect websocket during config_flow validation, fix tests

* Move websocket handling to external library

* Close websocket session on HA stop

* Use external library, revert unnecessary test change

* Async & lint fixes

* Clean up websocket stopper on entry unload

* Setup websocket in component, pass actual needed object to library
2019-10-25 10:49:34 -07:00
22 changed files with 279 additions and 51 deletions

View File

@@ -514,6 +514,7 @@ omit =
homeassistant/components/plex/media_player.py
homeassistant/components/plex/sensor.py
homeassistant/components/plex/server.py
homeassistant/components/plex/websockets.py
homeassistant/components/plugwise/*
homeassistant/components/plum_lightpad/*
homeassistant/components/pocketcasts/sensor.py

View File

@@ -235,6 +235,7 @@ async def async_attach_trigger(hass, config, action, automation_info):
event_id = deconz_event.serial
event_config = {
event.CONF_PLATFORM: "event",
event.CONF_EVENT_TYPE: CONF_DECONZ_EVENT,
event.CONF_EVENT_DATA: {CONF_UNIQUE_ID: event_id, CONF_EVENT: trigger},
}

View File

@@ -1,4 +1,5 @@
"""Support for Decora dimmers."""
import copy
from functools import wraps
import logging
import time
@@ -15,17 +16,34 @@ from homeassistant.components.light import (
)
from homeassistant.const import CONF_API_KEY, CONF_DEVICES, CONF_NAME
import homeassistant.helpers.config_validation as cv
import homeassistant.util as util
_LOGGER = logging.getLogger(__name__)
SUPPORT_DECORA_LED = SUPPORT_BRIGHTNESS
def _name_validator(config):
"""Validate the name."""
config = copy.deepcopy(config)
for address, device_config in config[CONF_DEVICES].items():
if CONF_NAME not in device_config:
device_config[CONF_NAME] = util.slugify(address)
return config
DEVICE_SCHEMA = vol.Schema(
{vol.Optional(CONF_NAME): cv.string, vol.Required(CONF_API_KEY): cv.string}
)
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{vol.Optional(CONF_DEVICES, default={}): {cv.string: DEVICE_SCHEMA}}
PLATFORM_SCHEMA = vol.Schema(
vol.All(
PLATFORM_SCHEMA.extend(
{vol.Optional(CONF_DEVICES, default={}): {cv.string: DEVICE_SCHEMA}}
),
_name_validator,
)
)

View File

@@ -156,7 +156,11 @@ async def _async_get_device_automation_capabilities(hass, automation_type, autom
# The device automation has no capabilities
return {}
capabilities = await getattr(platform, function_name)(hass, automation)
try:
capabilities = await getattr(platform, function_name)(hass, automation)
except InvalidDeviceAutomationConfig:
return {}
capabilities = capabilities.copy()
extra_fields = capabilities.get("extra_fields")

View File

@@ -3,7 +3,7 @@
"name": "Environment Canada",
"documentation": "https://www.home-assistant.io/integrations/environment_canada",
"requirements": [
"env_canada==0.0.25"
"env_canada==0.0.27"
],
"dependencies": [],
"codeowners": [

View File

@@ -3,7 +3,7 @@
"name": "Home Assistant Frontend",
"documentation": "https://www.home-assistant.io/integrations/frontend",
"requirements": [
"home-assistant-frontend==20191023.0"
"home-assistant-frontend==20191025.1"
],
"dependencies": [
"api",

View File

@@ -167,7 +167,14 @@ def _init_header(
# filter flags
for name, value in request.headers.items():
if name in (hdrs.CONTENT_LENGTH, hdrs.CONTENT_ENCODING):
if name in (
hdrs.CONTENT_LENGTH,
hdrs.CONTENT_ENCODING,
hdrs.SEC_WEBSOCKET_EXTENSIONS,
hdrs.SEC_WEBSOCKET_PROTOCOL,
hdrs.SEC_WEBSOCKET_VERSION,
hdrs.SEC_WEBSOCKET_KEY,
):
continue
headers[name] = value

View File

@@ -3,7 +3,7 @@
"name": "Microsoft",
"documentation": "https://www.home-assistant.io/integrations/microsoft",
"requirements": [
"pycsspeechtts==1.0.2"
"pycsspeechtts==1.0.3"
],
"dependencies": [],
"codeowners": []

View File

@@ -14,6 +14,7 @@ CONF_RATE = "rate"
CONF_VOLUME = "volume"
CONF_PITCH = "pitch"
CONF_CONTOUR = "contour"
CONF_REGION = "region"
_LOGGER = logging.getLogger(__name__)
@@ -72,6 +73,7 @@ DEFAULT_RATE = 0
DEFAULT_VOLUME = 0
DEFAULT_PITCH = "default"
DEFAULT_CONTOUR = ""
DEFAULT_REGION = "eastus"
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
@@ -87,6 +89,7 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
),
vol.Optional(CONF_PITCH, default=DEFAULT_PITCH): cv.string,
vol.Optional(CONF_CONTOUR, default=DEFAULT_CONTOUR): cv.string,
vol.Optional(CONF_REGION, default=DEFAULT_REGION): cv.string,
}
)
@@ -102,13 +105,16 @@ def get_engine(hass, config):
config[CONF_VOLUME],
config[CONF_PITCH],
config[CONF_CONTOUR],
config[CONF_REGION],
)
class MicrosoftProvider(Provider):
"""The Microsoft speech API provider."""
def __init__(self, apikey, lang, gender, ttype, rate, volume, pitch, contour):
def __init__(
self, apikey, lang, gender, ttype, rate, volume, pitch, contour, region
):
"""Init Microsoft TTS service."""
self._apikey = apikey
self._lang = lang
@@ -119,6 +125,7 @@ class MicrosoftProvider(Provider):
self._volume = f"{volume}%"
self._pitch = pitch
self._contour = contour
self._region = region
self.name = "Microsoft"
@property
@@ -138,7 +145,7 @@ class MicrosoftProvider(Provider):
from pycsspeechtts import pycsspeechtts
try:
trans = pycsspeechtts.TTSTranslator(self._apikey)
trans = pycsspeechtts.TTSTranslator(self._apikey, self._region)
data = trans.speak(
language=language,
gender=self._gender,

View File

@@ -1,9 +1,9 @@
"""Support to embed Plex."""
import asyncio
from datetime import timedelta
import logging
import plexapi.exceptions
from plexwebsocket import PlexWebsocket
import requests.exceptions
import voluptuous as vol
@@ -16,9 +16,14 @@ from homeassistant.const import (
CONF_TOKEN,
CONF_URL,
CONF_VERIFY_SSL,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.helpers.event import async_track_time_interval
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.dispatcher import (
async_dispatcher_connect,
async_dispatcher_send,
)
from .const import (
CONF_USE_EPISODE_ART,
@@ -33,8 +38,9 @@ from .const import (
PLATFORMS,
PLEX_MEDIA_PLAYER_OPTIONS,
PLEX_SERVER_CONFIG,
REFRESH_LISTENERS,
PLEX_UPDATE_PLATFORMS_SIGNAL,
SERVERS,
WEBSOCKETS,
)
from .server import PlexServer
@@ -67,9 +73,7 @@ _LOGGER = logging.getLogger(__package__)
def setup(hass, config):
"""Set up the Plex component."""
hass.data.setdefault(
PLEX_DOMAIN, {SERVERS: {}, REFRESH_LISTENERS: {}, DISPATCHERS: {}}
)
hass.data.setdefault(PLEX_DOMAIN, {SERVERS: {}, DISPATCHERS: {}, WEBSOCKETS: {}})
plex_config = config.get(PLEX_DOMAIN, {})
if plex_config:
@@ -136,7 +140,6 @@ async def async_setup_entry(hass, entry):
)
server_id = plex_server.machine_identifier
hass.data[PLEX_DOMAIN][SERVERS][server_id] = plex_server
hass.data[PLEX_DOMAIN][DISPATCHERS][server_id] = []
for platform in PLATFORMS:
hass.async_create_task(
@@ -145,9 +148,29 @@ async def async_setup_entry(hass, entry):
entry.add_update_listener(async_options_updated)
hass.data[PLEX_DOMAIN][REFRESH_LISTENERS][server_id] = async_track_time_interval(
hass, lambda now: plex_server.update_platforms(), timedelta(seconds=10)
unsub = async_dispatcher_connect(
hass,
PLEX_UPDATE_PLATFORMS_SIGNAL.format(server_id),
plex_server.update_platforms,
)
hass.data[PLEX_DOMAIN][DISPATCHERS].setdefault(server_id, [])
hass.data[PLEX_DOMAIN][DISPATCHERS][server_id].append(unsub)
def update_plex():
async_dispatcher_send(hass, PLEX_UPDATE_PLATFORMS_SIGNAL.format(server_id))
session = async_get_clientsession(hass)
websocket = PlexWebsocket(plex_server.plex_server, update_plex, session)
hass.loop.create_task(websocket.listen())
hass.data[PLEX_DOMAIN][WEBSOCKETS][server_id] = websocket
def close_websocket_session(_):
websocket.close()
unsub = hass.bus.async_listen_once(
EVENT_HOMEASSISTANT_STOP, close_websocket_session
)
hass.data[PLEX_DOMAIN][DISPATCHERS][server_id].append(unsub)
return True
@@ -156,8 +179,8 @@ async def async_unload_entry(hass, entry):
"""Unload a config entry."""
server_id = entry.data[CONF_SERVER_IDENTIFIER]
cancel = hass.data[PLEX_DOMAIN][REFRESH_LISTENERS].pop(server_id)
cancel()
websocket = hass.data[PLEX_DOMAIN][WEBSOCKETS].pop(server_id)
websocket.close()
dispatchers = hass.data[PLEX_DOMAIN][DISPATCHERS].pop(server_id)
for unsub in dispatchers:

View File

@@ -10,8 +10,8 @@ DEFAULT_VERIFY_SSL = True
DISPATCHERS = "dispatchers"
PLATFORMS = ["media_player", "sensor"]
REFRESH_LISTENERS = "refresh_listeners"
SERVERS = "servers"
WEBSOCKETS = "websockets"
PLEX_CONFIG_FILE = "plex.conf"
PLEX_MEDIA_PLAYER_OPTIONS = "plex_mp_options"
@@ -19,6 +19,7 @@ PLEX_SERVER_CONFIG = "server_config"
PLEX_NEW_MP_SIGNAL = "plex_new_mp_signal.{}"
PLEX_UPDATE_MEDIA_PLAYER_SIGNAL = "plex_update_mp_signal.{}"
PLEX_UPDATE_PLATFORMS_SIGNAL = "plex_update_platforms_signal.{}"
PLEX_UPDATE_SENSOR_SIGNAL = "plex_update_sensor_signal.{}"
CONF_CLIENT_IDENTIFIER = "client_id"

View File

@@ -5,7 +5,8 @@
"documentation": "https://www.home-assistant.io/integrations/plex",
"requirements": [
"plexapi==3.0.6",
"plexauth==0.0.5"
"plexauth==0.0.5",
"plexwebsocket==0.0.3"
],
"dependencies": [
"http"

View File

@@ -103,6 +103,8 @@ class PlexServer:
def update_platforms(self):
"""Update the platform entities."""
_LOGGER.debug("Updating devices")
available_clients = {}
new_clients = set()
@@ -164,6 +166,11 @@ class PlexServer:
sessions,
)
@property
def plex_server(self):
"""Return the plexapi PlexServer instance."""
return self._plex_server
@property
def friendly_name(self):
"""Return name of connected Plex server."""

View File

@@ -2,6 +2,9 @@
from typing import Dict, List
import voluptuous as vol
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
)
from homeassistant.core import HomeAssistant
from homeassistant.const import (
ATTR_DEVICE_CLASS,
@@ -141,3 +144,27 @@ def async_condition_from_config(
numeric_state_config[condition.CONF_BELOW] = config[CONF_BELOW]
return condition.async_numeric_state_from_config(numeric_state_config)
async def async_get_condition_capabilities(hass, config):
"""List condition capabilities."""
state = hass.states.get(config[CONF_ENTITY_ID])
unit_of_measurement = (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) if state else None
)
if not state or not unit_of_measurement:
raise InvalidDeviceAutomationConfig
return {
"extra_fields": vol.Schema(
{
vol.Optional(
CONF_ABOVE, description={"suffix": unit_of_measurement}
): vol.Coerce(float),
vol.Optional(
CONF_BELOW, description={"suffix": unit_of_measurement}
): vol.Coerce(float),
}
)
}

View File

@@ -3,6 +3,9 @@ import voluptuous as vol
import homeassistant.components.automation.numeric_state as numeric_state_automation
from homeassistant.components.device_automation import TRIGGER_BASE_SCHEMA
from homeassistant.components.device_automation.exceptions import (
InvalidDeviceAutomationConfig,
)
from homeassistant.const import (
ATTR_DEVICE_CLASS,
ATTR_UNIT_OF_MEASUREMENT,
@@ -146,9 +149,12 @@ async def async_get_trigger_capabilities(hass, config):
"""List trigger capabilities."""
state = hass.states.get(config[CONF_ENTITY_ID])
unit_of_measurement = (
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) if state else ""
state.attributes.get(ATTR_UNIT_OF_MEASUREMENT) if state else None
)
if not state or not unit_of_measurement:
raise InvalidDeviceAutomationConfig
return {
"extra_fields": vol.Schema(
{

View File

@@ -1,23 +1,12 @@
"""Support for performing TensorFlow classification on images."""
import io
import logging
import os
import sys
import io
import voluptuous as vol
from PIL import Image, ImageDraw
import numpy as np
try:
import cv2
except ImportError:
cv2 = None
try:
# Verify that the TensorFlow Object Detection API is pre-installed
import tensorflow as tf # noqa
from object_detection.utils import label_map_util # noqa
except ImportError:
label_map_util = None
import voluptuous as vol
from homeassistant.components.image_processing import (
CONF_CONFIDENCE,
@@ -98,8 +87,16 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
# append custom model path to sys.path
sys.path.append(model_dir)
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2"
if label_map_util is None:
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"
# These imports shouldn't be moved to the top, because they depend on code from the model_dir.
# (The model_dir is created during the manual setup process. See integration docs.)
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: "
@@ -107,7 +104,11 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
) # noqa
return
if cv2 is None:
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"
@@ -282,7 +283,13 @@ class TensorFlowImageProcessor(ImageProcessingEntity):
def process_image(self, image):
"""Process the image."""
if cv2 is None:
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:
img = Image.open(io.BytesIO(bytearray(image))).convert("RGB")
img.thumbnail((460, 460), Image.ANTIALIAS)
img_width, img_height = img.size
@@ -292,10 +299,6 @@ class TensorFlowImageProcessor(ImageProcessingEntity):
.astype(np.uint8)
)
inp_expanded = np.expand_dims(inp, axis=0)
else:
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)
image_tensor = self._graph.get_tensor_by_name("image_tensor:0")
boxes = self._graph.get_tensor_by_name("detection_boxes:0")

View File

@@ -1,7 +1,7 @@
"""Constants used by Home Assistant components."""
MAJOR_VERSION = 0
MINOR_VERSION = 101
PATCH_VERSION = "0b1"
PATCH_VERSION = "0"
__short_version__ = "{}.{}".format(MAJOR_VERSION, MINOR_VERSION)
__version__ = "{}.{}".format(__short_version__, PATCH_VERSION)
REQUIRED_PYTHON_VER = (3, 6, 1)

View File

@@ -11,7 +11,7 @@ contextvars==2.4;python_version<"3.7"
cryptography==2.8
distro==1.4.0
hass-nabucasa==0.22
home-assistant-frontend==20191023.0
home-assistant-frontend==20191025.1
importlib-metadata==0.23
jinja2>=2.10.1
netdisco==2.6.0

View File

@@ -456,7 +456,7 @@ enocean==0.50
enturclient==0.2.0
# homeassistant.components.environment_canada
env_canada==0.0.25
env_canada==0.0.27
# homeassistant.components.envirophat
# envirophat==0.0.6
@@ -646,7 +646,7 @@ hole==0.5.0
holidays==0.9.11
# homeassistant.components.frontend
home-assistant-frontend==20191023.0
home-assistant-frontend==20191025.1
# homeassistant.components.zwave
homeassistant-pyozw==0.1.4
@@ -973,6 +973,9 @@ plexapi==3.0.6
# homeassistant.components.plex
plexauth==0.0.5
# homeassistant.components.plex
plexwebsocket==0.0.3
# homeassistant.components.plum_lightpad
plumlightpad==0.0.11
@@ -1129,7 +1132,7 @@ pycomfoconnect==0.3
pycoolmasternet==0.0.4
# homeassistant.components.microsoft
pycsspeechtts==1.0.2
pycsspeechtts==1.0.3
# homeassistant.components.cups
# pycups==1.9.73

View File

@@ -242,7 +242,7 @@ hole==0.5.0
holidays==0.9.11
# homeassistant.components.frontend
home-assistant-frontend==20191023.0
home-assistant-frontend==20191025.1
# homeassistant.components.zwave
homeassistant-pyozw==0.1.4
@@ -345,6 +345,9 @@ plexapi==3.0.6
# homeassistant.components.plex
plexauth==0.0.5
# homeassistant.components.plex
plexwebsocket==0.0.3
# homeassistant.components.mhz19
# homeassistant.components.serial_pm
pmsensor==0.4

View File

@@ -14,6 +14,7 @@ from tests.common import (
mock_device_registry,
mock_registry,
async_get_device_automations,
async_get_device_automation_capabilities,
)
from tests.testing_config.custom_components.test.sensor import DEVICE_CLASSES
@@ -73,6 +74,86 @@ async def test_get_conditions(hass, device_reg, entity_reg):
assert conditions == expected_conditions
async def test_get_condition_capabilities(hass, device_reg, entity_reg):
"""Test we get the expected capabilities from a sensor condition."""
platform = getattr(hass.components, f"test.{DOMAIN}")
platform.init()
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
device_entry = device_reg.async_get_or_create(
config_entry_id=config_entry.entry_id,
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
)
entity_reg.async_get_or_create(
DOMAIN,
"test",
platform.ENTITIES["battery"].unique_id,
device_id=device_entry.id,
)
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
expected_capabilities = {
"extra_fields": [
{
"description": {"suffix": "%"},
"name": "above",
"optional": True,
"type": "float",
},
{
"description": {"suffix": "%"},
"name": "below",
"optional": True,
"type": "float",
},
]
}
conditions = await async_get_device_automations(hass, "condition", device_entry.id)
assert len(conditions) == 1
for condition in conditions:
capabilities = await async_get_device_automation_capabilities(
hass, "condition", condition
)
assert capabilities == expected_capabilities
async def test_get_condition_capabilities_none(hass, device_reg, entity_reg):
"""Test we get the expected capabilities from a sensor condition."""
platform = getattr(hass.components, f"test.{DOMAIN}")
platform.init()
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
conditions = [
{
"condition": "device",
"device_id": "8770c43885354d5fa27604db6817f63f",
"domain": "sensor",
"entity_id": "sensor.beer",
"type": "is_battery_level",
},
{
"condition": "device",
"device_id": "8770c43885354d5fa27604db6817f63f",
"domain": "sensor",
"entity_id": platform.ENTITIES["none"].entity_id,
"type": "is_battery_level",
},
]
expected_capabilities = {}
for condition in conditions:
capabilities = await async_get_device_automation_capabilities(
hass, "condition", condition
)
assert capabilities == expected_capabilities
async def test_if_state_not_above_below(hass, calls, caplog):
"""Test for bad value conditions."""
platform = getattr(hass.components, f"test.{DOMAIN}")

View File

@@ -124,6 +124,41 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg):
assert capabilities == expected_capabilities
async def test_get_trigger_capabilities_none(hass, device_reg, entity_reg):
"""Test we get the expected capabilities from a sensor trigger."""
platform = getattr(hass.components, f"test.{DOMAIN}")
platform.init()
config_entry = MockConfigEntry(domain="test", data={})
config_entry.add_to_hass(hass)
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
triggers = [
{
"platform": "device",
"device_id": "8770c43885354d5fa27604db6817f63f",
"domain": "sensor",
"entity_id": "sensor.beer",
"type": "is_battery_level",
},
{
"platform": "device",
"device_id": "8770c43885354d5fa27604db6817f63f",
"domain": "sensor",
"entity_id": platform.ENTITIES["none"].entity_id,
"type": "is_battery_level",
},
]
expected_capabilities = {}
for trigger in triggers:
capabilities = await async_get_device_automation_capabilities(
hass, "trigger", trigger
)
assert capabilities == expected_capabilities
async def test_if_fires_not_on_above_below(hass, calls, caplog):
"""Test for value triggers firing."""
platform = getattr(hass.components, f"test.{DOMAIN}")