Esempio n. 1
0
async def test_base(aiohttp_client):
    remove_existing_db()
    bumper.db = "tests/tmp.db"  # Set db location for testing

    # Start MQTT
    mqtt_address = ("127.0.0.1", 8883)
    mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd")
    bumper.mqtt_server = mqtt_server
    await mqtt_server.broker_coro()

    # Start XMPP
    xmpp_address = ("127.0.0.1", 5223)
    xmpp_server = bumper.XMPPServer(xmpp_address)
    bumper.xmpp_server = xmpp_server
    await xmpp_server.start_async_server()

    # Start Helperbot
    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    bumper.mqtt_helperbot = mqtt_helperbot
    await mqtt_helperbot.start_helper_bot()

    client = await aiohttp_client(create_app)
    resp = await client.get("/")
    assert resp.status == 200

    mqtt_helperbot.Client.disconnect()

    await mqtt_server.broker.shutdown()

    bumper.xmpp_server.disconnect()
Esempio n. 2
0
async def test_helperbot_expire_message():
    mqtt_address = ("127.0.0.1", 8883)
    mqtt_server = bumper.MQTTServer(mqtt_address)
    await mqtt_server.broker_coro()

    with LogCapture("helperbot") as l:

        # Test broadcast message
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (mqtt_helperbot.Client._connected_state._value == True
                )  # Check helperbot is connected

        expire_msg_payload = '{"ret":"ok","ver":"0.13.5"}'
        expire_msg_topic_name = "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helper1/bumper/helper1/p/testgood/j"
        currenttime = time.time()
        mqtt_helperbot.command_responses.append({
            "time": currenttime,
            "topic": expire_msg_topic_name,
            "payload": expire_msg_payload,
        })

        assert {
            "time": currenttime,
            "topic": expire_msg_topic_name,
            "payload": expire_msg_payload,
        } in mqtt_helperbot.command_responses  # check message is in command_responses

        await asyncio.sleep(0.2)
        mqtt_helperbot.expire_msg_seconds = (
            0.1
        )  # Set expire message seconds to 0.1 so we don't wait 10 seconds
        msg_payload = "<ctl ts='1547822804960' td='DustCaseST' st='0'/>"
        msg_topic_name = "iot/atr/DustCaseST/bot_serial/ls1ok3/wC3g/x"
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(),
            hbmqtt.client.QOS_0)  # Send another message to force get_msg

        try:
            await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(),
                                   timeout=0.1)
        except asyncio.TimeoutError:
            pass

        assert {
            "time": currenttime,
            "topic": expire_msg_topic_name,
            "payload": expire_msg_payload,
        } not in mqtt_helperbot.command_responses  # check message was expired and removed from command_responses

        l.check_present((
            "helperbot",
            "DEBUG",
            "Pruning Message Due To Expiration - Message Topic: {}".format(
                expire_msg_topic_name),
        ))  # Check received message was logged
        mqtt_helperbot.Client.disconnect()

    await mqtt_server.broker.shutdown()
Esempio n. 3
0
async def test_nofileauth_mqttserver():
    with LogCapture() as l:
        
        mqtt_address = ("127.0.0.1", 8883)
        mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd-notfound")
        await mqtt_server.broker_coro()
        await mqtt_server.broker.shutdown()        

    l.check_present(
        ("hbmqtt.broker.plugins.bumper", "WARNING", 'Password file tests/passwd-notfound not found'),
        order_matters=False
    )
