Esempio n. 1
0
async def test_ssdp_host_update(opp, mock_panel):
    """Test if a discovered panel has already been configured but changed host."""
    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({config_flow.CONF_IO: {}}),
    })

    device_options = config_flow.OPTIONS_SCHEMA({
        "io": {
            "2": "Binary Sensor",
            "6": "Binary Sensor",
            "10": "Binary Sensor",
            "3": "Digital Sensor",
            "7": "Digital Sensor",
            "11": "Binary Sensor",
            "4": "Switchable Output",
            "out1": "Switchable Output",
            "alarm1": "Switchable Output",
        },
        "binary_sensors": [
            {
                "zone": "2",
                "type": "door"
            },
            {
                "zone": "6",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
            {
                "zone": "10",
                "type": "door"
            },
            {
                "zone": "11",
                "type": "window"
            },
        ],
        "sensors": [
            {
                "zone": "3",
                "type": "dht"
            },
            {
                "zone": "7",
                "type": "ds18b20",
                "name": "temper"
            },
        ],
        "switches": [
            {
                "zone": "4"
            },
            {
                "zone": "8",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "zone": "out1"
            },
            {
                "zone": "alarm1"
            },
        ],
    })

    MockConfigEntry(
        domain="konnected",
        data=device_config,
        options=device_options,
        unique_id="112233445566",
    ).add_to_opp(opp)
    mock_panel.get_status.return_value = {
        "mac": "11:22:33:44:55:66",
        "model": "Konnected Pro",
    }

    result = await opp.config_entries.flow.async_init(
        config_flow.DOMAIN,
        context={"source": config_entries.SOURCE_SSDP},
        data={
            "ssdp_location": "http://1.1.1.1:1234/Device.xml",
            "manufacturer": config_flow.KONN_MANUFACTURER,
            "modelName": config_flow.KONN_MODEL_PRO,
        },
    )
    assert result["type"] == "abort"

    # confirm the host value was updated, access_token was not
    entry = opp.config_entries.async_entries(config_flow.DOMAIN)[0]
    assert entry.data["host"] == "1.1.1.1"
    assert entry.data["port"] == 1234
    assert entry.data["access_token"] == "11223344556677889900"
Esempio n. 2
0
async def test_option_flow(opp, mock_panel):
    """Test config flow options."""
    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({config_flow.CONF_IO: {}}),
    })

    device_options = config_flow.OPTIONS_SCHEMA({"io": {}})

    entry = MockConfigEntry(
        domain="konnected",
        data=device_config,
        options=device_options,
        unique_id="112233445566",
    )
    entry.add_to_opp(opp)

    result = await opp.config_entries.options.async_init(
        entry.entry_id, context={"source": "test"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_io"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "1": "Disabled",
            "2": "Binary Sensor",
            "3": "Digital Sensor",
            "4": "Switchable Output",
            "5": "Disabled",
            "6": "Binary Sensor",
            "out": "Switchable Output",
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"
    assert result["description_placeholders"] == {
        "zone": "Zone 2",
    }

    # zone 2
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "door"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"
    assert result["description_placeholders"] == {
        "zone": "Zone 6",
    }

    # zone 6
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "type": "window",
            "name": "winder",
            "inverse": True
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_digital"
    assert result["description_placeholders"] == {
        "zone": "Zone 3",
    }

    # zone 3
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "dht"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"
    assert result["description_placeholders"] == {
        "zone": "Zone 4",
        "state": "1",
    }

    # zone 4
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"
    assert result["description_placeholders"] == {
        "zone": "OUT",
        "state": "1",
    }

    # zone out
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "name": "switcher",
            "activation": "low",
            "momentary": 50,
            "pause": 100,
            "repeat": 4,
            "more_states": "Yes",
        },
    )

    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"
    assert result["description_placeholders"] == {
        "zone": "OUT",
        "state": "2",
    }

    # zone out - state 2
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "name": "alarm",
            "activation": "low",
            "momentary": 100,
            "pause": 100,
            "repeat": -1,
            "more_states": "No",
        },
    )

    assert result["type"] == "form"
    assert result["step_id"] == "options_misc"
    # make sure we enforce url format
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "discovery": False,
            "blink": True,
            "override_api_host": True,
            "api_host": "badhosturl",
        },
    )

    assert result["type"] == "form"
    assert result["step_id"] == "options_misc"
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "discovery": False,
            "blink": True,
            "override_api_host": True,
            "api_host": "http://overridehost:1111",
        },
    )
    assert result["type"] == "create_entry"
    assert result["data"] == {
        "io": {
            "2": "Binary Sensor",
            "3": "Digital Sensor",
            "4": "Switchable Output",
            "6": "Binary Sensor",
            "out": "Switchable Output",
        },
        "discovery":
        False,
        "blink":
        True,
        "api_host":
        "http://overridehost:1111",
        "binary_sensors": [
            {
                "zone": "2",
                "type": "door",
                "inverse": False
            },
            {
                "zone": "6",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
        ],
        "sensors": [{
            "zone": "3",
            "type": "dht",
            "poll_interval": 3
        }],
        "switches": [
            {
                "activation": "high",
                "zone": "4"
            },
            {
                "zone": "out",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "zone": "out",
                "name": "alarm",
                "activation": "low",
                "momentary": 100,
                "pause": 100,
                "repeat": -1,
            },
        ],
    }
Esempio n. 3
0
async def test_option_flow_import(opp, mock_panel):
    """Test config flow options imported from configuration.yaml."""
    device_options = config_flow.OPTIONS_SCHEMA({
        "io": {
            "1": "Binary Sensor",
            "2": "Digital Sensor",
            "3": "Switchable Output",
        },
        "binary_sensors": [
            {
                "zone": "1",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
        ],
        "sensors": [{
            "zone": "2",
            "type": "ds18b20",
            "name": "temper"
        }],
        "switches": [
            {
                "zone": "3",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "zone": "3",
                "name": "alarm",
                "activation": "low",
                "momentary": 100,
                "pause": 100,
                "repeat": -1,
            },
        ],
    })

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        device_options,
    })

    entry = MockConfigEntry(domain="konnected",
                            data=device_config,
                            unique_id="112233445566")
    entry.add_to_opp(opp)

    result = await opp.config_entries.options.async_init(
        entry.entry_id, context={"source": "test"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_io"

    # confirm the defaults are set based on current config - we"ll spot check this throughout
    schema = result["data_schema"]({})
    assert schema["1"] == "Binary Sensor"
    assert schema["2"] == "Digital Sensor"
    assert schema["3"] == "Switchable Output"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "1": "Binary Sensor",
            "2": "Digital Sensor",
            "3": "Switchable Output",
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_io_ext"
    schema = result["data_schema"]({})
    assert schema["8"] == "Disabled"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={},
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"

    # zone 1
    schema = result["data_schema"]({})
    assert schema["type"] == "window"
    assert schema["name"] == "winder"
    assert schema["inverse"] is True
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "door"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_digital"

    # zone 2
    schema = result["data_schema"]({})
    assert schema["type"] == "ds18b20"
    assert schema["name"] == "temper"
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={"type": "dht"},
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone 3
    schema = result["data_schema"]({})
    assert schema["name"] == "switcher"
    assert schema["activation"] == "low"
    assert schema["momentary"] == 50
    assert schema["pause"] == 100
    assert schema["repeat"] == 4
    assert schema["more_states"] == "Yes"
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "activation": "high",
            "more_states": "No"
        })
    assert result["type"] == "form"
    assert result["step_id"] == "options_misc"

    schema = result["data_schema"]({})
    assert schema["blink"] is True
    assert schema["discovery"] is True
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "discovery": True,
            "blink": False,
            "override_api_host": False
        },
    )

    # verify the updated fields
    assert result["type"] == "create_entry"
    assert result["data"] == {
        "io": {
            "1": "Binary Sensor",
            "2": "Digital Sensor",
            "3": "Switchable Output"
        },
        "discovery":
        True,
        "blink":
        False,
        "api_host":
        "",
        "binary_sensors": [
            {
                "zone": "1",
                "type": "door",
                "inverse": True,
                "name": "winder"
            },
        ],
        "sensors": [
            {
                "zone": "2",
                "type": "dht",
                "poll_interval": 3,
                "name": "temper"
            },
        ],
        "switches": [
            {
                "zone": "3",
                "name": "switcher",
                "activation": "high",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
        ],
    }
Esempio n. 4
0
async def test_option_flow_existing(opp, mock_panel):
    """Test config flow options with existing already in place."""
    device_options = config_flow.OPTIONS_SCHEMA({
        "io": {
            "1": "Binary Sensor",
            "2": "Digital Sensor",
            "3": "Switchable Output",
        },
        "binary_sensors": [
            {
                "zone": "1",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
        ],
        "sensors": [{
            "zone": "2",
            "type": "ds18b20",
            "name": "temper"
        }],
        "switches": [
            {
                "zone": "3",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
        ],
    })

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({"io": {}}),
    })

    entry = MockConfigEntry(
        domain="konnected",
        data=device_config,
        options=device_options,
        unique_id="112233445566",
    )
    entry.add_to_opp(opp)

    result = await opp.config_entries.options.async_init(
        entry.entry_id, context={"source": "test"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_io"

    # confirm the defaults are pulled in from the existing options
    schema = result["data_schema"]({})
    assert schema["1"] == "Binary Sensor"
    assert schema["2"] == "Digital Sensor"
    assert schema["3"] == "Switchable Output"
Esempio n. 5
0
async def test_option_flow_pro(opp, mock_panel):
    """Test config flow options for pro board."""
    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({config_flow.CONF_IO: {}}),
    })

    device_options = config_flow.OPTIONS_SCHEMA({"io": {}})

    entry = MockConfigEntry(
        domain="konnected",
        data=device_config,
        options=device_options,
        unique_id="112233445566",
    )
    entry.add_to_opp(opp)

    result = await opp.config_entries.options.async_init(
        entry.entry_id, context={"source": "test"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_io"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "1": "Disabled",
            "2": "Binary Sensor",
            "3": "Digital Sensor",
            "4": "Switchable Output",
            "5": "Disabled",
            "6": "Binary Sensor",
            "7": "Digital Sensor",
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_io_ext"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "8": "Switchable Output",
            "9": "Disabled",
            "10": "Binary Sensor",
            "11": "Binary Sensor",
            "12": "Disabled",
            "out1": "Switchable Output",
            "alarm1": "Switchable Output",
            "alarm2_out2": "Disabled",
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"

    # zone 2
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "door"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"

    # zone 6
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "type": "window",
            "name": "winder",
            "inverse": True
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"

    # zone 10
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "door"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_binary"

    # zone 11
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "window"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_digital"

    # zone 3
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={"type": "dht"})
    assert result["type"] == "form"
    assert result["step_id"] == "options_digital"

    # zone 7
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={
            "type": "ds18b20",
            "name": "temper"
        })
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone 4
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone 8
    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "name": "switcher",
            "activation": "low",
            "momentary": 50,
            "pause": 100,
            "repeat": 4,
        },
    )
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone out1
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone alarm1
    result = await opp.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_misc"

    result = await opp.config_entries.options.async_configure(
        result["flow_id"],
        user_input={
            "discovery": False,
            "blink": True,
            "override_api_host": False
        },
    )

    assert result["type"] == "create_entry"
    assert result["data"] == {
        "io": {
            "10": "Binary Sensor",
            "11": "Binary Sensor",
            "2": "Binary Sensor",
            "3": "Digital Sensor",
            "4": "Switchable Output",
            "6": "Binary Sensor",
            "7": "Digital Sensor",
            "8": "Switchable Output",
            "alarm1": "Switchable Output",
            "out1": "Switchable Output",
        },
        "discovery":
        False,
        "blink":
        True,
        "api_host":
        "",
        "binary_sensors": [
            {
                "zone": "2",
                "type": "door",
                "inverse": False
            },
            {
                "zone": "6",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
            {
                "zone": "10",
                "type": "door",
                "inverse": False
            },
            {
                "zone": "11",
                "type": "window",
                "inverse": False
            },
        ],
        "sensors": [
            {
                "zone": "3",
                "type": "dht",
                "poll_interval": 3
            },
            {
                "zone": "7",
                "type": "ds18b20",
                "name": "temper",
                "poll_interval": 3
            },
        ],
        "switches": [
            {
                "activation": "high",
                "zone": "4"
            },
            {
                "zone": "8",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "activation": "high",
                "zone": "out1"
            },
            {
                "activation": "high",
                "zone": "alarm1"
            },
        ],
    }
Esempio n. 6
0
async def test_state_updates_pin(opp, aiohttp_client, mock_panel):
    """Test callback view."""
    await async_process_op_core_config(
        opp,
        {"internal_url": "http://example.local:8123"},
    )

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected",
        "access_token":
        "abcdefgh",
        "default_options":
        config_flow.OPTIONS_SCHEMA({config_flow.CONF_IO: {}}),
    })

    device_options = config_flow.OPTIONS_SCHEMA({
        "io": {
            "1": "Binary Sensor",
            "2": "Binary Sensor",
            "3": "Binary Sensor",
            "4": "Digital Sensor",
            "5": "Digital Sensor",
            "6": "Switchable Output",
            "out": "Switchable Output",
        },
        "binary_sensors": [
            {
                "zone": "1",
                "type": "door"
            },
            {
                "zone": "2",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
            {
                "zone": "3",
                "type": "door"
            },
        ],
        "sensors": [
            {
                "zone": "4",
                "type": "dht"
            },
            {
                "zone": "5",
                "type": "ds18b20",
                "name": "temper"
            },
        ],
        "switches": [
            {
                "zone": "out",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "zone": "6"
            },
        ],
    })

    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Alarm Panel",
        data=device_config,
        options=device_options,
    )
    entry.add_to_opp(opp)

    # Add empty data field to ensure we process it correctly (possible if entry is ignored)
    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Alarm Panel",
        data={},
    )
    entry.add_to_opp(opp)

    assert (await async_setup_component(
        opp,
        konnected.DOMAIN,
        {konnected.DOMAIN: {
            konnected.CONF_ACCESS_TOKEN: "1122334455"
        }},
    ) is True)

    client = await aiohttp_client(opp.http.app)

    # Test updating a binary sensor
    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "1",
            "state": 0
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get(
        "binary_sensor.konnected_445566_zone_1").state == "off"

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "1",
            "state": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get(
        "binary_sensor.konnected_445566_zone_1").state == "on"

    # Test updating sht sensor
    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "6",
            "temp": 22,
            "humi": 20
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get(
        "sensor.konnected_445566_sensor_4_humidity").state == "20"
    assert (opp.states.get(
        "sensor.konnected_445566_sensor_4_temperature").state == "22.0")

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "6",
            "temp": 25,
            "humi": 23
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get(
        "sensor.konnected_445566_sensor_4_humidity").state == "23"
    assert (opp.states.get(
        "sensor.konnected_445566_sensor_4_temperature").state == "25.0")

    # Test updating ds sensor
    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "7",
            "temp": 32,
            "addr": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get("sensor.temper_temperature").state == "32.0"

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "pin": "7",
            "temp": 42,
            "addr": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await opp.async_block_till_done()
    assert opp.states.get("sensor.temper_temperature").state == "42.0"
