From 05e30ab414d78892ac0dbe2e2522b5293cd176c7 Mon Sep 17 00:00:00 2001 From: happyhaha1 <474248257@qq.com> Date: Fri, 31 Oct 2025 10:44:42 +0800 Subject: [PATCH] feat(lua): enhance runtime environment with resilient module loading Introduce robust Lua module deployment strategy that ensures proper library availability across different system configurations. The implementation now prioritizes Home Assistant's configuration directory for persistent storage, with automatic failover to temporary locations when permission restrictions occur. Additionally, the runtime now validates module dependencies during initialization and provides clear diagnostic warnings for any loading failures. --- .../midea_auto_cloud/__init__.py | 53 ++++++++++++++----- .../midea_auto_cloud/core/lua_runtime.py | 19 ++++++- 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/custom_components/midea_auto_cloud/__init__.py b/custom_components/midea_auto_cloud/__init__.py index 9b43d26..795325a 100644 --- a/custom_components/midea_auto_cloud/__init__.py +++ b/custom_components/midea_auto_cloud/__init__.py @@ -138,18 +138,47 @@ async def update_listener(hass: HomeAssistant, config_entry: ConfigEntry): async def async_setup(hass: HomeAssistant, config: ConfigType): hass.data.setdefault(DOMAIN, {}) - cjson = os.getcwd() + "/cjson.lua" - bit = os.getcwd() + "/bit.lua" - # if not os.path.exists(cjson): - from .const import CJSON_LUA - cjson_lua = base64.b64decode(CJSON_LUA.encode("utf-8")).decode("utf-8") - with open(cjson, "wt") as fp: - fp.write(cjson_lua) - # if not os.path.exists(bit): - from .const import BIT_LUA - bit_lua = base64.b64decode(BIT_LUA.encode("utf-8")).decode("utf-8") - with open(bit, "wt") as fp: - fp.write(bit_lua) + + # 使用Home Assistant配置目录而不是当前工作目录 + config_dir = hass.config.path(DOMAIN) + os.makedirs(config_dir, exist_ok=True) + + cjson = os.path.join(config_dir, "cjson.lua") + bit = os.path.join(config_dir, "bit.lua") + + # 只有文件不存在时才创建 + if not os.path.exists(cjson): + from .const import CJSON_LUA + cjson_lua = base64.b64decode(CJSON_LUA.encode("utf-8")).decode("utf-8") + try: + with open(cjson, "wt") as fp: + fp.write(cjson_lua) + except PermissionError as e: + MideaLogger.error(f"Failed to create cjson.lua at {cjson}: {e}") + # 如果无法创建文件,尝试使用临时目录 + import tempfile + temp_dir = tempfile.gettempdir() + cjson = os.path.join(temp_dir, "cjson.lua") + with open(cjson, "wt") as fp: + fp.write(cjson_lua) + MideaLogger.warning(f"Using temporary file for cjson.lua: {cjson}") + + if not os.path.exists(bit): + from .const import BIT_LUA + bit_lua = base64.b64decode(BIT_LUA.encode("utf-8")).decode("utf-8") + try: + with open(bit, "wt") as fp: + fp.write(bit_lua) + except PermissionError as e: + MideaLogger.error(f"Failed to create bit.lua at {bit}: {e}") + # 如果无法创建文件,尝试使用临时目录 + import tempfile + temp_dir = tempfile.gettempdir() + bit = os.path.join(temp_dir, "bit.lua") + with open(bit, "wt") as fp: + fp.write(bit_lua) + MideaLogger.warning(f"Using temporary file for bit.lua: {bit}") + return True diff --git a/custom_components/midea_auto_cloud/core/lua_runtime.py b/custom_components/midea_auto_cloud/core/lua_runtime.py index f9a504d..64e1a84 100644 --- a/custom_components/midea_auto_cloud/core/lua_runtime.py +++ b/custom_components/midea_auto_cloud/core/lua_runtime.py @@ -1,5 +1,5 @@ import traceback - +import os import lupa import threading import json @@ -9,6 +9,23 @@ from .logger import MideaLogger class LuaRuntime: def __init__(self, file): self._runtimes = lupa.lua51.LuaRuntime() + + # 设置Lua路径,包含cjson.lua和bit.lua的目录 + lua_dir = os.path.dirname(os.path.abspath(file)) + self._runtimes.execute(f'package.path = package.path .. ";{lua_dir}/?.lua"') + + # 加载必需的Lua库 + try: + self._runtimes.execute('require "cjson"') + except Exception as e: + MideaLogger.warning(f"Failed to load cjson: {e}") + + try: + self._runtimes.execute('require "bit"') + except Exception as e: + MideaLogger.warning(f"Failed to load bit: {e}") + + # 加载设备特定的Lua文件 string = f'dofile("{file}")' self._runtimes.execute(string) self._lock = threading.Lock()