async def test_no_data(event_loop, aresponses):
    """Test error is raised when info data is missing from API call."""
    # Handle to run asserts on request in
    aresponses.add(
        "example.com:8081",
        "/zeroconf/info",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 6,"error": 0}',
        ),
    )

    aresponses.add(
        "example.com:8081",
        "/zeroconf/signal_strength",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"signalStrength": -100}}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com",
            device_id="100090ab1a",
            session=session,
            loop=event_loop,
        )
        with pytest.raises(SonoffDIYError):
            await diy.update_info()
Exemple #2
0
async def test_ota_flash(event_loop, aresponses):
    """Test flashing Sonoff DIY device."""
    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {
            "deviceid": "100090ab1a",
            "data": {
                "downloadUrl": "https://frenck.dev",
                "sha256sum": "1d869a86cd206fc09aaa",
            },
        }

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add("example.com:8081", "/zeroconf/ota_flash", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com", device_id="100090ab1a", session=session, loop=event_loop,
        )
        await diy.ota_flash(
            "https://frenck.dev", "1d869a86cd206fc09aaa",
        )
async def test_invalid_content_type(event_loop, aresponses):
    """Test request timeout from Sonoff DIY device."""
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "other/content"},
            text='{"seq": 26, "error": 0, "data": {"test": "ok"}}',
        ),
    )
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            text='{"seq": 26, "error": 0, "data": {"test": "ok"}}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com", session=session, loop=event_loop)
        with pytest.raises(SonoffDIYError):
            await diy._request("/")
        with pytest.raises(SonoffDIYError):
            await diy._request("/")
Exemple #4
0
async def test_power_on_state_invalid(event_loop):
    """Test setting invalid power on state."""
    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com", device_id="100090ab1a", session=session, loop=event_loop,
        )
        with pytest.raises(SonoffDIYError):
            await diy.power_on_state("frenck")
async def main(loop):
    """Show example on controlling your Sonoff DIY device."""
    async with SonoffDIY("10.10.10.197", device_id="100090bc7b",
                         loop=loop) as diy:
        info = await diy.update_info()
        print(info)

        if not info.on:
            await diy.turn_on()
        else:
            await diy.turn_off()
async def test_info_update(event_loop, aresponses):
    """Test getting Sonoff DIY device information and states."""

    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {"deviceid": "100090ab1a", "data": {}}

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text=str(
                '{"seq": 6,"error": 0,"data": '
                '"{\\"switch\\":\\"on\\",\\"startup\\":\\"stay\\",'
                '\\"pulse\\":\\"off\\",\\"pulseWidth\\":1500,'
                '\\"ssid\\":\\"frenck\\",\\"otaUnlock\\":true}"}', ),
        )

    aresponses.add("example.com:8081", "/zeroconf/info", "POST",
                   response_handler)

    aresponses.add(
        "example.com:8081",
        "/zeroconf/signal_strength",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"signalStrength": -48}}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com",
            device_id="100090ab1a",
            session=session,
            loop=event_loop,
        )
        info = await diy.update_info()
        assert info
        assert info.on
        assert info.power_on_state == STATE_RESTORE
        assert not info.pulse
        assert info.pulse_width == 1500
        assert info.ssid == "frenck"
        assert info.ota_unlock
        assert info.signal_strength == -48
        assert info.signal_strength_percentage == 100
async def test_internal_eventloop(aresponses):
    """Test internal event loop creation is handled correctly."""
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"test": "ok"}}',
        ),
    )
    async with SonoffDIY("example.com") as diy:
        response = await diy._request("/")
        assert response["test"] == "ok"
async def test_encoded_json_request(event_loop, aresponses):
    """Test JSON response is handled correctly."""
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": "{\\"test\\": \\"ok\\"}"}',
        ),
    )
    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com", session=session, loop=event_loop)
        response = await diy._request("/")
        assert response["test"] == "ok"
async def test_error_response(event_loop, aresponses):
    """Test error response from Sonoff DIY device."""
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 422}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com", session=session, loop=event_loop)
        with pytest.raises(SonoffDIYError):
            await diy._request("/")
Exemple #10
0
async def test_pulse_width(event_loop, aresponses):
    """Test setting Sonoff DIY device pulse width."""
    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {
            "deviceid": "100090ab1a",
            "data": {"pulse": STATE_ON, "pulse_width": 1000},
        }

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add(
        "example.com:8081",
        "/zeroconf/info",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"pulse": "on"}}',
        ),
    )

    aresponses.add(
        "example.com:8081",
        "/zeroconf/signal_strength",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"signalStrength": -48}}',
        ),
    )

    aresponses.add("example.com:8081", "/zeroconf/pulse", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com", device_id="100090ab1a", session=session, loop=event_loop,
        )
        await diy.pulse_width(1000)
async def test_request_user_agent(event_loop, aresponses):
    """Test client sending correct user agent headers."""

    # Handle to run asserts on request in
    async def response_handler(request):
        assert request.headers[
            "User-Agent"] == f"PythonSonoffDIY/{__version__}"
        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add("example.com:8081", "/", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com", session=session, loop=event_loop)
        await diy._request("/")
async def test_request_port(event_loop, aresponses):
    """Test Sonoff DIY device running on non-standard port."""
    aresponses.add(
        "example.com:8888",
        "/",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"test": "ok"}}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com",
                        port=8888,
                        session=session,
                        loop=event_loop)
        response = await diy._request("/")
        assert response["test"] == "ok"