Esempio n. 7
0
async def test_api(opp, aiohttp_client, mock_panel):
    """Test callback view."""
    await async_setup_component(opp, "http", {"http": {}})

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "abcdefgh",
        "api_host":
        "http://192.168.86.32:8123",
        "default_options":
        config_flow.OPTIONS_SCHEMA({config_flow.CONF_IO: {}}),
    })

    device_options = config_flow.OPTIONS_SCHEMA({
        "api_host":
        "http://192.168.86.32:8123",
        "io": {
            "1": "Binary Sensor",
            "2": "Binary Sensor",
            "3": "Binary Sensor",
            "4": "Digital Sensor",
            "5": "Digital Sensor",
            "6": "Switchable Output",
            "out": "Switchable Output",
        },
        "binary_sensors": [
            {
                "zone": "1",
                "type": "door"
            },
            {
                "zone": "2",
                "type": "window",
                "name": "winder",
                "inverse": True
            },
            {
                "zone": "3",
                "type": "door"
            },
        ],
        "sensors": [
            {
                "zone": "4",
                "type": "dht"
            },
            {
                "zone": "5",
                "type": "ds18b20",
                "name": "temper"
            },
        ],
        "switches": [
            {
                "zone": "out",
                "name": "switcher",
                "activation": "low",
                "momentary": 50,
                "pause": 100,
                "repeat": 4,
            },
            {
                "zone": "6"
            },
        ],
    })

    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Alarm Panel",
        data=device_config,
        options=device_options,
    )
    entry.add_to_opp(opp)

    assert (await async_setup_component(
        opp,
        konnected.DOMAIN,
        {konnected.DOMAIN: {
            konnected.CONF_ACCESS_TOKEN: "globaltoken"
        }},
    ) is True)

    client = await aiohttp_client(opp.http.app)

    # Test the get endpoint for switch status polling
    resp = await client.get("/api/konnected")
    assert resp.status == HTTP_NOT_FOUND  # no device provided

    resp = await client.get("/api/konnected/223344556677")
    assert resp.status == HTTP_NOT_FOUND  # unknown device provided

    resp = await client.get("/api/konnected/device/112233445566")
    assert resp.status == HTTP_NOT_FOUND  # no zone provided
    result = await resp.json()
    assert result == {
        "message": "Switch on zone or pin unknown not configured"
    }

    resp = await client.get("/api/konnected/device/112233445566?zone=8")
    assert resp.status == HTTP_NOT_FOUND  # invalid zone
    result = await resp.json()
    assert result == {"message": "Switch on zone or pin 8 not configured"}

    resp = await client.get("/api/konnected/device/112233445566?pin=12")
    assert resp.status == HTTP_NOT_FOUND  # invalid pin
    result = await resp.json()
    assert result == {"message": "Switch on zone or pin 12 not configured"}

    resp = await client.get("/api/konnected/device/112233445566?zone=out")
    assert resp.status == 200
    result = await resp.json()
    assert result == {"state": 1, "zone": "out"}

    resp = await client.get("/api/konnected/device/112233445566?pin=8")
    assert resp.status == 200
    result = await resp.json()
    assert result == {"state": 1, "pin": "8"}

    # Test the post endpoint for sensor updates
    resp = await client.post("/api/konnected/device",
                             json={
                                 "zone": "1",
                                 "state": 1
                             })
    assert resp.status == HTTP_NOT_FOUND

    resp = await client.post("/api/konnected/device/112233445566",
                             json={
                                 "zone": "1",
                                 "state": 1
                             })
    assert resp.status == 401
    result = await resp.json()
    assert result == {"message": "unauthorized"}

    resp = await client.post(
        "/api/konnected/device/223344556677",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "1",
            "state": 1
        },
    )
    assert resp.status == 400

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "15",
            "state": 1
        },
    )
    assert resp.status == 400
    result = await resp.json()
    assert result == {"message": "unregistered sensor/actuator"}

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "1",
            "state": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer globaltoken"},
        json={
            "zone": "1",
            "state": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "4",
            "temp": 22,
            "humi": 20
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}

    # Test the put endpoint for sensor updates
    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "1",
            "state": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
