예제 #1
0
    async def async_step_config(self,
                                user_input: dict[str, Any] | None = None
                                ) -> FlowResult:
        """Confirm the setup."""
        errors = {}
        data = {CONF_DISCOVERY_PREFIX: self._prefix}

        if user_input is not None:
            bad_prefix = False
            prefix = user_input[CONF_DISCOVERY_PREFIX]
            if prefix.endswith("/#"):
                prefix = prefix[:-2]
            try:
                valid_subscribe_topic(f"{prefix}/#")
            except vol.Invalid:
                errors["base"] = "invalid_discovery_topic"
                bad_prefix = True
            else:
                data[CONF_DISCOVERY_PREFIX] = prefix
            if not bad_prefix:
                return self.async_create_entry(title="Tasmota", data=data)

        fields = {}
        fields[vol.Optional(CONF_DISCOVERY_PREFIX, default=self._prefix)] = str

        return self.async_show_form(step_id="config",
                                    data_schema=vol.Schema(fields),
                                    errors=errors)
예제 #2
0
    async def async_step_config(self, user_input=None):
        """Confirm the setup."""
        errors = {}
        data = {CONF_OPENWB_BASE_TOPIC: self._basetopic}

        if user_input is not None:
            bad_basetopic = False
            basetopic = user_input[CONF_OPENWB_BASE_TOPIC]
            if basetopic.endswith("/#"):
                basetopic = basetopic[:-2]
            try:
                valid_subscribe_topic(f"{basetopic}/#")
            except vol.Invalid:
                errors["base"] = "invalid_discovery_topic"
                bad_basetopic = True
            else:
                data[CONF_OPENWB_BASE_TOPIC] = basetopic
            if not bad_basetopic:
                return self.async_create_entry(title="OpenWB", data=data)

        fields = {}
        fields[vol.Optional(CONF_OPENWB_BASE_TOPIC,
                            default=self._basetopic)] = str

        return self.async_show_form(step_id="config",
                                    data_schema=vol.Schema(fields),
                                    errors=errors)
예제 #3
0
파일: config_flow.py 프로젝트: jbouwh/core
    async def async_step_gw_mqtt(self,
                                 user_input: dict[str, Any] | None = None
                                 ) -> FlowResult:
        """Create a config entry for a mqtt gateway."""
        # Naive check that doesn't consider config entry state.
        if MQTT_DOMAIN not in self.hass.config.components:
            return self.async_abort(reason="mqtt_required")

        gw_type = self._gw_type = CONF_GATEWAY_TYPE_MQTT
        errors: dict[str, str] = {}

        if user_input is not None:
            user_input[CONF_DEVICE] = MQTT_COMPONENT

            try:
                valid_subscribe_topic(user_input[CONF_TOPIC_IN_PREFIX])
            except vol.Invalid:
                errors[CONF_TOPIC_IN_PREFIX] = "invalid_subscribe_topic"
            else:
                if self._check_topic_exists(user_input[CONF_TOPIC_IN_PREFIX]):
                    errors[CONF_TOPIC_IN_PREFIX] = "duplicate_topic"

            try:
                valid_publish_topic(user_input[CONF_TOPIC_OUT_PREFIX])
            except vol.Invalid:
                errors[CONF_TOPIC_OUT_PREFIX] = "invalid_publish_topic"
            if not errors:
                if (user_input[CONF_TOPIC_IN_PREFIX] ==
                        user_input[CONF_TOPIC_OUT_PREFIX]):
                    errors[CONF_TOPIC_OUT_PREFIX] = "same_topic"
                elif self._check_topic_exists(
                        user_input[CONF_TOPIC_OUT_PREFIX]):
                    errors[CONF_TOPIC_OUT_PREFIX] = "duplicate_topic"

            errors.update(await self.validate_common(gw_type, errors,
                                                     user_input))
            if not errors:
                return self._async_create_entry(user_input)

        user_input = user_input or {}
        schema = {
            vol.Required(CONF_TOPIC_IN_PREFIX,
                         default=user_input.get(CONF_TOPIC_IN_PREFIX, "")):
            str,
            vol.Required(CONF_TOPIC_OUT_PREFIX,
                         default=user_input.get(CONF_TOPIC_OUT_PREFIX, "")):
            str,
            vol.Required(CONF_RETAIN,
                         default=user_input.get(CONF_RETAIN, True)):
            bool,
        }
        schema.update(_get_schema_common(user_input))

        schema = vol.Schema(schema)
        return self.async_show_form(step_id="gw_mqtt",
                                    data_schema=schema,
                                    errors=errors)
