mirror of
https://github.com/esphome/esphome.git
synced 2024-12-21 16:27:44 +01:00
Use /data directory for .esphome folder when running as HA add-on (#5374)
This commit is contained in:
parent
10eee47b6b
commit
fe81bcc003
@ -35,11 +35,16 @@ if bashio::config.has_value 'default_compile_process_limit'; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=$(bashio::config 'default_compile_process_limit')
|
||||
else
|
||||
if grep -q 'Raspberry Pi 3' /proc/cpuinfo; then
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1;
|
||||
export ESPHOME_DEFAULT_COMPILE_PROCESS_LIMIT=1
|
||||
fi
|
||||
fi
|
||||
|
||||
mkdir -p "${pio_cache_base}"
|
||||
|
||||
if bashio::fs.directory_exists '/config/esphome/.esphome'; then
|
||||
bashio::log.info "Removing old .esphome directory..."
|
||||
rm -rf /config/esphome/.esphome
|
||||
fi
|
||||
|
||||
bashio::log.info "Starting ESPHome dashboard..."
|
||||
exec esphome dashboard /config/esphome --socket /var/run/esphome.sock --ha-addon
|
||||
|
@ -98,10 +98,9 @@ def validate_truetype_file(value):
|
||||
|
||||
|
||||
def _compute_local_font_dir(name) -> Path:
|
||||
base_dir = Path(CORE.config_dir) / ".esphome" / DOMAIN
|
||||
h = hashlib.new("sha256")
|
||||
h.update(name.encode())
|
||||
return base_dir / h.hexdigest()[:8]
|
||||
return Path(CORE.data_dir) / DOMAIN / h.hexdigest()[:8]
|
||||
|
||||
|
||||
def _compute_gfonts_local_path(value) -> Path:
|
||||
|
@ -52,7 +52,7 @@ Image_ = image_ns.class_("Image")
|
||||
|
||||
|
||||
def _compute_local_icon_path(value) -> Path:
|
||||
base_dir = Path(CORE.config_dir) / ".esphome" / DOMAIN / "mdi"
|
||||
base_dir = Path(CORE.data_dir) / DOMAIN / "mdi"
|
||||
return base_dir / f"{value[CONF_ICON]}.svg"
|
||||
|
||||
|
||||
|
@ -87,12 +87,7 @@ def get_firmware(value):
|
||||
url = value[CONF_URL]
|
||||
|
||||
if CONF_SHA256 in value: # we have a hash, enable caching
|
||||
path = (
|
||||
Path(CORE.config_dir)
|
||||
/ ".esphome"
|
||||
/ DOMAIN
|
||||
/ (value[CONF_SHA256] + "_fw_stm.bin")
|
||||
)
|
||||
path = Path(CORE.data_dir) / DOMAIN / (value[CONF_SHA256] + "_fw_stm.bin")
|
||||
|
||||
if not path.is_file():
|
||||
firmware_data, dl_hash = dl(url)
|
||||
|
@ -554,6 +554,12 @@ class EsphomeCore:
|
||||
def config_dir(self):
|
||||
return os.path.dirname(self.config_path)
|
||||
|
||||
@property
|
||||
def data_dir(self):
|
||||
if is_ha_addon():
|
||||
return os.path.join("/data")
|
||||
return self.relative_config_path(".esphome")
|
||||
|
||||
@property
|
||||
def config_filename(self):
|
||||
return os.path.basename(self.config_path)
|
||||
@ -563,7 +569,7 @@ class EsphomeCore:
|
||||
return os.path.join(self.config_dir, path_)
|
||||
|
||||
def relative_internal_path(self, *path: str) -> str:
|
||||
return self.relative_config_path(".esphome", *path)
|
||||
return os.path.join(self.data_dir, *path)
|
||||
|
||||
def relative_build_path(self, *path):
|
||||
path_ = os.path.expanduser(os.path.join(*path))
|
||||
@ -573,13 +579,9 @@ class EsphomeCore:
|
||||
return self.relative_build_path("src", *path)
|
||||
|
||||
def relative_pioenvs_path(self, *path):
|
||||
if is_ha_addon():
|
||||
return os.path.join("/data", self.name, ".pioenvs", *path)
|
||||
return self.relative_build_path(".pioenvs", *path)
|
||||
|
||||
def relative_piolibdeps_path(self, *path):
|
||||
if is_ha_addon():
|
||||
return os.path.join("/data", self.name, ".piolibdeps", *path)
|
||||
return self.relative_build_path(".piolibdeps", *path)
|
||||
|
||||
@property
|
||||
|
@ -198,8 +198,8 @@ def preload_core_config(config, result):
|
||||
CORE.data[KEY_CORE] = {}
|
||||
|
||||
if CONF_BUILD_PATH not in conf:
|
||||
conf[CONF_BUILD_PATH] = f".esphome/build/{CORE.name}"
|
||||
CORE.build_path = CORE.relative_config_path(conf[CONF_BUILD_PATH])
|
||||
conf[CONF_BUILD_PATH] = f"build/{CORE.name}"
|
||||
CORE.build_path = CORE.relative_internal_path(conf[CONF_BUILD_PATH])
|
||||
|
||||
has_oldstyle = CONF_PLATFORM in conf
|
||||
newstyle_found = [key for key in TARGET_PLATFORMS if key in config]
|
||||
|
@ -32,6 +32,7 @@ import yaml
|
||||
from tornado.log import access_log
|
||||
|
||||
from esphome import const, platformio_api, util, yaml_util
|
||||
from esphome.core import CORE
|
||||
from esphome.helpers import get_bool_env, mkdir_p, run_system_command
|
||||
from esphome.storage_json import (
|
||||
EsphomeStorageJSON,
|
||||
@ -70,6 +71,7 @@ class DashboardSettings:
|
||||
self.password_hash = password_hash(password)
|
||||
self.config_dir = args.configuration
|
||||
self.absolute_config_dir = Path(self.config_dir).resolve()
|
||||
CORE.config_path = os.path.join(self.config_dir, ".")
|
||||
|
||||
@property
|
||||
def relative_url(self):
|
||||
@ -534,7 +536,7 @@ class DownloadListRequestHandler(BaseHandler):
|
||||
@authenticated
|
||||
@bind_config
|
||||
def get(self, configuration=None):
|
||||
storage_path = ext_storage_path(settings.config_dir, configuration)
|
||||
storage_path = ext_storage_path(configuration)
|
||||
storage_json = StorageJSON.load(storage_path)
|
||||
if storage_json is None:
|
||||
self.send_error(404)
|
||||
@ -577,7 +579,7 @@ class DownloadBinaryRequestHandler(BaseHandler):
|
||||
def get(self, configuration=None):
|
||||
compressed = self.get_argument("compressed", "0") == "1"
|
||||
|
||||
storage_path = ext_storage_path(settings.config_dir, configuration)
|
||||
storage_path = ext_storage_path(configuration)
|
||||
storage_json = StorageJSON.load(storage_path)
|
||||
if storage_json is None:
|
||||
self.send_error(404)
|
||||
@ -666,9 +668,7 @@ class DashboardEntry:
|
||||
@property
|
||||
def storage(self) -> Optional[StorageJSON]:
|
||||
if not self._loaded_storage:
|
||||
self._storage = StorageJSON.load(
|
||||
ext_storage_path(settings.config_dir, self.filename)
|
||||
)
|
||||
self._storage = StorageJSON.load(ext_storage_path(self.filename))
|
||||
self._loaded_storage = True
|
||||
return self._storage
|
||||
|
||||
@ -1044,9 +1044,9 @@ class DeleteRequestHandler(BaseHandler):
|
||||
@bind_config
|
||||
def post(self, configuration=None):
|
||||
config_file = settings.rel_path(configuration)
|
||||
storage_path = ext_storage_path(settings.config_dir, configuration)
|
||||
storage_path = ext_storage_path(configuration)
|
||||
|
||||
trash_path = trash_storage_path(settings.config_dir)
|
||||
trash_path = trash_storage_path()
|
||||
mkdir_p(trash_path)
|
||||
shutil.move(config_file, os.path.join(trash_path, configuration))
|
||||
|
||||
@ -1067,7 +1067,7 @@ class UndoDeleteRequestHandler(BaseHandler):
|
||||
@bind_config
|
||||
def post(self, configuration=None):
|
||||
config_file = settings.rel_path(configuration)
|
||||
trash_path = trash_storage_path(settings.config_dir)
|
||||
trash_path = trash_storage_path()
|
||||
shutil.move(os.path.join(trash_path, configuration), config_file)
|
||||
|
||||
|
||||
@ -1325,10 +1325,9 @@ def make_app(debug=get_bool_env(ENV_DEV)):
|
||||
|
||||
def start_web_server(args):
|
||||
settings.parse_args(args)
|
||||
mkdir_p(settings.rel_path(".esphome"))
|
||||
|
||||
if settings.using_auth:
|
||||
path = esphome_storage_path(settings.config_dir)
|
||||
path = esphome_storage_path()
|
||||
storage = EsphomeStorageJSON.load(path)
|
||||
if storage is None:
|
||||
storage = EsphomeStorageJSON.get_default()
|
||||
|
@ -35,7 +35,7 @@ def run_git_command(cmd, cwd=None) -> str:
|
||||
|
||||
|
||||
def _compute_destination_path(key: str, domain: str) -> Path:
|
||||
base_dir = Path(CORE.config_dir) / ".esphome" / domain
|
||||
base_dir = Path(CORE.data_dir) / domain
|
||||
h = hashlib.new("sha256")
|
||||
h.update(key.encode())
|
||||
return base_dir / h.hexdigest()[:8]
|
||||
|
@ -22,19 +22,19 @@ _LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def storage_path() -> str:
|
||||
return CORE.relative_internal_path(f"{CORE.config_filename}.json")
|
||||
return os.path.join(CORE.data_dir, "storage", f"{CORE.config_filename}.json")
|
||||
|
||||
|
||||
def ext_storage_path(base_path: str, config_filename: str) -> str:
|
||||
return os.path.join(base_path, ".esphome", f"{config_filename}.json")
|
||||
def ext_storage_path(config_filename: str) -> str:
|
||||
return os.path.join(CORE.data_dir, "storage", f"{config_filename}.json")
|
||||
|
||||
|
||||
def esphome_storage_path(base_path: str) -> str:
|
||||
return os.path.join(base_path, ".esphome", "esphome.json")
|
||||
def esphome_storage_path() -> str:
|
||||
return os.path.join(CORE.data_dir, "esphome.json")
|
||||
|
||||
|
||||
def trash_storage_path(base_path: str) -> str:
|
||||
return os.path.join(base_path, ".esphome", "trash")
|
||||
def trash_storage_path() -> str:
|
||||
return CORE.relative_config_path("trash")
|
||||
|
||||
|
||||
class StorageJSON:
|
||||
|
@ -6,12 +6,12 @@ import unicodedata
|
||||
import voluptuous as vol
|
||||
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import ALLOWED_NAME_CHARS, ENV_QUICKWIZARD
|
||||
from esphome.core import CORE
|
||||
from esphome.helpers import get_bool_env, write_file
|
||||
from esphome.log import color, Fore
|
||||
|
||||
from esphome.log import Fore, color
|
||||
from esphome.storage_json import StorageJSON, ext_storage_path
|
||||
from esphome.util import safe_print
|
||||
from esphome.const import ALLOWED_NAME_CHARS, ENV_QUICKWIZARD
|
||||
|
||||
CORE_BIG = r""" _____ ____ _____ ______
|
||||
/ ____/ __ \| __ \| ____|
|
||||
@ -193,10 +193,10 @@ captive_portal:
|
||||
|
||||
|
||||
def wizard_write(path, **kwargs):
|
||||
from esphome.components.esp8266 import boards as esp8266_boards
|
||||
from esphome.components.esp32 import boards as esp32_boards
|
||||
from esphome.components.rp2040 import boards as rp2040_boards
|
||||
from esphome.components.bk72xx import boards as bk72xx_boards
|
||||
from esphome.components.esp32 import boards as esp32_boards
|
||||
from esphome.components.esp8266 import boards as esp8266_boards
|
||||
from esphome.components.rp2040 import boards as rp2040_boards
|
||||
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
||||
|
||||
name = kwargs["name"]
|
||||
@ -225,7 +225,7 @@ def wizard_write(path, **kwargs):
|
||||
|
||||
write_file(path, wizard_file(**kwargs))
|
||||
storage = StorageJSON.from_wizard(name, name, f"{name}.local", hardware)
|
||||
storage_path = ext_storage_path(os.path.dirname(path), os.path.basename(path))
|
||||
storage_path = ext_storage_path(os.path.basename(path))
|
||||
storage.save(storage_path)
|
||||
|
||||
return True
|
||||
@ -265,9 +265,9 @@ def strip_accents(value):
|
||||
|
||||
|
||||
def wizard(path):
|
||||
from esphome.components.bk72xx import boards as bk72xx_boards
|
||||
from esphome.components.esp32 import boards as esp32_boards
|
||||
from esphome.components.esp8266 import boards as esp8266_boards
|
||||
from esphome.components.bk72xx import boards as bk72xx_boards
|
||||
from esphome.components.rtl87xx import boards as rtl87xx_boards
|
||||
|
||||
if not path.endswith(".yaml") and not path.endswith(".yml"):
|
||||
@ -280,6 +280,9 @@ def wizard(path):
|
||||
f"Uh oh, it seems like {color(Fore.CYAN, path)} already exists, please delete that file first or chose another configuration file."
|
||||
)
|
||||
return 2
|
||||
|
||||
CORE.config_path = path
|
||||
|
||||
safe_print("Hi there!")
|
||||
sleep(1.5)
|
||||
safe_print("I'm the wizard of ESPHome :)")
|
||||
|
@ -1,7 +1,9 @@
|
||||
"""Tests for the wizard.py file."""
|
||||
import os
|
||||
|
||||
import esphome.wizard as wz
|
||||
import pytest
|
||||
from esphome.core import CORE
|
||||
from esphome.components.esp8266.boards import ESP8266_BOARD_PINS
|
||||
from esphome.components.esp32.boards import ESP32_BOARD_PINS
|
||||
from esphome.components.bk72xx.boards import BK72XX_BOARD_PINS
|
||||
@ -110,6 +112,7 @@ def test_wizard_write_sets_platform(default_config, tmp_path, monkeypatch):
|
||||
# Given
|
||||
del default_config["platform"]
|
||||
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||
|
||||
# When
|
||||
wz.wizard_write(tmp_path, **default_config)
|
||||
@ -130,6 +133,7 @@ def test_wizard_write_defaults_platform_from_board_esp8266(
|
||||
default_config["board"] = [*ESP8266_BOARD_PINS][0]
|
||||
|
||||
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||
|
||||
# When
|
||||
wz.wizard_write(tmp_path, **default_config)
|
||||
@ -150,6 +154,7 @@ def test_wizard_write_defaults_platform_from_board_esp32(
|
||||
default_config["board"] = [*ESP32_BOARD_PINS][0]
|
||||
|
||||
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||
|
||||
# When
|
||||
wz.wizard_write(tmp_path, **default_config)
|
||||
@ -170,6 +175,7 @@ def test_wizard_write_defaults_platform_from_board_bk72xx(
|
||||
default_config["board"] = [*BK72XX_BOARD_PINS][0]
|
||||
|
||||
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||
|
||||
# When
|
||||
wz.wizard_write(tmp_path, **default_config)
|
||||
@ -190,6 +196,7 @@ def test_wizard_write_defaults_platform_from_board_rtl87xx(
|
||||
default_config["board"] = [*RTL87XX_BOARD_PINS][0]
|
||||
|
||||
monkeypatch.setattr(wz, "write_file", MagicMock())
|
||||
monkeypatch.setattr(CORE, "config_path", os.path.dirname(tmp_path))
|
||||
|
||||
# When
|
||||
wz.wizard_write(tmp_path, **default_config)
|
||||
|
Loading…
Reference in New Issue
Block a user