Ejemplo n.º 1
0
def test__mqtt_command_callback_ignore_retained(caplog, topic: bytes,
                                                payload: bytes):
    ActorMock = _mock_actor_class(
        switchbot_mqtt._ButtonAutomator.MQTT_COMMAND_TOPIC_LEVELS)
    message = MQTTMessage(topic=topic)
    message.payload = payload
    message.retain = True
    with unittest.mock.patch.object(
            ActorMock, "__init__",
            return_value=None) as init_mock, unittest.mock.patch.object(
                ActorMock,
                "execute_command") as execute_command_mock, caplog.at_level(
                    logging.DEBUG):
        ActorMock._mqtt_command_callback(
            "client_dummy",
            switchbot_mqtt._MQTTCallbackUserdata(retry_count=4,
                                                 device_passwords={}),
            message,
        )
    init_mock.assert_not_called()
    execute_command_mock.assert_not_called()
    assert caplog.record_tuples == [
        (
            "switchbot_mqtt",
            logging.DEBUG,
            "received topic={} payload={!r}".format(topic.decode(), payload),
        ),
        ("switchbot_mqtt", logging.INFO, "ignoring retained message"),
    ]
Ejemplo n.º 2
0
def test__mqtt_command_callback_invalid_mac_address(caplog, mac_address: str,
                                                    payload: bytes):
    ActorMock = _mock_actor_class(
        switchbot_mqtt._ButtonAutomator.MQTT_COMMAND_TOPIC_LEVELS)
    topic = "homeassistant/switch/switchbot/{}/set".format(
        mac_address).encode()
    message = MQTTMessage(topic=topic)
    message.payload = payload
    with unittest.mock.patch.object(
            ActorMock, "__init__",
            return_value=None) as init_mock, unittest.mock.patch.object(
                ActorMock,
                "execute_command") as execute_command_mock, caplog.at_level(
                    logging.DEBUG):
        ActorMock._mqtt_command_callback(
            "client_dummy",
            switchbot_mqtt._MQTTCallbackUserdata(retry_count=3,
                                                 device_passwords={}),
            message,
        )
    init_mock.assert_not_called()
    execute_command_mock.assert_not_called()
    assert caplog.record_tuples == [
        (
            "switchbot_mqtt",
            logging.DEBUG,
            "received topic={} payload={!r}".format(topic.decode(), payload),
        ),
        (
            "switchbot_mqtt",
            logging.WARNING,
            "invalid mac address {}".format(mac_address),
        ),
    ]
Ejemplo n.º 3
0
def test__mqtt_command_callback_password(mac_address, expected_password):
    ActorMock = _mock_actor_class([
        "switchbot",
        switchbot_mqtt._MQTTTopicPlaceholder.MAC_ADDRESS,
    ])
    message = MQTTMessage(topic=b"switchbot/" + mac_address.encode())
    message.payload = b"whatever"
    callback_userdata = switchbot_mqtt._MQTTCallbackUserdata(
        retry_count=3,
        device_passwords={
            "11:22:33:44:55:77": "test",
            "aa:bb:cc:dd:ee:ff": "secret",
            "11:22:33:dd:ee:ff": "äöü",
        },
    )
    with unittest.mock.patch.object(
            ActorMock, "__init__",
            return_value=None) as init_mock, unittest.mock.patch.object(
                ActorMock, "execute_command") as execute_command_mock:
        ActorMock._mqtt_command_callback("client_dummy", callback_userdata,
                                         message)
    init_mock.assert_called_once_with(mac_address=mac_address,
                                      retry_count=3,
                                      password=expected_password)
    execute_command_mock.assert_called_once_with(
        mqtt_client="client_dummy", mqtt_message_payload=b"whatever")
Ejemplo n.º 4
0
def test__mqtt_command_callback(
    caplog,
    command_topic_levels: typing.List[switchbot_mqtt._MQTTTopicLevel],
    topic: bytes,
    payload: bytes,
    expected_mac_address: str,
    retry_count: int,
):
    ActorMock = _mock_actor_class(command_topic_levels)
    message = MQTTMessage(topic=topic)
    message.payload = payload
    callback_userdata = switchbot_mqtt._MQTTCallbackUserdata(
        retry_count=retry_count, device_passwords={})
    with unittest.mock.patch.object(
            ActorMock, "__init__",
            return_value=None) as init_mock, unittest.mock.patch.object(
                ActorMock,
                "execute_command") as execute_command_mock, caplog.at_level(
                    logging.DEBUG):
        ActorMock._mqtt_command_callback("client_dummy", callback_userdata,
                                         message)
    init_mock.assert_called_once_with(mac_address=expected_mac_address,
                                      retry_count=retry_count,
                                      password=None)
    execute_command_mock.assert_called_once_with(mqtt_client="client_dummy",
                                                 mqtt_message_payload=payload)
    assert caplog.record_tuples == [(
        "switchbot_mqtt",
        logging.DEBUG,
        "received topic={} payload={!r}".format(topic.decode(), payload),
    )]
