Merge pull request #270 from sfam/dev

Add MQTT switch and sensor
This commit is contained in:
Paulus Schoutsen 2015-08-22 12:34:36 -07:00
commit 584e67a6d4
2 changed files with 247 additions and 0 deletions

View File

@ -0,0 +1,94 @@
# -*- coding: utf-8 -*-
"""
homeassistant.components.sensor.mqtt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allows to configure a MQTT sensor.
This generic sensor implementation uses the MQTT message payload
as the sensor value. If messages in this state_topic are published
with RETAIN flag, the sensor will receive an instant update with
last known value. Otherwise, the initial state will be undefined.
sensor:
platform: mqtt
name: "MQTT Sensor"
state_topic: "home/bedroom/temperature"
unit_of_measurement: "ºC"
Variables:
name
*Optional
The name of the sensor. Default is 'MQTT Sensor'.
state_topic
*Required
The MQTT topic subscribed to receive sensor values.
unit_of_measurement
*Optional
Defines the units of measurement of the sensor, if any.
"""
import logging
from homeassistant.helpers.entity import Entity
import homeassistant.components.mqtt as mqtt
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "MQTT Sensor"
DEPENDENCIES = ['mqtt']
# pylint: disable=unused-argument
def setup_platform(hass, config, add_devices_callback, discovery_info=None):
""" Add 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('unit_of_measurement'))])
class MqttSensor(Entity):
""" Represents a sensor that can be updated using MQTT """
def __init__(self, hass, name, state_topic, unit_of_measurement):
self._state = "-"
self._hass = hass
self._name = name
self._state_topic = state_topic
self._unit_of_measurement = unit_of_measurement
def message_received(topic, payload, qos):
""" A new MQTT message has been received. """
self._state = payload
self.update_ha_state()
mqtt.subscribe(hass, self._state_topic, message_received)
@property
def should_poll(self):
""" No polling needed """
return False
@property
def name(self):
""" The name of the sensor """
return self._name
@property
def unit_of_measurement(self):
""" Unit this state is expressed in. """
return self._unit_of_measurement
@property
def state(self):
""" Returns the state of the entity. """
return self._state

View File

@ -0,0 +1,153 @@
# -*- coding: utf-8 -*-
"""
homeassistant.components.switch.mqtt
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Allows to configure a MQTT switch.
In an ideal scenario, the MQTT device will have a state topic to publish
state changes. If these messages are published with RETAIN flag, the MQTT
switch will receive an instant state update after subscription and will
start with correct state. Otherwise, the initial state of the switch will
be false/off.
When a state topic is not available, the switch will work in optimistic mode.
In this mode, the switch will immediately change state after every command.
Otherwise, the switch will wait for state confirmation from device
(message from state_topic).
Optimistic mode can be forced, even if state topic is available.
Try to enable it, if experiencing incorrect switch operation.
Configuration:
switch:
platform: mqtt
name: "Bedroom Switch"
state_topic: "home/bedroom/switch1"
command_topic: "home/bedroom/switch1/set"
payload_on: "ON"
payload_off: "OFF"
optimistic: false
Variables:
name
*Optional
The name of the switch. Default is 'MQTT Switch'.
state_topic
*Optional
The MQTT topic subscribed to receive state updates.
If not specified, optimistic mode will be forced.
command_topic
*Required
The MQTT topic to publish commands to change the switch state.
payload_on
*Optional
The payload that represents enabled state. Default is "ON".
payload_off
*Optional
The payload that represents disabled state. Default is "OFF".
optimistic
*Optional
Flag that defines if switch works in optimistic mode. Default is false.
"""
import logging
import homeassistant.components.mqtt as mqtt
from homeassistant.components.switch import SwitchDevice
_LOGGER = logging.getLogger(__name__)
DEFAULT_NAME = "MQTT Switch"
DEFAULT_PAYLOAD_ON = "ON"
DEFAULT_PAYLOAD_OFF = "OFF"
DEFAULT_OPTIMISTIC = False
DEPENDENCIES = ['mqtt']
# 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,
config.get('name', DEFAULT_NAME),
config.get('state_topic'),
config.get('command_topic'),
config.get('payload_on', DEFAULT_PAYLOAD_ON),
config.get('payload_off', DEFAULT_PAYLOAD_OFF),
config.get('optimistic', DEFAULT_OPTIMISTIC))])
# pylint: disable=too-many-arguments, too-many-instance-attributes
class MqttSwitch(SwitchDevice):
""" Represents a switch that can be togggled using MQTT """
def __init__(self, hass, name, state_topic, command_topic,
payload_on, payload_off, optimistic):
self._state = False
self._hass = hass
self._name = name
self._state_topic = state_topic
self._command_topic = command_topic
self._payload_on = payload_on
self._payload_off = payload_off
self._optimistic = optimistic
def message_received(topic, payload, qos):
""" A new MQTT message has been received. """
if payload == self._payload_on:
self._state = True
self.update_ha_state()
elif payload == self._payload_off:
self._state = False
self.update_ha_state()
if self._state_topic is None:
# force optimistic mode
self._optimistic = True
else:
# subscribe the state_topic
mqtt.subscribe(hass, self._state_topic, message_received)
@property
def should_poll(self):
""" No polling needed """
return False
@property
def name(self):
""" The name of the switch """
return self._name
@property
def is_on(self):
""" True if device is on. """
return self._state
def turn_on(self, **kwargs):
""" Turn the device on. """
mqtt.publish(self.hass, self._command_topic, self._payload_on)
if self._optimistic:
# optimistically assume that switch has changed state
self._state = True
self.update_ha_state()
def turn_off(self, **kwargs):
""" Turn the device off. """
mqtt.publish(self.hass, self._command_topic, self._payload_off)
if self._optimistic:
# optimistically assume that switch has changed state
self._state = False
self.update_ha_state()