Esempio n. 4
0
async def test_mqttserver():
    if os.path.exists("tests/tmp.db"):
        os.remove("tests/tmp.db")  # Remove existing db

    bumper.db = "tests/tmp.db"  # Set db location for testing

    mqtt_address = ("127.0.0.1", 8883)

    mqtt_server = bumper.MQTTServer(mqtt_address)
    await mqtt_server.broker_coro()

    # Test helperbot connect
    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    await mqtt_helperbot.start_helper_bot()
    assert (mqtt_helperbot.Client._connected_state._value == True
            )  # Check helperbot is connected
    await mqtt_helperbot.Client.disconnect()

    # Test client connect
    bumper.user_add("user_123")  # Add user to db
    bumper.client_add("user_123", "ecouser.net",
                      "resource_123")  # Add client to db
    test_client = bumper.MQTTHelperBot(mqtt_address)
    test_client.client_id = "[email protected]/resource_123"
    # await test_client.start_helper_bot()
    test_client.Client = hbmqtt.client.MQTTClient(
        client_id=test_client.client_id, config={"check_hostname": False})

    await test_client.Client.connect(
        "mqtts://{}:{}/".format(test_client.address[0],
                                test_client.address[1]),
        cafile=bumper.ca_cert,
    )
    assert (test_client.Client._connected_state._value == True
            )  # Check client is connected
    await test_client.Client.disconnect()
    assert (test_client.Client._connected_state._value == False
            )  # Check client is disconnected

    # Test fake_bot connect
    fake_bot = bumper.MQTTHelperBot(mqtt_address)
    fake_bot.client_id = "bot_serial@ls1ok3/wC3g"
    await fake_bot.start_helper_bot()
    assert (fake_bot.Client._connected_state._value == True
            )  # Check fake_bot is connected
    await fake_bot.Client.disconnect()

    await asyncio.sleep(0.1)

    await mqtt_server.broker.shutdown()
Esempio n. 5
0
# bclient.set(bclienttemp)

if platform.system() == "Darwin":
    listen_host = "0.0.0.0"
else:
    listen_host = socket.gethostbyname(socket.gethostname())
    #listen_host = "localhost" #Try this if the above doesn't work

conf_address_443 = (listen_host, 443)
conf_address_8007 = (listen_host, 8007)
xmpp_address = (listen_host, 5223)
mqtt_address = (listen_host, 8883)

# start mqtt server on port 8883 (async)
mqtt_server = bumper.MQTTServer(mqtt_address,
                                run_async=True,
                                bumper_bots=bumper.bumper_bots_var,
                                bumper_clients=bumper.bumper_clients_var)
time.sleep(1.5)  #Wait for broker startup
# start mqtt_helperbot (async)
mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address,
                                      run_async=True,
                                      bumper_bots=bumper.bumper_bots_var,
                                      bumper_clients=bumper.bumper_clients_var)
# start conf server on port 443 (async) - Used for most https calls
conf_server = bumper.ConfServer(conf_address_443,
                                usessl=True,
                                run_async=True,
                                bumper_bots=bumper.bumper_bots_var,
                                bumper_clients=bumper.bumper_clients_var,
                                helperbot=mqtt_helperbot)
# start conf server on port 8007 (async) - Used for a load balancer request
Esempio n. 6
0
async def test_mqttserver():
    if os.path.exists("tests/tmp.db"):
        os.remove("tests/tmp.db")  # Remove existing db

    bumper.db = "tests/tmp.db"  # Set db location for testing

    mqtt_address = ("127.0.0.1", 8883)

    mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd", allow_anonymous=True)
    
    await mqtt_server.broker_coro()

    # Test helperbot connect
    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    await mqtt_helperbot.start_helper_bot()
    assert (
        mqtt_helperbot.Client._connected_state._value == True
    )  # Check helperbot is connected
    await mqtt_helperbot.Client.disconnect()

    # Test client connect
    bumper.user_add("user_123")  # Add user to db
    bumper.client_add("user_123", "ecouser.net", "resource_123")  # Add client to db
    test_client = bumper.MQTTHelperBot(mqtt_address)
    test_client.client_id = "[email protected]/resource_123"
    # await test_client.start_helper_bot()
    test_client.Client = hbmqtt.client.MQTTClient(
        client_id=test_client.client_id, config={"check_hostname": False}
    )

    await test_client.Client.connect(
        "mqtts://{}:{}/".format(test_client.address[0], test_client.address[1]),
        cafile=bumper.ca_cert,
    )
    assert (
        test_client.Client._connected_state._value == True
    )  # Check client is connected
    await test_client.Client.disconnect()
    assert (
        test_client.Client._connected_state._value == False
    )  # Check client is disconnected

    # Test fake_bot connect
    fake_bot = bumper.MQTTHelperBot(mqtt_address)
    fake_bot.client_id = "bot_serial@ls1ok3/wC3g"
    await fake_bot.start_helper_bot()
    assert (
        fake_bot.Client._connected_state._value == True
    )  # Check fake_bot is connected
    await fake_bot.Client.disconnect()

    # Test file auth client connect
    test_client = bumper.MQTTHelperBot(mqtt_address)
    test_client.client_id = "test-file-auth"
    # await test_client.start_helper_bot()
    test_client.Client = hbmqtt.client.MQTTClient(
        client_id=test_client.client_id, config={"check_hostname": False, "auto_reconnect": False, "reconnect_retries": 1}
    )

    # good user/pass
    await test_client.Client.connect(
        f"mqtts://*****:*****@{test_client.address[0]}:{test_client.address[1]}/",
        cafile=bumper.ca_cert, cleansession=True
    )

    assert (
        test_client.Client._connected_state._value == True
    )  # Check client is connected
    await test_client.Client.disconnect()
    assert (
        test_client.Client._connected_state._value == False
    )  # Check client is disconnected
    
    # bad password
    with LogCapture() as l:
        
        await test_client.Client.connect(
            f"mqtts://*****:*****@{test_client.address[0]}:{test_client.address[1]}/",
            cafile=bumper.ca_cert, cleansession=True
        )

        l.check_present(
                ("mqttserver", "INFO", "File Authentication Failed - Username: test-client - ClientID: test-file-auth"),
                order_matters=False
            )
    # no username in file    
        await test_client.Client.connect(
            f"mqtts://*****:*****@{test_client.address[0]}:{test_client.address[1]}/",
            cafile=bumper.ca_cert, cleansession=True
        )


        l.check_present(
            ("mqttserver", "INFO", 'File Authentication Failed - No Entry for Username: test-client-noexist - ClientID: test-file-auth'),
            order_matters=False
        )
    
    await mqtt_server.broker.shutdown()