Ejemplo n.º 5
0
def test_mqtt_handle_on_message_save_device_data(app_and_ctx, capsys):
    device_id = 9999  # not present
    tid_bi = 'b209eba637a54f1f617cf5a6f925e4eb9fc083e66029061018b369e64b9864d7'  # blind_index(hex_to_key("622c23fe2623e54ba103c13b88072ca3fdc5836fc459cb2b5c31d8df3f07ebc2"), "8")
    payload = b"{'added': 6987, 'num_data': 31164, 'data': 'gAAAAABcTFAz9Wr5ZsnMcVYbQiXlnZCvT36MfDatZNyLwDpm_ixbzkZhM1NA4w7MN2p3CW3gyTA8gYtuKtDTomhulszvLTFfPA==', 'tid': 'encrypted_tid(8)', 'tid_bi': '%b', 'correctness_hash': '$2b$12$9hxKg4pjXbm0kpbItQTd2uMICAGn2ntRw1qQskHIL/7tLa3ISIlmO'}" % tid_bi.encode(
    )

    topic = b"d:%a/server/save_data" % device_id
    msg = MQTTMessage(topic=topic)
    msg.payload = payload

    invalid_topic = b"d:%a/server/invalid" % device_id
    msg_invalid = MQTTMessage(topic=invalid_topic)
    msg_invalid.payload = payload

    from app.mqtt.mqtt import handle_on_message
    app, ctx = app_and_ctx
    with app.app_context():
        handle_on_message(None, None, msg_invalid, app, db)
        captured = capsys.readouterr()
        assert f"Invalid topic: {msg_invalid.topic}" in captured.out

        handle_on_message(None, None, msg, app, db)
        captured = capsys.readouterr()
        assert f"Device with id: {device_id} doesn't exist." in captured.out
        device_data = db.session.query(DeviceData).filter(
            and_(
                DeviceData.tid_bi == tid_bi,
                DeviceData.device_id == device_id,
            )).first()
        assert device_data is None
        msg.payload = payload  # reassign, because `handle_on_message` causes side-effect and converts it to `dict`
        device_id = 23
        topic = b"d:%a/server/save_data" % device_id
        msg.topic = topic

        handle_on_message(None, None, msg, app, db)

        device_data = db.session.query(DeviceData).filter(
            and_(
                DeviceData.tid_bi == tid_bi,
                DeviceData.device_id == device_id,
            )).first()
        assert device_data is not None
        assert device_data.added == 6987
        assert device_data.num_data == 31164
Ejemplo n.º 6
0
def test_mqtt_handle_on_message_invalid_message(app_and_ctx, capsys):
    msg = MQTTMessage(topic=b"anything")
    msg.payload = b"invalid"
    from app.mqtt.mqtt import handle_on_message
    app, ctx = app_and_ctx
    with app.app_context():
        handle_on_message(None, None, msg, app, db)
        captured = capsys.readouterr()
        assert f"Received invalid message '" in captured.out
 def setUp(self):
     self.ddm = DeviceDataManager()
     self.ddm.actuator.addValue(15)
     self.mqt = MqttClientConnector()
     self.sd = SensorData()
     self.sd.addValue(14)
     mm = MQTTMessage()
     mm.payload = "ss"
     pass
Ejemplo n.º 8
0
 def private_publish(self, topic, payload=None, qos=0, retain=False):
     """
     Queue message internally without distribute to MQTT.
     """
     msg = MQTTMessage(topic=topic.encode())
     msg.payload = payload.encode() if payload else None
     msg.qos = qos
     msg.retain = retain
     self._queue.put(msg)
Ejemplo n.º 9
0
        def process_mqtt_message_to_action(command) -> Fsr61Action:
            message = MQTTMessage()
            message.payload = command

            device.packets.clear()
            device.process_mqtt_message(message)

            self.assertEqual(len(device.packets), 1)
            return Fsr61Eep.extract_packet(device.packets[0])