Esempio n. 8
0
async def test_connect_retry(opp, mock_panel):
    """Test that we create a Konnected Panel and save the data."""
    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({
            "io": {
                "1": "Binary Sensor",
                "2": "Binary Sensor",
                "3": "Binary Sensor",
                "4": "Digital Sensor",
                "5": "Digital Sensor",
                "6": "Switchable Output",
                "out": "Switchable Output",
            },
            "binary_sensors": [
                {
                    "zone": "1",
                    "type": "door"
                },
                {
                    "zone": "2",
                    "type": "window",
                    "name": "winder",
                    "inverse": True,
                },
                {
                    "zone": "3",
                    "type": "door"
                },
            ],
            "sensors": [
                {
                    "zone": "4",
                    "type": "dht"
                },
                {
                    "zone": "5",
                    "type": "ds18b20",
                    "name": "temper"
                },
            ],
            "switches": [
                {
                    "zone": "out",
                    "name": "switcher",
                    "activation": "low",
                    "momentary": 50,
                    "pause": 100,
                    "repeat": 4,
                },
                {
                    "zone": "6"
                },
            ],
        }),
    })

    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Alarm Panel",
        data=device_config,
        options={},
    )
    entry.add_to_opp(opp)

    # fail first 2 attempts, and succeed the third
    mock_panel.get_status.side_effect = [
        mock_panel.ClientError,
        mock_panel.ClientError,
        {
            "hwVersion": "2.3.0",
            "swVersion": "2.3.1",
            "heap": 10000,
            "uptime": 12222,
            "ip": "192.168.1.90",
            "port": 9123,
            "sensors": [],
            "actuators": [],
            "dht_sensors": [],
            "ds18b20_sensors": [],
            "mac": "11:22:33:44:55:66",
            "model": "Konnected Pro",
            "settings": {},
        },
    ]

    # setup the integration and inspect panel behavior
    assert (await async_setup_component(
        opp,
        panel.DOMAIN,
        {
            panel.DOMAIN: {
                panel.CONF_ACCESS_TOKEN: "arandomstringvalue",
                panel.CONF_API_HOST: "http://192.168.1.1:8123",
            }
        },
    ) is True)

    # confirm switch is unavailable after initial attempt
    await opp.async_block_till_done()
    assert opp.states.get(
        "switch.konnected_445566_actuator_6").state == "unavailable"

    # confirm switch is unavailable after second attempt
    async_fire_time_changed(opp, utcnow() + timedelta(seconds=11))
    await opp.async_block_till_done()
    await opp.helpers.entity_component.async_update_entity(
        "switch.konnected_445566_actuator_6")
    assert opp.states.get(
        "switch.konnected_445566_actuator_6").state == "unavailable"

    # confirm switch is available after third attempt
    async_fire_time_changed(opp, utcnow() + timedelta(seconds=21))
    await opp.async_block_till_done()
    await opp.helpers.entity_component.async_update_entity(
        "switch.konnected_445566_actuator_6")
    assert opp.states.get("switch.konnected_445566_actuator_6").state == "off"