예제 #4
0
    async def async_step_gw_mqtt(
        self, user_input: dict[str, Any] | None = None
    ) -> FlowResult:
        """Create a config entry for a mqtt gateway."""
        errors = {}
        if user_input is not None:
            user_input[CONF_DEVICE] = MQTT_COMPONENT

            try:
                valid_subscribe_topic(user_input[CONF_TOPIC_IN_PREFIX])
            except vol.Invalid:
                errors[CONF_TOPIC_IN_PREFIX] = "invalid_subscribe_topic"
            else:
                if self._check_topic_exists(user_input[CONF_TOPIC_IN_PREFIX]):
                    errors[CONF_TOPIC_IN_PREFIX] = "duplicate_topic"

            try:
                valid_publish_topic(user_input[CONF_TOPIC_OUT_PREFIX])
            except vol.Invalid:
                errors[CONF_TOPIC_OUT_PREFIX] = "invalid_publish_topic"
            if not errors:
                if (
                    user_input[CONF_TOPIC_IN_PREFIX]
                    == user_input[CONF_TOPIC_OUT_PREFIX]
                ):
                    errors[CONF_TOPIC_OUT_PREFIX] = "same_topic"
                elif self._check_topic_exists(user_input[CONF_TOPIC_OUT_PREFIX]):
                    errors[CONF_TOPIC_OUT_PREFIX] = "duplicate_topic"

            errors.update(
                await self.validate_common(CONF_GATEWAY_TYPE_MQTT, errors, user_input)
            )
            if not errors:
                return self._async_create_entry(user_input)

        user_input = user_input or {}
        schema = _get_schema_common(user_input)
        schema[
            vol.Required(CONF_RETAIN, default=user_input.get(CONF_RETAIN, True))
        ] = bool
        schema[
            vol.Required(
                CONF_TOPIC_IN_PREFIX, default=user_input.get(CONF_TOPIC_IN_PREFIX, "")
            )
        ] = str
        schema[
            vol.Required(
                CONF_TOPIC_OUT_PREFIX, default=user_input.get(CONF_TOPIC_OUT_PREFIX, "")
            )
        ] = str

        schema = vol.Schema(schema)
        return self.async_show_form(
            step_id="gw_mqtt", data_schema=schema, errors=errors
        )
예제 #5
0
    def _validate_topics(self, user_input: dict[str, Any]) -> None:
        topics = {x.strip() for x in user_input[CONF_MQTT_TOPICS].split(",")}
        if not topics:
            self.errors[
                CONF_MQTT_TOPICS] = VALIDATION_ERROR_MQTT_INVALID_SUBSCRIBE_TOPIC

        for topic in topics:
            try:
                mqtt.valid_subscribe_topic(topic)
            except vol.Invalid:
                self.errors[
                    CONF_MQTT_TOPICS] = VALIDATION_ERROR_MQTT_INVALID_SUBSCRIBE_TOPIC
예제 #6
0
    async def async_step_mqtt(self, discovery_info=None):
        """Handle a flow initialized by MQTT discovery."""
        if self._async_in_progress() or self._async_current_entries():
            return self.async_abort(reason="single_instance_allowed")

        await self.async_set_unique_id(DOMAIN)

        # Validate the topic, will throw if it fails
        prefix = discovery_info.subscribed_topic
        if prefix.endswith("/#"):
            prefix = prefix[:-2]
        try:
            valid_subscribe_topic(f"{prefix}/#")
        except vol.Invalid:
            return self.async_abort(reason="invalid_discovery_info")

        self._prefix = prefix

        return await self.async_step_confirm()
예제 #7
0
    def test_validate_subscribe_topic(self):
        """Test invalid subscribe topics."""
        mqtt.valid_subscribe_topic('#')
        mqtt.valid_subscribe_topic('sport/#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/#/')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('foo/bar#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('foo/#/bar')

        mqtt.valid_subscribe_topic('+')
        mqtt.valid_subscribe_topic('+/tennis/#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport+')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport+/')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/+1')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/+#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('bad+topic')
        mqtt.valid_subscribe_topic('sport/+/player1')
        mqtt.valid_subscribe_topic('/finance')
        mqtt.valid_subscribe_topic('+/+')
        mqtt.valid_subscribe_topic('$SYS/#')
예제 #8
0
    def test_validate_subscribe_topic(self):
        """Test invalid subscribe topics."""
        mqtt.valid_subscribe_topic('#')
        mqtt.valid_subscribe_topic('sport/#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/#/')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('foo/bar#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('foo/#/bar')

        mqtt.valid_subscribe_topic('+')
        mqtt.valid_subscribe_topic('+/tennis/#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport+')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport+/')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/+1')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('sport/+#')
        with pytest.raises(vol.Invalid):
            mqtt.valid_subscribe_topic('bad+topic')
        mqtt.valid_subscribe_topic('sport/+/player1')
        mqtt.valid_subscribe_topic('/finance')
        mqtt.valid_subscribe_topic('+/+')
        mqtt.valid_subscribe_topic('$SYS/#')
예제 #9
0
def test_validate_subscribe_topic():
    """Test invalid subscribe topics."""
    mqtt.valid_subscribe_topic("#")
    mqtt.valid_subscribe_topic("sport/#")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("sport/#/")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("foo/bar#")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("foo/#/bar")

    mqtt.valid_subscribe_topic("+")
    mqtt.valid_subscribe_topic("+/tennis/#")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("sport+")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("sport+/")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("sport/+1")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("sport/+#")
    with pytest.raises(vol.Invalid):
        mqtt.valid_subscribe_topic("bad+topic")
    mqtt.valid_subscribe_topic("sport/+/player1")
    mqtt.valid_subscribe_topic("/finance")
    mqtt.valid_subscribe_topic("+/+")
    mqtt.valid_subscribe_topic("$SYS/#")