Esempio n. 7
0
async def test_helperbot_sendcommand():
    mqtt_address = ("127.0.0.1", 8883)
    mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd")
    await mqtt_server.broker_coro()

    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    bumper.mqtt_helperbot = mqtt_helperbot
    await mqtt_helperbot.start_helper_bot()
    assert (
        mqtt_helperbot.Client._connected_state._value == True
    )  # Check helperbot is connected

    cmdjson = {
        "toType": "ls1ok3",
        "payloadType": "j",
        "toRes": "wC3g",
        "payload": {},
        "td": "q",
        "toId": "bot_serial",
        "cmdName": "GetWKVer",
        "auth": {
            "token": "us_52cb21fef8e547f38f4ec9a699a5d77e",
            "resource": "IOSF53D07BA",
            "userid": "fuid_tmpuser",
            "with": "users",
            "realm": "ecouser.net",
        },
    }
    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.1
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    commandresult = await mqtt_helperbot.send_command(cmdjson, "testfail")
    # Don't send a response, ensure timeout
    assert commandresult == {
        "debug": "wait for response timed out",
        "errno": 500,
        "id": "testfail",
        "ret": "fail",
    }  # Check timeout

    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.2
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    # Send response beforehand
    msg_payload = '{"ret":"ok","ver":"0.13.5"}'
    msg_topic_name = (
        "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testgood/j"
    )
    await mqtt_helperbot.Client.publish(
        msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
    )

    commandresult = await mqtt_helperbot.send_command(cmdjson, "testgood")
    assert commandresult == {
        "id": "testgood",
        "resp": {"ret": "ok", "ver": "0.13.5"},
        "ret": "ok",
    }

    #mqtt_helperbot.Client.disconnect()

    # Test GetLifeSpan (xml command)
    cmdjson = {
        "toType": "ls1ok3",
        "payloadType": "x",
        "toRes": "wC3g",
        "payload": '<ctl type="Brush"/>',
        "td": "q",
        "toId": "bot_serial",
        "cmdName": "GetLifeSpan",
        "auth": {
            "token": "us_52cb21fef8e547f38f4ec9a699a5d77e",
            "resource": "IOSF53D07BA",
            "userid": "fuid_tmpuser",
            "with": "users",
            "realm": "ecouser.net",
        },
    }

    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.2
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    # Send response beforehand
    msg_payload = "<ctl ret='ok' type='Brush' left='4142' total='18000'/>"
    msg_topic_name = (
        "iot/p2p/GetLifeSpan/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testx/q"
    )
    await mqtt_helperbot.Client.publish(
        msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
    )

    commandresult = await mqtt_helperbot.send_command(cmdjson, "testx")
    assert commandresult == {
        "id": "testx",
        "resp": "<ctl ret='ok' type='Brush' left='4142' total='18000'/>",
        "ret": "ok",
    }

    # Test json payload (OZMO950)
    cmdjson = {
        "toType": "ls1ok3",
        "payloadType": "j",
        "toRes": "wC3g",
        "payload": {
            "header": {
            "pri": 1,
            "ts": "1569380075887",
            "tzm": -240,
            "ver": "0.0.50"
        }
        },
        "td": "q",
        "toId": "bot_serial",
        "cmdName": "getStats",
        "auth": {
            "token": "us_52cb21fef8e547f38f4ec9a699a5d77e",
            "resource": "IOSF53D07BA",
            "userid": "fuid_tmpuser",
            "with": "users",
            "realm": "ecouser.net",
        },
    }

    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.2
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    # Send response beforehand
    msg_payload = '{"body":{"code":0,"data":{"area":0,"cid":"111","start":"1569378657","time":6,"type":"auto"},"msg":"ok"},"header":{"fwVer":"1.6.4","hwVer":"0.1.1","pri":1,"ts":"1569380074036","tzm":480,"ver":"0.0.1"}}'
    
    msg_topic_name = (
        "iot/p2p/getStats/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/testj/j"
    )
    await mqtt_helperbot.Client.publish(
        msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
    )

    commandresult = await mqtt_helperbot.send_command(cmdjson, "testj")

    assert commandresult == {
        "id": "testj",
        "resp": {'body':{'code':0,'data':{'area':0,'cid':'111','start':'1569378657','time':6,'type':'auto'},'msg':'ok'},'header':{'fwVer':'1.6.4','hwVer':'0.1.1','pri':1,'ts':'1569380074036','tzm':480,'ver':'0.0.1'}},
        "ret": "ok",
    }

    mqtt_helperbot.Client.disconnect()

    await mqtt_server.broker.shutdown()
