Merge pull request #1703 from jaharkes/config-validation-mqtt
Config validation for MQTT
This commit is contained in:
commit
5ff9479f0b
25 changed files with 512 additions and 299 deletions
|
@ -12,6 +12,7 @@ from homeassistant.const import (
|
|||
ATTR_CODE, ATTR_CODE_FORMAT, ATTR_ENTITY_ID, SERVICE_ALARM_TRIGGER,
|
||||
SERVICE_ALARM_DISARM, SERVICE_ALARM_ARM_HOME, SERVICE_ALARM_ARM_AWAY)
|
||||
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_component import EntityComponent
|
||||
|
||||
|
|
|
@ -6,43 +6,55 @@ https://home-assistant.io/components/alarm_control_panel.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.alarm_control_panel as alarm
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.const import (
|
||||
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__)
|
||||
|
||||
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']
|
||||
|
||||
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):
|
||||
"""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(
|
||||
hass,
|
||||
config.get('name', DEFAULT_NAME),
|
||||
config.get('state_topic'),
|
||||
config.get('command_topic'),
|
||||
config.get('qos', DEFAULT_QOS),
|
||||
config.get('payload_disarm', DEFAULT_PAYLOAD_DISARM),
|
||||
config.get('payload_arm_home', DEFAULT_PAYLOAD_ARM_HOME),
|
||||
config.get('payload_arm_away', DEFAULT_PAYLOAD_ARM_AWAY),
|
||||
config.get('code'))])
|
||||
config[CONF_NAME],
|
||||
config[CONF_STATE_TOPIC],
|
||||
config[CONF_COMMAND_TOPIC],
|
||||
config[CONF_QOS],
|
||||
config[CONF_PAYLOAD_DISARM],
|
||||
config[CONF_PAYLOAD_ARM_HOME],
|
||||
config[CONF_PAYLOAD_ARM_AWAY],
|
||||
config.get(CONF_CODE))])
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||
|
@ -62,7 +74,7 @@ class MqttAlarm(alarm.AlarmControlPanel):
|
|||
self._payload_disarm = payload_disarm
|
||||
self._payload_arm_home = payload_arm_home
|
||||
self._payload_arm_away = payload_arm_away
|
||||
self._code = str(code) if code else None
|
||||
self._code = code
|
||||
|
||||
def message_received(topic, payload, qos):
|
||||
"""A new MQTT message has been received."""
|
||||
|
|
|
@ -4,26 +4,29 @@ Offer MQTT listening automation rules.
|
|||
For more details about this automation rule, please refer to the documentation
|
||||
at https://home-assistant.io/components/automation/#mqtt-trigger
|
||||
"""
|
||||
import logging
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
CONF_TOPIC = 'topic'
|
||||
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):
|
||||
"""Listen for state changes based on configuration."""
|
||||
topic = config.get(CONF_TOPIC)
|
||||
topic = config[CONF_TOPIC]
|
||||
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):
|
||||
"""Listen for MQTT messages."""
|
||||
if payload is None or payload == msg_payload:
|
||||
|
|
|
@ -6,43 +6,50 @@ https://home-assistant.io/components/binary_sensor.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.binary_sensor import (BinarySensorDevice,
|
||||
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
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_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_QOS = 0
|
||||
DEFAULT_PAYLOAD_ON = 'ON'
|
||||
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
|
||||
def setup_platform(hass, config, add_devices, discovery_info=None):
|
||||
"""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(
|
||||
hass,
|
||||
config.get('name', DEFAULT_NAME),
|
||||
config.get('state_topic', None),
|
||||
sensor_class,
|
||||
config.get('qos', DEFAULT_QOS),
|
||||
config.get('payload_on', DEFAULT_PAYLOAD_ON),
|
||||
config.get('payload_off', DEFAULT_PAYLOAD_OFF),
|
||||
config.get(CONF_VALUE_TEMPLATE))])
|
||||
config[CONF_NAME],
|
||||
config[CONF_STATE_TOPIC],
|
||||
config[CONF_SENSOR_CLASS],
|
||||
config[CONF_QOS],
|
||||
config[CONF_PAYLOAD_ON],
|
||||
config[CONF_PAYLOAD_OFF],
|
||||
config.get(CONF_VALUE_TEMPLATE)
|
||||
)])
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||
|
|
|
@ -6,28 +6,27 @@ https://home-assistant.io/components/device_tracker.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
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']
|
||||
|
||||
CONF_QOS = 'qos'
|
||||
CONF_DEVICES = 'devices'
|
||||
|
||||
DEFAULT_QOS = 0
|
||||
|
||||
_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):
|
||||
"""Setup the MQTT tracker."""
|
||||
devices = config.get(CONF_DEVICES)
|
||||
qos = util.convert(config.get(CONF_QOS), int, DEFAULT_QOS)
|
||||
|
||||
if not isinstance(devices, dict):
|
||||
_LOGGER.error('Expected %s to be a dict, found %s', CONF_DEVICES,
|
||||
devices)
|
||||
return False
|
||||
devices = config[CONF_DEVICES]
|
||||
qos = config[CONF_QOS]
|
||||
|
||||
dev_id_lookup = {}
|
||||
|
||||
|
|
|
@ -7,46 +7,85 @@ https://home-assistant.io/components/light.mqtt/
|
|||
import logging
|
||||
from functools import partial
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.components.light import (
|
||||
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.util import convert
|
||||
|
||||
_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_QOS = 0
|
||||
DEFAULT_PAYLOAD_ON = 'ON'
|
||||
DEFAULT_PAYLOAD_OFF = 'OFF'
|
||||
DEFAULT_OPTIMISTIC = False
|
||||
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):
|
||||
"""Add MQTT Light."""
|
||||
if config.get('command_topic') is None:
|
||||
_LOGGER.error("Missing required variable: command_topic")
|
||||
return False
|
||||
|
||||
config.setdefault(CONF_STATE_VALUE_TEMPLATE,
|
||||
config.get(CONF_VALUE_TEMPLATE))
|
||||
add_devices_callback([MqttLight(
|
||||
hass,
|
||||
convert(config.get('name'), str, DEFAULT_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),
|
||||
config[CONF_NAME],
|
||||
{
|
||||
'on': convert(config.get('payload_on'), str, DEFAULT_PAYLOAD_ON),
|
||||
'off': convert(config.get('payload_off'), str, DEFAULT_PAYLOAD_OFF)
|
||||
key: config.get(key) for key in (
|
||||
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."""
|
||||
|
||||
# pylint: disable=too-many-arguments,too-many-instance-attributes
|
||||
def __init__(self, hass, name, topic, templates, qos, payload, optimistic,
|
||||
brightness_scale):
|
||||
def __init__(self, hass, name, topic, templates, qos, retain, payload,
|
||||
optimistic, brightness_scale):
|
||||
"""Initialize MQTT light."""
|
||||
self._hass = hass
|
||||
self._name = name
|
||||
self._topic = topic
|
||||
self._qos = qos
|
||||
self._retain = retain
|
||||
self._payload = payload
|
||||
self._optimistic = optimistic or topic["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:
|
||||
|
||||
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:
|
||||
self._rgb = kwargs[ATTR_RGB_COLOR]
|
||||
|
@ -167,14 +208,14 @@ class MqttLight(Light):
|
|||
percent_bright = float(kwargs[ATTR_BRIGHTNESS]) / 255
|
||||
device_brightness = int(percent_bright * self._brightness_scale)
|
||||
mqtt.publish(self._hass, self._topic["brightness_command_topic"],
|
||||
device_brightness, self._qos)
|
||||
device_brightness, self._qos, self._retain)
|
||||
|
||||
if self._optimistic_brightness:
|
||||
self._brightness = kwargs[ATTR_BRIGHTNESS]
|
||||
should_update = True
|
||||
|
||||
mqtt.publish(self._hass, self._topic["command_topic"],
|
||||
self._payload["on"], self._qos)
|
||||
self._payload["on"], self._qos, self._retain)
|
||||
|
||||
if self._optimistic:
|
||||
# Optimistically assume that switch has changed state.
|
||||
|
@ -187,7 +228,7 @@ class MqttLight(Light):
|
|||
def turn_off(self, **kwargs):
|
||||
"""Turn the device off."""
|
||||
mqtt.publish(self._hass, self._topic["command_topic"],
|
||||
self._payload["off"], self._qos)
|
||||
self._payload["off"], self._qos, self._retain)
|
||||
|
||||
if self._optimistic:
|
||||
# Optimistically assume that switch has changed state.
|
||||
|
|
|
@ -6,40 +6,51 @@ https://home-assistant.io/components/lock.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
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
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
CONF_PAYLOAD_LOCK = 'payload_lock'
|
||||
CONF_PAYLOAD_UNLOCK = 'payload_unlock'
|
||||
|
||||
DEFAULT_NAME = "MQTT Lock"
|
||||
DEFAULT_PAYLOAD_LOCK = "LOCK"
|
||||
DEFAULT_PAYLOAD_UNLOCK = "UNLOCK"
|
||||
DEFAULT_QOS = 0
|
||||
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
|
||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
"""Setup the MQTT lock."""
|
||||
if config.get('command_topic') is None:
|
||||
_LOGGER.error("Missing required variable: command_topic")
|
||||
return False
|
||||
|
||||
add_devices_callback([MqttLock(
|
||||
hass,
|
||||
config.get('name', DEFAULT_NAME),
|
||||
config.get('state_topic'),
|
||||
config.get('command_topic'),
|
||||
config.get('qos', DEFAULT_QOS),
|
||||
config.get('retain', DEFAULT_RETAIN),
|
||||
config.get('payload_lock', DEFAULT_PAYLOAD_LOCK),
|
||||
config.get('payload_unlock', DEFAULT_PAYLOAD_UNLOCK),
|
||||
config.get('optimistic', DEFAULT_OPTIMISTIC),
|
||||
config[CONF_NAME],
|
||||
config.get(CONF_STATE_TOPIC),
|
||||
config[CONF_COMMAND_TOPIC],
|
||||
config[CONF_QOS],
|
||||
config[CONF_RETAIN],
|
||||
config[CONF_PAYLOAD_LOCK],
|
||||
config[CONF_PAYLOAD_UNLOCK],
|
||||
config[CONF_OPTIMISTIC],
|
||||
config.get(CONF_VALUE_TEMPLATE))])
|
||||
|
||||
|
||||
|
|
|
@ -14,11 +14,11 @@ import voluptuous as vol
|
|||
from homeassistant.bootstrap import prepare_setup_platform
|
||||
from homeassistant.config import load_yaml_config_file
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
import homeassistant.util as util
|
||||
from homeassistant.helpers import template
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
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__)
|
||||
|
||||
|
@ -41,6 +41,11 @@ CONF_PASSWORD = 'password'
|
|||
CONF_CERTIFICATE = 'certificate'
|
||||
CONF_PROTOCOL = 'protocol'
|
||||
|
||||
CONF_STATE_TOPIC = 'state_topic'
|
||||
CONF_COMMAND_TOPIC = 'command_topic'
|
||||
CONF_QOS = 'qos'
|
||||
CONF_RETAIN = 'retain'
|
||||
|
||||
PROTOCOL_31 = '3.1'
|
||||
PROTOCOL_311 = '3.1.1'
|
||||
|
||||
|
@ -53,25 +58,71 @@ DEFAULT_PROTOCOL = PROTOCOL_311
|
|||
ATTR_TOPIC = 'topic'
|
||||
ATTR_PAYLOAD = 'payload'
|
||||
ATTR_PAYLOAD_TEMPLATE = 'payload_template'
|
||||
ATTR_QOS = 'qos'
|
||||
ATTR_RETAIN = 'retain'
|
||||
ATTR_QOS = CONF_QOS
|
||||
ATTR_RETAIN = CONF_RETAIN
|
||||
|
||||
MAX_RECONNECT_WAIT = 300 # seconds
|
||||
|
||||
|
||||
# Service call validation schema
|
||||
def mqtt_topic(value):
|
||||
"""Validate that we can publish using this MQTT topic."""
|
||||
if isinstance(value, str) and all(c not in value for c in '#+\0'):
|
||||
def valid_subscribe_topic(value, invalid_chars='\0'):
|
||||
"""Validate that we can subscribe using this MQTT topic."""
|
||||
if isinstance(value, str) and all(c not in value for c in invalid_chars):
|
||||
return vol.Length(min=1, max=65535)(value)
|
||||
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({
|
||||
vol.Required(ATTR_TOPIC): mqtt_topic,
|
||||
vol.Required(ATTR_TOPIC): valid_publish_topic,
|
||||
vol.Exclusive(ATTR_PAYLOAD, 'payload'): object,
|
||||
vol.Exclusive(ATTR_PAYLOAD_TEMPLATE, 'payload'): cv.string,
|
||||
vol.Required(ATTR_QOS, default=DEFAULT_QOS):
|
||||
vol.All(vol.Coerce(int), vol.In([0, 1, 2])),
|
||||
vol.Required(ATTR_QOS, default=DEFAULT_QOS): _VALID_QOS_SCHEMA,
|
||||
vol.Required(ATTR_RETAIN, default=DEFAULT_RETAIN): cv.boolean,
|
||||
}, required=True)
|
||||
|
||||
|
@ -136,8 +187,8 @@ def setup(hass, config):
|
|||
# pylint: disable=too-many-locals
|
||||
conf = config.get(DOMAIN, {})
|
||||
|
||||
client_id = util.convert(conf.get(CONF_CLIENT_ID), str)
|
||||
keepalive = util.convert(conf.get(CONF_KEEPALIVE), int, DEFAULT_KEEPALIVE)
|
||||
client_id = conf.get(CONF_CLIENT_ID)
|
||||
keepalive = conf.get(CONF_KEEPALIVE)
|
||||
|
||||
broker_config = _setup_server(hass, config)
|
||||
|
||||
|
@ -151,16 +202,11 @@ def setup(hass, config):
|
|||
|
||||
if CONF_BROKER in conf:
|
||||
broker = conf[CONF_BROKER]
|
||||
port = util.convert(conf.get(CONF_PORT), int, DEFAULT_PORT)
|
||||
username = util.convert(conf.get(CONF_USERNAME), str)
|
||||
password = util.convert(conf.get(CONF_PASSWORD), str)
|
||||
certificate = util.convert(conf.get(CONF_CERTIFICATE), str)
|
||||
protocol = util.convert(conf.get(CONF_PROTOCOL), str, DEFAULT_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
|
||||
port = conf[CONF_PORT]
|
||||
username = conf.get(CONF_USERNAME)
|
||||
password = conf.get(CONF_PASSWORD)
|
||||
certificate = conf.get(CONF_CERTIFICATE)
|
||||
protocol = conf[CONF_PROTOCOL]
|
||||
|
||||
# For cloudmqtt.com, secured connection, auto fill in certificate
|
||||
if certificate is None and 19999 < port < 30000 and \
|
||||
|
|
|
@ -6,9 +6,11 @@ https://home-assistant.io/components/mqtt_eventstream/
|
|||
"""
|
||||
import json
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.loader as loader
|
||||
from homeassistant.components.mqtt import DOMAIN as MQTT_DOMAIN
|
||||
from homeassistant.components.mqtt import SERVICE_PUBLISH as MQTT_SVC_PUBLISH
|
||||
from homeassistant.components.mqtt import (
|
||||
valid_publish_topic, valid_subscribe_topic)
|
||||
from homeassistant.const import (
|
||||
ATTR_SERVICE_DATA, EVENT_CALL_SERVICE, EVENT_SERVICE_EXECUTED,
|
||||
EVENT_STATE_CHANGED, EVENT_TIME_CHANGED, MATCH_ALL)
|
||||
|
@ -18,12 +20,23 @@ from homeassistant.remote import JSONEncoder
|
|||
DOMAIN = "mqtt_eventstream"
|
||||
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):
|
||||
"""Setup th MQTT eventstream component."""
|
||||
"""Setup the MQTT eventstream component."""
|
||||
mqtt = loader.get_component('mqtt')
|
||||
pub_topic = config[DOMAIN].get('publish_topic', None)
|
||||
sub_topic = config[DOMAIN].get('subscribe_topic', None)
|
||||
conf = config.get(DOMAIN, {})
|
||||
pub_topic = conf.get(CONF_PUBLISH_TOPIC)
|
||||
sub_topic = conf.get(CONF_SUBSCRIBE_TOPIC)
|
||||
|
||||
def _event_publisher(event):
|
||||
"""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.
|
||||
if event.event_type == EVENT_CALL_SERVICE:
|
||||
if (
|
||||
event.data.get('domain') == MQTT_DOMAIN and
|
||||
event.data.get('service') == MQTT_SVC_PUBLISH and
|
||||
event.data.get('domain') == mqtt.DOMAIN and
|
||||
event.data.get('service') == mqtt.SERVICE_PUBLISH and
|
||||
event.data[ATTR_SERVICE_DATA].get('topic') == pub_topic
|
||||
):
|
||||
return
|
||||
|
|
|
@ -9,7 +9,8 @@ import logging
|
|||
import homeassistant.bootstrap as bootstrap
|
||||
from homeassistant.const import (
|
||||
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
|
||||
|
||||
CONF_GATEWAYS = 'gateways'
|
||||
|
@ -19,7 +20,6 @@ CONF_PERSISTENCE = 'persistence'
|
|||
CONF_PERSISTENCE_FILE = 'persistence_file'
|
||||
CONF_VERSION = 'version'
|
||||
CONF_BAUD_RATE = 'baud_rate'
|
||||
CONF_OPTIMISTIC = 'optimistic'
|
||||
DEFAULT_VERSION = '1.4'
|
||||
DEFAULT_BAUD_RATE = 115200
|
||||
|
||||
|
|
|
@ -6,38 +6,50 @@ https://home-assistant.io/components/rollershutter.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
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
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
CONF_PAYLOAD_UP = 'payload_up'
|
||||
CONF_PAYLOAD_DOWN = 'payload_down'
|
||||
CONF_PAYLOAD_STOP = 'payload_stop'
|
||||
|
||||
DEFAULT_NAME = "MQTT Rollershutter"
|
||||
DEFAULT_QOS = 0
|
||||
DEFAULT_PAYLOAD_UP = "UP"
|
||||
DEFAULT_PAYLOAD_DOWN = "DOWN"
|
||||
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):
|
||||
"""Add MQTT Rollershutter."""
|
||||
if config.get('command_topic') is None:
|
||||
_LOGGER.error("Missing required variable: command_topic")
|
||||
return False
|
||||
|
||||
add_devices_callback([MqttRollershutter(
|
||||
hass,
|
||||
config.get('name', DEFAULT_NAME),
|
||||
config.get('state_topic'),
|
||||
config.get('command_topic'),
|
||||
config.get('qos', DEFAULT_QOS),
|
||||
config.get('payload_up', DEFAULT_PAYLOAD_UP),
|
||||
config.get('payload_down', DEFAULT_PAYLOAD_DOWN),
|
||||
config.get('payload_stop', DEFAULT_PAYLOAD_STOP),
|
||||
config.get(CONF_VALUE_TEMPLATE))])
|
||||
config[CONF_NAME],
|
||||
config.get(CONF_STATE_TOPIC),
|
||||
config[CONF_COMMAND_TOPIC],
|
||||
config[CONF_QOS],
|
||||
config[CONF_PAYLOAD_UP],
|
||||
config[CONF_PAYLOAD_DOWN],
|
||||
config[CONF_PAYLOAD_STOP],
|
||||
config.get(CONF_VALUE_TEMPLATE)
|
||||
)])
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||
|
|
|
@ -6,33 +6,40 @@ https://home-assistant.io/components/sensor.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
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 import template
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = "MQTT Sensor"
|
||||
DEFAULT_QOS = 0
|
||||
|
||||
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
|
||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
"""Setup MQTT Sensor."""
|
||||
if config.get('state_topic') is None:
|
||||
_LOGGER.error("Missing required variable: state_topic")
|
||||
return False
|
||||
|
||||
add_devices_callback([MqttSensor(
|
||||
hass,
|
||||
config.get('name', DEFAULT_NAME),
|
||||
config.get('state_topic'),
|
||||
config.get('qos', DEFAULT_QOS),
|
||||
config.get('unit_of_measurement'),
|
||||
config.get(CONF_VALUE_TEMPLATE))])
|
||||
config[CONF_NAME],
|
||||
config[CONF_STATE_TOPIC],
|
||||
config[CONF_QOS],
|
||||
config.get(CONF_UNIT_OF_MEASUREMENT),
|
||||
config.get(CONF_VALUE_TEMPLATE),
|
||||
)])
|
||||
|
||||
|
||||
# pylint: disable=too-many-arguments, too-many-instance-attributes
|
||||
|
|
|
@ -6,41 +6,49 @@ https://home-assistant.io/components/switch.mqtt/
|
|||
"""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
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.util import convert
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
|
||||
CONF_PAYLOAD_ON = 'payload_on'
|
||||
CONF_PAYLOAD_OFF = 'payload_off'
|
||||
|
||||
DEFAULT_NAME = "MQTT Switch"
|
||||
DEFAULT_QOS = 0
|
||||
DEFAULT_PAYLOAD_ON = "ON"
|
||||
DEFAULT_PAYLOAD_OFF = "OFF"
|
||||
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
|
||||
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
|
||||
"""Add MQTT switch."""
|
||||
if config.get('command_topic') is None:
|
||||
_LOGGER.error("Missing required variable: command_topic")
|
||||
return False
|
||||
|
||||
add_devices_callback([MqttSwitch(
|
||||
hass,
|
||||
convert(config.get('name'), str, DEFAULT_NAME),
|
||||
config.get('state_topic'),
|
||||
config.get('command_topic'),
|
||||
convert(config.get('qos'), int, DEFAULT_QOS),
|
||||
convert(config.get('retain'), bool, DEFAULT_RETAIN),
|
||||
convert(config.get('payload_on'), str, DEFAULT_PAYLOAD_ON),
|
||||
convert(config.get('payload_off'), str, DEFAULT_PAYLOAD_OFF),
|
||||
convert(config.get('optimistic'), bool, DEFAULT_OPTIMISTIC),
|
||||
config[CONF_NAME],
|
||||
config.get(CONF_STATE_TOPIC),
|
||||
config[CONF_COMMAND_TOPIC],
|
||||
config[CONF_QOS],
|
||||
config[CONF_RETAIN],
|
||||
config[CONF_PAYLOAD_ON],
|
||||
config[CONF_PAYLOAD_OFF],
|
||||
config[CONF_OPTIMISTIC],
|
||||
config.get(CONF_VALUE_TEMPLATE))])
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ CONF_PASSWORD = "password"
|
|||
CONF_API_KEY = "api_key"
|
||||
CONF_ACCESS_TOKEN = "access_token"
|
||||
CONF_FILENAME = "filename"
|
||||
CONF_OPTIMISTIC = 'optimistic'
|
||||
CONF_SCAN_INTERVAL = "scan_interval"
|
||||
CONF_VALUE_TEMPLATE = "value_template"
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from datetime import timedelta
|
|||
from unittest import mock
|
||||
|
||||
from homeassistant import core as ha, loader
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
from homeassistant.const import (
|
||||
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')
|
||||
def mock_mqtt_component(hass, mock_mqtt):
|
||||
"""Mock the MQTT component."""
|
||||
mqtt.setup(hass, {
|
||||
_setup_component(hass, mqtt.DOMAIN, {
|
||||
mqtt.DOMAIN: {
|
||||
mqtt.CONF_BROKER: 'mock-broker',
|
||||
}
|
||||
})
|
||||
hass.config.components.append(mqtt.DOMAIN)
|
||||
return mock_mqtt
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""The tests the MQTT alarm control panel component."""
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import (
|
||||
STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME, STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_PENDING, STATE_ALARM_TRIGGERED, STATE_UNKNOWN)
|
||||
|
@ -25,37 +25,37 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
|
|||
"""Stop down stuff we started."""
|
||||
self.hass.stop()
|
||||
|
||||
@patch('homeassistant.components.alarm_control_panel.mqtt._LOGGER.error')
|
||||
def test_fail_setup_without_state_topic(self, mock_error):
|
||||
def test_fail_setup_without_state_topic(self):
|
||||
"""Test for failing with no state topic."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'command_topic': 'alarm/command'
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
self.assertEqual(1, mock_error.call_count)
|
||||
|
||||
@patch('homeassistant.components.alarm_control_panel.mqtt._LOGGER.error')
|
||||
def test_fail_setup_without_command_topic(self, mock_error):
|
||||
def test_fail_setup_without_command_topic(self):
|
||||
"""Test failing with no command topic."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert not _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'state_topic': 'alarm/state'
|
||||
}}))
|
||||
|
||||
self.assertEqual(1, mock_error.call_count)
|
||||
}
|
||||
})
|
||||
|
||||
def test_update_state_via_state_topic(self):
|
||||
"""Test updating with via state topic."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
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):
|
||||
"""Test ignoring updates via state topic."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
entity_id = 'alarm_control_panel.test'
|
||||
|
||||
|
@ -90,13 +92,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
|
|||
|
||||
def test_arm_home_publishes_mqtt(self):
|
||||
"""Test publishing of MQTT messages while armed."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
alarm_control_panel.alarm_arm_home(self.hass)
|
||||
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):
|
||||
"""Test not publishing of MQTT messages with invalid code."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
'code': '1234'
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
call_count = self.mock_publish.call_count
|
||||
alarm_control_panel.alarm_arm_home(self.hass, 'abcd')
|
||||
|
@ -121,13 +127,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
|
|||
|
||||
def test_arm_away_publishes_mqtt(self):
|
||||
"""Test publishing of MQTT messages while armed."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
alarm_control_panel.alarm_arm_away(self.hass)
|
||||
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):
|
||||
"""Test not publishing of MQTT messages with invalid code."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
'code': '1234'
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
call_count = self.mock_publish.call_count
|
||||
alarm_control_panel.alarm_arm_away(self.hass, 'abcd')
|
||||
|
@ -152,13 +162,15 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
|
|||
|
||||
def test_disarm_publishes_mqtt(self):
|
||||
"""Test publishing of MQTT messages while disarmed."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
alarm_control_panel.alarm_disarm(self.hass)
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -167,14 +179,16 @@ class TestAlarmControlPanelMQTT(unittest.TestCase):
|
|||
|
||||
def test_disarm_not_publishes_mqtt_with_invalid_code(self):
|
||||
"""Test not publishing of MQTT messages with invalid code."""
|
||||
self.assertTrue(alarm_control_panel.setup(self.hass, {
|
||||
'alarm_control_panel': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, alarm_control_panel.DOMAIN, {
|
||||
alarm_control_panel.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'alarm/state',
|
||||
'command_topic': 'alarm/command',
|
||||
'code': '1234'
|
||||
}}))
|
||||
}
|
||||
})
|
||||
|
||||
call_count = self.mock_publish.call_count
|
||||
alarm_control_panel.alarm_disarm(self.hass, 'abcd')
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT binary sensor platform."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
import homeassistant.components.binary_sensor as binary_sensor
|
||||
from tests.common import mock_mqtt_component, fire_mqtt_message
|
||||
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):
|
||||
"""Test the setting of the value via MQTT."""
|
||||
self.assertTrue(binary_sensor.setup(self.hass, {
|
||||
'binary_sensor': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, binary_sensor.DOMAIN, {
|
||||
binary_sensor.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test-topic',
|
||||
'payload_on': 'ON',
|
||||
'payload_off': 'OFF',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('binary_sensor.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -47,28 +49,30 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
|
||||
def test_valid_sensor_class(self):
|
||||
"""Test the setting of a valid sensor class."""
|
||||
self.assertTrue(binary_sensor.setup(self.hass, {
|
||||
'binary_sensor': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, binary_sensor.DOMAIN, {
|
||||
binary_sensor.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'sensor_class': 'motion',
|
||||
'state_topic': 'test-topic',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('binary_sensor.test')
|
||||
self.assertEqual('motion', state.attributes.get('sensor_class'))
|
||||
|
||||
def test_invalid_sensor_class(self):
|
||||
"""Test the setting of an invalid sensor class."""
|
||||
self.assertTrue(binary_sensor.setup(self.hass, {
|
||||
'binary_sensor': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, binary_sensor.DOMAIN, {
|
||||
binary_sensor.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'sensor_class': 'abc123',
|
||||
'state_topic': 'test-topic',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('binary_sensor.test')
|
||||
self.assertIsNone(state.attributes.get('sensor_class'))
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import unittest
|
||||
import os
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.components import device_tracker
|
||||
from homeassistant.const import CONF_PLATFORM
|
||||
|
||||
|
@ -31,11 +32,13 @@ class TestComponentsDeviceTrackerMQTT(unittest.TestCase):
|
|||
topic = '/location/paulus'
|
||||
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: {
|
||||
CONF_PLATFORM: 'mqtt',
|
||||
'devices': {dev_id: topic}
|
||||
}}))
|
||||
}
|
||||
})
|
||||
fire_mqtt_message(self.hass, topic, location)
|
||||
self.hass.pool.block_till_done()
|
||||
self.assertEqual(location, self.hass.states.get(enttiy_id).state)
|
||||
|
|
|
@ -58,6 +58,7 @@ light:
|
|||
"""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
|
||||
import homeassistant.components.light as light
|
||||
from tests.common import (
|
||||
|
@ -78,24 +79,26 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_fail_setup_if_no_command_topic(self):
|
||||
"""Test if command fails with command topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert not _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
}
|
||||
}))
|
||||
})
|
||||
self.assertIsNone(self.hass.states.get('light.test'))
|
||||
|
||||
def test_no_color_or_brightness_if_no_topics(self):
|
||||
"""Test if there is no color and brightness if no topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -112,8 +115,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic(self):
|
||||
"""Test the controlling of the state via topic."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
|
@ -126,7 +130,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 1,
|
||||
'payload_off': 0
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -172,8 +176,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_scale(self):
|
||||
"""Test the controlling scale."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_scale/status',
|
||||
|
@ -185,7 +190,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -218,8 +223,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic_with_templates(self):
|
||||
"""Test the setting og the state with a template."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
|
@ -230,7 +236,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'brightness_value_template': '{{ value_json.hello }}',
|
||||
'rgb_value_template': '{{ value_json.hello | join(",") }}',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -252,8 +258,9 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_sending_mqtt_commands_and_optimistic(self):
|
||||
"""Test the sending of command in optimistic mode."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
|
@ -263,7 +270,7 @@ class TestLightMQTT(unittest.TestCase):
|
|||
'payload_on': 'on',
|
||||
'payload_off': 'off'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -310,15 +317,16 @@ class TestLightMQTT(unittest.TestCase):
|
|||
|
||||
def test_show_brightness_if_only_command_topic(self):
|
||||
"""Test the brightness if only a command topic is present."""
|
||||
self.assertTrue(light.setup(self.hass, {
|
||||
'light': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, light.DOMAIN, {
|
||||
light.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'brightness_command_topic': 'test_light_rgb/brightness/set',
|
||||
'command_topic': 'test_light_rgb/set',
|
||||
'state_topic': 'test_light_rgb/status',
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('light.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT lock platform."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import (STATE_LOCKED, STATE_UNLOCKED,
|
||||
ATTR_ASSUMED_STATE)
|
||||
import homeassistant.components.lock as lock
|
||||
|
@ -22,8 +23,9 @@ class TestLockMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic(self):
|
||||
"""Test the controlling state via topic."""
|
||||
self.assertTrue(lock.setup(self.hass, {
|
||||
'lock': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, lock.DOMAIN, {
|
||||
lock.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -31,7 +33,7 @@ class TestLockMQTT(unittest.TestCase):
|
|||
'payload_lock': 'LOCK',
|
||||
'payload_unlock': 'UNLOCK'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('lock.test')
|
||||
self.assertEqual(STATE_UNLOCKED, state.state)
|
||||
|
@ -51,8 +53,9 @@ class TestLockMQTT(unittest.TestCase):
|
|||
|
||||
def test_sending_mqtt_commands_and_optimistic(self):
|
||||
"""Test the sending MQTT commands in optimistic mode."""
|
||||
self.assertTrue(lock.setup(self.hass, {
|
||||
'lock': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, lock.DOMAIN, {
|
||||
lock.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'command_topic': 'command-topic',
|
||||
|
@ -60,7 +63,7 @@ class TestLockMQTT(unittest.TestCase):
|
|||
'payload_unlock': 'UNLOCK',
|
||||
'qos': 2
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('lock.test')
|
||||
self.assertEqual(STATE_UNLOCKED, state.state)
|
||||
|
@ -84,8 +87,9 @@ class TestLockMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic_and_json_message(self):
|
||||
"""Test the controlling state via topic and JSON message."""
|
||||
self.assertTrue(lock.setup(self.hass, {
|
||||
'lock': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, lock.DOMAIN, {
|
||||
lock.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -94,7 +98,7 @@ class TestLockMQTT(unittest.TestCase):
|
|||
'payload_unlock': 'UNLOCK',
|
||||
'value_template': '{{ value_json.val }}'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('lock.test')
|
||||
self.assertEqual(STATE_UNLOCKED, state.state)
|
||||
|
|
|
@ -4,6 +4,7 @@ import unittest
|
|||
from unittest import mock
|
||||
import socket
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
from homeassistant.const import (
|
||||
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."""
|
||||
with mock.patch('homeassistant.components.mqtt.MQTT',
|
||||
side_effect=socket.error()):
|
||||
self.assertFalse(mqtt.setup(self.hass, {mqtt.DOMAIN: {
|
||||
mqtt.CONF_BROKER: 'test-broker',
|
||||
}}))
|
||||
self.hass.config.components = []
|
||||
assert not _setup_component(self.hass, mqtt.DOMAIN, {
|
||||
mqtt.DOMAIN: {
|
||||
mqtt.CONF_BROKER: 'test-broker',
|
||||
}
|
||||
})
|
||||
|
||||
def test_publish_calls_service(self):
|
||||
"""Test the publishing of call to services."""
|
||||
|
@ -211,12 +215,12 @@ class TestMQTTCallbacks(unittest.TestCase):
|
|||
# mock_mqtt_component(self.hass)
|
||||
|
||||
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.CONF_BROKER: 'mock-broker',
|
||||
}
|
||||
})
|
||||
self.hass.config.components.append(mqtt.DOMAIN)
|
||||
|
||||
def tearDown(self): # pylint: disable=invalid-name
|
||||
"""Stop everything that was started."""
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT component embedded server."""
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
import homeassistant.components.mqtt as mqtt
|
||||
|
||||
from tests.common import get_test_home_assistant
|
||||
|
@ -27,15 +28,16 @@ class TestMQTT:
|
|||
password = 'super_secret'
|
||||
|
||||
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.mock_calls[0][1][5] == 'homeassistant'
|
||||
assert mock_mqtt.mock_calls[0][1][6] == password
|
||||
|
||||
mock_mqtt.reset_mock()
|
||||
|
||||
self.hass.config.components = ['http']
|
||||
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.mock_calls[0][1][5] is None
|
||||
assert mock_mqtt.mock_calls[0][1][6] is None
|
||||
|
@ -50,6 +52,6 @@ class TestMQTT:
|
|||
mock_gather.side_effect = BrokerException
|
||||
|
||||
self.hass.config.api = MagicMock(api_password=None)
|
||||
assert not mqtt.setup(self.hass, {
|
||||
'mqtt': {'embedded': {}}
|
||||
assert not _setup_component(self.hass, mqtt.DOMAIN, {
|
||||
mqtt.DOMAIN: {mqtt.CONF_EMBEDDED: {}}
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT roller shutter platform."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import STATE_OPEN, STATE_CLOSED, STATE_UNKNOWN
|
||||
import homeassistant.components.rollershutter as rollershutter
|
||||
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):
|
||||
"""Test the controlling state via topic."""
|
||||
self.assertTrue(rollershutter.setup(self.hass, {
|
||||
'rollershutter': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, rollershutter.DOMAIN, {
|
||||
rollershutter.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -33,7 +35,7 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
'payload_down': 'DOWN',
|
||||
'payload_stop': 'STOP'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('rollershutter.test')
|
||||
self.assertEqual(STATE_UNKNOWN, state.state)
|
||||
|
@ -58,15 +60,16 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
|
||||
def test_send_move_up_command(self):
|
||||
"""Test the sending of move_up."""
|
||||
self.assertTrue(rollershutter.setup(self.hass, {
|
||||
'rollershutter': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, rollershutter.DOMAIN, {
|
||||
rollershutter.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
'command_topic': 'command-topic',
|
||||
'qos': 2
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('rollershutter.test')
|
||||
self.assertEqual(STATE_UNKNOWN, state.state)
|
||||
|
@ -81,15 +84,16 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
|
||||
def test_send_move_down_command(self):
|
||||
"""Test the sending of move_down."""
|
||||
self.assertTrue(rollershutter.setup(self.hass, {
|
||||
'rollershutter': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, rollershutter.DOMAIN, {
|
||||
rollershutter.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
'command_topic': 'command-topic',
|
||||
'qos': 2
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('rollershutter.test')
|
||||
self.assertEqual(STATE_UNKNOWN, state.state)
|
||||
|
@ -104,15 +108,16 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
|
||||
def test_send_stop_command(self):
|
||||
"""Test the sending of stop."""
|
||||
self.assertTrue(rollershutter.setup(self.hass, {
|
||||
'rollershutter': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, rollershutter.DOMAIN, {
|
||||
rollershutter.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
'command_topic': 'command-topic',
|
||||
'qos': 2
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('rollershutter.test')
|
||||
self.assertEqual(STATE_UNKNOWN, state.state)
|
||||
|
@ -127,8 +132,9 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
|
||||
def test_state_attributes_current_position(self):
|
||||
"""Test the current position."""
|
||||
self.assertTrue(rollershutter.setup(self.hass, {
|
||||
'rollershutter': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, rollershutter.DOMAIN, {
|
||||
rollershutter.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -137,7 +143,7 @@ class TestRollershutterMQTT(unittest.TestCase):
|
|||
'payload_down': 'DOWN',
|
||||
'payload_stop': 'STOP'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state_attributes_dict = self.hass.states.get(
|
||||
'rollershutter.test').attributes
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT sensor platform."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
import homeassistant.components.sensor as sensor
|
||||
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):
|
||||
"""Test the setting of the value via MQTT."""
|
||||
self.assertTrue(sensor.setup(self.hass, {
|
||||
'sensor': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, sensor.DOMAIN, {
|
||||
sensor.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test-topic',
|
||||
'unit_of_measurement': 'fav unit'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
fire_mqtt_message(self.hass, 'test-topic', '100')
|
||||
self.hass.pool.block_till_done()
|
||||
|
@ -40,15 +42,16 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
|
||||
def test_setting_sensor_value_via_mqtt_json_message(self):
|
||||
"""Test the setting of the value via MQTT with JSON playload."""
|
||||
self.assertTrue(sensor.setup(self.hass, {
|
||||
'sensor': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, sensor.DOMAIN, {
|
||||
sensor.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'test-topic',
|
||||
'unit_of_measurement': 'fav unit',
|
||||
'value_template': '{{ value_json.val }}'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
fire_mqtt_message(self.hass, 'test-topic', '{ "val": "100" }')
|
||||
self.hass.pool.block_till_done()
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""The tests for the MQTT switch platform."""
|
||||
import unittest
|
||||
|
||||
from homeassistant.bootstrap import _setup_component
|
||||
from homeassistant.const import STATE_ON, STATE_OFF, ATTR_ASSUMED_STATE
|
||||
import homeassistant.components.switch as switch
|
||||
from tests.common import (
|
||||
|
@ -21,8 +22,9 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic(self):
|
||||
"""Test the controlling state via topic."""
|
||||
self.assertTrue(switch.setup(self.hass, {
|
||||
'switch': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -30,7 +32,7 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
'payload_on': 1,
|
||||
'payload_off': 0
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('switch.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -50,8 +52,9 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
|
||||
def test_sending_mqtt_commands_and_optimistic(self):
|
||||
"""Test the sending MQTT commands in optimistic mode."""
|
||||
self.assertTrue(switch.setup(self.hass, {
|
||||
'switch': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'command_topic': 'command-topic',
|
||||
|
@ -59,7 +62,7 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
'payload_off': 'beer off',
|
||||
'qos': '2'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('switch.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
@ -83,8 +86,9 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
|
||||
def test_controlling_state_via_topic_and_json_message(self):
|
||||
"""Test the controlling state via topic and JSON message."""
|
||||
self.assertTrue(switch.setup(self.hass, {
|
||||
'switch': {
|
||||
self.hass.config.components = ['mqtt']
|
||||
assert _setup_component(self.hass, switch.DOMAIN, {
|
||||
switch.DOMAIN: {
|
||||
'platform': 'mqtt',
|
||||
'name': 'test',
|
||||
'state_topic': 'state-topic',
|
||||
|
@ -93,7 +97,7 @@ class TestSensorMQTT(unittest.TestCase):
|
|||
'payload_off': 'beer off',
|
||||
'value_template': '{{ value_json.val }}'
|
||||
}
|
||||
}))
|
||||
})
|
||||
|
||||
state = self.hass.states.get('switch.test')
|
||||
self.assertEqual(STATE_OFF, state.state)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue