async def test_option_flow_existing(hass, 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_hass(hass)

    result = await hass.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"
async def test_flow_works(hass, mock_panel):
    """Test config flow ."""
    result = await hass.config_entries.flow.async_init(
        config_flow.DOMAIN, context={"source": config_entries.SOURCE_USER}
    )
    assert result["type"] == "form"
    assert result["step_id"] == "user"

    mock_panel.get_status.return_value = {
        "mac": "11:22:33:44:55:66",
        "model": "Konnected",
    }
    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], user_input={"port": 1234, "host": "1.2.3.4"}
    )
    assert result["type"] == "form"
    assert result["step_id"] == "confirm"
    assert result["description_placeholders"] == {
        "model": "Konnected Alarm Panel",
        "id": "112233445566",
        "host": "1.2.3.4",
        "port": 1234,
    }

    result = await hass.config_entries.flow.async_configure(
        result["flow_id"], user_input={}
    )
    assert result["type"] == "create_entry"
    assert result["data"]["host"] == "1.2.3.4"
    assert result["data"]["port"] == 1234
    assert result["data"]["model"] == "Konnected"
    assert len(result["data"]["access_token"]) == 20  # confirm generated token size
    assert result["data"]["default_options"] == config_flow.OPTIONS_SCHEMA(
        {config_flow.CONF_IO: {}}
    )
Пример #3
0
async def test_state_updates(hass, aiohttp_client, mock_panel):
    """Test callback view."""
    await async_setup_component(hass, "http", {"http": {}})

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "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_hass(hass)

    # 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_hass(hass)

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

    client = await aiohttp_client(hass.http.app)

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

    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"}
    await hass.async_block_till_done()
    assert hass.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={
            "zone": "4",
            "temp": 22,
            "humi": 20
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await hass.async_block_till_done()
    assert hass.states.get(
        "sensor.konnected_445566_sensor_4_humidity").state == "20"
    assert (hass.states.get(
        "sensor.konnected_445566_sensor_4_temperature").state == "22.0")

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "4",
            "temp": 25,
            "humi": 23
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await hass.async_block_till_done()
    assert hass.states.get(
        "sensor.konnected_445566_sensor_4_humidity").state == "23"
    assert (hass.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={
            "zone": "5",
            "temp": 32,
            "addr": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await hass.async_block_till_done()
    assert hass.states.get("sensor.temper_temperature").state == "32.0"

    resp = await client.post(
        "/api/konnected/device/112233445566",
        headers={"Authorization": "Bearer abcdefgh"},
        json={
            "zone": "5",
            "temp": 42,
            "addr": 1
        },
    )
    assert resp.status == 200
    result = await resp.json()
    assert result == {"message": "ok"}
    await hass.async_block_till_done()
    assert hass.states.get("sensor.temper_temperature").state == "42.0"
Пример #4
0
async def test_api(hass, aiohttp_client, mock_panel):
    """Test callback view."""
    await async_setup_component(hass, "http", {"http": {}})

    device_config = config_flow.CONFIG_ENTRY_SCHEMA({
        "host":
        "1.2.3.4",
        "port":
        1234,
        "id":
        "112233445566",
        "model":
        "Konnected Pro",
        "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_hass(hass)

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

    client = await aiohttp_client(hass.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"}
async def test_option_flow(hass, 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_hass(hass)

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

    result = await hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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,
            },
        ],
    }
async def test_ssdp_host_update(hass, 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_hass(hass)
    mock_panel.get_status.return_value = {
        "mac": "11:22:33:44:55:66",
        "model": "Konnected Pro",
    }

    result = await hass.config_entries.flow.async_init(
        config_flow.DOMAIN,
        context={"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 = hass.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"
async def test_option_flow_import(hass, 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_hass(hass)

    result = await hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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,
            },
        ],
    }
async def test_option_flow_pro(hass, 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_hass(hass)

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

    result = await hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.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 hass.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

    # zone 8
    result = await hass.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 hass.config_entries.options.async_configure(
        result["flow_id"], user_input={})
    assert result["type"] == "form"
    assert result["step_id"] == "options_switch"

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

    result = await hass.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"
            },
        ],
    }
Пример #9
0
async def test_connect_retry(hass, 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_hass(hass)

    # 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(
            hass,
            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 hass.async_block_till_done()
    assert hass.states.get("switch.konnected_445566_actuator_6").state == "unavailable"

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

    # confirm switch is available after third attempt
    async_fire_time_changed(hass, utcnow() + timedelta(seconds=21))
    await hass.async_block_till_done()
    await hass.helpers.entity_component.async_update_entity(
        "switch.konnected_445566_actuator_6"
    )
    assert hass.states.get("switch.konnected_445566_actuator_6").state == "off"
Пример #10
0
async def test_create_and_setup(hass, 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({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_hass(hass)

    # 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(
            hass,
            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
    # hass.data is the only mechanism to get a reference to the created panel instance
    device = hass.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 hass.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",
            },
        ],
    }
Пример #11
0
async def test_create_and_setup_pro(hass, mock_panel):
    """Test that we create a Konnected Pro 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({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": "Digital Sensor",
                "4": "Switchable Output",
                "8": "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"},
            ],
            "sensors": [
                {"zone": "3", "type": "dht"},
                {"zone": "7", "type": "ds18b20", "name": "temper"},
                {"zone": "11", "type": "dht", "poll_interval": 5},
            ],
            "switches": [
                {"zone": "4"},
                {
                    "zone": "8",
                    "name": "switcher",
                    "activation": "low",
                    "momentary": 50,
                    "pause": 100,
                    "repeat": 4,
                },
                {"zone": "out1"},
                {"zone": "alarm1"},
            ],
        }
    )

    entry = MockConfigEntry(
        domain="konnected",
        title="Konnected Pro Alarm Panel",
        data=device_config,
        options=device_options,
    )
    entry.add_to_hass(hass)
    hass.data[panel.DOMAIN] = {
        panel.CONF_API_HOST: "192.168.1.1",
    }

    device = panel.AlarmPanel(hass, entry)
    await device.async_save_data()
    await device.async_connect()
    await device.update_switch("2", 1)

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

    # confirm the settings are sent to the panel
    # pylint: disable=no-member
    assert device.client.put_settings.call_args_list[0][1] == {
        "sensors": [{"zone": "2"}, {"zone": "6"}, {"zone": "10"}],
        "actuators": [
            {"trigger": 1, "zone": "4"},
            {"trigger": 0, "zone": "8"},
            {"trigger": 1, "zone": "out1"},
            {"trigger": 1, "zone": "alarm1"},
        ],
        "dht_sensors": [
            {"poll_interval": 3, "zone": "3"},
            {"poll_interval": 5, "zone": "11"},
        ],
        "ds18b20_sensors": [{"zone": "7"}],
        "auth_token": "11223344556677889900",
        "blink": True,
        "discovery": True,
        "endpoint": "192.168.1.1/api/konnected",
    }

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