예제 #1
0
    def __init__(self, hass, name, state_topic, command_topic, qos,
                 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._qos = qos
        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,
                           self._qos)
예제 #2
0
    def __init__(self, hass, name, state_topic, command_topic, qos,
                 payload_disarm, payload_arm_home, payload_arm_away, code):
        """Initalize the MQTT alarm panel."""
        self._state = STATE_UNKNOWN
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        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

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if payload not in (STATE_ALARM_DISARMED, STATE_ALARM_ARMED_HOME,
                               STATE_ALARM_ARMED_AWAY, STATE_ALARM_PENDING,
                               STATE_ALARM_TRIGGERED):
                _LOGGER.warning('Received unexpected payload: %s', payload)
                return
            self._state = payload
            self.update_ha_state()

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #3
0
    def test_subscribe_topic_subtree_wildcard_no_match(self):
        mqtt.subscribe(self.hass, 'test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'another-test-topic', 'test-payload')

        self.hass.pool.block_till_done()
        self.assertEqual(0, len(self.calls))
예제 #4
0
def setup_scanner(hass, config, see):
    """ Set up a OwnTracksks tracker. """

    def owntracks_location_update(topic, payload, qos):
        """ MQTT message received. """

        # Docs on available data:
        # http://owntracks.org/booklet/tech/json/#_typelocation
        try:
            data = json.loads(payload)
        except ValueError:
            # If invalid JSON
            logging.getLogger(__name__).error(
                'Unable to parse payload as JSON: %s', payload)
            return

        if not isinstance(data, dict) or data.get('_type') != 'location':
            return

        parts = topic.split('/')
        kwargs = {
            'dev_id': '{}_{}'.format(parts[1], parts[2]),
            'host_name': parts[1],
            'gps': (data['lat'], data['lon']),
        }
        if 'acc' in data:
            kwargs['gps_accuracy'] = data['acc']
        if 'batt' in data:
            kwargs['battery'] = data['batt']

        see(**kwargs)

    mqtt.subscribe(hass, LOCATION_TOPIC, owntracks_location_update, 1)

    return True
예제 #5
0
    def __init__(self, hass, name, state_topic, command_topic, qos,
                 payload_up, payload_down, payload_stop, value_template):
        """Initialize the roller shutter."""
        self._state = None
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._payload_up = payload_up
        self._payload_down = payload_down
        self._payload_stop = payload_stop

        if self._state_topic is None:
            return

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = value_template.render_with_possible_json_value(
                    payload)
            if payload.isnumeric() and 0 <= int(payload) <= 100:
                self._state = int(payload)
                self.update_ha_state()
            else:
                _LOGGER.warning(
                    "Payload is expected to be an integer between 0 and 100")

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #6
0
    def __init__(self, hass, name, state_topic, command_topic, qos,
                 payload_up, payload_down, payload_stop, state_format):
        self._state = None
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._payload_up = payload_up
        self._payload_down = payload_down
        self._payload_stop = payload_stop
        self._parse = mqtt.FmtParser(state_format)

        if self._state_topic is None:
            return

        def message_received(topic, payload, qos):
            """ A new MQTT message has been received. """
            value = self._parse(payload)
            if value.isnumeric() and 0 <= int(value) <= 100:
                self._state = int(value)
                self.update_ha_state()
            else:
                _LOGGER.warning(
                    "Payload is expected to be an integer between 0 and 100")

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #7
0
    def __init__(self, hass, name, state_topic, sensor_class, qos, payload_on,
                 payload_off, value_template):
        """Initialize the MQTT binary sensor."""
        self._hass = hass
        self._name = name
        self._state = False
        self._state_topic = state_topic
        self._sensor_class = sensor_class
        self._payload_on = payload_on
        self._payload_off = payload_off
        self._qos = qos

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = template.render_with_possible_json_value(
                    hass, value_template, payload)
            if payload == self._payload_on:
                self._state = True
                self.update_ha_state()
            elif payload == self._payload_off:
                self._state = False
                self.update_ha_state()

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #8
0
    def __init__(self, hass, name, state_topic, command_topic, qos, retain,
                 payload_lock, payload_unlock, optimistic, value_template):
        """Initialize the lock."""
        self._state = False
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._retain = retain
        self._payload_lock = payload_lock
        self._payload_unlock = payload_unlock
        self._optimistic = optimistic

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = value_template.render_with_possible_json_value(
                    payload)
            if payload == self._payload_lock:
                self._state = True
                self.schedule_update_ha_state()
            elif payload == self._payload_unlock:
                self._state = False
                self.schedule_update_ha_state()

        if self._state_topic is None:
            # Force into optimistic mode.
            self._optimistic = True
        else:
            mqtt.subscribe(
                hass, self._state_topic, message_received, self._qos)
예제 #9
0
    def __init__(self, hass, name, state_topic, command_topic, qos, retain,
                 payload_on, payload_off, optimistic, value_template):
        """Initialize the MQTT switch."""
        self._state = False
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._retain = retain
        self._payload_on = payload_on
        self._payload_off = payload_off
        self._optimistic = optimistic

        @callback
        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = value_template.async_render_with_possible_json_value(
                    payload)
            if payload == self._payload_on:
                self._state = True
                hass.async_add_job(self.async_update_ha_state())
            elif payload == self._payload_off:
                self._state = False
                hass.async_add_job(self.async_update_ha_state())

        if self._state_topic is None:
            # Force into optimistic mode.
            self._optimistic = True
        else:
            mqtt.subscribe(
                hass, self._state_topic, message_received, self._qos)
예제 #10
0
    def test_restore_all_active_subscriptions_on_reconnect(self):
        """Test active subscriptions are restored correctly on reconnect."""
        self.hass.data['mqtt']._mqttc.subscribe.side_effect = (
            (0, 1), (0, 2), (0, 3), (0, 4)
        )

        unsub = mqtt.subscribe(self.hass, 'test/state', None, qos=2)
        mqtt.subscribe(self.hass, 'test/state', None)
        mqtt.subscribe(self.hass, 'test/state', None, qos=1)
        self.hass.block_till_done()

        expected = [
            mock.call('test/state', 2),
            mock.call('test/state', 0),
            mock.call('test/state', 1)
        ]
        assert self.hass.data['mqtt']._mqttc.subscribe.mock_calls == \
            expected

        unsub()
        self.hass.block_till_done()
        assert self.hass.data['mqtt']._mqttc.unsubscribe.call_count == \
            0

        self.hass.data['mqtt']._mqtt_on_disconnect(None, None, 0)
        self.hass.data['mqtt']._mqtt_on_connect(None, None, None, 0)
        self.hass.block_till_done()

        expected.append(mock.call('test/state', 1))
        assert self.hass.data['mqtt']._mqttc.subscribe.mock_calls == \
            expected
예제 #11
0
    def __init__(self, hass, name, state_topic, command_topic, qos, retain,
                 state_open, state_closed, service_open, service_close,
                 optimistic, value_template):
        """Initialize the garage door."""
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._retain = retain
        self._state_open = state_open
        self._state_closed = state_closed
        self._service_open = service_open
        self._service_close = service_close
        self._optimistic = optimistic or state_topic is None
        self._state = False

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = template.render_with_possible_json_value(
                    hass, value_template, payload)
            if payload == self._state_open:
                self._state = True
                self.update_ha_state()
            elif payload == self._state_closed:
                self._state = False
                self.update_ha_state()

        if self._state_topic is None:
            # Force into optimistic mode.
            self._optimistic = True
        else:
            mqtt.subscribe(hass, self._state_topic, message_received,
                           self._qos)
예제 #12
0
    def __init__(self, hass, name, state_topic, command_topic, qos, retain,
                 payload_on, payload_off, optimistic, value_template):
        self._state = False
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._retain = retain
        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 value_template is not None:
                payload = template.render_with_possible_json_value(
                    hass, value_template, payload)
            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,
                           self._qos)