Esempio n. 8
0
async def test_helperbot_message():
    mqtt_address = ("127.0.0.1", 8883)
    mqtt_server = bumper.MQTTServer(mqtt_address, password_file="tests/passwd")
    await mqtt_server.broker_coro()

    with LogCapture() as l:

        # Test broadcast message
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (
            mqtt_helperbot.Client._connected_state._value == True
        )  # Check helperbot is connected
        msg_payload = "<ctl ts='1547822804960' td='DustCaseST' st='0'/>"
        msg_topic_name = "iot/atr/DustCaseST/bot_serial/ls1ok3/wC3g/x"
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
        )

        await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)

        l.check_present(
            (
                "helperbot",
                "DEBUG",
                "Received Broadcast - Topic: iot/atr/DustCaseST/bot_serial/ls1ok3/wC3g/x - Message: <ctl ts='1547822804960' td='DustCaseST' st='0'/>",
            )
        )  # Check broadcast message was logged
        l.clear()
        mqtt_helperbot.Client.disconnect()

        # Send command to bot
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (
            mqtt_helperbot.Client._connected_state._value == True
        )  # Check helperbot is connected
        msg_payload = "{}"
        msg_topic_name = (
            "iot/p2p/GetWKVer/helperbot/bumper/helperbot/bot_serial/ls1ok3/wC3g/q/iCmuqp/j"
        )
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
        )
        
        await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)

        l.check_present(
            (
                "helperbot",
                "DEBUG",
                "Send Command - Topic: iot/p2p/GetWKVer/helperbot/bumper/helperbot/bot_serial/ls1ok3/wC3g/q/iCmuqp/j - Message: {}",
            )
        )  # Check send command message was logged
        l.clear()
        mqtt_helperbot.Client.disconnect()

        # Received response to command
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (
            mqtt_helperbot.Client._connected_state._value == True
        )  # Check helperbot is connected
        msg_payload = '{"ret":"ok","ver":"0.13.5"}'
        msg_topic_name = (
            "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/iCmuqp/j"
        )
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
        )

        await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)

        l.check_present(
            (
                "helperbot",
                "DEBUG",
                'Received Response - Topic: iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helperbot/bumper/helperbot/p/iCmuqp/j - Message: {"ret":"ok","ver":"0.13.5"}',
            )
        )  # Check received response message was logged
        l.clear()
        mqtt_helperbot.Client.disconnect()

        # Received unknown message
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (
            mqtt_helperbot.Client._connected_state._value == True
        )  # Check helperbot is connected
        msg_payload = "test"
        msg_topic_name = (
            "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/TESTBAD/bumper/helperbot/p/iCmuqp/j"
        )
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
        )

        await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)


        l.check_present(
            (
                "helperbot",
                "DEBUG",
                "Received Message - Topic: iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/TESTBAD/bumper/helperbot/p/iCmuqp/j - Message: test",
            )
        )  # Check received message was logged
        l.clear()
        mqtt_helperbot.Client.disconnect()

        # Received error message
        mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
        await mqtt_helperbot.start_helper_bot()
        assert (
            mqtt_helperbot.Client._connected_state._value == True
        )  # Check helperbot is connected
        msg_payload = "<ctl ts='1560904925396' td='errors' old='' new='110'/>"
        msg_topic_name = "iot/atr/errors/bot_serial/ls1ok3/wC3g/x"
        await mqtt_helperbot.Client.publish(
            msg_topic_name, msg_payload.encode(), hbmqtt.client.QOS_0
        )
            
        await asyncio.wait_for(mqtt_helperbot.Client.deliver_message(), timeout=0.1)

        l.check_present(
            (
                "boterror",
                "ERROR",
                "Received Error - Topic: iot/atr/errors/bot_serial/ls1ok3/wC3g/x - Message: <ctl ts='1560904925396' td='errors' old='' new='110'/>",
            )
        )  # Check received message was logged
        l.clear()
        mqtt_helperbot.Client.disconnect()

    await mqtt_server.broker.shutdown()
