"""Дефолты feature-модели: device_capabilities, num_dir, presence.""" from __future__ import annotations from custom_components.fglair.features import ( FeatureSet, device_default, resolve_features, ) from pyfglair import Prop, Template, Value, ValueKind def _value(value: int) -> Value: return Value(ValueKind.INT, value) def test_caps_defaults_ap_wc1e(): values = {Prop.DEVICE_CAPABILITIES: _value(5119)} # 0x13FF assert device_default("mode_cool", values) is True assert device_default("mode_heat", values) is True assert device_default("fan_auto", values) is True assert device_default("swing_vertical", values) is False assert device_default("swing_horizontal", values) is False assert device_default("economy_mode", values) is True assert device_default("powerful_mode", values) is False assert device_default("min_heat", values) is False assert device_default("coil_dry_mode", values) is False def test_caps_unknown_keeps_everything(): assert device_default("swing_vertical", {}) is True assert device_default( "min_heat", {Prop.DEVICE_CAPABILITIES: _value(0)} ) is True def test_directions_need_num_dir(): zero = {Prop.AF_VERTICAL_NUM_DIR: _value(0)} five = {Prop.AF_VERTICAL_NUM_DIR: _value(5)} assert device_default("af_vertical_direction", zero) is False assert device_default("af_vertical_direction", five) is True assert device_default("af_vertical_direction", {}) is False assert device_default("af_horizontal_direction", zero) is False def test_presence_defaults(): values = {Prop.DISPLAY_TEMPERATURE: _value(200)} assert device_default("display_temperature", values) is True assert device_default("wifi_led_enable", values) is False assert ( device_default( "display_temperature", {}, {Prop.DISPLAY_TEMPERATURE} ) is True ) assert device_default("wifi_led_enable", {}, set()) is False def test_resolve_and_featureset_override(): values = {Prop.DEVICE_CAPABILITIES: _value(5119)} resolved = resolve_features(values, set(), {"swing_vertical": True}) assert resolved["swing_vertical"] is True assert resolved["powerful_mode"] is False from custom_components.fglair.const import FEATURES assert len(resolved) == len(FEATURES) feature_set = FeatureSet({"swing_vertical": True}, values) assert feature_set.enabled("swing_vertical") is True assert feature_set.enabled("powerful_mode") is False default_set = FeatureSet(None, values) assert default_set.enabled("economy_mode") is True assert default_set.enabled("swing_vertical") is False def test_classify_template(): from custom_components.fglair.trial import classify_template assert classify_template( {Prop.AF_VERTICAL_MOVE_STEP1} ) is Template.B assert classify_template( {Prop.MONITOR1, Prop.AF_VERTICAL_DIRECTION} ) is Template.F assert classify_template( {Prop.AF_VERTICAL_DIRECTION} ) is Template.A assert classify_template({Prop.DISPLAY_TEMPERATURE}) is Template.A assert classify_template(set()) is None def test_resolved_features_for_ap_wc1e_without_sensor(): """Канальный блок: датчик комнаты есть, ламелей/swing нет.""" values = { Prop.DEVICE_CAPABILITIES: _value(5119), Prop.AF_VERTICAL_NUM_DIR: _value(0), Prop.AF_HORIZONTAL_NUM_DIR: _value(0), Prop.DISPLAY_TEMPERATURE: _value(205), } resolved = resolve_features(values, set(values)) assert resolved["display_temperature"] is True assert resolved["swing_vertical"] is False assert resolved["af_vertical_direction"] is False assert resolved["af_horizontal_direction"] is False assert resolved["mode_cool"] is True assert resolved["economy_mode"] is True assert resolved["powerful_mode"] is False def test_probe_stops_on_unreachable(monkeypatch): """Недоступный модуль не перебираем трижды — выходим после первой сессии.""" from custom_components.fglair import trial as tr calls: list = [] def fake_trial(*args, **kwargs): calls.append(kwargs.get("template")) return tr.TrialResult(ok=False, reason="unreachable") monkeypatch.setattr(tr, "trial_connect", fake_trial) template, props, fatal = tr.probe_template("host", "dsn", "key", 1) assert template is None assert props == {} assert fatal == "unreachable" assert calls == [Template.A]