예제 #13
0
    def test_subscribe_topic_level_wildcard_and_wildcard_level_no_match(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, '+/test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'hi/here-iam/test-topic', 'test-payload')

        self.hass.block_till_done()
        self.assertEqual(0, len(self.calls))
예제 #14
0
    def test_subscribe_topic_not_match(self):
        """Test if subscribed topic is not a match."""
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls)

        fire_mqtt_message(self.hass, 'another-test-topic', 'test-payload')

        self.hass.block_till_done()
        self.assertEqual(0, len(self.calls))
예제 #15
0
    def test_subscribe_topic_level_wildcard_no_subtree_match(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, 'test-topic/+/on', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic/bier', 'test-payload')

        self.hass.block_till_done()
        self.assertEqual(0, len(self.calls))
예제 #16
0
    def test_subscribe_topic_subtree_wildcard_no_match(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, 'test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'another-test-topic', 'test-payload')

        self.hass.block_till_done()
        assert 0 == len(self.calls)
예제 #17
0
    def test_subscribe_topic_subtree_wildcard_no_match(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, "test-topic/#", self.record_calls)

        fire_mqtt_message(self.hass, "another-test-topic", "test-payload")

        self.hass.block_till_done()
        self.assertEqual(0, len(self.calls))
예제 #18
0
    def test_subscribe_topic_subtree_wildcard_root_topic(self):
        mqtt.subscribe(self.hass, 'test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic', 'test-payload')

        self.hass.pool.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('test-topic', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #19
0
    def test_subscribe_topic_level_wildcard(self):
        mqtt.subscribe(self.hass, 'test-topic/+/on', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic/bier/on', 'test-payload')

        self.hass.pool.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('test-topic/bier/on', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #20
0
    def __init__(self, hass, name, topic, qos, retain,
                 optimistic, brightness, rgb, flash_times):
        """Initialize MQTT JSON light."""
        self._hass = hass
        self._name = name
        self._topic = topic
        self._qos = qos
        self._retain = retain
        self._optimistic = optimistic or topic[CONF_STATE_TOPIC] is None
        self._state = False
        if brightness:
            self._brightness = 255
        else:
            self._brightness = None

        if rgb:
            self._rgb = [0, 0, 0]
        else:
            self._rgb = None

        self._flash_times = flash_times

        def state_received(topic, payload, qos):
            """A new MQTT message has been received."""
            values = json.loads(payload)

            if values['state'] == 'ON':
                self._state = True
            elif values['state'] == 'OFF':
                self._state = False

            if self._rgb is not None:
                try:
                    red = int(values['color']['r'])
                    green = int(values['color']['g'])
                    blue = int(values['color']['b'])

                    self._rgb = [red, green, blue]
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning("Invalid color value received")

            if self._brightness is not None:
                try:
                    self._brightness = int(values['brightness'])
                except KeyError:
                    pass
                except ValueError:
                    _LOGGER.warning('Invalid brightness value received')

            self.update_ha_state()

        if self._topic[CONF_STATE_TOPIC] is not None:
            mqtt.subscribe(self._hass, self._topic[CONF_STATE_TOPIC],
                           state_received, self._qos)
예제 #21
0
    def test_subscribe_topic_sys_root(self):
        """Test the subscription of $ root topics."""
        mqtt.subscribe(self.hass, '$test-topic/subtree/on', self.record_calls)

        fire_mqtt_message(self.hass, '$test-topic/subtree/on', 'test-payload')

        self.hass.block_till_done()
        assert 1 == len(self.calls)
        assert '$test-topic/subtree/on' == self.calls[0][0].topic
        assert 'test-payload' == self.calls[0][0].payload
예제 #22
0
    def test_subscribe_topic_subtree_wildcard_subtree_topic(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, 'test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic/bier/on', 'test-payload')

        self.hass.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('test-topic/bier/on', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #23
0
    def test_not_calling_unsubscribe_with_active_subscribers(self):
        """Test not calling unsubscribe() when other subscribers are active."""
        unsub = mqtt.subscribe(self.hass, 'test/state', None)
        mqtt.subscribe(self.hass, 'test/state', None)
        self.hass.block_till_done()
        assert self.hass.data['mqtt']._mqttc.subscribe.called

        unsub()
        self.hass.block_till_done()
        assert not self.hass.data['mqtt']._mqttc.unsubscribe.called
예제 #24
0
    def test_restore_subscriptions_on_reconnect(self):
        """Test subscriptions are restored on reconnect."""
        mqtt.subscribe(self.hass, 'test/state', None)
        self.hass.block_till_done()
        assert self.hass.data['mqtt']._mqttc.subscribe.call_count == 1

        self.hass.data['mqtt']._mqtt_on_disconnect(None, None, 0)
        self.hass.data['mqtt']._mqtt_on_connect(None, None, None, 0)
        self.hass.block_till_done()
        assert self.hass.data['mqtt']._mqttc.subscribe.call_count == 2
예제 #25
0
    def test_subscribe_topic_subtree_wildcard_root_topic(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, 'test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic', 'test-payload')

        self.hass.block_till_done()
        assert 1 == len(self.calls)
        assert 'test-topic' == self.calls[0][0]
        assert 'test-payload' == self.calls[0][1]
예제 #26
0
    def test_subscribe_topic(self):
        """Test the subscription of a topic."""
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic', 'test-payload')

        self.hass.pool.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('test-topic', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #27
0
    def test_subscribe_topic_level_wildcard_and_wildcard_subtree_topic(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, '+/test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, 'hi/test-topic/here-iam', 'test-payload')

        self.hass.block_till_done()
        assert 1 == len(self.calls)
        assert 'hi/test-topic/here-iam' == self.calls[0][0].topic
        assert 'test-payload' == self.calls[0][0].payload
예제 #28
0
    def test_subscribe_topic_sys_root_and_wildcard_topic(self):
        """Test the subscription of $ root and wildcard topics."""
        mqtt.subscribe(self.hass, '$test-topic/#', self.record_calls)

        fire_mqtt_message(self.hass, '$test-topic/some-topic', 'test-payload')

        self.hass.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('$test-topic/some-topic', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #29
0
    def test_subscribe_topic_level_wildcard(self):
        """Test the subscription of wildcard topics."""
        mqtt.subscribe(self.hass, 'test-topic/+/on', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic/bier/on', 'test-payload')

        self.hass.block_till_done()
        assert 1 == len(self.calls)
        assert 'test-topic/bier/on' == self.calls[0][0].topic
        assert 'test-payload' == self.calls[0][0].payload
예제 #30
0
    def test_all_subscriptions_run_when_decode_fails(self):
        """Test all other subscriptions still run when decode fails for one."""
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls,
                       encoding='ascii')
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic', '°C')

        self.hass.block_till_done()
        assert 1 == len(self.calls)
예제 #31
0
    def test_subscribe_topic_sys_root_and_wildcard_subtree_topic(self):
        """Test the subscription of $ root and wildcard subtree topics."""
        mqtt.subscribe(self.hass, "$test-topic/subtree/#", self.record_calls)

        fire_mqtt_message(self.hass, "$test-topic/subtree/some-topic",
                          "test-payload")

        self.hass.block_till_done()
        assert len(self.calls) == 1
        assert self.calls[0][0].topic == "$test-topic/subtree/some-topic"
        assert self.calls[0][0].payload == "test-payload"
예제 #32
0
    def test_subscribe_topic_sys_root_and_wildcard_subtree_topic(self):
        """Test the subscription of $ root and wildcard subtree topics."""
        mqtt.subscribe(self.hass, '$test-topic/subtree/#', self.record_calls)

        fire_mqtt_message(self.hass, '$test-topic/subtree/some-topic',
                          'test-payload')

        self.hass.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual('$test-topic/subtree/some-topic', self.calls[0][0])
        self.assertEqual('test-payload', self.calls[0][1])
예제 #33
0
    def test_all_subscriptions_run_when_decode_fails(self):
        """Test all other subscriptions still run when decode fails for one."""
        mqtt.subscribe(self.hass,
                       "test-topic",
                       self.record_calls,
                       encoding="ascii")
        mqtt.subscribe(self.hass, "test-topic", self.record_calls)

        fire_mqtt_message(self.hass, "test-topic", "°C")

        self.hass.block_till_done()
        assert len(self.calls) == 1
예제 #34
0
    def test_subscribe_special_characters(self):
        """Test the subscription to topics with special characters."""
        topic = "/test-topic/$(.)[^]{-}"
        payload = "p4y.l[]a|> ?"

        mqtt.subscribe(self.hass, topic, self.record_calls)

        fire_mqtt_message(self.hass, topic, payload)
        self.hass.block_till_done()
        assert len(self.calls) == 1
        assert self.calls[0][0].topic == topic
        assert self.calls[0][0].payload == payload
예제 #35
0
    def test_receiving_non_utf8_message_gets_logged(self):
        """Test receiving a non utf8 encoded message."""
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls)

        with self.assertLogs(level='WARNING') as test_handle:
            fire_mqtt_message(self.hass, 'test-topic', b'\x9a')

            self.hass.block_till_done()
            self.assertIn(
                "WARNING:homeassistant.components.mqtt:Can't decode payload "
                "b'\\x9a' on test-topic with encoding utf-8",
                test_handle.output[0])
예제 #36
0
    def test_all_subscriptions_run_when_decode_fails(self):
        """Test all other subscriptions still run when decode fails for one."""
        mqtt.subscribe(self.hass,
                       'test-topic',
                       self.record_calls,
                       encoding='ascii')
        mqtt.subscribe(self.hass, 'test-topic', self.record_calls)

        fire_mqtt_message(self.hass, 'test-topic', '°C')

        self.hass.block_till_done()
        self.assertEqual(1, len(self.calls))
예제 #37
0
    def test_subscribe_special_characters(self):
        """Test the subscription to topics with special characters."""
        topic = '/test-topic/$(.)[^]{-}'
        payload = 'p4y.l[]a|> ?'

        mqtt.subscribe(self.hass, topic, self.record_calls)

        fire_mqtt_message(self.hass, topic, payload)
        self.hass.block_till_done()
        self.assertEqual(1, len(self.calls))
        self.assertEqual(topic, self.calls[0][0])
        self.assertEqual(payload, self.calls[0][1])
예제 #38
0
파일: mqtt.py 프로젝트: wuub/home-assistant
    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)
예제 #39
0
    def test_not_calling_unsubscribe_with_active_subscribers(self):
        """Test not calling unsubscribe() when other subscribers are active."""
        # Fake that the client is connected
        self.hass.data["mqtt"].connected = True

        unsub = mqtt.subscribe(self.hass, "test/state", None)
        mqtt.subscribe(self.hass, "test/state", None)
        self.hass.block_till_done()
        assert self.hass.data["mqtt"]._mqttc.subscribe.called

        unsub()
        self.hass.block_till_done()
        assert not self.hass.data["mqtt"]._mqttc.unsubscribe.called
예제 #40
0
    def test_restore_subscriptions_on_reconnect(self):
        """Test subscriptions are restored on reconnect."""
        # Fake that the client is connected
        self.hass.data["mqtt"].connected = True

        mqtt.subscribe(self.hass, "test/state", None)
        self.hass.block_till_done()
        assert self.hass.data["mqtt"]._mqttc.subscribe.call_count == 1

        self.hass.data["mqtt"]._mqtt_on_disconnect(None, None, 0)
        self.hass.data["mqtt"]._mqtt_on_connect(None, None, None, 0)
        self.hass.block_till_done()
        assert self.hass.data["mqtt"]._mqttc.subscribe.call_count == 2
예제 #41
0
def trigger(hass, config, action):
    """Listen for state changes based on configuration."""
    topic = config[CONF_TOPIC]
    payload = config.get(CONF_PAYLOAD)

    def mqtt_automation_listener(msg_topic, msg_payload, qos):
        """Listen for MQTT messages."""
        if payload is None or payload == msg_payload:
            action()

    mqtt.subscribe(hass, topic, mqtt_automation_listener)

    return True
예제 #42
0
    def __init__(self, hass, name, min_volume, max_volume, power_dict,
                 vol_dict, mute_dict, source_dict):
        """Initialize the MQTT_MEDIA Receiver device."""
        self._name = name
        self._min_volume = min_volume
        self._max_volume = max_volume
        self._source_dict = source_dict
        self._power_dict = power_dict
        self._vol_dict = vol_dict
        self._mute_dict = mute_dict
        self._volume = 0
        self._state = STATE_UNKNOWN
        self._mute = STATE_OFF
        self._source = None
        self._payload_off = "OFF"
        self._payload_on = "ON"
        self._retain = False
        self._qos = 0

        mqtt.subscribe(hass, self._source_dict["status_topic"],
                       self.message_source_selected, self._qos)
        mqtt.subscribe(hass, self._power_dict["status_topic"],
                       self.message_power_changed, self._qos)
        mqtt.subscribe(hass, self._vol_dict["status_topic"],
                       self.message_volume_changed, self._qos)
        mqtt.subscribe(hass, self._mute_dict["status_topic"],
                       self.message_mute_changed, self._qos)
예제 #43
0
    def __init__(self, hass, name, state_topic, device_id, timeout,
                 consider_home):
        """Initialize the sensor."""
        self._state = STATE_AWAY
        self._hass = hass
        self._name = name
        self._state_topic = '{}{}'.format(state_topic, '/+')
        self._device_id = slugify(device_id).upper()
        self._timeout = timeout
        self._consider_home = \
            timedelta(seconds=consider_home) if consider_home \
            else None
        self._distance = None
        self._updated = None

        def update_state(device_id, room, distance):
            """Update the sensor state."""
            self._state = room
            self._distance = distance
            self._updated = dt.utcnow()

            self.update_ha_state()

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            try:
                data = MQTT_PAYLOAD(payload)
            except vol.MultipleInvalid as error:
                _LOGGER.debug(
                    'skipping update because of malformatted '
                    'data: %s', error)
                return

            device = _parse_update_data(topic, data)
            if device.get(CONF_DEVICE_ID) == self._device_id:
                if self._distance is None or self._updated is None:
                    update_state(**device)
                else:
                    # update if:
                    # device is in the same room OR
                    # device is closer to another room OR
                    # last update from other room was too long ago
                    timediff = dt.utcnow() - self._updated
                    if device.get(ATTR_ROOM) == self._state \
                            or device.get(ATTR_DISTANCE) < self._distance \
                            or timediff.seconds >= self._timeout:
                        update_state(**device)

        mqtt.subscribe(hass, self._state_topic, message_received, 1)
예제 #44
0
    def __init__(self, hass, name, state_topic, temperature_state_topic,
                 command_topic, qos, retain):
        """Initialize the MQTT Heatpump."""
        # self._state = False
        self._state = STATE_UNKNOWN
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._temperature_state_topic = temperature_state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._retain = retain
        self._current_temperature = None
        self._target_temperature = None
        self._fan_list = ["AUTO", "QUIET", "1", "2", "3", "4"]
        self._current_fan_mode = None
        self._operation_list = ["OFF", "HEAT", "DRY", "COOL", "FAN", "AUTO"]
        self._current_operation = None
        self._current_power = None
        self._swing_list = ["AUTO", "1", "2", "3", "4", "5", "SWING"]
        self._current_swing_mode = None

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            parsed = json.loads(payload)
            if topic == self._state_topic:
                self._target_temperature = float(parsed['temperature'])
                self._current_fan_mode = parsed['fan']
                self._current_swing_mode = parsed['vane']
                if parsed['power'] == "OFF":
                    _LOGGER.debug("Power Off")
                    self._current_operation = "OFF"
                    self._current_power = "OFF"
                else:
                    _LOGGER.debug("Power On")
                    self._current_operation = parsed['mode']
                    self._current_power = "ON"
            elif topic == self._temperature_state_topic:
                _LOGGER.debug('Room Temp: {0}'.format(
                    parsed['roomTemperature']))
                self._current_temperature = float(parsed['roomTemperature'])
            else:
                print("unknown topic")
            self.schedule_update_ha_state()
            _LOGGER.debug("Power=%s, Operation=%s", self._current_power,
                          self._current_operation)

        for topic in [self._state_topic, self._temperature_state_topic]:
            mqtt.subscribe(hass, topic, message_received, self._qos)
예제 #45
0
    def __init__(self, hass, name, state_topic, command_topic, qos, retain,
                 state_open, state_closed, payload_open, payload_close,
                 payload_stop, optimistic, value_template):
        """Initialize the cover."""
        self._position = None
        self._state = None
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._payload_open = payload_open
        self._payload_close = payload_close
        self._payload_stop = payload_stop
        self._state_open = state_open
        self._state_closed = state_closed
        self._retain = retain
        self._optimistic = optimistic or state_topic is None

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = value_template.render_with_possible_json_value(
                    payload)
            if payload == self._state_open:
                self._state = False
                _LOGGER.warning("state=%s", int(self._state))
                self.update_ha_state()
            elif payload == self._state_closed:
                self._state = True
                self.update_ha_state()
            elif payload.isnumeric() and 0 <= int(payload) <= 100:
                if int(payload) > 0:
                    self._state = False
                else:
                    self._state = True
                self._position = int(payload)
                self.update_ha_state()
            else:
                _LOGGER.warning(
                    "Payload is not True, False, or integer (0-100): %s",
                    payload)

        if self._state_topic is None:
            # Force into optimistic mode.
            self._optimistic = True
        else:
            mqtt.subscribe(hass, self._state_topic, message_received,
                           self._qos)
예제 #46
0
    def test_message_callback_exception_gets_logged(self):
        """Test exception raised by message handler."""
        @callback
        def bad_handler(*args):
            """Record calls."""
            raise Exception('This is a bad message callback')
        mqtt.subscribe(self.hass, 'test-topic', bad_handler)

        with self.assertLogs(level='WARNING') as test_handle:
            fire_mqtt_message(self.hass, 'test-topic', 'test')

            self.hass.block_till_done()
            assert \
                "Exception in bad_handler when handling msg on 'test-topic':" \
                " 'test'" in \
                test_handle.output[0]
예제 #47
0
파일: mqtt.py 프로젝트: loraxx753/skynet
def setup_scanner(hass, config, see, discovery_info=None):
    """Setup the MQTT tracker."""
    devices = config[CONF_DEVICES]
    qos = config[CONF_QOS]

    dev_id_lookup = {}

    def device_tracker_message_received(topic, payload, qos):
        """MQTT message received."""
        see(dev_id=dev_id_lookup[topic], location_name=payload)

    for dev_id, topic in devices.items():
        dev_id_lookup[topic] = dev_id
        mqtt.subscribe(hass, topic, device_tracker_message_received, qos)

    return True
예제 #48
0
    def test_retained_message_on_subscribe_received(self):
        """Test every subscriber receives retained message on subscribe."""
        def side_effect(*args):
            async_fire_mqtt_message(self.hass, 'test/state', 'online')
            return 0, 0

        self.hass.data['mqtt']._mqttc.subscribe.side_effect = side_effect

        calls_a = mock.MagicMock()
        mqtt.subscribe(self.hass, 'test/state', calls_a)
        self.hass.block_till_done()
        self.assertTrue(calls_a.called)

        calls_b = mock.MagicMock()
        mqtt.subscribe(self.hass, 'test/state', calls_b)
        self.hass.block_till_done()
        self.assertTrue(calls_b.called)
예제 #49
0
    def update_battery_level(self, now=None):
        payload = '85,3,1,16'
        sub_topic = self._mac_address + self._topic
        pub_topic = sub_topic + self._set_suffix
        mqtt.publish(self._hass, pub_topic, payload)

        @callback
        def msg_callback(msg):
            """Receive events published by and fire them on this hass instance."""
            results = msg.payload.split(',')
            # 返回数据5位是电量信息
            if len(results) == 5:
                battery_level = round(int(results[4]) / 10, 1)
                self._temperature_sensor.update_battery(battery_level)
                self._humidity_sensor.update_battery(battery_level)

        mqtt.subscribe(self._hass, sub_topic, msg_callback)
예제 #50
0
    def __init__(self, hass, name, state_topic, qos, unit_of_measurement,
                 value_template):
        self._state = STATE_UNKNOWN
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._qos = qos
        self._unit_of_measurement = unit_of_measurement

        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = template.render_with_possible_json_value(
                    hass, value_template, payload)
            self._state = payload
            self.update_ha_state()

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #51
0
파일: mqtt.py 프로젝트: wuub/home-assistant
def register(hass, config, action):
    """ Listen for state changes based on `config`. """
    topic = config.get(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):
        """ Listens for MQTT messages. """
        if payload is None or payload == msg_payload:
            action()

    mqtt.subscribe(hass, topic, mqtt_automation_listener)

    return True
예제 #52
0
    def __init__(self, hass, name, state_topic, command_topic, qos,
                 payload_disarm, payload_arm_home, payload_arm_away, code):
        self._state = STATE_UNKNOWN
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._command_topic = command_topic
        self._qos = qos
        self._payload_disarm = payload_disarm
        self._payload_arm_home = payload_arm_home
        self._payload_arm_away = payload_arm_away
        self._code = code

        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, self._qos)
예제 #53
0
    def test_retained_message_on_subscribe_received(self):
        """Test every subscriber receives retained message on subscribe."""
        def side_effect(*args):
            async_fire_mqtt_message(self.hass, "test/state", "online")
            return 0, 0

        self.hass.data["mqtt"]._mqttc.subscribe.side_effect = side_effect

        # Fake that the client is connected
        self.hass.data["mqtt"].connected = True

        calls_a = mock.MagicMock()
        mqtt.subscribe(self.hass, "test/state", calls_a)
        self.hass.block_till_done()
        assert calls_a.called

        calls_b = mock.MagicMock()
        mqtt.subscribe(self.hass, "test/state", calls_b)
        self.hass.block_till_done()
        assert calls_b.called
예제 #54
0
    def __init__(self, hass, name, state_topic, qos, unit_of_measurement,
                 value_template):
        """Initialize the sensor."""
        self._state = STATE_UNKNOWN
        self._hass = hass
        self._name = name
        self._state_topic = state_topic
        self._qos = qos
        self._unit_of_measurement = unit_of_measurement

        @callback
        def message_received(topic, payload, qos):
            """A new MQTT message has been received."""
            if value_template is not None:
                payload = value_template.async_render_with_possible_json_value(
                    payload, self._state)
            self._state = payload
            hass.async_add_job(self.async_update_ha_state())

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #55
0
def setup_scanner(hass, config, see):
    """ Set up a 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

    dev_id_lookup = {}

    def device_tracker_message_received(topic, payload, qos):
        """ MQTT message received. """
        see(dev_id=dev_id_lookup[topic], location_name=payload)

    for dev_id, topic in devices.items():
        dev_id_lookup[topic] = dev_id
        mqtt.subscribe(hass, topic, device_tracker_message_received, qos)

    return True
예제 #56
0
def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the ARWN platform."""
    def sensor_event_received(topic, payload, qos):
        """Process events as sensors.

        When a new event on our topic (arwn/#) is received we map it
        into a known kind of sensor based on topic name. If we've
        never seen this before, we keep this sensor around in a global
        cache. If we have seen it before, we update the values of the
        existing sensor. Either way, we push an ha state update at the
        end for the new event we've seen.

        This lets us dynamically incorporate sensors without any
        configuration on our side.
        """
        event = json.loads(payload)
        sensors = discover_sensors(topic, event)
        if not sensors:
            return

        if isinstance(sensors, ArwnSensor):
            sensors = (sensors, )

        if 'timestamp' in event:
            del event['timestamp']

        for sensor in sensors:
            if sensor.name not in SENSORS:
                sensor.hass = hass
                sensor.set_event(event)
                SENSORS[sensor.name] = sensor
                _LOGGER.debug("Registering new sensor %(name)s => %(event)s",
                              dict(name=sensor.name, event=event))
                add_devices((sensor, ))
            else:
                SENSORS[sensor.name].set_event(event)
            SENSORS[sensor.name].update_ha_state()

    mqtt.subscribe(hass, TOPIC, sensor_event_received, 0)
    return True
예제 #57
0
    def update_temperature_humidity(self, now=None):
        #check if battery level out of date
        if not (self._temperature_sensor.device_state_attributes[ATTR_BATTERY] and self._humidity_sensor.device_state_attributes[ATTR_BATTERY]):
            _LOGGER.info("update meizu battery because it's out of date")
            self.update_battery_level()
        payload = '85,3,8,17'
        sub_topic = self._mac_address + self._topic
        pub_topic = sub_topic + self._set_suffix
        mqtt.publish(self._hass, pub_topic, payload)

        @callback
        def msg_callback(msg):
            """Receive events published by and fire them on this hass instance."""
            results = msg.payload.split(',')
            # 返回数据8位是温湿度信息, 45位温度,67位是湿度
            if len(results) == 8:
                temperature = round((int(results[4]) + int(results[5]) * 16 * 16) / 100, 1)
                humidity = round((int(results[6]) + int(results[7]) * 16 * 16) / 100, 1)
                self._temperature_sensor.update_state(temperature)
                self._humidity_sensor.update_state(humidity)

        mqtt.subscribe(self._hass, sub_topic, msg_callback)
예제 #58
0
    def __init__(self, hass, name, state_topic, qos, payload_on, payload_off,
                 value_template):
        self._hass = hass
        self._name = name
        self._state = False
        self._state_topic = state_topic
        self._payload_on = payload_on
        self._payload_off = payload_off
        self._qos = qos

        def message_received(topic, payload, qos):
            """ A new MQTT message has been received. """
            if value_template is not None:
                payload = template.render_with_possible_json_value(
                    hass, value_template, payload)
            if payload == self._payload_on:
                self._state = True
                self.update_ha_state()
            elif payload == self._payload_off:
                self._state = False
                self.update_ha_state()

        mqtt.subscribe(hass, self._state_topic, message_received, self._qos)
예제 #59
0
    def __init__(self, hass, name, topic, rgb, qos, payload, brightness,
                 optimistic):

        self._hass = hass
        self._name = name
        self._topic = topic
        self._rgb = rgb
        self._qos = qos
        self._payload = payload
        self._brightness = brightness
        self._optimistic = optimistic
        self._state = False
        self._xy = None

        def message_received(topic, payload, qos):
            """ A new MQTT message has been received. """
            if payload == self._payload["on"]:
                self._state = True
            elif payload == self._payload["off"]:
                self._state = False

            self.update_ha_state()

        if self._topic["state_topic"] is None:
            # force optimistic mode
            self._optimistic = True
        else:
            # Subscribe the state_topic
            mqtt.subscribe(self._hass, self._topic["state_topic"],
                           message_received, self._qos)

        def brightness_received(topic, payload, qos):
            """ A new MQTT message for the brightness has been received. """
            self._brightness = int(payload)
            self.update_ha_state()

        def rgb_received(topic, payload, qos):
            """ A new MQTT message has been received. """
            self._rgb = [int(val) for val in payload.split(',')]
            self._xy = color_util.color_RGB_to_xy(int(self._rgb[0]),
                                                  int(self._rgb[1]),
                                                  int(self._rgb[2]))
            self.update_ha_state()

        if self._topic["brightness_state_topic"] is not None:
            mqtt.subscribe(self._hass, self._topic["brightness_state_topic"],
                           brightness_received, self._qos)
            self._brightness = 255
        else:
            self._brightness = None

        if self._topic["rgb_state_topic"] is not None:
            mqtt.subscribe(self._hass, self._topic["rgb_state_topic"],
                           rgb_received, self._qos)
            self._xy = [0, 0]
        else:
            self._xy = None
def setup(hass, config):
    """Setup the MQTT example component."""
    topic = config[DOMAIN][CONF_TOPIC]
    entity_id = 'mqtt_example.last_message'

    # Listen to a message on MQTT.
    def message_received(topic, payload, qos):
        """A new MQTT message has been received."""
        hass.states.set(entity_id, payload)

    mqtt.subscribe(hass, topic, message_received)

    hass.states.set(entity_id, 'No messages')

    # Service to publish a message on MQTT.
    def set_state_service(call):
        """Service to send a message."""
        mqtt.publish(hass, topic, call.data.get('new_state'))

    # Register our service with Home Assistant.
    hass.services.register(DOMAIN, 'set_state', set_state_service)

    # Return boolean to indicate that initialization was successfully.
    return True