- config flow: шаг preview (шаблон A/B/F, диапазон/шаг уставки, линейные коэффициенты num/den/offset, текст-превью по данным trial: hvac/fan/ swing/capabilities/текущая температура) - coordinator: push-driven DataUpdateCoordinator (снимок кэша, доступность online/recovering, первичный GET-батч, один batch_commit на действие) - overrides.py: ConversionSet (ручные линейные конверсии и диапазон поверх таблиц ядра, применяются в HA) - entity.py: DeviceInfo/unique_id/доступность, capabilities-фильтры - climate: hvac/fan/swing/vertical+horizontal swing/preset ECO-BOOST, уставка 16-30 °C (шаг по шаблону), current_temperature - sensor: room_temperature, error_code, connection_state (диагностика) - binary_sensor: connectivity + флаги op_status (PROTOCOL §8.4) - switch: 8 флагов-свойств; select: положения заслонок 0..N-1 - тесты: превью/конверсии/ошибки диапазона, сущности против mock_ac (снимок, команды, capabilities-фильтр, ручная конверсия), ConversionSet - mock_ac: --set NAME=VALUE (0b/0x) для сценариев - план: demand_control отложен (семантика не зафиксирована)
138 lines
4.2 KiB
Python
138 lines
4.2 KiB
Python
"""Константы и словари значений интеграции fglair (PROTOCOL §8)."""
|
|
from __future__ import annotations
|
|
|
|
from homeassistant.components.climate import HVACMode
|
|
|
|
from pyfglair import Prop, State, Template
|
|
from pyfglair.provision import REGIONS as _PROVISION_REGIONS
|
|
|
|
DOMAIN = "fglair"
|
|
|
|
CONF_HOST = "host"
|
|
CONF_DEVICE_PORT = "device_port"
|
|
CONF_DSN = "dsn"
|
|
CONF_LANIP_KEY = "lanip_key"
|
|
CONF_LANIP_KEY_ID = "lanip_key_id"
|
|
CONF_MODEL = "model"
|
|
CONF_TEMPLATE = "template"
|
|
CONF_NAME = "name"
|
|
CONF_LISTEN_PORT = "listen_port"
|
|
CONF_KEEPALIVE_MS = "keepalive_ms"
|
|
CONF_REGION = "region"
|
|
CONF_EMAIL = "email"
|
|
CONF_PASSWORD = "password"
|
|
CONF_CONFIG_JSON = "config_json"
|
|
CONF_OVERRIDES = "overrides"
|
|
CONF_TEMP_STEP = "temp_step"
|
|
CONF_TEMP_MIN = "temp_min"
|
|
CONF_TEMP_MAX = "temp_max"
|
|
CONF_TEMP_NUM = "temp_num"
|
|
CONF_TEMP_DEN = "temp_den"
|
|
CONF_TEMP_OFFSET = "temp_offset"
|
|
|
|
DEFAULT_DEVICE_PORT = 80
|
|
# 0 => свободный эфемерный порт: несколько ConfigEntry (несколько
|
|
# кондиционеров) не конфликтуют; модулю фактический порт сообщается в
|
|
# local_reg (PROTOCOL §1).
|
|
DEFAULT_LISTEN_PORT = 0
|
|
DEFAULT_KEEPALIVE_MS = 15000
|
|
TRIAL_TIMEOUT = 10.0
|
|
|
|
REGIONS = sorted(_PROVISION_REGIONS)
|
|
|
|
TRIAL_ERRORS = {
|
|
"no_slots": "no_slots",
|
|
"key_mismatch": "key_mismatch",
|
|
"unreachable": "cannot_connect",
|
|
"timeout": "timeout",
|
|
"start_failed": "cannot_connect",
|
|
"properties_missing": "properties_missing",
|
|
}
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# operation_mode (PROTOCOL §8.3): 0=OFF, 1=ON, 2=AUTO, 3=COOL, 4=DRY,
|
|
# 5=FAN, 6=HEAT
|
|
# ---------------------------------------------------------------------------
|
|
OPERATION_MODE_OFF = 0
|
|
OPERATION_MODE_ON = 1
|
|
HVAC_MODE_TO_VALUE = {
|
|
HVACMode.AUTO: 2,
|
|
HVACMode.COOL: 3,
|
|
HVACMode.DRY: 4,
|
|
HVACMode.FAN_ONLY: 5,
|
|
HVACMode.HEAT: 6,
|
|
}
|
|
HVAC_VALUE_TO_MODE = {value: mode for mode, value in HVAC_MODE_TO_VALUE.items()}
|
|
|
|
# device_capabilities, биты (PROTOCOL §8.5)
|
|
CAP_HVAC = {
|
|
HVACMode.AUTO: 4,
|
|
HVACMode.COOL: 0,
|
|
HVACMode.DRY: 1,
|
|
HVACMode.FAN_ONLY: 2,
|
|
HVACMode.HEAT: 3,
|
|
}
|
|
CAP_FAN = {"auto": 5, "high": 6, "medium": 7, "low": 8, "quiet": 9}
|
|
CAP_SWING_VERTICAL = 10
|
|
CAP_SWING_HORIZONTAL = 11
|
|
CAP_ECONOMY = 12
|
|
CAP_MIN_HEAT = 13
|
|
CAP_INDOOR_FAN_CONTROL = 14
|
|
CAP_POWERFUL = 16
|
|
CAP_OUTDOOR_LOW_NOISE = 17
|
|
CAP_COIL_DRY = 18
|
|
|
|
# fan_speed (PROTOCOL §8.3)
|
|
FAN_VALUE_TO_MODE = {0: "quiet", 1: "low", 2: "medium", 3: "high", 4: "auto"}
|
|
FAN_MODE_TO_VALUE = {mode: value for value, mode in FAN_VALUE_TO_MODE.items()}
|
|
|
|
# preset: ECO = economy_mode, BOOST = powerful_mode
|
|
PRESET_ECO = "eco"
|
|
PRESET_BOOST = "boost"
|
|
PRESET_PROP = {
|
|
PRESET_ECO: Prop.ECONOMY_MODE,
|
|
PRESET_BOOST: Prop.POWERFUL_MODE,
|
|
}
|
|
PRESET_CAP = {
|
|
PRESET_ECO: CAP_ECONOMY,
|
|
PRESET_BOOST: CAP_POWERFUL,
|
|
}
|
|
|
|
SWING_MODES = ["off", "on"]
|
|
SWING_HORIZONTAL_MODES = ["off", "on"]
|
|
|
|
# switch-свойства: prop -> (translation_key, capability bit | None)
|
|
SWITCH_PROPS: dict[Prop, tuple[str, int | None]] = {
|
|
Prop.ECONOMY_MODE: ("economy_mode", CAP_ECONOMY),
|
|
Prop.POWERFUL_MODE: ("powerful_mode", CAP_POWERFUL),
|
|
Prop.COIL_DRY_MODE: ("coil_dry_mode", CAP_COIL_DRY),
|
|
Prop.MIN_HEAT: ("min_heat", CAP_MIN_HEAT),
|
|
Prop.OUTDOOR_LOW_NOISE: ("outdoor_low_noise", CAP_OUTDOOR_LOW_NOISE),
|
|
Prop.HUMAN_DET_AUTO_SAVE: ("human_det_auto_save", None),
|
|
Prop.WIFI_LED_ENABLE: ("wifi_led_enable", None),
|
|
Prop.INDOOR_FAN_CONTROL: ("indoor_fan_control", CAP_INDOOR_FAN_CONTROL),
|
|
}
|
|
|
|
# op_status, биты (PROTOCOL §8.4): translation_key -> bit
|
|
OP_STATUS_BITS: dict[str, int] = {
|
|
"defrost": 24,
|
|
"maintenance": 22,
|
|
"oil_recovery": 28,
|
|
"pump_down": 29,
|
|
"check_operation": 30,
|
|
"simultaneous": 25,
|
|
}
|
|
|
|
# Уставка: фактические ограничения бытового прибора (PROTOCOL §8.3 [LEGACY]);
|
|
# единицы API = 0.1 °C.
|
|
TEMP_MIN_TENTHS = 160
|
|
TEMP_MAX_TENTHS = 300
|
|
TEMP_STEP_TENTHS = {
|
|
Template.A: 5,
|
|
Template.B: 10,
|
|
Template.F: 5,
|
|
}
|
|
|
|
# Состояния, в которых сущности доступны (PROTOCOL/план §5).
|
|
AVAILABLE_STATES = (State.ONLINE, State.RECOVERING)
|