Esempio n. 9
0
async def test_default_options(opp, mock_panel):
    """Test that we create a Konnected Panel and save the data."""
    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "access_token":
        "11223344556677889900",
        "default_options":
        config_flow.OPTIONS_SCHEMA({
            "io": {
                "1": "Binary Sensor",
                "2": "Binary Sensor",
                "3": "Binary Sensor",
                "4": "Digital Sensor",
                "5": "Digital Sensor",
                "6": "Switchable Output",
                "out": "Switchable Output",
            },
            "binary_sensors": [
                {
                    "zone": "1",
                    "type": "door"
                },
                {
                    "zone": "2",
                    "type": "window",
                    "name": "winder",
                    "inverse": True,
                },
                {
                    "zone": "3",
                    "type": "door"
                },
            ],
            "sensors": [
                {
                    "zone": "4",
                    "type": "dht"
                },
                {
                    "zone": "5",
                    "type": "ds18b20",
                    "name": "temper"
                },
            ],
            "switches": [
                {
                    "zone": "out",
                    "name": "switcher",
                    "activation": "low",
                    "momentary": 50,
                    "pause": 100,
                    "repeat": 4,
                },
                {
                    "zone": "6"
                },
            ],
        }),
    })

    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Alarm Panel",
        data=device_config,
        options={},
    )
    entry.add_to_opp(opp)

    # override get_status to reflect non-pro board
    mock_panel.get_status.return_value = {
        "hwVersion": "2.3.0",
        "swVersion": "2.3.1",
        "heap": 10000,
        "uptime": 12222,
        "ip": "192.168.1.90",
        "port": 9123,
        "sensors": [],
        "actuators": [],
        "dht_sensors": [],
        "ds18b20_sensors": [],
        "mac": "11:22:33:44:55:66",
        "settings": {},
    }

    # setup the integration and inspect panel behavior
    assert (await async_setup_component(
        opp,
        panel.DOMAIN,
        {
            panel.DOMAIN: {
                panel.CONF_ACCESS_TOKEN: "arandomstringvalue",
                panel.CONF_API_HOST: "http://192.168.1.1:8123",
            }
        },
    ) is True)

    # confirm panel instance was created and configured.
    # opp.data is the only mechanism to get a reference to the created panel instance
    device = opp.data[panel.DOMAIN][
        panel.CONF_DEVICES]["112233445566"]["panel"]
    await device.update_switch("1", 0)

    # confirm the correct api is used
    # pylint: disable=no-member
    assert mock_panel.put_device.call_count == 1
    assert mock_panel.put_zone.call_count == 0

    # confirm the settings are sent to the panel
    # pylint: disable=no-member
    assert mock_panel.put_settings.call_args_list[0][1] == {
        "sensors": [{
            "pin": "1"
        }, {
            "pin": "2"
        }, {
            "pin": "5"
        }],
        "actuators": [{
            "trigger": 0,
            "pin": "8"
        }, {
            "trigger": 1,
            "pin": "9"
        }],
        "dht_sensors": [{
            "poll_interval": 3,
            "pin": "6"
        }],
        "ds18b20_sensors": [{
            "pin": "7"
        }],
        "auth_token": "11223344556677889900",
        "blink": True,
        "discovery": True,
        "endpoint": "http://192.168.1.1:8123/api/konnected",
    }

    # confirm the device settings are saved in opp.data
    assert device.stored_configuration == {
        "binary_sensors": {
            "1": {
                "inverse": False,
                "name": "Konnected 445566 Zone 1",
                "state": None,
                "type": "door",
            },
            "2": {
                "inverse": True,
                "name": "winder",
                "state": None,
                "type": "window"
            },
            "3": {
                "inverse": False,
                "name": "Konnected 445566 Zone 3",
                "state": None,
                "type": "door",
            },
        },
        "blink":
        True,
        "panel":
        device,
        "discovery":
        True,
        "host":
        "1.2.3.4",
        "port":
        1234,
        "sensors": [
            {
                "name": "Konnected 445566 Sensor 4",
                "poll_interval": 3,
                "type": "dht",
                "zone": "4",
            },
            {
                "name": "temper",
                "poll_interval": 3,
                "type": "ds18b20",
                "zone": "5"
            },
        ],
        "switches": [
            {
                "activation": "low",
                "momentary": 50,
                "name": "switcher",
                "pause": 100,
                "repeat": 4,
                "state": None,
                "zone": "out",
            },
            {
                "activation": "high",
                "momentary": None,
                "name": "Konnected 445566 Actuator 6",
                "pause": None,
                "repeat": None,
                "state": None,
                "zone": "6",
            },
        ],
    }