Esempio n. 9
0
def main():
    args = sys.argv

    if len(args) > 0:
        if "--debug" in args:
            logging.basicConfig(
                level=logging.DEBUG,
                format=
                "[%(asctime)s] :: %(levelname)s :: %(name)s :: %(module)s :: %(funcName)s :: %(lineno)d :: %(message)s",
            )
        else:
            logging.basicConfig(
                level=logging.INFO,
                format=
                "[%(asctime)s] :: %(levelname)s :: %(name)s :: %(message)s",
            )
            # format="[%(asctime)s] :: %(levelname)s :: %(name)s :: %(module)s :: %(funcName)s :: %(lineno)d :: %(message)s")

    if platform.system() == "Darwin":  # If a Mac, use 0.0.0.0 for listening
        listen_host = "0.0.0.0"
    else:
        listen_host = socket.gethostbyname(socket.gethostname())
        #listen_host = "localhost"  # Try this if the above doesn't work

    conf_address_443 = (listen_host, 443)
    conf_address_8007 = (listen_host, 8007)
    xmpp_address = (listen_host, 5223)
    mqtt_address = (listen_host, 8883)

    xmpp_server = bumper.XMPPServer(xmpp_address)
    mqtt_server = bumper.MQTTServer(mqtt_address)
    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    conf_server = bumper.ConfServer(conf_address_443,
                                    usessl=True,
                                    helperbot=mqtt_helperbot)
    conf_server_2 = bumper.ConfServer(conf_address_8007,
                                      usessl=False,
                                      helperbot=mqtt_helperbot)

    # add user
    # users = bumper.bumper_users_var.get()
    # user1 = bumper.BumperUser('user1')
    # user1.add_device('devid')
    # user1.add_bot('bot_did')
    # users.append(user1)
    # bumper.bumper_users_var.set(users)

    # start xmpp server on port 5223 (sync)
    xmpp_server.run(run_async=True)  # Start in new thread

    # start mqtt server on port 8883 (async)
    mqtt_server.run(run_async=True)  # Start in new thread

    time.sleep(1.5)  # Wait for broker startup

    # start mqtt_helperbot (async)
    mqtt_helperbot.run(run_async=True)  # Start in new thread

    # start conf server on port 443 (async) - Used for most https calls
    conf_server.run(run_async=True)  # Start in new thread

    # start conf server on port 8007 (async) - Used for a load balancer request
    conf_server_2.run(run_async=True)  # Start in new thread

    while True:
        try:
            time.sleep(30)
            bumper.revoke_expired_tokens()
            disconnected_clients = bumper.get_disconnected_xmpp_clients()
            for client in disconnected_clients:
                xmpp_server.remove_client_byuid(client["userid"])

        except KeyboardInterrupt:
            bumper.bumperlog.info("Bumper Exiting - Keyboard Interrupt")
            print("Bumper Exiting")
            exit(0)
