Merge pull request #1703 from jaharkes/config-validation-mqtt

Config validation for MQTT
This commit is contained in:
Paulus Schoutsen 2016-04-07 08:43:01 -07:00
commit 5ff9479f0b
25 changed files with 512 additions and 299 deletions

View File

@ -12,6 +12,7 @@ from homeassistant.const import (
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER, ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY) SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
from homeassistant.config import load_yaml_config_file from homeassistant.config import load_yaml_config_file
from homeassistant.helpers.config_validation import PLATFORM_SCHEMA # noqa
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity_component import EntityComponent

View File

@ -6,43 +6,55 @@ https://home-assistant.io/components/alarm_control_panel.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_HOME, STATE_ALARM_DISARMED,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN) STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN,
CONF_NAME)
from homeassistant.components.mqtt import (
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS)
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "MQTT Alarm"
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_DISARM = "DISARM"
DEFAULT_PAYLOAD_ARM_HOME = "ARM_HOME"
DEFAULT_PAYLOAD_ARM_AWAY = "ARM_AWAY"
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_PAYLOAD_DISARM = 'payload_disarm'
CONF_PAYLOAD_ARM_HOME = 'payload_arm_home'
CONF_PAYLOAD_ARM_AWAY = 'payload_arm_away'
CONF_CODE = 'code'
DEFAULT_NAME = "MQTT Alarm"
DEFAULT_DISARM = "DISARM"
DEFAULT_ARM_HOME = "ARM_HOME"
DEFAULT_ARM_AWAY = "ARM_AWAY"
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Required(CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Required(CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_PAYLOAD_DISARM, default=DEFAULT_DISARM): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_HOME, default=DEFAULT_ARM_HOME): cv.string,
vol.Optional(CONF_PAYLOAD_ARM_AWAY, default=DEFAULT_ARM_AWAY): cv.string,
vol.Optional(CONF_CODE): cv.string,
})
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Setup the MQTT platform.""" """Setup the MQTT platform."""
if config.get('state_topic') is None:
_LOGGER.error("Missing required variable: state_topic")
return False
if config.get('command_topic') is None:
_LOGGER.error("Missing required variable: command_topic")
return False
add_devices([MqttAlarm( add_devices([MqttAlarm(
hass, hass,
config.get('name', DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic'), config[CONF_STATE_TOPIC],
config.get('command_topic'), config[CONF_COMMAND_TOPIC],
config.get('qos', DEFAULT_QOS), config[CONF_QOS],
config.get('payload_disarm', DEFAULT_PAYLOAD_DISARM), config[CONF_PAYLOAD_DISARM],
config.get('payload_arm_home', DEFAULT_PAYLOAD_ARM_HOME), config[CONF_PAYLOAD_ARM_HOME],
config.get('payload_arm_away', DEFAULT_PAYLOAD_ARM_AWAY), config[CONF_PAYLOAD_ARM_AWAY],
config.get('code'))]) config.get(CONF_CODE))])
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes
@ -62,7 +74,7 @@ class MqttAlarm(alarm.AlarmControlPanel):
self._payload_disarm = payload_disarm self._payload_disarm = payload_disarm
self._payload_arm_home = payload_arm_home self._payload_arm_home = payload_arm_home
self._payload_arm_away = payload_arm_away self._payload_arm_away = payload_arm_away
self._code = str(code) if code else None self._code = code
def message_received(topic, payload, qos): def message_received(topic, payload, qos):
"""A new MQTT message has been received.""" """A new MQTT message has been received."""

View File

@ -4,26 +4,29 @@ Offer MQTT listening automation rules.
For more details about this automation rule, please refer to the documentation For more details about this automation rule, please refer to the documentation
at https://home-assistant.io/components/automation/#mqtt-trigger at https://home-assistant.io/components/automation/#mqtt-trigger
""" """
import logging import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.const import CONF_PLATFORM
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_TOPIC = 'topic' CONF_TOPIC = 'topic'
CONF_PAYLOAD = 'payload' CONF_PAYLOAD = 'payload'
TRIGGER_SCHEMA = vol.Schema({
vol.Required(CONF_PLATFORM): mqtt.DOMAIN,
vol.Required(CONF_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_PAYLOAD): cv.string,
})
def trigger(hass, config, action): def trigger(hass, config, action):
"""Listen for state changes based on configuration.""" """Listen for state changes based on configuration."""
topic = config.get(CONF_TOPIC) topic = config[CONF_TOPIC]
payload = config.get(CONF_PAYLOAD) payload = config.get(CONF_PAYLOAD)
if topic is None:
logging.getLogger(__name__).error(
"Missing configuration key %s", CONF_TOPIC)
return False
def mqtt_automation_listener(msg_topic, msg_payload, qos): def mqtt_automation_listener(msg_topic, msg_payload, qos):
"""Listen for MQTT messages.""" """Listen for MQTT messages."""
if payload is None or payload == msg_payload: if payload is None or payload == msg_payload:

View File

@ -6,43 +6,50 @@ https://home-assistant.io/components/binary_sensor.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.components.binary_sensor import (BinarySensorDevice, from homeassistant.components.binary_sensor import (BinarySensorDevice,
SENSOR_CLASSES) SENSOR_CLASSES)
from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.const import CONF_NAME, CONF_VALUE_TEMPLATE
from homeassistant.components.mqtt import CONF_STATE_TOPIC, CONF_QOS
from homeassistant.helpers import template from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt']
CONF_SENSOR_CLASS = 'sensor_class'
CONF_PAYLOAD_ON = 'payload_on'
CONF_PAYLOAD_OFF = 'payload_off'
DEFAULT_NAME = 'MQTT Binary sensor' DEFAULT_NAME = 'MQTT Binary sensor'
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_ON = 'ON' DEFAULT_PAYLOAD_ON = 'ON'
DEFAULT_PAYLOAD_OFF = 'OFF' DEFAULT_PAYLOAD_OFF = 'OFF'
DEPENDENCIES = ['mqtt'] PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_SENSOR_CLASS, default=None):
vol.Any(vol.In(SENSOR_CLASSES), vol.SetTo(None)),
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices, discovery_info=None): def setup_platform(hass, config, add_devices, discovery_info=None):
"""Add MQTT binary sensor.""" """Add MQTT binary sensor."""
if config.get('state_topic') is None:
_LOGGER.error('Missing required variable: state_topic')
return False
sensor_class = config.get('sensor_class')
if sensor_class not in SENSOR_CLASSES:
_LOGGER.warning('Unknown sensor class: %s', sensor_class)
sensor_class = None
add_devices([MqttBinarySensor( add_devices([MqttBinarySensor(
hass, hass,
config.get('name', DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic', None), config[CONF_STATE_TOPIC],
sensor_class, config[CONF_SENSOR_CLASS],
config.get('qos', DEFAULT_QOS), config[CONF_QOS],
config.get('payload_on', DEFAULT_PAYLOAD_ON), config[CONF_PAYLOAD_ON],
config.get('payload_off', DEFAULT_PAYLOAD_OFF), config[CONF_PAYLOAD_OFF],
config.get(CONF_VALUE_TEMPLATE))]) config.get(CONF_VALUE_TEMPLATE)
)])
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes

View File

@ -6,28 +6,27 @@ https://home-assistant.io/components/device_tracker.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant import util from homeassistant.components.mqtt import CONF_QOS
import homeassistant.helpers.config_validation as cv
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_QOS = 'qos'
CONF_DEVICES = 'devices' CONF_DEVICES = 'devices'
DEFAULT_QOS = 0
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Required(CONF_DEVICES): {cv.string: mqtt.valid_subscribe_topic},
})
def setup_scanner(hass, config, see): def setup_scanner(hass, config, see):
"""Setup the MQTT tracker.""" """Setup the MQTT tracker."""
devices = config.get(CONF_DEVICES) devices = config[CONF_DEVICES]
qos = util.convert(config.get(CONF_QOS), int, DEFAULT_QOS) qos = config[CONF_QOS]
if not isinstance(devices, dict):
_LOGGER.error('Expected %s to be a dict, found %s', CONF_DEVICES,
devices)
return False
dev_id_lookup = {} dev_id_lookup = {}

View File

@ -7,46 +7,85 @@ https://home-assistant.io/components/light.mqtt/
import logging import logging
from functools import partial from functools import partial
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_RGB_COLOR, Light) ATTR_BRIGHTNESS, ATTR_RGB_COLOR, Light)
from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE
from homeassistant.components.mqtt import (
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.template import render_with_possible_json_value from homeassistant.helpers.template import render_with_possible_json_value
from homeassistant.util import convert
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt']
CONF_STATE_VALUE_TEMPLATE = 'state_value_template'
CONF_BRIGHTNESS_STATE_TOPIC = 'brightness_state_topic'
CONF_BRIGHTNESS_COMMAND_TOPIC = 'brightness_command_topic'
CONF_BRIGHTNESS_VALUE_TEMPLATE = 'brightness_value_template'
CONF_RGB_STATE_TOPIC = 'rgb_state_topic'
CONF_RGB_COMMAND_TOPIC = 'rgb_command_topic'
CONF_RGB_VALUE_TEMPLATE = 'rgb_value_template'
CONF_PAYLOAD_ON = 'payload_on'
CONF_PAYLOAD_OFF = 'payload_off'
CONF_BRIGHTNESS_SCALE = 'brightness_scale'
DEFAULT_NAME = 'MQTT Light' DEFAULT_NAME = 'MQTT Light'
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_ON = 'ON' DEFAULT_PAYLOAD_ON = 'ON'
DEFAULT_PAYLOAD_OFF = 'OFF' DEFAULT_PAYLOAD_OFF = 'OFF'
DEFAULT_OPTIMISTIC = False DEFAULT_OPTIMISTIC = False
DEFAULT_BRIGHTNESS_SCALE = 255 DEFAULT_BRIGHTNESS_SCALE = 255
DEPENDENCIES = ['mqtt'] PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_STATE_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_BRIGHTNESS_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_BRIGHTNESS_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_BRIGHTNESS_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_RGB_STATE_TOPIC): mqtt.valid_subscribe_topic,
vol.Optional(CONF_RGB_COMMAND_TOPIC): mqtt.valid_publish_topic,
vol.Optional(CONF_RGB_VALUE_TEMPLATE): cv.template,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
vol.Optional(CONF_BRIGHTNESS_SCALE, default=DEFAULT_BRIGHTNESS_SCALE):
vol.All(vol.Coerce(int), vol.Range(min=1)),
})
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Add MQTT Light.""" """Add MQTT Light."""
if config.get('command_topic') is None: config.setdefault(CONF_STATE_VALUE_TEMPLATE,
_LOGGER.error("Missing required variable: command_topic") config.get(CONF_VALUE_TEMPLATE))
return False
add_devices_callback([MqttLight( add_devices_callback([MqttLight(
hass, hass,
convert(config.get('name'), str, DEFAULT_NAME), config[CONF_NAME],
{key: convert(config.get(key), str) for key in
(typ + topic
for typ in ('', 'brightness_', 'rgb_')
for topic in ('state_topic', 'command_topic'))},
{key: convert(config.get(key + '_value_template'), str)
for key in ('state', 'brightness', 'rgb')},
convert(config.get('qos'), int, DEFAULT_QOS),
{ {
'on': convert(config.get('payload_on'), str, DEFAULT_PAYLOAD_ON), key: config.get(key) for key in (
'off': convert(config.get('payload_off'), str, DEFAULT_PAYLOAD_OFF) CONF_STATE_TOPIC,
CONF_COMMAND_TOPIC,
CONF_BRIGHTNESS_STATE_TOPIC,
CONF_BRIGHTNESS_COMMAND_TOPIC,
CONF_RGB_STATE_TOPIC,
CONF_RGB_COMMAND_TOPIC,
)
}, },
convert(config.get('optimistic'), bool, DEFAULT_OPTIMISTIC), {
convert(config.get('brightness_scale'), int, DEFAULT_BRIGHTNESS_SCALE) 'state': config.get(CONF_STATE_VALUE_TEMPLATE),
'brightness': config.get(CONF_BRIGHTNESS_VALUE_TEMPLATE),
'rgb': config.get(CONF_RGB_VALUE_TEMPLATE)
},
config[CONF_QOS],
config[CONF_RETAIN],
{
'on': config[CONF_PAYLOAD_ON],
'off': config[CONF_PAYLOAD_OFF],
},
config[CONF_OPTIMISTIC],
config[CONF_BRIGHTNESS_SCALE],
)]) )])
@ -54,13 +93,14 @@ class MqttLight(Light):
"""MQTT light.""" """MQTT light."""
# pylint: disable=too-many-arguments,too-many-instance-attributes # pylint: disable=too-many-arguments,too-many-instance-attributes
def __init__(self, hass, name, topic, templates, qos, payload, optimistic, def __init__(self, hass, name, topic, templates, qos, retain, payload,
brightness_scale): optimistic, brightness_scale):
"""Initialize MQTT light.""" """Initialize MQTT light."""
self._hass = hass self._hass = hass
self._name = name self._name = name
self._topic = topic self._topic = topic
self._qos = qos self._qos = qos
self._retain = retain
self._payload = payload self._payload = payload
self._optimistic = optimistic or topic["state_topic"] is None self._optimistic = optimistic or topic["state_topic"] is None
self._optimistic_rgb = optimistic or topic["rgb_state_topic"] is None self._optimistic_rgb = optimistic or topic["rgb_state_topic"] is None
@ -156,7 +196,8 @@ class MqttLight(Light):
self._topic["rgb_command_topic"] is not None: self._topic["rgb_command_topic"] is not None:
mqtt.publish(self._hass, self._topic["rgb_command_topic"], mqtt.publish(self._hass, self._topic["rgb_command_topic"],
"{},{},{}".format(*kwargs[ATTR_RGB_COLOR]), self._qos) "{},{},{}".format(*kwargs[ATTR_RGB_COLOR]),
self._qos, self._retain)
if self._optimistic_rgb: if self._optimistic_rgb:
self._rgb = kwargs[ATTR_RGB_COLOR] self._rgb = kwargs[ATTR_RGB_COLOR]
@ -167,14 +208,14 @@ class MqttLight(Light):
percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255 percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
device_brightness = int(percent_bright * self._brightness_scale) device_brightness = int(percent_bright * self._brightness_scale)
mqtt.publish(self._hass, self._topic["brightness_command_topic"], mqtt.publish(self._hass, self._topic["brightness_command_topic"],
device_brightness, self._qos) device_brightness, self._qos, self._retain)
if self._optimistic_brightness: if self._optimistic_brightness:
self._brightness = kwargs[ATTR_BRIGHTNESS] self._brightness = kwargs[ATTR_BRIGHTNESS]
should_update = True should_update = True
mqtt.publish(self._hass, self._topic["command_topic"], mqtt.publish(self._hass, self._topic["command_topic"],
self._payload["on"], self._qos) self._payload["on"], self._qos, self._retain)
if self._optimistic: if self._optimistic:
# Optimistically assume that switch has changed state. # Optimistically assume that switch has changed state.
@ -187,7 +228,7 @@ class MqttLight(Light):
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
"""Turn the device off.""" """Turn the device off."""
mqtt.publish(self._hass, self._topic["command_topic"], mqtt.publish(self._hass, self._topic["command_topic"],
self._payload["off"], self._qos) self._payload["off"], self._qos, self._retain)
if self._optimistic: if self._optimistic:
# Optimistically assume that switch has changed state. # Optimistically assume that switch has changed state.