Ejemplo n.º 10
0
def get_client_with_messages(msgs: dict) -> HomieClient:
    c = HomieClient()

    for topic, payload in msgs.items():
        msg = MQTTMessage()
        msg.topic = topic.encode('utf-8')
        msg.payload = payload.encode('utf-8')
        c.on_message(None, None, msg)

    return c
Ejemplo n.º 11
0
def test_mqtt_handle_zone_control_utf8(mocker):
    interface = BasicMQTTInterface()
    interface.alarm = mocker.MagicMock()

    message = MQTTMessage(topic='paradox/control/zones/Előtér'.encode('utf-8'))
    message.payload = b'clear_bypass'

    interface._mqtt_handle_zone_control(None, None, message)

    interface.alarm.control_zone.assert_called_once_with(
        "Előtér", "clear_bypass")
Ejemplo n.º 12
0
def test_mqtt_handle_partition_control(command, expected, mocker):
    interface = BasicMQTTInterface()
    interface.alarm = mocker.MagicMock()

    message = MQTTMessage(topic=b'paradox/control/partition/First_floor')
    message.payload = command

    interface._mqtt_handle_partition_control(None, None, message)

    interface.alarm.control_partition.assert_called_once_with(
        "First_floor", expected)
Ejemplo n.º 13
0
	def payload(message: MQTTMessage) -> dict:
		try:
			payload = json.loads(message.payload)
			if isinstance(payload, bool):
				message.payload = payload
				raise TypeError
		except (ValueError, TypeError):
			var = message.topic.split('/')[-1]
			payload = {var: message.payload}

		return payload
Ejemplo n.º 14
0
def send_message(topic=None, payload=None):

    # Mock an instance of an Eclipse Paho MQTTMessage
    message = MQTTMessage(mid=42, topic=topic.encode('utf-8'))
    message.payload = payload.encode('utf-8')

    # Signal the message to the machinery
    on_message(None, None, message)

    # Give the machinery some time to process the message
    time.sleep(0.05)
        def process_mqtt_message_to_command(mqtt_command) -> Fsb61Command:
            message = MQTTMessage()
            message.payload = mqtt_command

            device.packets.clear()
            device.process_mqtt_message(message)

            self.assertEqual(len(device.packets), 1)
            fsb61_command = Fsb61CommandConverter.extract_packet(
                device.packets[0])
            return fsb61_command
    def test_construct_message_2(self, fakedevice, interface):
        topic = "iot-2/type/testproduct123/id/{}/mon"
        topic = topic.format(fakedevice.id).encode("utf8")
        paho_message = MQTTMessage(topic=topic)
        paho_message.payload = b'{"Action": "Disconnect"}'
        event = Status(paho_message)

        message_2 = interface.construct_zconnect_message(event)

        assert message_2.category == "status"
        assert message_2.body == {"Action": "Disconnect"}
        assert message_2.device == fakedevice
    def test_generate_status_callback(self, fakedevice, interface):
        mocked = mock.Mock()

        topic = "iot-2/type/testproduct123/id/{}/mon"
        topic = topic.format(fakedevice.id).encode("utf8")
        paho_message = MQTTMessage(topic=topic)
        paho_message.payload = b'{"Action": "Disconnect"}'
        event = Status(paho_message)
        callback = interface.generate_status_callback(mocked)
        callback(event)

        assert mocked.call_count == 1
    def test_construct_message(self, fakedevice, interface):
        topic = (TOPIC.format("testproduct123", fakedevice.id,
                              "periodic").encode("utf8"))
        paho_message = MQTTMessage(topic=topic)
        paho_message.payload = b'{"foo": "bar"}'
        event = Event(paho_message, {"json": jsonCodec})

        message = interface.construct_zconnect_message(event)

        assert message.category == "periodic"
        assert message.body == {"foo": "bar"}
        assert message.device == fakedevice
Ejemplo n.º 19
0
def test_mqtt_handle_on_message_receive_pk_user_doesnt_have_this_device(
        app_and_ctx, capsys):
    pk = b'-----BEGIN PUBLIC KEY-----\\nMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE2rD6Bhju8WSEFogdBxZt/N+n7ziUPi5C\\nQU1gSQQDNm57fdDuYNDOR7Wwb1fq5tSl2TC1D6WRTIt1gzzCsApGpZ3PIs7Wdbil\\neJL/ETGa2Sqwav7JDH4r0V30sF4NqDok\\n-----END PUBLIC KEY-----\\n'
    user_id = 1
    device_id = 34
    msg = MQTTMessage(topic=b"d:%a/server/" % device_id)
    msg.payload = b"{'user_id': %a, " \
                  b"'device_public_key': '%b'}" % (user_id, pk)
    from app.mqtt.mqtt import handle_on_message
    app, ctx = app_and_ctx
    with app.app_context():
        handle_on_message(None, None, msg, app, db)
        captured = capsys.readouterr()
        assert f"This User can't access device {device_id}" in captured.out