Exemple #13
0
async def test_switch_on(event_loop, aresponses):
    """Test turning on Sonoff DIY device switch."""
    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {"deviceid": "100090ab1a", "data": {"switch": STATE_ON}}

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add("example.com:8081", "/zeroconf/switch", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com", device_id="100090ab1a", session=session, loop=event_loop,
        )
        await diy.turn_on()
async def test_timeout(event_loop, aresponses):
    """Test request timeout from Sonoff DIY device."""

    # Faking a timeout by sleeping
    async def response_handler(_):
        await asyncio.sleep(2)
        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add("example.com:8081", "/", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com",
                        session=session,
                        loop=event_loop,
                        request_timeout=1)
        with pytest.raises(SonoffDIYConnectionError):
            assert await diy._request("/")
async def test_http_error(event_loop, aresponses):
    """Test HTTP error response handling."""
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(text="OMG PUPPIES!", status=404),
    )
    aresponses.add(
        "example.com:8081",
        "/",
        "POST",
        aresponses.Response(text="OMG PUPPIES!", status=500),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY("example.com", session=session, loop=event_loop)
        with pytest.raises(SonoffDIYError):
            assert await diy._request("/")

        with pytest.raises(SonoffDIYError):
            assert await diy._request("/")
async def test_signal_strength(event_loop, aresponses):
    """Test retreiving Sonoff DIY device WiFi signal strength."""

    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {"deviceid": "100090ab1a", "data": {}}

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 6,"error": 0,"data": {}}',
        )

    aresponses.add("example.com:8081", "/zeroconf/info", "POST",
                   response_handler)

    aresponses.add(
        "example.com:8081",
        "/zeroconf/signal_strength",
        "POST",
        aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 26, "error": 0, "data": {"signalStrength": -60}}',
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com",
            device_id="100090ab1a",
            session=session,
            loop=event_loop,
        )
        info = await diy.update_info()
        assert info
        assert info.signal_strength == -60
        assert info.signal_strength_percentage == 80
Exemple #17
0
async def switchMain(loop, ip, deviceID, state):
    tryAgain = True
    count = 4

    """Show example on controlling your Sonoff DIY device."""
    while tryAgain:
        try:
            #            async with SonoffDIY("192.168.10.169", device_id="1000c8c4b5", loop=loop) as diy:
            async with SonoffDIY(ip, device_id=deviceID, loop=loop) as diy:
                info = await diy.update_info()

                if state == "on":
                    await diy.turn_on()
                else:
                    await diy.turn_off()

                tryAgain = False
        except:
            count -= 1
            tryAgain = True

            if count < 0:
                print("Tried and failed.")
Exemple #18
0
async def test_wifi(event_loop, aresponses):
    """Test setting Sonoff DIY device WiFi settings."""
    # Handle to run asserts on request in
    async def response_handler(request):
        data = await request.json()
        assert data == {
            "deviceid": "100090ab1a",
            "data": {"ssid": "frenck", "password": "******"},
        }

        return aresponses.Response(
            status=200,
            headers={"Content-Type": "application/json"},
            text='{"seq": 1, "error": 0}',
        )

    aresponses.add("example.com:8081", "/zeroconf/wifi", "POST", response_handler)

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com", device_id="100090ab1a", session=session, loop=event_loop,
        )
        await diy.wifi("frenck", "choochoo")
async def test_info_none(event_loop, aresponses):
    """Test info data is None when communication has occured."""
    # Handle to run asserts on request in
    aresponses.add(
        "example.com:8081",
        "/zeroconf/info",
        "POST",
        aresponses.Response(
            status=500,
            headers={"Content-Type": "application/json"},
            text="Invalid response",
        ),
    )

    async with aiohttp.ClientSession(loop=event_loop) as session:
        diy = SonoffDIY(
            "example.com",
            device_id="100090ab1a",
            session=session,
            loop=event_loop,
        )
        with pytest.raises(SonoffDIYError):
            await diy.update_info()
        assert diy.info is None
async def infoMain(loop):
    tryAgain = True
    count = 4

    configFile = "/etc/HomeAutomation/config.json"
    name = ""

    verbose = False

    try:
        opts, args = getopt.getopt(sys.argv[1:], "c:hvn:",
                                   ["config=", "help", "name="])
    except getopt.GetoptError as err:
        print(err)
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ("-v", "--verbose"):
            verbose = True
        elif o in ("-c", "--config"):
            configFile = a
        elif o in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif o in ("-n", "--name"):
            name = a

    sonoff = readConfig(configFile)

    ip = ""
    deviceID = ""
    if sonoff.get(name):
        ip = sonoff["test"]["ip"]
        deviceID = sonoff["test"]["device_id"]

        if verbose:
            print("Name :" + name)
            print("\tIP        :" + ip)
            print("\tDevice ID :" + deviceID)
    else:
        print(name + " not found")
        tryAgain = False

    while tryAgain:
        try:
            async with SonoffDIY(ip, device_id=deviceID, loop=loop) as diy:
                info = await diy.update_info_json()

                tmp = json.loads(info)

                if verbose:
                    print(tmp)

                print(tmp['switch'].upper())
            tryAgain = False

        except Exception as ex:
            template = "An exception of type {0} occurred. Arguments:\n{1!r}"
            message = template.format(type(ex).__name__, ex.args)
            print(message)

            tryAgain = False

        except SonoffDIYConnectionError:
            count -= 1
            tryAgain = True
            if count < 0:
                print("Tried and failed.")
                sys.exit(1)
            else:
                sleep(0.2)