View File

@ -6,40 +6,51 @@ https://home-assistant.io/components/lock.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.components.lock import LockDevice from homeassistant.components.lock import LockDevice
from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE
from homeassistant.components.mqtt import (
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
from homeassistant.helpers import template from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt']
CONF_PAYLOAD_LOCK = 'payload_lock'
CONF_PAYLOAD_UNLOCK = 'payload_unlock'
DEFAULT_NAME = "MQTT Lock" DEFAULT_NAME = "MQTT Lock"
DEFAULT_PAYLOAD_LOCK = "LOCK" DEFAULT_PAYLOAD_LOCK = "LOCK"
DEFAULT_PAYLOAD_UNLOCK = "UNLOCK" DEFAULT_PAYLOAD_UNLOCK = "UNLOCK"
DEFAULT_QOS = 0
DEFAULT_OPTIMISTIC = False DEFAULT_OPTIMISTIC = False
DEFAULT_RETAIN = False
DEPENDENCIES = ['mqtt'] PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_LOCK, default=DEFAULT_PAYLOAD_LOCK):
cv.string,
vol.Optional(CONF_PAYLOAD_UNLOCK, default=DEFAULT_PAYLOAD_UNLOCK):
cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup the MQTT lock.""" """Setup the MQTT lock."""
if config.get('command_topic') is None:
_LOGGER.error("Missing required variable: command_topic")
return False
add_devices_callback([MqttLock( add_devices_callback([MqttLock(
hass, hass,
config.get('name', DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic'), config.get(CONF_STATE_TOPIC),
config.get('command_topic'), config[CONF_COMMAND_TOPIC],
config.get('qos', DEFAULT_QOS), config[CONF_QOS],
config.get('retain', DEFAULT_RETAIN), config[CONF_RETAIN],
config.get('payload_lock', DEFAULT_PAYLOAD_LOCK), config[CONF_PAYLOAD_LOCK],
config.get('payload_unlock', DEFAULT_PAYLOAD_UNLOCK), config[CONF_PAYLOAD_UNLOCK],
config.get('optimistic', DEFAULT_OPTIMISTIC), config[CONF_OPTIMISTIC],
config.get(CONF_VALUE_TEMPLATE))]) config.get(CONF_VALUE_TEMPLATE))])

View File

@ -14,11 +14,11 @@ import voluptuous as vol
from homeassistant.bootstrap import prepare_setup_platform from homeassistant.bootstrap import prepare_setup_platform
from homeassistant.config import load_yaml_config_file from homeassistant.config import load_yaml_config_file
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
import homeassistant.util as util
from homeassistant.helpers import template from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv import homeassistant.helpers.config_validation as cv
from homeassistant.const import ( from homeassistant.const import (
EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP) EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP,
CONF_PLATFORM, CONF_SCAN_INTERVAL, CONF_VALUE_TEMPLATE)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -41,6 +41,11 @@ CONF_PASSWORD = 'password'
CONF_CERTIFICATE = 'certificate' CONF_CERTIFICATE = 'certificate'
CONF_PROTOCOL = 'protocol' CONF_PROTOCOL = 'protocol'
CONF_STATE_TOPIC = 'state_topic'
CONF_COMMAND_TOPIC = 'command_topic'
CONF_QOS = 'qos'
CONF_RETAIN = 'retain'
PROTOCOL_31 = '3.1' PROTOCOL_31 = '3.1'
PROTOCOL_311 = '3.1.1' PROTOCOL_311 = '3.1.1'
@ -53,25 +58,71 @@ DEFAULT_PROTOCOL = PROTOCOL_311
ATTR_TOPIC = 'topic' ATTR_TOPIC = 'topic'
ATTR_PAYLOAD = 'payload' ATTR_PAYLOAD = 'payload'
ATTR_PAYLOAD_TEMPLATE = 'payload_template' ATTR_PAYLOAD_TEMPLATE = 'payload_template'
ATTR_QOS = 'qos' ATTR_QOS = CONF_QOS
ATTR_RETAIN = 'retain' ATTR_RETAIN = CONF_RETAIN
MAX_RECONNECT_WAIT = 300 # seconds MAX_RECONNECT_WAIT = 300 # seconds
# Service call validation schema def valid_subscribe_topic(value, invalid_chars='\0'):
def mqtt_topic(value): """Validate that we can subscribe using this MQTT topic."""
"""Validate that we can publish using this MQTT topic.""" if isinstance(value, str) and all(c not in value for c in invalid_chars):
if isinstance(value, str) and all(c not in value for c in '#+\0'):
return vol.Length(min=1, max=65535)(value) return vol.Length(min=1, max=65535)(value)
raise vol.Invalid('Invalid MQTT topic name') raise vol.Invalid('Invalid MQTT topic name')
def valid_publish_topic(value):
"""Validate that we can publish using this MQTT topic."""
return valid_subscribe_topic(value, invalid_chars='#+\0')
_VALID_QOS_SCHEMA = vol.All(vol.Coerce(int), vol.In([0, 1, 2]))
_HBMQTT_CONFIG_SCHEMA = vol.Schema(dict)
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Optional(CONF_CLIENT_ID): cv.string,
vol.Optional(CONF_KEEPALIVE, default=DEFAULT_KEEPALIVE):
vol.All(vol.Coerce(int), vol.Range(min=15)),
vol.Optional(CONF_BROKER): cv.string,
vol.Optional(CONF_PORT, default=DEFAULT_PORT):
vol.All(vol.Coerce(int), vol.Range(min=1, max=65535)),
vol.Optional(CONF_USERNAME): cv.string,
vol.Optional(CONF_PASSWORD): cv.string,
vol.Optional(CONF_CERTIFICATE): vol.IsFile,
vol.Optional(CONF_PROTOCOL, default=DEFAULT_PROTOCOL):
[PROTOCOL_31, PROTOCOL_311],
vol.Optional(CONF_EMBEDDED): _HBMQTT_CONFIG_SCHEMA,
}),
}, extra=vol.ALLOW_EXTRA)
MQTT_BASE_PLATFORM_SCHEMA = vol.Schema({
vol.Required(CONF_PLATFORM): DOMAIN,
vol.Optional(CONF_SCAN_INTERVAL):
vol.All(vol.Coerce(int), vol.Range(min=1)),
vol.Optional(CONF_QOS, default=DEFAULT_QOS): _VALID_QOS_SCHEMA,
})
# Sensor type platforms subscribe to mqtt events
MQTT_RO_PLATFORM_SCHEMA = MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Required(CONF_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
})
# Switch type platforms publish to mqtt and may subscribe
MQTT_RW_PLATFORM_SCHEMA = MQTT_BASE_PLATFORM_SCHEMA.extend({
vol.Required(CONF_COMMAND_TOPIC): valid_publish_topic,
vol.Optional(CONF_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
vol.Optional(CONF_STATE_TOPIC): valid_subscribe_topic,
vol.Optional(CONF_VALUE_TEMPLATE): cv.template,
})
# Service call validation schema
MQTT_PUBLISH_SCHEMA = vol.Schema({ MQTT_PUBLISH_SCHEMA = vol.Schema({
vol.Required(ATTR_TOPIC): mqtt_topic, vol.Required(ATTR_TOPIC): valid_publish_topic,
vol.Exclusive(ATTR_PAYLOAD, 'payload'): object, vol.Exclusive(ATTR_PAYLOAD, 'payload'): object,
vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, 'payload'): cv.string, vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, 'payload'): cv.string,
vol.Required(ATTR_QOS, default=DEFAULT_QOS): vol.Required(ATTR_QOS, default=DEFAULT_QOS): _VALID_QOS_SCHEMA,
vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
vol.Required(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean, vol.Required(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
}, required=True) }, required=True)
@ -136,8 +187,8 @@ def setup(hass, config):
# pylint: disable=too-many-locals # pylint: disable=too-many-locals
conf = config.get(DOMAIN, {}) conf = config.get(DOMAIN, {})
client_id = util.convert(conf.get(CONF_CLIENT_ID), str) client_id = conf.get(CONF_CLIENT_ID)
keepalive = util.convert(conf.get(CONF_KEEPALIVE), int, DEFAULT_KEEPALIVE) keepalive = conf.get(CONF_KEEPALIVE)
broker_config = _setup_server(hass, config) broker_config = _setup_server(hass, config)
@ -151,16 +202,11 @@ def setup(hass, config):
if CONF_BROKER in conf: if CONF_BROKER in conf:
broker = conf[CONF_BROKER] broker = conf[CONF_BROKER]
port = util.convert(conf.get(CONF_PORT), int, DEFAULT_PORT) port = conf[CONF_PORT]
username = util.convert(conf.get(CONF_USERNAME), str) username = conf.get(CONF_USERNAME)
password = util.convert(conf.get(CONF_PASSWORD), str) password = conf.get(CONF_PASSWORD)
certificate = util.convert(conf.get(CONF_CERTIFICATE), str) certificate = conf.get(CONF_CERTIFICATE)
protocol = util.convert(conf.get(CONF_PROTOCOL), str, DEFAULT_PROTOCOL) protocol = conf[CONF_PROTOCOL]
if protocol not in (PROTOCOL_31, PROTOCOL_311):
_LOGGER.error('Invalid protocol specified: %s. Allowed values: %s, %s',
protocol, PROTOCOL_31, PROTOCOL_311)
return False
# For cloudmqtt.com, secured connection, auto fill in certificate # For cloudmqtt.com, secured connection, auto fill in certificate
if certificate is None and 19999 < port < 30000 and \ if certificate is None and 19999 < port < 30000 and \

View File

@ -6,9 +6,11 @@ https://home-assistant.io/components/mqtt_eventstream/
""" """
import json import json
import voluptuous as vol
import homeassistant.loader as loader import homeassistant.loader as loader
from homeassistant.components.mqtt import DOMAIN as MQTT_DOMAIN from homeassistant.components.mqtt import (
from homeassistant.components.mqtt import SERVICE_PUBLISH as MQTT_SVC_PUBLISH valid_publish_topic, valid_subscribe_topic)
from homeassistant.const import ( from homeassistant.const import (
ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, EVENT_SERVICE_EXECUTED, ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, EVENT_SERVICE_EXECUTED,
EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL) EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL)
@ -18,12 +20,23 @@ from homeassistant.remote import JSONEncoder
DOMAIN = "mqtt_eventstream" DOMAIN = "mqtt_eventstream"
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_PUBLISH_TOPIC = 'publish_topic'
CONF_SUBSCRIBE_TOPIC = 'subscribe_topic'
CONFIG_SCHEMA = vol.Schema({
DOMAIN: vol.Schema({
vol.Optional(CONF_PUBLISH_TOPIC): valid_publish_topic,
vol.Optional(CONF_SUBSCRIBE_TOPIC): valid_subscribe_topic,
}),
}, extra=vol.ALLOW_EXTRA)
def setup(hass, config): def setup(hass, config):
"""Setup th MQTT eventstream component.""" """Setup the MQTT eventstream component."""
mqtt = loader.get_component('mqtt') mqtt = loader.get_component('mqtt')
pub_topic = config[DOMAIN].get('publish_topic', None) conf = config.get(DOMAIN, {})
sub_topic = config[DOMAIN].get('subscribe_topic', None) pub_topic = conf.get(CONF_PUBLISH_TOPIC)
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
def _event_publisher(event): def _event_publisher(event):
"""Handle events by publishing them on the MQTT queue.""" """Handle events by publishing them on the MQTT queue."""
@ -36,8 +49,8 @@ def setup(hass, config):
# to the MQTT topic, or you will end up in an infinite loop. # to the MQTT topic, or you will end up in an infinite loop.
if event.event_type == EVENT_CALL_SERVICE: if event.event_type == EVENT_CALL_SERVICE:
if ( if (
event.data.get('domain') == MQTT_DOMAIN and event.data.get('domain') == mqtt.DOMAIN and
event.data.get('service') == MQTT_SVC_PUBLISH and event.data.get('service') == mqtt.SERVICE_PUBLISH and
event.data[ATTR_SERVICE_DATA].get('topic') == pub_topic event.data[ATTR_SERVICE_DATA].get('topic') == pub_topic
): ):
return return

View File

@ -9,7 +9,8 @@ import logging
import homeassistant.bootstrap as bootstrap import homeassistant.bootstrap as bootstrap
from homeassistant.const import ( from homeassistant.const import (
ATTR_DISCOVERED, ATTR_SERVICE, EVENT_HOMEASSISTANT_START, ATTR_DISCOVERED, ATTR_SERVICE, EVENT_HOMEASSISTANT_START,
EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, TEMP_CELCIUS) EVENT_HOMEASSISTANT_STOP, EVENT_PLATFORM_DISCOVERED, TEMP_CELCIUS,
CONF_OPTIMISTIC)
from homeassistant.helpers import validate_config from homeassistant.helpers import validate_config
CONF_GATEWAYS = 'gateways' CONF_GATEWAYS = 'gateways'
@ -19,7 +20,6 @@ CONF_PERSISTENCE = 'persistence'
CONF_PERSISTENCE_FILE = 'persistence_file' CONF_PERSISTENCE_FILE = 'persistence_file'
CONF_VERSION = 'version' CONF_VERSION = 'version'
CONF_BAUD_RATE = 'baud_rate' CONF_BAUD_RATE = 'baud_rate'
CONF_OPTIMISTIC = 'optimistic'
DEFAULT_VERSION = '1.4' DEFAULT_VERSION = '1.4'
DEFAULT_BAUD_RATE = 115200 DEFAULT_BAUD_RATE = 115200

View File

@ -6,38 +6,50 @@ https://home-assistant.io/components/rollershutter.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.components.rollershutter import RollershutterDevice from homeassistant.components.rollershutter import RollershutterDevice
from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.const import CONF_NAME, CONF_VALUE_TEMPLATE
from homeassistant.components.mqtt import (
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS)
from homeassistant.helpers import template from homeassistant.helpers import template
import homeassistant.helpers.config_validation as cv
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_PAYLOAD_UP = 'payload_up'
CONF_PAYLOAD_DOWN = 'payload_down'
CONF_PAYLOAD_STOP = 'payload_stop'
DEFAULT_NAME = "MQTT Rollershutter" DEFAULT_NAME = "MQTT Rollershutter"
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_UP = "UP" DEFAULT_PAYLOAD_UP = "UP"
DEFAULT_PAYLOAD_DOWN = "DOWN" DEFAULT_PAYLOAD_DOWN = "DOWN"
DEFAULT_PAYLOAD_STOP = "STOP" DEFAULT_PAYLOAD_STOP = "STOP"
PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_UP, default=DEFAULT_PAYLOAD_UP): cv.string,
vol.Optional(CONF_PAYLOAD_DOWN, default=DEFAULT_PAYLOAD_DOWN): cv.string,
vol.Optional(CONF_PAYLOAD_STOP, default=DEFAULT_PAYLOAD_STOP): cv.string,
})
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Add MQTT Rollershutter.""" """Add MQTT Rollershutter."""
if config.get('command_topic') is None:
_LOGGER.error("Missing required variable: command_topic")
return False
add_devices_callback([MqttRollershutter( add_devices_callback([MqttRollershutter(
hass, hass,
config.get('name', DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic'), config.get(CONF_STATE_TOPIC),
config.get('command_topic'), config[CONF_COMMAND_TOPIC],
config.get('qos', DEFAULT_QOS), config[CONF_QOS],
config.get('payload_up', DEFAULT_PAYLOAD_UP), config[CONF_PAYLOAD_UP],
config.get('payload_down', DEFAULT_PAYLOAD_DOWN), config[CONF_PAYLOAD_DOWN],
config.get('payload_stop', DEFAULT_PAYLOAD_STOP), config[CONF_PAYLOAD_STOP],
config.get(CONF_VALUE_TEMPLATE))]) config.get(CONF_VALUE_TEMPLATE)
)])
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes

View File

@ -6,33 +6,40 @@ https://home-assistant.io/components/sensor.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.const import CONF_VALUE_TEMPLATE, STATE_UNKNOWN from homeassistant.const import CONF_NAME, CONF_VALUE_TEMPLATE, STATE_UNKNOWN
from homeassistant.components.mqtt import CONF_STATE_TOPIC, CONF_QOS
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity import Entity
from homeassistant.helpers import template from homeassistant.helpers import template
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "MQTT Sensor"
DEFAULT_QOS = 0
DEPENDENCIES = ['mqtt'] DEPENDENCIES = ['mqtt']
CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement'
DEFAULT_NAME = "MQTT Sensor"
PLATFORM_SCHEMA = mqtt.MQTT_RO_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string,
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup MQTT Sensor.""" """Setup MQTT Sensor."""
if config.get('state_topic') is None:
_LOGGER.error("Missing required variable: state_topic")
return False
add_devices_callback([MqttSensor( add_devices_callback([MqttSensor(
hass, hass,
config.get('name', DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic'), config[CONF_STATE_TOPIC],
config.get('qos', DEFAULT_QOS), config[CONF_QOS],
config.get('unit_of_measurement'), config.get(CONF_UNIT_OF_MEASUREMENT),
config.get(CONF_VALUE_TEMPLATE))]) config.get(CONF_VALUE_TEMPLATE),
)])
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes

View File

@ -6,41 +6,49 @@ https://home-assistant.io/components/switch.mqtt/
""" """
import logging import logging
import voluptuous as vol
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.components.switch import SwitchDevice from homeassistant.components.switch import SwitchDevice
from homeassistant.const import CONF_VALUE_TEMPLATE from homeassistant.const import CONF_NAME, CONF_OPTIMISTIC, CONF_VALUE_TEMPLATE
from homeassistant.components.mqtt import (
CONF_STATE_TOPIC, CONF_COMMAND_TOPIC, CONF_QOS, CONF_RETAIN)
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers import template from homeassistant.helpers import template
from homeassistant.util import convert
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
DEPENDENCIES = ['mqtt']
CONF_PAYLOAD_ON = 'payload_on'
CONF_PAYLOAD_OFF = 'payload_off'
DEFAULT_NAME = "MQTT Switch" DEFAULT_NAME = "MQTT Switch"
DEFAULT_QOS = 0
DEFAULT_PAYLOAD_ON = "ON" DEFAULT_PAYLOAD_ON = "ON"
DEFAULT_PAYLOAD_OFF = "OFF" DEFAULT_PAYLOAD_OFF = "OFF"
DEFAULT_OPTIMISTIC = False DEFAULT_OPTIMISTIC = False
DEFAULT_RETAIN = False
DEPENDENCIES = ['mqtt'] PLATFORM_SCHEMA = mqtt.MQTT_RW_PLATFORM_SCHEMA.extend({
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
vol.Optional(CONF_PAYLOAD_ON, default=DEFAULT_PAYLOAD_ON): cv.string,
vol.Optional(CONF_PAYLOAD_OFF, default=DEFAULT_PAYLOAD_OFF): cv.string,
vol.Optional(CONF_OPTIMISTIC, default=DEFAULT_OPTIMISTIC): cv.boolean,
})
# pylint: disable=unused-argument # pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None): def setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Add MQTT switch.""" """Add MQTT switch."""
if config.get('command_topic') is None:
_LOGGER.error("Missing required variable: command_topic")
return False
add_devices_callback([MqttSwitch( add_devices_callback([MqttSwitch(
hass, hass,
convert(config.get('name'), str, DEFAULT_NAME), config[CONF_NAME],
config.get('state_topic'), config.get(CONF_STATE_TOPIC),
config.get('command_topic'), config[CONF_COMMAND_TOPIC],
convert(config.get('qos'), int, DEFAULT_QOS), config[CONF_QOS],
convert(config.get('retain'), bool, DEFAULT_RETAIN), config[CONF_RETAIN],
convert(config.get('payload_on'), str, DEFAULT_PAYLOAD_ON), config[CONF_PAYLOAD_ON],
convert(config.get('payload_off'), str, DEFAULT_PAYLOAD_OFF), config[CONF_PAYLOAD_OFF],
convert(config.get('optimistic'), bool, DEFAULT_OPTIMISTIC), config[CONF_OPTIMISTIC],
config.get(CONF_VALUE_TEMPLATE))]) config.get(CONF_VALUE_TEMPLATE))])

View File

@ -29,6 +29,7 @@ CONF_PASSWORD = "password"
CONF_API_KEY = "api_key" CONF_API_KEY = "api_key"
CONF_ACCESS_TOKEN = "access_token" CONF_ACCESS_TOKEN = "access_token"
CONF_FILENAME = "filename" CONF_FILENAME = "filename"
CONF_OPTIMISTIC = 'optimistic'
CONF_SCAN_INTERVAL = "scan_interval" CONF_SCAN_INTERVAL = "scan_interval"
CONF_VALUE_TEMPLATE = "value_template" CONF_VALUE_TEMPLATE = "value_template"

View File

@ -4,6 +4,7 @@ from datetime import timedelta
from unittest import mock from unittest import mock
from homeassistant import core as ha, loader from homeassistant import core as ha, loader
from homeassistant.bootstrap import _setup_component
from homeassistant.helpers.entity import ToggleEntity from homeassistant.helpers.entity import ToggleEntity
from homeassistant.const import ( from homeassistant.const import (
STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, EVENT_TIME_CHANGED, STATE_ON, STATE_OFF, DEVICE_DEFAULT_NAME, EVENT_TIME_CHANGED,
@ -123,12 +124,11 @@ def mock_http_component(hass):
@mock.patch('homeassistant.components.mqtt.MQTT') @mock.patch('homeassistant.components.mqtt.MQTT')
def mock_mqtt_component(hass, mock_mqtt): def mock_mqtt_component(hass, mock_mqtt):
"""Mock the MQTT component.""" """Mock the MQTT component."""
mqtt.setup(hass, { _setup_component(hass, mqtt.DOMAIN, {
mqtt.DOMAIN: { mqtt.DOMAIN: {
mqtt.CONF_BROKER: 'mock-broker', mqtt.CONF_BROKER: 'mock-broker',
} }
}) })
hass.config.components.append(mqtt.DOMAIN)
return mock_mqtt return mock_mqtt

View File

@ -1,7 +1,7 @@
"""The tests the MQTT alarm control panel component.""" """The tests the MQTT alarm control panel component."""
import unittest import unittest
from unittest.mock import patch
from homeassistant.bootstrap import _setup_component
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY, STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY,
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN) STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN)
@ -25,37 +25,37 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
"""Stop down stuff we started.""" """Stop down stuff we started."""
self.hass.stop() self.hass.stop()
@patch('homeassistant.components.alarm_control_panel.mqtt._LOGGER.error') def test_fail_setup_without_state_topic(self):
def test_fail_setup_without_state_topic(self, mock_error):
"""Test for failing with no state topic.""" """Test for failing with no state topic."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'command_topic': 'alarm/command' 'command_topic': 'alarm/command'
}})) }
})
self.assertEqual(1, mock_error.call_count) def test_fail_setup_without_command_topic(self):
@patch('homeassistant.components.alarm_control_panel.mqtt._LOGGER.error')
def test_fail_setup_without_command_topic(self, mock_error):
"""Test failing with no command topic.""" """Test failing with no command topic."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'state_topic': 'alarm/state' 'state_topic': 'alarm/state'
}})) }
})
self.assertEqual(1, mock_error.call_count)
def test_update_state_via_state_topic(self): def test_update_state_via_state_topic(self):
"""Test updating with via state topic.""" """Test updating with via state topic."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
}})) }
})
entity_id = 'alarm_control_panel.test' entity_id = 'alarm_control_panel.test'
@ -71,13 +71,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_ignore_update_state_if_unknown_via_state_topic(self): def test_ignore_update_state_if_unknown_via_state_topic(self):
"""Test ignoring updates via state topic.""" """Test ignoring updates via state topic."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
}})) }
})
entity_id = 'alarm_control_panel.test' entity_id = 'alarm_control_panel.test'
@ -90,13 +92,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_home_publishes_mqtt(self): def test_arm_home_publishes_mqtt(self):
"""Test publishing of MQTT messages while armed.""" """Test publishing of MQTT messages while armed."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
}})) }
})
alarm_control_panel.alarm_arm_home(self.hass) alarm_control_panel.alarm_arm_home(self.hass)
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
@ -105,14 +109,16 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_home_not_publishes_mqtt_with_invalid_code(self): def test_arm_home_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
'code': '1234' 'code': '1234'
}})) }
})
call_count = self.mock_publish.call_count call_count = self.mock_publish.call_count
alarm_control_panel.alarm_arm_home(self.hass, 'abcd') alarm_control_panel.alarm_arm_home(self.hass, 'abcd')
@ -121,13 +127,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_away_publishes_mqtt(self): def test_arm_away_publishes_mqtt(self):
"""Test publishing of MQTT messages while armed.""" """Test publishing of MQTT messages while armed."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
}})) }
})
alarm_control_panel.alarm_arm_away(self.hass) alarm_control_panel.alarm_arm_away(self.hass)
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
@ -136,14 +144,16 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_arm_away_not_publishes_mqtt_with_invalid_code(self): def test_arm_away_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
'code': '1234' 'code': '1234'
}})) }
})
call_count = self.mock_publish.call_count call_count = self.mock_publish.call_count
alarm_control_panel.alarm_arm_away(self.hass, 'abcd') alarm_control_panel.alarm_arm_away(self.hass, 'abcd')
@ -152,13 +162,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_disarm_publishes_mqtt(self): def test_disarm_publishes_mqtt(self):
"""Test publishing of MQTT messages while disarmed.""" """Test publishing of MQTT messages while disarmed."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
}})) }
})
alarm_control_panel.alarm_disarm(self.hass) alarm_control_panel.alarm_disarm(self.hass)
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
@ -167,14 +179,16 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
def test_disarm_not_publishes_mqtt_with_invalid_code(self): def test_disarm_not_publishes_mqtt_with_invalid_code(self):
"""Test not publishing of MQTT messages with invalid code.""" """Test not publishing of MQTT messages with invalid code."""
self.assertTrue(alarm_control_panel.setup(self.hass, { self.hass.config.components = ['mqtt']
'alarm_control_panel': { assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
alarm_control_panel.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'alarm/state', 'state_topic': 'alarm/state',
'command_topic': 'alarm/command', 'command_topic': 'alarm/command',
'code': '1234' 'code': '1234'
}})) }
})
call_count = self.mock_publish.call_count call_count = self.mock_publish.call_count
alarm_control_panel.alarm_disarm(self.hass, 'abcd') alarm_control_panel.alarm_disarm(self.hass, 'abcd')

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT binary sensor platform.""" """The tests for the MQTT binary sensor platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component
import homeassistant.components.binary_sensor as binary_sensor import homeassistant.components.binary_sensor as binary_sensor
from tests.common import mock_mqtt_component, fire_mqtt_message from tests.common import mock_mqtt_component, fire_mqtt_message
from homeassistant.const import (STATE_OFF, STATE_ON) from homeassistant.const import (STATE_OFF, STATE_ON)
@ -22,15 +23,16 @@ class TestSensorMQTT(unittest.TestCase):
def test_setting_sensor_value_via_mqtt_message(self): def test_setting_sensor_value_via_mqtt_message(self):
"""Test the setting of the value via MQTT.""" """Test the setting of the value via MQTT."""
self.assertTrue(binary_sensor.setup(self.hass, { self.hass.config.components = ['mqtt']
'binary_sensor': { assert _setup_component(self.hass, binary_sensor.DOMAIN, {
binary_sensor.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test-topic', 'state_topic': 'test-topic',
'payload_on': 'ON', 'payload_on': 'ON',
'payload_off': 'OFF', 'payload_off': 'OFF',
} }
})) })
state = self.hass.states.get('binary_sensor.test') state = self.hass.states.get('binary_sensor.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -47,28 +49,30 @@ class TestSensorMQTT(unittest.TestCase):
def test_valid_sensor_class(self): def test_valid_sensor_class(self):
"""Test the setting of a valid sensor class.""" """Test the setting of a valid sensor class."""
self.assertTrue(binary_sensor.setup(self.hass, { self.hass.config.components = ['mqtt']
'binary_sensor': { assert _setup_component(self.hass, binary_sensor.DOMAIN, {
binary_sensor.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'sensor_class': 'motion', 'sensor_class': 'motion',
'state_topic': 'test-topic', 'state_topic': 'test-topic',
} }
})) })
state = self.hass.states.get('binary_sensor.test') state = self.hass.states.get('binary_sensor.test')
self.assertEqual('motion', state.attributes.get('sensor_class')) self.assertEqual('motion', state.attributes.get('sensor_class'))
def test_invalid_sensor_class(self): def test_invalid_sensor_class(self):
"""Test the setting of an invalid sensor class.""" """Test the setting of an invalid sensor class."""
self.assertTrue(binary_sensor.setup(self.hass, { self.hass.config.components = ['mqtt']
'binary_sensor': { assert _setup_component(self.hass, binary_sensor.DOMAIN, {
binary_sensor.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'sensor_class': 'abc123', 'sensor_class': 'abc123',
'state_topic': 'test-topic', 'state_topic': 'test-topic',
} }
})) })
state = self.hass.states.get('binary_sensor.test') state = self.hass.states.get('binary_sensor.test')
self.assertIsNone(state.attributes.get('sensor_class')) self.assertIsNone(state.attributes.get('sensor_class'))

View File

@ -2,6 +2,7 @@
import unittest import unittest
import os import os
from homeassistant.bootstrap import _setup_component
from homeassistant.components import device_tracker from homeassistant.components import device_tracker
from homeassistant.const import CONF_PLATFORM from homeassistant.const import CONF_PLATFORM
@ -31,11 +32,13 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
topic = '/location/paulus' topic = '/location/paulus'
location = 'work' location = 'work'
self.assertTrue(device_tracker.setup(self.hass, { self.hass.config.components = ['mqtt', 'zone']
assert _setup_component(self.hass, device_tracker.DOMAIN, {
device_tracker.DOMAIN: { device_tracker.DOMAIN: {
CONF_PLATFORM: 'mqtt', CONF_PLATFORM: 'mqtt',
'devices': {dev_id: topic} 'devices': {dev_id: topic}
}})) }
})
fire_mqtt_message(self.hass, topic, location) fire_mqtt_message(self.hass, topic, location)
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
self.assertEqual(location, self.hass.states.get(enttiy_id).state) self.assertEqual(location, self.hass.states.get(enttiy_id).state)

View File

@ -58,6 +58,7 @@ light:
""" """
import unittest import unittest
from homeassistant.bootstrap import _setup_component
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
import homeassistant.components.light as light import homeassistant.components.light as light
from tests.common import ( from tests.common import (
@ -78,24 +79,26 @@ class TestLightMQTT(unittest.TestCase):
def test_fail_setup_if_no_command_topic(self): def test_fail_setup_if_no_command_topic(self):
"""Test if command fails with command topic.""" """Test if command fails with command topic."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert not _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
} }
})) })
self.assertIsNone(self.hass.states.get('light.test')) self.assertIsNone(self.hass.states.get('light.test'))
def test_no_color_or_brightness_if_no_topics(self): def test_no_color_or_brightness_if_no_topics(self):
"""Test if there is no color and brightness if no topic.""" """Test if there is no color and brightness if no topic."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test_light_rgb/status', 'state_topic': 'test_light_rgb/status',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -112,8 +115,9 @@ class TestLightMQTT(unittest.TestCase):
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self):
"""Test the controlling of the state via topic.""" """Test the controlling of the state via topic."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test_light_rgb/status', 'state_topic': 'test_light_rgb/status',
@ -126,7 +130,7 @@ class TestLightMQTT(unittest.TestCase):
'payload_on': 1, 'payload_on': 1,
'payload_off': 0 'payload_off': 0
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -172,8 +176,9 @@ class TestLightMQTT(unittest.TestCase):
def test_controlling_scale(self): def test_controlling_scale(self):
"""Test the controlling scale.""" """Test the controlling scale."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test_scale/status', 'state_topic': 'test_scale/status',
@ -185,7 +190,7 @@ class TestLightMQTT(unittest.TestCase):
'payload_on': 'on', 'payload_on': 'on',
'payload_off': 'off' 'payload_off': 'off'
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -218,8 +223,9 @@ class TestLightMQTT(unittest.TestCase):
def test_controlling_state_via_topic_with_templates(self): def test_controlling_state_via_topic_with_templates(self):
"""Test the setting og the state with a template.""" """Test the setting og the state with a template."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test_light_rgb/status', 'state_topic': 'test_light_rgb/status',
@ -230,7 +236,7 @@ class TestLightMQTT(unittest.TestCase):
'brightness_value_template': '{{ value_json.hello }}', 'brightness_value_template': '{{ value_json.hello }}',
'rgb_value_template': '{{ value_json.hello | join(",") }}', 'rgb_value_template': '{{ value_json.hello | join(",") }}',
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -252,8 +258,9 @@ class TestLightMQTT(unittest.TestCase):
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self):
"""Test the sending of command in optimistic mode.""" """Test the sending of command in optimistic mode."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
@ -263,7 +270,7 @@ class TestLightMQTT(unittest.TestCase):
'payload_on': 'on', 'payload_on': 'on',
'payload_off': 'off' 'payload_off': 'off'
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -310,15 +317,16 @@ class TestLightMQTT(unittest.TestCase):
def test_show_brightness_if_only_command_topic(self): def test_show_brightness_if_only_command_topic(self):
"""Test the brightness if only a command topic is present.""" """Test the brightness if only a command topic is present."""
self.assertTrue(light.setup(self.hass, { self.hass.config.components = ['mqtt']
'light': { assert _setup_component(self.hass, light.DOMAIN, {
light.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'brightness_command_topic': 'test_light_rgb/brightness/set', 'brightness_command_topic': 'test_light_rgb/brightness/set',
'command_topic': 'test_light_rgb/set', 'command_topic': 'test_light_rgb/set',
'state_topic': 'test_light_rgb/status', 'state_topic': 'test_light_rgb/status',
} }
})) })
state = self.hass.states.get('light.test') state = self.hass.states.get('light.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT lock platform.""" """The tests for the MQTT lock platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component
from homeassistant.const import (STATE_LOCKED, STATE_UNLOCKED, from homeassistant.const import (STATE_LOCKED, STATE_UNLOCKED,
ATTR_ASSUMED_STATE) ATTR_ASSUMED_STATE)
import homeassistant.components.lock as lock import homeassistant.components.lock as lock
@ -22,8 +23,9 @@ class TestLockMQTT(unittest.TestCase):
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self):
"""Test the controlling state via topic.""" """Test the controlling state via topic."""
self.assertTrue(lock.setup(self.hass, { self.hass.config.components = ['mqtt']
'lock': { assert _setup_component(self.hass, lock.DOMAIN, {
lock.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -31,7 +33,7 @@ class TestLockMQTT(unittest.TestCase):
'payload_lock': 'LOCK', 'payload_lock': 'LOCK',
'payload_unlock': 'UNLOCK' 'payload_unlock': 'UNLOCK'
} }
})) })
state = self.hass.states.get('lock.test') state = self.hass.states.get('lock.test')
self.assertEqual(STATE_UNLOCKED, state.state) self.assertEqual(STATE_UNLOCKED, state.state)
@ -51,8 +53,9 @@ class TestLockMQTT(unittest.TestCase):
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self):
"""Test the sending MQTT commands in optimistic mode.""" """Test the sending MQTT commands in optimistic mode."""
self.assertTrue(lock.setup(self.hass, { self.hass.config.components = ['mqtt']
'lock': { assert _setup_component(self.hass, lock.DOMAIN, {
lock.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'command_topic': 'command-topic', 'command_topic': 'command-topic',
@ -60,7 +63,7 @@ class TestLockMQTT(unittest.TestCase):
'payload_unlock': 'UNLOCK', 'payload_unlock': 'UNLOCK',
'qos': 2 'qos': 2
} }
})) })
state = self.hass.states.get('lock.test') state = self.hass.states.get('lock.test')
self.assertEqual(STATE_UNLOCKED, state.state) self.assertEqual(STATE_UNLOCKED, state.state)
@ -84,8 +87,9 @@ class TestLockMQTT(unittest.TestCase):
def test_controlling_state_via_topic_and_json_message(self): def test_controlling_state_via_topic_and_json_message(self):
"""Test the controlling state via topic and JSON message.""" """Test the controlling state via topic and JSON message."""
self.assertTrue(lock.setup(self.hass, { self.hass.config.components = ['mqtt']
'lock': { assert _setup_component(self.hass, lock.DOMAIN, {
lock.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -94,7 +98,7 @@ class TestLockMQTT(unittest.TestCase):
'payload_unlock': 'UNLOCK', 'payload_unlock': 'UNLOCK',
'value_template': '{{ value_json.val }}' 'value_template': '{{ value_json.val }}'
} }
})) })
state = self.hass.states.get('lock.test') state = self.hass.states.get('lock.test')
self.assertEqual(STATE_UNLOCKED, state.state) self.assertEqual(STATE_UNLOCKED, state.state)

View File

@ -4,6 +4,7 @@ import unittest
from unittest import mock from unittest import mock
import socket import socket
from homeassistant.bootstrap import _setup_component
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from homeassistant.const import ( from homeassistant.const import (
EVENT_CALL_SERVICE, ATTR_DOMAIN, ATTR_SERVICE, EVENT_HOMEASSISTANT_START, EVENT_CALL_SERVICE, ATTR_DOMAIN, ATTR_SERVICE, EVENT_HOMEASSISTANT_START,
@ -48,9 +49,12 @@ class TestMQTT(unittest.TestCase):
"""Test for setup failure if connection to broker is missing.""" """Test for setup failure if connection to broker is missing."""
with mock.patch('homeassistant.components.mqtt.MQTT', with mock.patch('homeassistant.components.mqtt.MQTT',
side_effect=socket.error()): side_effect=socket.error()):
self.assertFalse(mqtt.setup(self.hass, {mqtt.DOMAIN: { self.hass.config.components = []
mqtt.CONF_BROKER: 'test-broker', assert not _setup_component(self.hass, mqtt.DOMAIN, {
}})) mqtt.DOMAIN: {
mqtt.CONF_BROKER: 'test-broker',
}
})
def test_publish_calls_service(self): def test_publish_calls_service(self):
"""Test the publishing of call to services.""" """Test the publishing of call to services."""
@ -211,12 +215,12 @@ class TestMQTTCallbacks(unittest.TestCase):
# mock_mqtt_component(self.hass) # mock_mqtt_component(self.hass)
with mock.patch('paho.mqtt.client.Client'): with mock.patch('paho.mqtt.client.Client'):
mqtt.setup(self.hass, { self.hass.config.components = []
assert _setup_component(self.hass, mqtt.DOMAIN, {
mqtt.DOMAIN: { mqtt.DOMAIN: {
mqtt.CONF_BROKER: 'mock-broker', mqtt.CONF_BROKER: 'mock-broker',
} }
}) })
self.hass.config.components.append(mqtt.DOMAIN)
def tearDown(self): # pylint: disable=invalid-name def tearDown(self): # pylint: disable=invalid-name
"""Stop everything that was started.""" """Stop everything that was started."""

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT component embedded server.""" """The tests for the MQTT component embedded server."""
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
from homeassistant.bootstrap import _setup_component
import homeassistant.components.mqtt as mqtt import homeassistant.components.mqtt as mqtt
from tests.common import get_test_home_assistant from tests.common import get_test_home_assistant
@ -27,15 +28,16 @@ class TestMQTT:
password = 'super_secret' password = 'super_secret'
self.hass.config.api = MagicMock(api_password=password) self.hass.config.api = MagicMock(api_password=password)
assert mqtt.setup(self.hass, {}) assert _setup_component(self.hass, mqtt.DOMAIN, {})
assert mock_mqtt.called assert mock_mqtt.called
assert mock_mqtt.mock_calls[0][1][5] == 'homeassistant' assert mock_mqtt.mock_calls[0][1][5] == 'homeassistant'
assert mock_mqtt.mock_calls[0][1][6] == password assert mock_mqtt.mock_calls[0][1][6] == password
mock_mqtt.reset_mock() mock_mqtt.reset_mock()
self.hass.config.components = ['http']
self.hass.config.api = MagicMock(api_password=None) self.hass.config.api = MagicMock(api_password=None)
assert mqtt.setup(self.hass, {}) assert _setup_component(self.hass, mqtt.DOMAIN, {})
assert mock_mqtt.called assert mock_mqtt.called
assert mock_mqtt.mock_calls[0][1][5] is None assert mock_mqtt.mock_calls[0][1][5] is None
assert mock_mqtt.mock_calls[0][1][6] is None assert mock_mqtt.mock_calls[0][1][6] is None
@ -50,6 +52,6 @@ class TestMQTT:
mock_gather.side_effect = BrokerException mock_gather.side_effect = BrokerException
self.hass.config.api = MagicMock(api_password=None) self.hass.config.api = MagicMock(api_password=None)
assert not mqtt.setup(self.hass, { assert not _setup_component(self.hass, mqtt.DOMAIN, {
'mqtt': {'embedded': {}} mqtt.DOMAIN: {mqtt.CONF_EMBEDDED: {}}
}) })

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT roller shutter platform.""" """The tests for the MQTT roller shutter platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component
from homeassistant.const import STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN from homeassistant.const import STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN
import homeassistant.components.rollershutter as rollershutter import homeassistant.components.rollershutter as rollershutter
from tests.common import mock_mqtt_component, fire_mqtt_message from tests.common import mock_mqtt_component, fire_mqtt_message
@ -22,8 +23,9 @@ class TestRollershutterMQTT(unittest.TestCase):
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self):
"""Test the controlling state via topic.""" """Test the controlling state via topic."""
self.assertTrue(rollershutter.setup(self.hass, { self.hass.config.components = ['mqtt']
'rollershutter': { assert _setup_component(self.hass, rollershutter.DOMAIN, {
rollershutter.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -33,7 +35,7 @@ class TestRollershutterMQTT(unittest.TestCase):
'payload_down': 'DOWN', 'payload_down': 'DOWN',
'payload_stop': 'STOP' 'payload_stop': 'STOP'
} }
})) })
state = self.hass.states.get('rollershutter.test') state = self.hass.states.get('rollershutter.test')
self.assertEqual(STATE_UNKNOWN, state.state) self.assertEqual(STATE_UNKNOWN, state.state)
@ -58,15 +60,16 @@ class TestRollershutterMQTT(unittest.TestCase):
def test_send_move_up_command(self): def test_send_move_up_command(self):
"""Test the sending of move_up.""" """Test the sending of move_up."""
self.assertTrue(rollershutter.setup(self.hass, { self.hass.config.components = ['mqtt']
'rollershutter': { assert _setup_component(self.hass, rollershutter.DOMAIN, {
rollershutter.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
'command_topic': 'command-topic', 'command_topic': 'command-topic',
'qos': 2 'qos': 2
} }
})) })
state = self.hass.states.get('rollershutter.test') state = self.hass.states.get('rollershutter.test')
self.assertEqual(STATE_UNKNOWN, state.state) self.assertEqual(STATE_UNKNOWN, state.state)
@ -81,15 +84,16 @@ class TestRollershutterMQTT(unittest.TestCase):
def test_send_move_down_command(self): def test_send_move_down_command(self):
"""Test the sending of move_down.""" """Test the sending of move_down."""
self.assertTrue(rollershutter.setup(self.hass, { self.hass.config.components = ['mqtt']
'rollershutter': { assert _setup_component(self.hass, rollershutter.DOMAIN, {
rollershutter.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
'command_topic': 'command-topic', 'command_topic': 'command-topic',
'qos': 2 'qos': 2
} }
})) })
state = self.hass.states.get('rollershutter.test') state = self.hass.states.get('rollershutter.test')
self.assertEqual(STATE_UNKNOWN, state.state) self.assertEqual(STATE_UNKNOWN, state.state)
@ -104,15 +108,16 @@ class TestRollershutterMQTT(unittest.TestCase):
def test_send_stop_command(self): def test_send_stop_command(self):
"""Test the sending of stop.""" """Test the sending of stop."""
self.assertTrue(rollershutter.setup(self.hass, { self.hass.config.components = ['mqtt']
'rollershutter': { assert _setup_component(self.hass, rollershutter.DOMAIN, {
rollershutter.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
'command_topic': 'command-topic', 'command_topic': 'command-topic',
'qos': 2 'qos': 2
} }
})) })
state = self.hass.states.get('rollershutter.test') state = self.hass.states.get('rollershutter.test')
self.assertEqual(STATE_UNKNOWN, state.state) self.assertEqual(STATE_UNKNOWN, state.state)
@ -127,8 +132,9 @@ class TestRollershutterMQTT(unittest.TestCase):
def test_state_attributes_current_position(self): def test_state_attributes_current_position(self):
"""Test the current position.""" """Test the current position."""
self.assertTrue(rollershutter.setup(self.hass, { self.hass.config.components = ['mqtt']
'rollershutter': { assert _setup_component(self.hass, rollershutter.DOMAIN, {
rollershutter.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -137,7 +143,7 @@ class TestRollershutterMQTT(unittest.TestCase):
'payload_down': 'DOWN', 'payload_down': 'DOWN',
'payload_stop': 'STOP' 'payload_stop': 'STOP'
} }
})) })
state_attributes_dict = self.hass.states.get( state_attributes_dict = self.hass.states.get(
'rollershutter.test').attributes 'rollershutter.test').attributes

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT sensor platform.""" """The tests for the MQTT sensor platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component
import homeassistant.components.sensor as sensor import homeassistant.components.sensor as sensor
from tests.common import mock_mqtt_component, fire_mqtt_message from tests.common import mock_mqtt_component, fire_mqtt_message
@ -21,14 +22,15 @@ class TestSensorMQTT(unittest.TestCase):
def test_setting_sensor_value_via_mqtt_message(self): def test_setting_sensor_value_via_mqtt_message(self):
"""Test the setting of the value via MQTT.""" """Test the setting of the value via MQTT."""
self.assertTrue(sensor.setup(self.hass, { self.hass.config.components = ['mqtt']
'sensor': { assert _setup_component(self.hass, sensor.DOMAIN, {
sensor.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test-topic', 'state_topic': 'test-topic',
'unit_of_measurement': 'fav unit' 'unit_of_measurement': 'fav unit'
} }
})) })
fire_mqtt_message(self.hass, 'test-topic', '100') fire_mqtt_message(self.hass, 'test-topic', '100')
self.hass.pool.block_till_done() self.hass.pool.block_till_done()
@ -40,15 +42,16 @@ class TestSensorMQTT(unittest.TestCase):
def test_setting_sensor_value_via_mqtt_json_message(self): def test_setting_sensor_value_via_mqtt_json_message(self):
"""Test the setting of the value via MQTT with JSON playload.""" """Test the setting of the value via MQTT with JSON playload."""
self.assertTrue(sensor.setup(self.hass, { self.hass.config.components = ['mqtt']
'sensor': { assert _setup_component(self.hass, sensor.DOMAIN, {
sensor.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'test-topic', 'state_topic': 'test-topic',
'unit_of_measurement': 'fav unit', 'unit_of_measurement': 'fav unit',
'value_template': '{{ value_json.val }}' 'value_template': '{{ value_json.val }}'
} }
})) })
fire_mqtt_message(self.hass, 'test-topic', '{ "val": "100" }') fire_mqtt_message(self.hass, 'test-topic', '{ "val": "100" }')
self.hass.pool.block_till_done() self.hass.pool.block_till_done()