Esempio n. 10
0
async def test_helperbot_sendcommand():
    mqtt_address = ("127.0.0.1", 8883)
    mqtt_server = bumper.MQTTServer(mqtt_address)
    await mqtt_server.broker_coro()

    mqtt_helperbot = bumper.MQTTHelperBot(mqtt_address)
    await mqtt_helperbot.start_helper_bot()
    assert (mqtt_helperbot.Client._connected_state._value == True
            )  # Check helperbot is connected

    cmdjson = {
        "toType": "ls1ok3",
        "payloadType": "j",
        "toRes": "wC3g",
        "payload": {},
        "td": "q",
        "toId": "bot_serial",
        "cmdName": "GetWKVer",
        "auth": {
            "token": "us_52cb21fef8e547f38f4ec9a699a5d77e",
            "resource": "IOSF53D07BA",
            "userid": "fuid_tmpuser",
            "with": "users",
            "realm": "ecouser.net",
        },
    }
    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.1
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    commandresult = await mqtt_helperbot.send_command(cmdjson, "testfail")
    # Don't send a response, ensure timeout
    assert commandresult == {
        "debug": "wait for response timed out",
        "errno": 500,
        "id": "testfail",
        "ret": "fail",
    }  # Check timeout

    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.2
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    # Send response beforehand
    msg_payload = '{"ret":"ok","ver":"0.13.5"}'
    msg_topic_name = (
        "iot/p2p/GetWKVer/bot_serial/ls1ok3/wC3g/helper1/bumper/helper1/p/testgood/j"
    )
    await mqtt_helperbot.Client.publish(msg_topic_name, msg_payload.encode(),
                                        hbmqtt.client.QOS_0)

    commandresult = await mqtt_helperbot.send_command(cmdjson, "testgood")
    assert commandresult == {
        "id": "testgood",
        "resp": {
            "ret": "ok",
            "ver": "0.13.5"
        },
        "ret": "ok",
    }

    mqtt_helperbot.Client.disconnect()

    cmdjson = {
        "toType": "ls1ok3",
        "payloadType": "x",
        "toRes": "wC3g",
        "payload": '<ctl type="Brush"/>',
        "td": "q",
        "toId": "bot_serial",
        "cmdName": "GetLifeSpan",
        "auth": {
            "token": "us_52cb21fef8e547f38f4ec9a699a5d77e",
            "resource": "IOSF53D07BA",
            "userid": "fuid_tmpuser",
            "with": "users",
            "realm": "ecouser.net",
        },
    }

    mqtt_helperbot.wait_resp_timeout_seconds = (
        0.2
    )  # Override wait_resp_timeout (so we don't wait 10 seconds for timeout)
    # Send response beforehand
    msg_payload = ("{'id': 'testx', 'ret': 'ok', 'resp': "
                   "<ctl ret='ok' type='Brush' left='4142' total='18000'/>"
                   "}")
    msg_topic_name = (
        "iot/p2p/GetLifeSpan/bot_serial/ls1ok3/wC3g/helper1/bumper/helper1/p/testx/q"
    )
    await mqtt_helperbot.Client.publish(msg_topic_name, msg_payload.encode(),
                                        hbmqtt.client.QOS_0)

    commandresult = await mqtt_helperbot.send_command(cmdjson, "testx")
    assert commandresult == {
        "id": "testx",
        "resp":
        "{'id': 'testx', 'ret': 'ok', 'resp': <ctl ret='ok' type='Brush' left='4142' total='18000'/>}",
        "ret": "ok",
    }

    mqtt_helperbot.Client.disconnect()

    await mqtt_server.broker.shutdown()