ha(H1): pyfglair — cffi-ядро (очередь событий), wheel, CLI discover/monitor

- CMake: shared-таргет fgl-aircon-shared (FGL_BUILD_SHARED, PIC, SOVERSION)
- C-API: fgl_prop_raw_range + кольцевые очереди событий/логов
  (fgl_session_poll/wait_events, fgl_log_poll/wait_events): прямые колбэки
  из потоков ядра со стеком 8 КБ небезопасны для интерпретатора Python
- pyfglair: _corebuild (cmake->wheel), _cffi (ABI), Session (reader-поток ->
  loop.call_soon_threadsafe), templates (интроспекция C-таблиц), provision
  (aiohttp), CLI discover/monitor + esphome-secrets
- setup.py/pyproject: платформенный wheel py3-none-linux_x86_64 с .so
- tests/pyfglair: templates, provision (мок-облако), session + CLI против
  mock_ac.py; scripts/py-ci.sh; ci.sh запускает python-часть
This commit is contained in:
2026-09-29 11:31:57 +03:00
parent 97842276c8
commit 0292404756
26 changed files with 2236 additions and 63 deletions
+81
View File
@@ -0,0 +1,81 @@
"""Перечисления pyfglair (значения совпадают с include/fgl-aircon/c_api.h)."""
from __future__ import annotations
from enum import IntEnum
class State(IntEnum):
IDLE = 0
REGISTERING = 1
ONLINE = 2
RECOVERING = 3
OFFLINE = 4
KEY_ERROR = 5
class Error(IntEnum):
NONE = 0
NO_SLOT = 1
UNREACHABLE = 2
KEY_MISMATCH = 3
BAD_KEY_EXCHANGE = 4
ACTIVATION_TIMEOUT = 5
DECRYPT_FAILED = 6
class Template(IntEnum):
A = 0
B = 1
F = 2
class Prop(IntEnum):
OPERATION_MODE = 0
FAN_SPEED = 1
ADJUST_TEMPERATURE = 2
DISPLAY_TEMPERATURE = 3
AF_VERTICAL_DIRECTION = 4
AF_VERTICAL_SWING = 5
AF_HORIZONTAL_DIRECTION = 6
AF_HORIZONTAL_SWING = 7
AF_VERTICAL_MOVE_STEP1 = 8
AF_HORIZONTAL_MOVE_STEP1 = 9
OUTDOOR_LOW_NOISE = 10
INDOOR_FAN_CONTROL = 11
HUMAN_DET_AUTO_SAVE = 12
MIN_HEAT = 13
POWERFUL_MODE = 14
COIL_DRY_MODE = 15
ECONOMY_MODE = 16
MASTER_TIMER_ON_OFF_1 = 17
MASTER_TIMER_ON_OFF_2 = 18
ERROR_CODE = 19
DEMAND_CONTROL = 20
FILTER_SIGN_RESET_DISPLAY = 21
FILTER_SIGN_RESET = 22
OP_STATUS = 23
DEVICE_NAME = 24
BUILDING_NAME = 25
WIFI_LED_ENABLE = 26
SERVICE_CONTACT_NAME = 27
SERVICE_CONTACT_PHONE = 28
SERVICE_CONTACT_EMAIL = 29
AF_HORIZONTAL_NUM_DIR = 30
AF_VERTICAL_NUM_DIR = 31
DEVICE_CAPABILITIES = 32
GET_PROP = 33
HUMAN_DET = 34
MONITOR1 = 35
REFRESH = 36
class ValueKind(IntEnum):
INT = 0
BOOL = 1
STRING = 2
TEMPLATE_NAMES = {Template.A: "A", Template.B: "B", Template.F: "F"}
STATE_NAMES = {state: state.name.lower() for state in State}
ERROR_NAMES = {error: error.name.lower() for error in Error}