Esempio n. 1
0
    def test_parse_transcoder_from_subclass(self):
        """Test parsing only subclasses of a DPT class."""
        assert DPTBase.parse_transcoder("string") == DPTString
        assert DPTNumeric.parse_transcoder("string") is None
        assert DPT2ByteFloat.parse_transcoder("string") is None

        assert DPTBase.parse_transcoder("percent") == DPTScaling
        assert DPTNumeric.parse_transcoder("percent") == DPTScaling
        assert DPT2ByteFloat.parse_transcoder("percent") is None

        assert DPTBase.parse_transcoder("temperature") == DPTTemperature
        assert DPTNumeric.parse_transcoder("temperature") == DPTTemperature
        assert DPT2ByteFloat.parse_transcoder("temperature") == DPTTemperature
Esempio n. 2
0
def number_limit_sub_validator(entity_config: OrderedDict) -> OrderedDict:
    """Validate a number entity configurations dependent on configured value type."""
    value_type = entity_config[CONF_TYPE]
    min_config: float | None = entity_config.get(NumberSchema.CONF_MIN)
    max_config: float | None = entity_config.get(NumberSchema.CONF_MAX)
    step_config: float | None = entity_config.get(NumberSchema.CONF_STEP)
    dpt_class = DPTNumeric.parse_transcoder(value_type)

    if dpt_class is None:
        raise vol.Invalid(f"'type: {value_type}' is not a valid numeric sensor type.")
    # Inifinity is not supported by Home Assistant frontend so user defined
    # config is required if if xknx DPTNumeric subclass defines it as limit.
    if min_config is None and dpt_class.value_min == float("-inf"):
        raise vol.Invalid(f"'min' key required for value type '{value_type}'")
    if min_config is not None and min_config < dpt_class.value_min:
        raise vol.Invalid(
            f"'min: {min_config}' undercuts possible minimum"
            f" of value type '{value_type}': {dpt_class.value_min}"
        )

    if max_config is None and dpt_class.value_max == float("inf"):
        raise vol.Invalid(f"'max' key required for value type '{value_type}'")
    if max_config is not None and max_config > dpt_class.value_max:
        raise vol.Invalid(
            f"'max: {max_config}' exceeds possible maximum"
            f" of value type '{value_type}': {dpt_class.value_max}"
        )

    if step_config is not None and step_config < dpt_class.resolution:
        raise vol.Invalid(
            f"'step: {step_config}' undercuts possible minimum step"
            f" of value type '{value_type}': {dpt_class.resolution}"
        )

    return entity_config
Esempio n. 3
0
def numeric_type_validator(value: Any) -> str | int:
    """Validate that value is parsable as numeric sensor type."""
    if isinstance(
            value,
        (str, int)) and DPTNumeric.parse_transcoder(value) is not None:
        return value
    raise vol.Invalid(f"value '{value}' is not a valid numeric sensor type.")
Esempio n. 4
0
class TestDPTNumeric:
    """Test class for numeric transcoder base object."""
    @pytest.mark.parametrize("dpt_class", DPTNumeric.dpt_class_tree())
    def test_values(self, dpt_class):
        """Test boundary values are set for numeric definitions (because mypy doesn't)."""

        assert isinstance(dpt_class.value_min, (int, float))
        assert isinstance(dpt_class.value_max, (int, float))
        assert isinstance(dpt_class.resolution, (int, float))