Ejemplo n.º 20
0
def test__mqtt_on_message(
    topic: bytes,
    payload: bytes,
    expected_mac_address: str,
    expected_action: switchbot_mqtt._SwitchbotAction,
):
    message = MQTTMessage(topic=topic)
    message.payload = payload
    with unittest.mock.patch("switchbot_mqtt._send_command") as send_command_mock:
        switchbot_mqtt._mqtt_on_message("client_dummy", None, message)
    send_command_mock.assert_called_once_with(
        mqtt_client="client_dummy",
        switchbot_mac_address=expected_mac_address,
        action=expected_action,
    )
Ejemplo n.º 21
0
 def mqtt_pub(self, topic, payload):
     if isinstance(payload, unicode):
         local_payload = payload.encode('utf-8')
     elif isinstance(payload, (bytes, bytearray)):
         local_payload = payload
     elif isinstance(payload, (int, float)):
         local_payload = str(payload).encode('ascii')
     elif payload is None:
         local_payload = b''
     else:
         raise Exception(
             'payload must be a string, bytearray, int, float or None.')
     message = MQTTMessage(0, topic.encode('utf-8'))
     message.payload = local_payload
     cls.m2i._on_mqtt_message(None, None, message)
Ejemplo n.º 22
0
async def test_read_write(mqtt, client_id):
    """Test MQTT transport read and write."""
    mqtt_client = mqtt.return_value
    topic = f"{IN_PREFIX}/0/255/3/1/11"
    payload = "test"
    msg = MQTTMessage()
    msg.topic = topic.encode()
    msg.payload = payload.encode()
    messages = [msg]

    async def mock_messages():
        """Mock the messages generator."""
        for message in messages:
            yield message

    @asynccontextmanager
    async def filter_messages():
        """Mock filter messages."""
        yield mock_messages()

    mqtt_client.unfiltered_messages.side_effect = filter_messages

    transport = MQTTClient(HOST, PORT, IN_PREFIX, OUT_PREFIX)

    await transport.connect()

    assert mqtt.call_count == 1
    assert mqtt.call_args == call(
        HOST,
        PORT,
        client_id=client_id,
        logger=PAHO_MQTT_LOGGER,
        clean_session=True,
    )

    await asyncio.sleep(0)
    read = await transport.read()
    assert read == "0;255;3;1;11;test"

    await transport.write(read)
    assert mqtt_client.publish.call_count == 1
    assert mqtt_client.publish.call_args == call(
        f"{OUT_PREFIX}/0/255/3/1/11", qos=1, retain=False, timeout=10, payload=payload
    )

    await transport.disconnect()

    assert mqtt_client.disconnect.call_count == 1
Ejemplo n.º 23
0
async def test_mqtt_handle_door_control(mocker):
    interface = get_interface(mocker)
    try:
        await asyncio.sleep(0.01)

        message = MQTTMessage(topic="paradox/control/doors/Door 1".encode("utf-8"))
        message.payload = b"unlock"

        interface._mqtt_handle_door_control(None, None, message)

        await asyncio.sleep(0.01)
        interface.alarm.control_door.assert_called_once_with("Door 1", "unlock")
    finally:
        interface.stop()
        interface.join()
        assert not interface.is_alive()
    def test_parse_ibm_event(self, fakedevice, interface):
        topic = (TOPIC.format("testproduct123", fakedevice.id,
                              "example_category").encode("utf8"))

        paho_message = MQTTMessage(topic=topic)
        paho_message.payload = b'{"foo": "bar"}'

        event = Event(paho_message, {"json": jsonCodec})

        zconnect_message = interface.construct_zconnect_message(event)

        assert zconnect_message.device.id == fakedevice.id
        assert (zconnect_message.device.product.iot_name ==
                fakedevice.product.iot_name == "testproduct123")
        assert zconnect_message.category == "example_category"
        assert zconnect_message.body == {"foo": "bar"}