View File

@ -1,6 +1,7 @@
"""The tests for the MQTT switch platform.""" """The tests for the MQTT switch platform."""
import unittest import unittest
from homeassistant.bootstrap import _setup_component
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
import homeassistant.components.switch as switch import homeassistant.components.switch as switch
from tests.common import ( from tests.common import (
@ -21,8 +22,9 @@ class TestSensorMQTT(unittest.TestCase):
def test_controlling_state_via_topic(self): def test_controlling_state_via_topic(self):
"""Test the controlling state via topic.""" """Test the controlling state via topic."""
self.assertTrue(switch.setup(self.hass, { self.hass.config.components = ['mqtt']
'switch': { assert _setup_component(self.hass, switch.DOMAIN, {
switch.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -30,7 +32,7 @@ class TestSensorMQTT(unittest.TestCase):
'payload_on': 1, 'payload_on': 1,
'payload_off': 0 'payload_off': 0
} }
})) })
state = self.hass.states.get('switch.test') state = self.hass.states.get('switch.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -50,8 +52,9 @@ class TestSensorMQTT(unittest.TestCase):
def test_sending_mqtt_commands_and_optimistic(self): def test_sending_mqtt_commands_and_optimistic(self):
"""Test the sending MQTT commands in optimistic mode.""" """Test the sending MQTT commands in optimistic mode."""
self.assertTrue(switch.setup(self.hass, { self.hass.config.components = ['mqtt']
'switch': { assert _setup_component(self.hass, switch.DOMAIN, {
switch.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'command_topic': 'command-topic', 'command_topic': 'command-topic',
@ -59,7 +62,7 @@ class TestSensorMQTT(unittest.TestCase):
'payload_off': 'beer off', 'payload_off': 'beer off',
'qos': '2' 'qos': '2'
} }
})) })
state = self.hass.states.get('switch.test') state = self.hass.states.get('switch.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)
@ -83,8 +86,9 @@ class TestSensorMQTT(unittest.TestCase):
def test_controlling_state_via_topic_and_json_message(self): def test_controlling_state_via_topic_and_json_message(self):
"""Test the controlling state via topic and JSON message.""" """Test the controlling state via topic and JSON message."""
self.assertTrue(switch.setup(self.hass, { self.hass.config.components = ['mqtt']
'switch': { assert _setup_component(self.hass, switch.DOMAIN, {
switch.DOMAIN: {
'platform': 'mqtt', 'platform': 'mqtt',
'name': 'test', 'name': 'test',
'state_topic': 'state-topic', 'state_topic': 'state-topic',
@ -93,7 +97,7 @@ class TestSensorMQTT(unittest.TestCase):
'payload_off': 'beer off', 'payload_off': 'beer off',
'value_template': '{{ value_json.val }}' 'value_template': '{{ value_json.val }}'
} }
})) })
state = self.hass.states.get('switch.test') state = self.hass.states.get('switch.test')
self.assertEqual(STATE_OFF, state.state) self.assertEqual(STATE_OFF, state.state)