commit
ee37fc344b
|
@ -213,7 +213,7 @@ class APIEntityStateView(HomeAssistantView):
|
|||
|
||||
new_state = data.get('state')
|
||||
|
||||
if not new_state:
|
||||
if new_state is None:
|
||||
return self.json_message('No state specified', HTTP_BAD_REQUEST)
|
||||
|
||||
attributes = data.get('attributes')
|
||||
|
|
|
@ -49,7 +49,7 @@ class ArloCam(Camera):
|
|||
"""Initialize an Arlo camera."""
|
||||
super().__init__()
|
||||
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._motion_status = False
|
||||
self._ffmpeg = hass.data[DATA_FFMPEG]
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
FINGERPRINTS = {
|
||||
"compatibility.js": "8e4c44b5f4288cc48ec1ba94a9bec812",
|
||||
"core.js": "d4a7cb8c80c62b536764e0e81385f6aa",
|
||||
"frontend.html": "f170a7221615ca2839cb8fd51a82f50a",
|
||||
"frontend.html": "bdcde4695ce32595a9e1d813b9d7c5f9",
|
||||
"mdi.html": "c92bd28c434865d6cabb34cd3c0a3e4c",
|
||||
"micromarkdown-js.html": "93b5ec4016f0bba585521cf4d18dec1a",
|
||||
"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)
|
||||
tls_insecure = conf.get(CONF_TLS_INSECURE)
|
||||
protocol = conf[CONF_PROTOCOL]
|
||||
|
||||
# hbmqtt requires a client id to be set.
|
||||
if client_id is None:
|
||||
client_id = 'home-assistant'
|
||||
elif broker_config:
|
||||
# If no broker passed in, auto config to internal server
|
||||
broker, port, username, password, certificate, protocol = broker_config
|
||||
|
|
|
@ -26,7 +26,7 @@ _LOGGER = logging.getLogger(__name__)
|
|||
|
||||
DEFAULT_PORT = 5222
|
||||
DEVICES = []
|
||||
CONF_DEVICE_CACHE = 'device_cache'
|
||||
CONF_DEVICE_CACHE = 'harmony_device_cache'
|
||||
|
||||
SERVICE_SYNC = 'harmony_sync'
|
||||
|
||||
|
@ -69,7 +69,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
|||
port)
|
||||
|
||||
# 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)
|
||||
return
|
||||
elif CONF_HOST in config:
|
||||
|
@ -147,7 +147,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||
|
||||
_LOGGER.debug("HarmonyRemote device init started for: %s", name)
|
||||
self._name = name
|
||||
self._ip = host
|
||||
self.host = host
|
||||
self._port = port
|
||||
self._state = None
|
||||
self._current_activity = None
|
||||
|
@ -182,7 +182,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||
name = self._name
|
||||
_LOGGER.debug("Polling %s for current activity", name)
|
||||
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)
|
||||
self._current_activity = state
|
||||
self._state = bool(state != 'PowerOff')
|
||||
|
@ -197,7 +197,7 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||
|
||||
if 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
|
||||
else:
|
||||
_LOGGER.error("No activity specified with turn_on service")
|
||||
|
@ -205,13 +205,13 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||
def turn_off(self):
|
||||
"""Start the PowerOff activity."""
|
||||
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):
|
||||
"""Send a set of commands to one device."""
|
||||
import pyharmony
|
||||
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]),
|
||||
float(kwargs[ATTR_DELAY_SECS]))
|
||||
|
||||
|
@ -219,8 +219,8 @@ class HarmonyRemote(remote.RemoteDevice):
|
|||
"""Sync the Harmony device with the web service."""
|
||||
import pyharmony
|
||||
_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._token, self._ip, self._port)
|
||||
self._token, self.host, self._port)
|
||||
_LOGGER.debug("Writing hub config to file: %s", 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.components.arlo import (
|
||||
CONF_ATTRIBUTION, DEFAULT_BRAND)
|
||||
CONF_ATTRIBUTION, DEFAULT_BRAND, DATA_ARLO)
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION, CONF_MONITORED_CONDITIONS, STATE_UNKNOWN)
|
||||
|
@ -40,7 +40,7 @@ SCAN_INTERVAL = timedelta(seconds=90)
|
|||
@asyncio.coroutine
|
||||
def async_setup_platform(hass, config, async_add_devices, discovery_info=None):
|
||||
"""Set up an Arlo IP sensor."""
|
||||
arlo = hass.data.get('arlo')
|
||||
arlo = hass.data.get(DATA_ARLO)
|
||||
if not arlo:
|
||||
return False
|
||||
|
||||
|
|
|
@ -32,12 +32,12 @@ CONFIG_SCHEMA = vol.Schema({
|
|||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
INTENT_SCHEMA = vol.Schema({
|
||||
vol.Required('text'): str,
|
||||
vol.Required('input'): str,
|
||||
vol.Required('intent'): {
|
||||
vol.Required('intent_name'): str
|
||||
vol.Required('intentName'): str
|
||||
},
|
||||
vol.Optional('slots'): [{
|
||||
vol.Required('slot_name'): str,
|
||||
vol.Required('slotName'): str,
|
||||
vol.Required('value'): {
|
||||
vol.Required('kind'): str,
|
||||
vol.Required('value'): cv.match_all
|
||||
|
@ -95,7 +95,7 @@ class IntentHandler(object):
|
|||
LOGGER.error('Intent has invalid schema: %s. %s', err, response)
|
||||
return
|
||||
|
||||
intent = response['intent']['intent_name'].split('__')[-1]
|
||||
intent = response['intent']['intentName'].split('__')[-1]
|
||||
config = self.intents.get(intent)
|
||||
|
||||
if config is None:
|
||||
|
@ -113,26 +113,9 @@ class IntentHandler(object):
|
|||
parameters = {}
|
||||
|
||||
for slot in response.get('slots', []):
|
||||
key = slot['slot_name']
|
||||
value = self.get_value(slot['value'])
|
||||
key = slot['slotName']
|
||||
value = slot['value']['value']
|
||||
if value is not None:
|
||||
parameters[key] = value
|
||||
|
||||
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."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 48
|
||||
PATCH_VERSION = 0
|
||||
PATCH_VERSION = 1
|
||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||
|
|
|
@ -1079,7 +1079,7 @@ class Config(object):
|
|||
"""Check if the path is valid for access from outside."""
|
||||
parent = pathlib.Path(path).parent
|
||||
try:
|
||||
parent.resolve() # pylint: disable=no-member
|
||||
parent = parent.resolve() # pylint: disable=no-member
|
||||
except (FileNotFoundError, RuntimeError, PermissionError):
|
||||
return False
|
||||
|
||||
|
|
|
@ -96,6 +96,23 @@ def test_api_state_change_with_bad_data(hass, mock_api_client):
|
|||
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
|
||||
@asyncio.coroutine
|
||||
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 = """
|
||||
{
|
||||
"text": "turn the lights green",
|
||||
"input": "turn the lights green",
|
||||
"intent": {
|
||||
"intent_name": "Lights",
|
||||
"intentName": "Lights",
|
||||
"probability": 1
|
||||
},
|
||||
"slots": [
|
||||
{
|
||||
"slot_name": "light_color",
|
||||
"slotName": "light_color",
|
||||
"value": {
|
||||
"kind": "Custom",
|
||||
"value": "blue"
|
||||
|
|
|
@ -821,13 +821,13 @@ class TestConfig(unittest.TestCase):
|
|||
for path in valid:
|
||||
assert self.config.is_allowed_path(path)
|
||||
|
||||
self.config.whitelist_external_dirs = set(('/home',))
|
||||
self.config.whitelist_external_dirs = set(('/home', '/var'))
|
||||
|
||||
unvalid = [
|
||||
"/hass/config/secure",
|
||||
"/etc/passwd",
|
||||
"/root/secure_file",
|
||||
"/hass/config/test/../../../etc/passwd",
|
||||
"/var/../etc/passwd",
|
||||
test_file,
|
||||
]
|
||||
for path in unvalid:
|
||||
|
|
Loading…
Reference in New Issue