Ejemplo n.º 25
0
async def test_mqtt_handle_zone_control_utf8(mocker):
    interface = get_interface(mocker)
    try:
        await asyncio.sleep(0.01)

        message = MQTTMessage(topic="paradox/control/zones/Előtér".encode("utf-8"))
        message.payload = b"clear_bypass"

        interface._mqtt_handle_zone_control(None, None, message)

        await asyncio.sleep(0.01)
        interface.alarm.control_zone.assert_called_once_with("Előtér", "clear_bypass")
    finally:
        interface.stop()
        interface.join()
        assert not interface.is_alive()
Ejemplo n.º 26
0
async def test_read_failure(mqtt, client_id):
    """Test MQTT transport read failure."""
    mqtt_client = mqtt.return_value
    topic = f"{IN_PREFIX}/0/0/0/0/0"
    payload = "test"
    msg = MQTTMessage()
    msg.topic = topic.encode()
    msg.payload = payload.encode()
    messages = [msg]

    async def mock_messages():
        """Mock the messages generator."""
        for message in messages:
            yield message

    @asynccontextmanager
    async def filter_messages():
        """Mock filter messages."""
        yield mock_messages()
        raise MqttError("Boom")

    mqtt_client.unfiltered_messages.side_effect = filter_messages

    transport = MQTTClient(HOST, PORT, IN_PREFIX, OUT_PREFIX)

    await transport.connect()

    assert mqtt.call_count == 1
    assert mqtt.call_args == call(
        HOST,
        PORT,
        client_id=client_id,
        logger=PAHO_MQTT_LOGGER,
        clean_session=True,
    )

    await asyncio.sleep(0)
    read = await transport.read()

    assert read == "0;0;0;0;0;test"

    with pytest.raises(TransportFailedError):
        await transport.read()

    await transport.disconnect()

    assert mqtt_client.disconnect.call_count == 1
Ejemplo n.º 27
0
async def test_mqtt_handle_partition_control(command, expected, mocker):
    interface = get_interface(mocker)
    try:
        await asyncio.sleep(0.01)

        message = MQTTMessage(topic=b"paradox/control/partition/First_floor")
        message.payload = command

        interface._mqtt_handle_partition_control(None, None, message)
        await asyncio.sleep(0.01)

        interface.alarm.control_partition.assert_called_once_with(
            "First_floor", expected)
    finally:
        interface.stop()
        interface.join()
        assert not interface.is_alive()
Ejemplo n.º 28
0
 def resend_command(self):
     '''
     resend commands in self.pending_commands
     intended to be run 5 seconds or so after command sent to PLM
     '''
     self.log.debug('Running resend_command: {}'.format('no commands pending' if len(self.pending_commands.keys())==0 else self.pending_commands))
     for name, value in self.pending_commands.copy().items():
         if value[1] <=5:    #max 5 retries
             msg = MQTTMessage(topic=name.encode())
             msg.payload = str(value[0]).encode()
         else:
             self.log.error('Too many retries on sending command {}, {} - giving up'.format(name, value[0]))
             del self.pending_commands[name]
             self.publish_node(self.nodes[name])
             return
         self.log.warning('resending command {}, {} retry: {}'.format(name, value[0], value[1]))
         self.q.put_nowait(msg)
Ejemplo n.º 29
0
def test_subscribe(mock_broker, mocker):
    mqttc = MqttClient(port=1883, callback=callback)
    mqttc.subscribe(topic="sensor/temperature")

    # create a fake MQTT message
    msg = MQTTMessage(mid=MID)
    msg.topic = b"sensor/temperature"
    msg.payload = b"22.5"

    mocker.spy(mqttc, "callback")

    # trigger 2 messages received on the MQTT bus
    mqttc._client.on_message(mqttc._client, None, msg)
    mqttc._client.on_message(mqttc._client, None, msg)

    mqttc.stop()

    assert mqttc.callback.call_count == 2
Ejemplo n.º 30
0
    def publishText(self, session: DialogSession) -> Response:
        message = MQTTMessage()
        message.payload = json.dumps({
            'sessionId': session.sessionId,
            'siteId': session.deviceUid,
            'text': session.input
        })
        session.extend(message=message)

        self.MqttManager.publish(topic=constants.TOPIC_TEXT_CAPTURED,
                                 payload={
                                     'sessionId': session.sessionId,
                                     'text': session.input,
                                     'device': session.deviceUid,
                                     'likelihood': 1,
                                     'seconds': 1
                                 })
        return jsonify(success=True, sessionId=session.sessionId)