Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d4e2332ce0 | |||
| e4685de459 | |||
| 73547c8c4b | |||
| 0b327cd4d9 | |||
| dfe9af7110 | |||
| 016e8f833d | |||
| 574df0f420 | |||
| f18f181962 | |||
| 4754455295 | |||
| 8c1317f278 | |||
| c9a88322d6 | |||
| 46b58db2ff | |||
| 78cbfa3f96 | |||
| dba5c74c8f | |||
| a94a5ac9b5 |
@@ -38,7 +38,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
|
||||
for device_name, device_config in devices.items():
|
||||
value_template = device_config.get(CONF_VALUE_TEMPLATE)
|
||||
value_template.hass = hass
|
||||
if value_template is not None:
|
||||
value_template.hass = hass
|
||||
|
||||
covers.append(
|
||||
CommandCover(
|
||||
|
||||
@@ -46,6 +46,7 @@ CONF_TRACK_NEW = 'track_new_devices'
|
||||
DEFAULT_TRACK_NEW = True
|
||||
|
||||
CONF_CONSIDER_HOME = 'consider_home'
|
||||
DEFAULT_CONSIDER_HOME = 180
|
||||
|
||||
CONF_SCAN_INTERVAL = 'interval_seconds'
|
||||
DEFAULT_SCAN_INTERVAL = 12
|
||||
@@ -119,8 +120,9 @@ def setup(hass: HomeAssistantType, config: ConfigType):
|
||||
return False
|
||||
else:
|
||||
conf = conf[0] if len(conf) > 0 else {}
|
||||
consider_home = conf[CONF_CONSIDER_HOME]
|
||||
track_new = conf[CONF_TRACK_NEW]
|
||||
consider_home = conf.get(CONF_CONSIDER_HOME,
|
||||
timedelta(seconds=DEFAULT_CONSIDER_HOME))
|
||||
track_new = conf.get(CONF_TRACK_NEW, DEFAULT_TRACK_NEW)
|
||||
|
||||
devices = load_config(yaml_path, hass, consider_home)
|
||||
|
||||
@@ -415,7 +417,7 @@ def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta):
|
||||
for dev_id, device in devices.items():
|
||||
try:
|
||||
device = dev_schema(device)
|
||||
device['dev_id'] = cv.slug(dev_id)
|
||||
device['dev_id'] = cv.slugify(dev_id)
|
||||
except vol.Invalid as exp:
|
||||
log_exception(exp, dev_id, devices)
|
||||
else:
|
||||
|
||||
@@ -14,6 +14,7 @@ import requests
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from homeassistant.helpers.event import track_point_in_utc_time
|
||||
from homeassistant.util.dt import utcnow
|
||||
from homeassistant.util import slugify
|
||||
from homeassistant.const import (
|
||||
CONF_PASSWORD,
|
||||
CONF_SCAN_INTERVAL,
|
||||
@@ -87,7 +88,7 @@ def setup_scanner(hass, config, see):
|
||||
vehicle_url = rel["vehicle"] + '/'
|
||||
attributes = query("attributes", vehicle_url)
|
||||
|
||||
dev_id = "volvo_" + attributes["registrationNumber"]
|
||||
dev_id = "volvo_" + slugify(attributes["registrationNumber"])
|
||||
host_name = "%s %s/%s" % (attributes["registrationNumber"],
|
||||
attributes["vehicleType"],
|
||||
attributes["modelYear"])
|
||||
|
||||
@@ -353,7 +353,8 @@ def _get_devices(device_type, keys):
|
||||
name = _create_ha_name(
|
||||
name=device.NAME,
|
||||
channel=channel,
|
||||
param=param
|
||||
param=param,
|
||||
count=len(channels)
|
||||
)
|
||||
device_dict = {
|
||||
CONF_PLATFORM: "homematic",
|
||||
@@ -377,22 +378,22 @@ def _get_devices(device_type, keys):
|
||||
return device_arr
|
||||
|
||||
|
||||
def _create_ha_name(name, channel, param):
|
||||
def _create_ha_name(name, channel, param, count):
|
||||
"""Generate a unique object name."""
|
||||
# HMDevice is a simple device
|
||||
if channel == 1 and param is None:
|
||||
if count == 1 and param is None:
|
||||
return name
|
||||
|
||||
# Has multiple elements/channels
|
||||
if channel > 1 and param is None:
|
||||
if count > 1 and param is None:
|
||||
return "{} {}".format(name, channel)
|
||||
|
||||
# With multiple param first elements
|
||||
if channel == 1 and param is not None:
|
||||
if count == 1 and param is not None:
|
||||
return "{} {}".format(name, param)
|
||||
|
||||
# Multiple param on object with multiple elements
|
||||
if channel > 1 and param is not None:
|
||||
if count > 1 and param is not None:
|
||||
return "{} {} {}".format(name, channel, param)
|
||||
|
||||
|
||||
@@ -600,12 +601,6 @@ class HMDevice(Entity):
|
||||
if self._state:
|
||||
self._state = self._state.upper()
|
||||
|
||||
# Generate name
|
||||
if not self._name:
|
||||
self._name = _create_ha_name(name=self._address,
|
||||
channel=self._channel,
|
||||
param=self._state)
|
||||
|
||||
@property
|
||||
def should_poll(self):
|
||||
"""Return false. Homematic states are pushed by the XML RPC Server."""
|
||||
|
||||
@@ -41,7 +41,7 @@ def get_status():
|
||||
|
||||
def get_unit_status(code):
|
||||
"""Get on/off status for given unit."""
|
||||
unit = int(code[1])
|
||||
unit = int(code[1:])
|
||||
return get_status()[16 - int(unit)] == '1'
|
||||
|
||||
|
||||
|
||||
@@ -100,8 +100,8 @@ def setup(hass, config):
|
||||
kwargs[ATTR_TITLE] = title.render()
|
||||
|
||||
if targets.get(call.service) is not None:
|
||||
kwargs[ATTR_TARGET] = targets[call.service]
|
||||
else:
|
||||
kwargs[ATTR_TARGET] = [targets[call.service]]
|
||||
elif call.data.get(ATTR_TARGET) is not None:
|
||||
kwargs[ATTR_TARGET] = call.data.get(ATTR_TARGET)
|
||||
|
||||
message.hass = hass
|
||||
|
||||
@@ -344,12 +344,15 @@ class HTML5NotificationService(BaseNotificationService):
|
||||
# Pick out fields that should go into the notification directly vs
|
||||
# into the notification data dictionary.
|
||||
|
||||
for key, val in data.copy().items():
|
||||
data_tmp = {}
|
||||
|
||||
for key, val in data.items():
|
||||
if key in HTML5_SHOWNOTIFICATION_PARAMETERS:
|
||||
payload[key] = val
|
||||
del data[key]
|
||||
else:
|
||||
data_tmp[key] = val
|
||||
|
||||
payload[ATTR_DATA] = data
|
||||
payload[ATTR_DATA] = data_tmp
|
||||
|
||||
if (payload[ATTR_DATA].get(ATTR_URL) is None and
|
||||
payload.get(ATTR_ACTIONS) is None):
|
||||
|
||||
@@ -63,6 +63,9 @@ class PushoverNotificationService(BaseNotificationService):
|
||||
|
||||
targets = kwargs.get(ATTR_TARGET)
|
||||
|
||||
if not isinstance(targets, list):
|
||||
targets = [targets]
|
||||
|
||||
for target in targets:
|
||||
if target is not None:
|
||||
data['device'] = target
|
||||
|
||||
@@ -68,7 +68,10 @@ class SlackNotificationService(BaseNotificationService):
|
||||
"""Send a message to a user."""
|
||||
import slacker
|
||||
|
||||
targets = kwargs.get(ATTR_TARGET, [self._default_channel])
|
||||
if kwargs.get(ATTR_TARGET) is None:
|
||||
targets = [self._default_channel]
|
||||
else:
|
||||
targets = kwargs.get(ATTR_TARGET)
|
||||
|
||||
data = kwargs.get('data')
|
||||
attachments = data.get('attachments') if data else None
|
||||
|
||||
@@ -55,7 +55,7 @@ CONFIG_SCHEMA = vol.Schema({
|
||||
|
||||
PLATFORM_SCHEMA = vol.Schema({
|
||||
vol.Required(CONF_NAME): cv.string,
|
||||
vol.Required(CONF_PIN): cv.positive_int,
|
||||
vol.Optional(CONF_PIN): cv.positive_int,
|
||||
vol.Optional(CONF_ADDRESS): cv.string,
|
||||
}, extra=vol.ALLOW_EXTRA)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"""Constants used by Home Assistant components."""
|
||||
MAJOR_VERSION = 0
|
||||
MINOR_VERSION = 30
|
||||
PATCH_VERSION = '0'
|
||||
PATCH_VERSION = '2'
|
||||
__short_version__ = '{}.{}'.format(MAJOR_VERSION, MINOR_VERSION)
|
||||
__version__ = '{}.{}'.format(__short_version__, PATCH_VERSION)
|
||||
REQUIRED_PYTHON_VER = (3, 4, 2)
|
||||
|
||||
@@ -17,7 +17,7 @@ from homeassistant.const import (
|
||||
from homeassistant.core import valid_entity_id
|
||||
from homeassistant.exceptions import TemplateError
|
||||
import homeassistant.util.dt as dt_util
|
||||
from homeassistant.util import slugify
|
||||
from homeassistant.util import slugify as util_slugify
|
||||
from homeassistant.helpers import template as template_helper
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
@@ -218,12 +218,22 @@ def slug(value):
|
||||
if value is None:
|
||||
raise vol.Invalid('Slug should not be None')
|
||||
value = str(value)
|
||||
slg = slugify(value)
|
||||
slg = util_slugify(value)
|
||||
if value == slg:
|
||||
return value
|
||||
raise vol.Invalid('invalid slug {} (try {})'.format(value, slg))
|
||||
|
||||
|
||||
def slugify(value):
|
||||
"""Coerce a value to a slug."""
|
||||
if value is None:
|
||||
raise vol.Invalid('Slug should not be None')
|
||||
slg = util_slugify(str(value))
|
||||
if len(slg) > 0:
|
||||
return slg
|
||||
raise vol.Invalid('Unable to slugify {}'.format(value))
|
||||
|
||||
|
||||
def string(value: Any) -> str:
|
||||
"""Coerce value to string, except for None."""
|
||||
if value is not None:
|
||||
|
||||
@@ -60,12 +60,27 @@ class TestComponentsDeviceTracker(unittest.TestCase):
|
||||
"""Test when known devices contains invalid data."""
|
||||
files = {'empty.yaml': '',
|
||||
'nodict.yaml': '100',
|
||||
'allok.yaml': 'my_device:\n name: Device'}
|
||||
'badkey.yaml': '@:\n name: Device',
|
||||
'noname.yaml': 'my_device:\n',
|
||||
'allok.yaml': 'My Device:\n name: Device',
|
||||
'oneok.yaml': ('My Device!:\n name: Device\n'
|
||||
'bad_device:\n nme: Device')}
|
||||
args = {'hass': self.hass, 'consider_home': timedelta(seconds=60)}
|
||||
with patch_yaml_files(files):
|
||||
assert device_tracker.load_config('empty.yaml', **args) == []
|
||||
assert device_tracker.load_config('nodict.yaml', **args) == []
|
||||
assert len(device_tracker.load_config('allok.yaml', **args)) == 1
|
||||
assert device_tracker.load_config('noname.yaml', **args) == []
|
||||
assert device_tracker.load_config('badkey.yaml', **args) == []
|
||||
|
||||
res = device_tracker.load_config('allok.yaml', **args)
|
||||
assert len(res) == 1
|
||||
assert res[0].name == 'Device'
|
||||
assert res[0].dev_id == 'my_device'
|
||||
|
||||
res = device_tracker.load_config('oneok.yaml', **args)
|
||||
assert len(res) == 1
|
||||
assert res[0].name == 'Device'
|
||||
assert res[0].dev_id == 'my_device'
|
||||
|
||||
def test_reading_yaml_config(self):
|
||||
"""Test the rendering of the YAML configuration."""
|
||||
|
||||
@@ -64,7 +64,6 @@ class TestNotifyDemo(unittest.TestCase):
|
||||
data = self.events[0].data
|
||||
assert {
|
||||
'message': 'my message',
|
||||
'target': None,
|
||||
'title': 'my title',
|
||||
'data': {'hello': 'world'}
|
||||
} == data
|
||||
@@ -92,7 +91,6 @@ data_template:
|
||||
self.assertTrue(len(self.events) == 1)
|
||||
assert {
|
||||
'message': 'Test 123 4',
|
||||
'target': None,
|
||||
'data': {
|
||||
'push': {
|
||||
'sound':
|
||||
@@ -124,7 +122,6 @@ data_template:
|
||||
assert {
|
||||
'message': 'Test 123 4',
|
||||
'title': 'Test',
|
||||
'target': None,
|
||||
'data': {
|
||||
'push': {
|
||||
'sound':
|
||||
@@ -152,7 +149,7 @@ data_template:
|
||||
|
||||
assert {
|
||||
'message': 'my message',
|
||||
'target': 'test target id',
|
||||
'target': ['test target id'],
|
||||
'title': 'my title',
|
||||
'data': {'hello': 'world'}
|
||||
} == data
|
||||
|
||||
Reference in New Issue
Block a user