Allow setting the retain flag for mqtt switch.

Some devices can read the initial value on startup.
If the retain flag is set they always receive the value as last set by
home assistant.
This commit is contained in:
Pascal Bach 2015-11-24 21:30:06 +01:00
parent 3e60c4801c
commit 69e9d39690
2 changed files with 17 additions and 7 deletions

View File

@ -28,6 +28,7 @@ MQTT_CLIENT = None
DEFAULT_PORT = 1883 DEFAULT_PORT = 1883
DEFAULT_KEEPALIVE = 60 DEFAULT_KEEPALIVE = 60
DEFAULT_QOS = 0 DEFAULT_QOS = 0
DEFAULT_RETAIN = False
SERVICE_PUBLISH = 'publish' SERVICE_PUBLISH = 'publish'
EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED' EVENT_MQTT_MESSAGE_RECEIVED = 'MQTT_MESSAGE_RECEIVED'
@ -46,11 +47,12 @@ CONF_CERTIFICATE = 'certificate'
ATTR_TOPIC = 'topic' ATTR_TOPIC = 'topic'
ATTR_PAYLOAD = 'payload' ATTR_PAYLOAD = 'payload'
ATTR_QOS = 'qos' ATTR_QOS = 'qos'
ATTR_RETAIN = 'retain'
MAX_RECONNECT_WAIT = 300 # seconds MAX_RECONNECT_WAIT = 300 # seconds
def publish(hass, topic, payload, qos=None): def publish(hass, topic, payload, qos=None, retain=None):
""" Send an MQTT message. """ """ Send an MQTT message. """
data = { data = {
ATTR_TOPIC: topic, ATTR_TOPIC: topic,
@ -58,6 +60,10 @@ def publish(hass, topic, payload, qos=None):
} }
if qos is not None: if qos is not None:
data[ATTR_QOS] = qos data[ATTR_QOS] = qos
if retain is not None:
data[ATTR_RETAIN] = retain
hass.services.call(DOMAIN, SERVICE_PUBLISH, data) hass.services.call(DOMAIN, SERVICE_PUBLISH, data)
@ -119,9 +125,10 @@ def setup(hass, config):
msg_topic = call.data.get(ATTR_TOPIC) msg_topic = call.data.get(ATTR_TOPIC)
payload = call.data.get(ATTR_PAYLOAD) payload = call.data.get(ATTR_PAYLOAD)
qos = call.data.get(ATTR_QOS, DEFAULT_QOS) qos = call.data.get(ATTR_QOS, DEFAULT_QOS)
retain = call.data.get(ATTR_RETAIN, DEFAULT_RETAIN)
if msg_topic is None or payload is None: if msg_topic is None or payload is None:
return return
MQTT_CLIENT.publish(msg_topic, payload, qos) MQTT_CLIENT.publish(msg_topic, payload, qos, retain)
hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_mqtt) hass.bus.listen_once(EVENT_HOMEASSISTANT_START, start_mqtt)
@ -190,9 +197,9 @@ class MQTT(object):
self._mqttc.connect(broker, port, keepalive) self._mqttc.connect(broker, port, keepalive)
def publish(self, topic, payload, qos): def publish(self, topic, payload, qos, retain):
""" Publish a MQTT message. """ """ Publish a MQTT message. """
self._mqttc.publish(topic, payload, qos) self._mqttc.publish(topic, payload, qos, retain)
def start(self): def start(self):
""" Run the MQTT client. """ """ Run the MQTT client. """

View File

@ -17,6 +17,7 @@ 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'] DEPENDENCIES = ['mqtt']
@ -35,6 +36,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
config.get('state_topic'), config.get('state_topic'),
config.get('command_topic'), config.get('command_topic'),
config.get('qos', DEFAULT_QOS), config.get('qos', DEFAULT_QOS),
config.get('retain', DEFAULT_RETAIN),
config.get('payload_on', DEFAULT_PAYLOAD_ON), config.get('payload_on', DEFAULT_PAYLOAD_ON),
config.get('payload_off', DEFAULT_PAYLOAD_OFF), config.get('payload_off', DEFAULT_PAYLOAD_OFF),
config.get('optimistic', DEFAULT_OPTIMISTIC), config.get('optimistic', DEFAULT_OPTIMISTIC),
@ -44,7 +46,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None):
# pylint: disable=too-many-arguments, too-many-instance-attributes # pylint: disable=too-many-arguments, too-many-instance-attributes
class MqttSwitch(SwitchDevice): class MqttSwitch(SwitchDevice):
""" Represents a switch that can be toggled using MQTT. """ """ Represents a switch that can be toggled using MQTT. """
def __init__(self, hass, name, state_topic, command_topic, qos, def __init__(self, hass, name, state_topic, command_topic, qos, retain,
payload_on, payload_off, optimistic, state_format): payload_on, payload_off, optimistic, state_format):
self._state = False self._state = False
self._hass = hass self._hass = hass
@ -52,6 +54,7 @@ class MqttSwitch(SwitchDevice):
self._state_topic = state_topic self._state_topic = state_topic
self._command_topic = command_topic self._command_topic = command_topic
self._qos = qos self._qos = qos
self._retain = retain
self._payload_on = payload_on self._payload_on = payload_on
self._payload_off = payload_off self._payload_off = payload_off
self._optimistic = optimistic self._optimistic = optimistic
@ -93,7 +96,7 @@ class MqttSwitch(SwitchDevice):
def turn_on(self, **kwargs): def turn_on(self, **kwargs):
""" Turn the device on. """ """ Turn the device on. """
mqtt.publish(self.hass, self._command_topic, self._payload_on, mqtt.publish(self.hass, self._command_topic, self._payload_on,
self._qos) self._qos, self._retain)
if self._optimistic: if self._optimistic:
# optimistically assume that switch has changed state # optimistically assume that switch has changed state
self._state = True self._state = True
@ -102,7 +105,7 @@ class MqttSwitch(SwitchDevice):
def turn_off(self, **kwargs): def turn_off(self, **kwargs):
""" Turn the device off. """ """ Turn the device off. """
mqtt.publish(self.hass, self._command_topic, self._payload_off, mqtt.publish(self.hass, self._command_topic, self._payload_off,
self._qos) self._qos, self._retain)
if self._optimistic: if self._optimistic:
# optimistically assume that switch has changed state # optimistically assume that switch has changed state
self._state = False self._state = False