core(M3): aircon-слой — шаблоны A/B/F, конверсии+override, публичный API + C-API
- include/fgl-aircon: types.hpp (Prop/State/Error/Value/Template/ Conversion-linear-custom/PropOverride/Config с задокументированными lifetime-контрактами), templates.hpp (PropInfo-таблицы, интроспекция, конверсии c контрактом Linear num/den!=0), session.hpp (Session: set_int/bool/string, get_prop, batch, cached, set_log_sink с контрактом), c_api.h (extern "C" для cffi/pyfglair). - src/aircon: tables.cpp (шаблоны A=33/B=20/F=34 по PROTOCOL §8.2, template_detect + template_is_known; конверсии: default тождественно, DisplayTemperature raw 0.01°C(+5000)→API 0.1°C; linear с инверсией raw=(api-offset)*den/num и насыщением __builtin_*_overflow; custom fn; af_*_swing base_type integer, kind bool), session.cpp (маппинг имя↔Prop, коэрсинг int-push к kBool по таблице, кэш со спинлоком, оптимистичный кэш, валидация overrides: терминатор/linear/custom_fn), c_api.cpp (шейм, static_assert'ы на все enum-значения, fgl_template_detect -1 для неизвестных). - ayla: set_property_string (Command.str_value, coalescing копирует строку в т.ч. в batch-ветке); kMaxQueue 48 + static_assert (полный батч A=33); commit_batch всегда ставит notify; oversized-строка дропает событие (кэш не затирается); max_queue default 40. - tests/aircon: test_tables (составы/атрибуты/дубли/template_detect/ swings-integer), test_convert (default/linear/custom/диапазоны/насыщение в обе стороны/UB-экстремумы), aircon_runner + test_aircon_mock (маппинг+конверсии+batch=1-notify с ожиданием async REG; SET+кэш+ RO/не-шаблон отказы+клэмпинг raw 450 на модуле; C-API smoke). - Прибор AP-WC1E: полный батч шаблона A одним notify — 28 int/bool свойств (DisplayTemperature 7000→200=20.0°C, DeviceCapabilities=5119), boolean SET (JSON true) принят, RO/клэмп/NOTMPL отказы корректны. - CI: 10/10 ×3 стабильно (3 полных прогона); ESP-IDF esp32 build complete. Ревью независимым агентом: 3 круга — B1 kMaxQueue<батча, B2 linear div/0, B3 c_api контракт -1, B4 batch-строки, BL1 INT64_MIN negation UB, BL2 DisplayTemperature экстремумы, flake aircon_mock — всё закрыто; APPROVED (условие круга 3: фикс + зелёный CI ×3).
This commit is contained in:
@@ -34,9 +34,24 @@ fgl_add_test(ayla_envelope ayla/test_envelope.cpp)
|
||||
fgl_add_test(ayla_json ayla/test_json.cpp)
|
||||
fgl_add_test(ayla_httpc ayla/test_httpc.cpp)
|
||||
|
||||
# aircon-слой: юнит-тесты таблиц/конверсий + C-API smoke.
|
||||
fgl_add_test(aircon_tables aircon/test_tables.cpp)
|
||||
fgl_add_test(aircon_convert aircon/test_convert.cpp)
|
||||
target_link_libraries(test_aircon_tables PRIVATE fgl-aircon)
|
||||
target_link_libraries(test_aircon_convert PRIVATE fgl-aircon)
|
||||
|
||||
add_executable(aircon_runner aircon/aircon_runner.cpp)
|
||||
target_compile_features(aircon_runner PRIVATE cxx_std_20)
|
||||
target_link_libraries(aircon_runner PRIVATE fgl-aircon)
|
||||
target_include_directories(aircon_runner PRIVATE "${CMAKE_SOURCE_DIR}/src")
|
||||
|
||||
# Интеграционные сценарии с mock-модулем (python, stdlib-only).
|
||||
find_package(Python3 COMPONENTS Interpreter REQUIRED)
|
||||
add_test(NAME ayla_session_mock
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/ayla/test_session_mock.py
|
||||
$<TARGET_FILE:session_runner> ${CMAKE_CURRENT_SOURCE_DIR}/ayla/mock_ac.py)
|
||||
set_tests_properties(ayla_session_mock PROPERTIES TIMEOUT 180)
|
||||
add_test(NAME aircon_session_mock
|
||||
COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/aircon/test_aircon_mock.py
|
||||
$<TARGET_FILE:aircon_runner> ${CMAKE_CURRENT_SOURCE_DIR}/ayla/mock_ac.py)
|
||||
set_tests_properties(aircon_session_mock PROPERTIES TIMEOUT 180)
|
||||
|
||||
Reference in New Issue
Block a user