mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 22:27:07 +00:00
commit
ee37fc344b
@ -213,7 +213,7 @@ class APIEntityStateView(HomeAssistantView):
|
|||||||
|
|
||||||
new_state = data.get('state')
|
new_state = data.get('state')
|
||||||
|
|
||||||
if not new_state:
|
if new_state is None:
|
||||||
return self.json_message('No state specified', HTTP_BAD_REQUEST)
|
return self.json_message('No state specified', HTTP_BAD_REQUEST)
|
||||||
|
|
||||||
attributes = data.get('attributes')
|
attributes = data.get('attributes')
|
||||||
|
@ -49,7 +49,7 @@ class ArloCam(Camera):
|
|||||||
"""Initialize an Arlo camera."""
|
"""Initialize an Arlo camera."""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._camera = camera
|
self._camera = camera
|
||||||
self._base_stn = hass.data['arlo'].base_stations[0]
|
self._base_stn = hass.data[DATA_ARLO].base_stations[0]
|
||||||
self._name = self._camera.name
|
self._name = self._camera.name
|
||||||
self._motion_status = False
|
self._motion_status = False
|
||||||
self._ffmpeg = hass.data[DATA_FFMPEG]
|
self._ffmpeg = hass.data[DATA_FFMPEG]
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
FINGERPRINTS = {
|
FINGERPRINTS = {
|
||||||
"compatibility.js": "8e4c44b5f4288cc48ec1ba94a9bec812",
|
"compatibility.js": "8e4c44b5f4288cc48ec1ba94a9bec812",
|
||||||
"core.js": "d4a7cb8c80c62b536764e0e81385f6aa",
|
"core.js": "d4a7cb8c80c62b536764e0e81385f6aa",
|
||||||
"frontend.html": "f170a7221615ca2839cb8fd51a82f50a",
|
"frontend.html": "bdcde4695ce32595a9e1d813b9d7c5f9",
|
||||||
"mdi.html": "c92bd28c434865d6cabb34cd3c0a3e4c",
|
"mdi.html": "c92bd28c434865d6cabb34cd3c0a3e4c",
|
||||||
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
|
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
|
||||||
"panels/ha-panel-automation.html": "4f98839bb082885657bbcd0ac04fc680",
|
"panels/ha-panel-automation.html": "4f98839bb082885657bbcd0ac04fc680",
|
||||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -1 +1 @@
|
|||||||
Subproject commit 1ad42592134c290119879e8f8505ef5736a3071e
|
Subproject commit 6e30534e2dc906d29ce497bf0a2eacb18e36f9c5
|
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -315,6 +315,10 @@ def async_setup(hass, config):
|
|||||||
client_cert = conf.get(CONF_CLIENT_CERT)
|
client_cert = conf.get(CONF_CLIENT_CERT)
|
||||||
tls_insecure = conf.get(CONF_TLS_INSECURE)
|
tls_insecure = conf.get(CONF_TLS_INSECURE)
|
||||||
protocol = conf[CONF_PROTOCOL]
|
protocol = conf[CONF_PROTOCOL]
|
||||||
|
|
||||||
|
# hbmqtt requires a client id to be set.
|
||||||
|
if client_id is None:
|
||||||
|
client_id = 'home-assistant'
|
||||||
elif broker_config:
|
elif broker_config:
|
||||||
# If no broker passed in, auto config to internal server
|
# If no broker passed in, auto config to internal server
|
||||||
broker, port, username, password, certificate, protocol = broker_config
|
broker, port, username, password, certificate, protocol = broker_config
|
||||||
|
@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||||||
|
|
||||||
DEFAULT_PORT = 5222
|
DEFAULT_PORT = 5222
|
||||||
DEVICES = []
|
DEVICES = []
|
||||||
CONF_DEVICE_CACHE = 'device_cache'
|
CONF_DEVICE_CACHE = 'harmony_device_cache'
|
||||||
|
|
||||||
SERVICE_SYNC = 'harmony_sync'
|
SERVICE_SYNC = 'harmony_sync'
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||||||
port)
|
port)
|
||||||
|
|
||||||
# Ignore hub name when checking if this hub is known - ip and port only
|
# Ignore hub name when checking if this hub is known - ip and port only
|
||||||
if host and host[1:] in set([h[1:] for h in DEVICES]):
|
if host and host[1:] in (h.host for h in DEVICES):
|
||||||
_LOGGER.debug("Discovered host already known: %s", host)
|
_LOGGER.debug("Discovered host already known: %s", host)
|
||||||
return
|
return
|
||||||
elif CONF_HOST in config:
|
elif CONF_HOST in config:
|
||||||
@ -147,7 +147,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||||||
|
|
||||||
_LOGGER.debug("HarmonyRemote device init started for: %s", name)
|
_LOGGER.debug("HarmonyRemote device init started for: %s", name)
|
||||||
self._name = name
|
self._name = name
|
||||||
self._ip = host
|
self.host = host
|
||||||
self._port = port
|
self._port = port
|
||||||
self._state = None
|
self._state = None
|
||||||
self._current_activity = None
|
self._current_activity = None
|
||||||
@ -182,7 +182,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||||||
name = self._name
|
name = self._name
|
||||||
_LOGGER.debug("Polling %s for current activity", name)
|
_LOGGER.debug("Polling %s for current activity", name)
|
||||||
state = pyharmony.ha_get_current_activity(
|
state = pyharmony.ha_get_current_activity(
|
||||||
self._token, self._config, self._ip, self._port)
|
self._token, self._config, self.host, self._port)
|
||||||
_LOGGER.debug("%s current activity reported as: %s", name, state)
|
_LOGGER.debug("%s current activity reported as: %s", name, state)
|
||||||
self._current_activity = state
|
self._current_activity = state
|
||||||
self._state = bool(state != 'PowerOff')
|
self._state = bool(state != 'PowerOff')
|
||||||
@ -197,7 +197,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||||||
|
|
||||||
if activity:
|
if activity:
|
||||||
pyharmony.ha_start_activity(
|
pyharmony.ha_start_activity(
|
||||||
self._token, self._ip, self._port, self._config, activity)
|
self._token, self.host, self._port, self._config, activity)
|
||||||
self._state = True
|
self._state = True
|
||||||
else:
|
else:
|
||||||
_LOGGER.error("No activity specified with turn_on service")
|
_LOGGER.error("No activity specified with turn_on service")
|
||||||
@ -205,13 +205,13 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||||||
def turn_off(self):
|
def turn_off(self):
|
||||||
"""Start the PowerOff activity."""
|
"""Start the PowerOff activity."""
|
||||||
import pyharmony
|
import pyharmony
|
||||||
pyharmony.ha_power_off(self._token, self._ip, self._port)
|
pyharmony.ha_power_off(self._token, self.host, self._port)
|
||||||
|
|
||||||
def send_command(self, **kwargs):
|
def send_command(self, **kwargs):
|
||||||
"""Send a set of commands to one device."""
|
"""Send a set of commands to one device."""
|
||||||
import pyharmony
|
import pyharmony
|
||||||
pyharmony.ha_send_commands(
|
pyharmony.ha_send_commands(
|
||||||
self._token, self._ip, self._port, kwargs[ATTR_DEVICE],
|
self._token, self.host, self._port, kwargs[ATTR_DEVICE],
|
||||||
kwargs[ATTR_COMMAND], int(kwargs[ATTR_NUM_REPEATS]),
|
kwargs[ATTR_COMMAND], int(kwargs[ATTR_NUM_REPEATS]),
|
||||||
float(kwargs[ATTR_DELAY_SECS]))
|
float(kwargs[ATTR_DELAY_SECS]))
|
||||||
|
|
||||||
@ -219,8 +219,8 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||||||
"""Sync the Harmony device with the web service."""
|
"""Sync the Harmony device with the web service."""
|
||||||
import pyharmony
|
import pyharmony
|
||||||
_LOGGER.debug("Syncing hub with Harmony servers")
|
_LOGGER.debug("Syncing hub with Harmony servers")
|
||||||
pyharmony.ha_sync(self._token, self._ip, self._port)
|
pyharmony.ha_sync(self._token, self.host, self._port)
|
||||||
self._config = pyharmony.ha_get_config(
|
self._config = pyharmony.ha_get_config(
|
||||||
self._token, self._ip, self._port)
|
self._token, self.host, self._port)
|
||||||
_LOGGER.debug("Writing hub config to file: %s", self._config_path)
|
_LOGGER.debug("Writing hub config to file: %s", self._config_path)
|
||||||
pyharmony.ha_write_config_file(self._config, self._config_path)
|
pyharmony.ha_write_config_file(self._config, self._config_path)
|
||||||
|
@ -11,7 +11,7 @@ import voluptuous as vol
|
|||||||
|
|
||||||
from homeassistant.helpers import config_validation as cv
|
from homeassistant.helpers import config_validation as cv
|
||||||
from homeassistant.components.arlo import (
|
from homeassistant.components.arlo import (
|
||||||
CONF_ATTRIBUTION, DEFAULT_BRAND)
|
CONF_ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO)
|
||||||
|
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN)
|
ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN)
|
||||||
@ -40,7 +40,7 @@ SCAN_INTERVAL = timedelta(seconds=90)
|
|||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||||
"""Set up an Arlo IP sensor."""
|
"""Set up an Arlo IP sensor."""
|
||||||
arlo = hass.data.get('arlo')
|
arlo = hass.data.get(DATA_ARLO)
|
||||||
if not arlo:
|
if not arlo:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ CONFIG_SCHEMA = vol.Schema({
|
|||||||
}, extra=vol.ALLOW_EXTRA)
|
}, extra=vol.ALLOW_EXTRA)
|
||||||
|
|
||||||
INTENT_SCHEMA = vol.Schema({
|
INTENT_SCHEMA = vol.Schema({
|
||||||
vol.Required('text'): str,
|
vol.Required('input'): str,
|
||||||
vol.Required('intent'): {
|
vol.Required('intent'): {
|
||||||
vol.Required('intent_name'): str
|
vol.Required('intentName'): str
|
||||||
},
|
},
|
||||||
vol.Optional('slots'): [{
|
vol.Optional('slots'): [{
|
||||||
vol.Required('slot_name'): str,
|
vol.Required('slotName'): str,
|
||||||
vol.Required('value'): {
|
vol.Required('value'): {
|
||||||
vol.Required('kind'): str,
|
vol.Required('kind'): str,
|
||||||
vol.Required('value'): cv.match_all
|
vol.Required('value'): cv.match_all
|
||||||
@ -95,7 +95,7 @@ class IntentHandler(object):
|
|||||||
LOGGER.error('Intent has invalid schema: %s. %s', err, response)
|
LOGGER.error('Intent has invalid schema: %s. %s', err, response)
|
||||||
return
|
return
|
||||||
|
|
||||||
intent = response['intent']['intent_name'].split('__')[-1]
|
intent = response['intent']['intentName'].split('__')[-1]
|
||||||
config = self.intents.get(intent)
|
config = self.intents.get(intent)
|
||||||
|
|
||||||
if config is None:
|
if config is None:
|
||||||
@ -113,26 +113,9 @@ class IntentHandler(object):
|
|||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
for slot in response.get('slots', []):
|
for slot in response.get('slots', []):
|
||||||
key = slot['slot_name']
|
key = slot['slotName']
|
||||||
value = self.get_value(slot['value'])
|
value = slot['value']['value']
|
||||||
if value is not None:
|
if value is not None:
|
||||||
parameters[key] = value
|
parameters[key] = value
|
||||||
|
|
||||||
return parameters
|
return parameters
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_value(value):
|
|
||||||
"""Return the value of a given slot."""
|
|
||||||
kind = value['kind']
|
|
||||||
|
|
||||||
if kind == "Custom":
|
|
||||||
return value["value"]
|
|
||||||
elif kind == "Builtin":
|
|
||||||
try:
|
|
||||||
return value["value"]["value"]
|
|
||||||
except KeyError:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
LOGGER.warning('Received unknown slot type: %s', kind)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"""Constants used by Home Assistant components."""
|
"""Constants used by Home Assistant components."""
|
||||||
MAJOR_VERSION = 0
|
MAJOR_VERSION = 0
|
||||||
MINOR_VERSION = 48
|
MINOR_VERSION = 48
|
||||||
PATCH_VERSION = 0
|
PATCH_VERSION = 1
|
||||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||||
|
@ -1079,7 +1079,7 @@ class Config(object):
|
|||||||
"""Check if the path is valid for access from outside."""
|
"""Check if the path is valid for access from outside."""
|
||||||
parent = pathlib.Path(path).parent
|
parent = pathlib.Path(path).parent
|
||||||
try:
|
try:
|
||||||
parent.resolve() # pylint: disable=no-member
|
parent = parent.resolve() # pylint: disable=no-member
|
||||||
except (FileNotFoundError, RuntimeError, PermissionError):
|
except (FileNotFoundError, RuntimeError, PermissionError):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -96,6 +96,23 @@ def test_api_state_change_with_bad_data(hass, mock_api_client):
|
|||||||
assert resp.status == 400
|
assert resp.status == 400
|
||||||
|
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
|
@asyncio.coroutine
|
||||||
|
def test_api_state_change_to_zero_value(hass, mock_api_client):
|
||||||
|
"""Test if changing a state to a zero value is possible."""
|
||||||
|
resp = yield from mock_api_client.post(
|
||||||
|
const.URL_API_STATES_ENTITY.format("test_entity.with_zero_state"),
|
||||||
|
json={'state': 0})
|
||||||
|
|
||||||
|
assert resp.status == 201
|
||||||
|
|
||||||
|
resp = yield from mock_api_client.post(
|
||||||
|
const.URL_API_STATES_ENTITY.format("test_entity.with_zero_state"),
|
||||||
|
json={'state': 0.})
|
||||||
|
|
||||||
|
assert resp.status == 200
|
||||||
|
|
||||||
|
|
||||||
# pylint: disable=invalid-name
|
# pylint: disable=invalid-name
|
||||||
@asyncio.coroutine
|
@asyncio.coroutine
|
||||||
def test_api_state_change_push(hass, mock_api_client):
|
def test_api_state_change_push(hass, mock_api_client):
|
||||||
|
@ -6,14 +6,14 @@ from tests.common import async_fire_mqtt_message, async_mock_service
|
|||||||
|
|
||||||
EXAMPLE_MSG = """
|
EXAMPLE_MSG = """
|
||||||
{
|
{
|
||||||
"text": "turn the lights green",
|
"input": "turn the lights green",
|
||||||
"intent": {
|
"intent": {
|
||||||
"intent_name": "Lights",
|
"intentName": "Lights",
|
||||||
"probability": 1
|
"probability": 1
|
||||||
},
|
},
|
||||||
"slots": [
|
"slots": [
|
||||||
{
|
{
|
||||||
"slot_name": "light_color",
|
"slotName": "light_color",
|
||||||
"value": {
|
"value": {
|
||||||
"kind": "Custom",
|
"kind": "Custom",
|
||||||
"value": "blue"
|
"value": "blue"
|
||||||
|
@ -821,13 +821,13 @@ class TestConfig(unittest.TestCase):
|
|||||||
for path in valid:
|
for path in valid:
|
||||||
assert self.config.is_allowed_path(path)
|
assert self.config.is_allowed_path(path)
|
||||||
|
|
||||||
self.config.whitelist_external_dirs = set(('/home',))
|
self.config.whitelist_external_dirs = set(('/home', '/var'))
|
||||||
|
|
||||||
unvalid = [
|
unvalid = [
|
||||||
"/hass/config/secure",
|
"/hass/config/secure",
|
||||||
"/etc/passwd",
|
"/etc/passwd",
|
||||||
"/root/secure_file",
|
"/root/secure_file",
|
||||||
"/hass/config/test/../../../etc/passwd",
|
"/var/../etc/passwd",
|
||||||
test_file,
|
test_file,
|
||||||
]
|
]
|
||||||
for path in unvalid:
|
for path in unvalid:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user