diff --git a/README.md b/README.md index 58b916c4..7f498a27 100644 --- a/README.md +++ b/README.md @@ -707,7 +707,9 @@ Example: If defined you can use the services `display_boot_logo` and `display_version` to display the defined logo or the version of ehmtx. -**icons2html** (optional, boolean): If true, generate the HTML-file (*filename*.html) to show all included icons.  (default = `false`) +**icons2html** (optional, boolean): If true, generate the HTML-file (*filename*.html) to show all included icons. (default = `false`) + +**iconscache** (optional, boolean): If true, it caches icons in the `.cache\icons` folder and if it finds the specified icons in the cache, it uses them instead of trying to download them again from the Internet. (default = `false`) **always_show_rl_indicators** (optional, boolean): If true, always show the r/l indicators on all screens. Default is to not show either on clock, date, full, and bitmap screens, left on icon, or if display gauge displayed. (default = `false`) diff --git a/components/ehmtxv2/__init__.py b/components/ehmtxv2/__init__.py index c01e11a1..a5dfbe74 100644 --- a/components/ehmtxv2/__init__.py +++ b/components/ehmtxv2/__init__.py @@ -3,6 +3,7 @@ import io import json import requests +import os from esphome import core, automation from esphome.components import display, font, time, graph @@ -13,6 +14,8 @@ from esphome.core import CORE, HexInt from esphome.cpp_generator import RawExpression +from urllib.parse import urlparse + _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ["display", "light", "api"] @@ -98,6 +101,7 @@ def rgb565_888(v565): CONF_SCROLLCOUNT = "scroll_count" CONF_MATRIXCOMPONENT = "matrix_component" CONF_HTML = "icons2html" +CONF_CACHE = "iconscache" CONF_SCROLLINTERVAL = "scroll_interval" CONF_BLENDSTEPS = "blend_steps" CONF_RAINBOWINTERVAL = "rainbow_interval" @@ -146,6 +150,9 @@ def rgb565_888(v565): ): cv.templatable(cv.positive_int), cv.Optional( CONF_HTML, default=False + ): cv.boolean, + cv.Optional( + CONF_CACHE, default=False ): cv.boolean, cv.Optional( CONF_RTL, default=False @@ -330,15 +337,46 @@ def thumbnails(frames): except Exception as e: raise core.EsphomeError(f" ICONS: Could not load image file {path}: {e}") elif CONF_LAMEID in conf: - r = requests.get("https://developer.lametric.com/content/apps/icon_thumbs/" + conf[CONF_LAMEID], timeout=4.0) - if r.status_code != requests.codes.ok: - raise core.EsphomeError(f" ICONS: Could not download image file {conf[CONF_LAMEID]}: {conf[CONF_ID]}") - image = Image.open(io.BytesIO(r.content)) + path = CORE.relative_config_path(".cache/icons/lameid/" + conf[CONF_LAMEID]) + if config[CONF_CACHE] and os.path.isfile(path): + try: + image = openImageFile(path) + logging.info(f" ICONS: Load {conf[CONF_LAMEID]} from cache.") + except Exception as e: + raise core.EsphomeError(f" ICONS: Could not load image file {path}: {e}") + else: + r = requests.get("https://developer.lametric.com/content/apps/icon_thumbs/" + conf[CONF_LAMEID], timeout=4.0) + if r.status_code != requests.codes.ok: + raise core.EsphomeError(f" ICONS: Could not download image file {conf[CONF_LAMEID]}: {conf[CONF_ID]}") + image = Image.open(io.BytesIO(r.content)) + + if config[CONF_CACHE]: + os.makedirs(os.path.dirname(path), exist_ok=True) + f = open(path,"wb") + f.write(r.content) + f.close() + logging.info(f" ICONS: Save {conf[CONF_LAMEID]} to cache.") elif CONF_URL in conf: - r = requests.get(conf[CONF_URL], timeout=4.0) - if r.status_code != requests.codes.ok: - raise core.EsphomeError(f" ICONS: Could not download image file {conf[CONF_URL]}: {conf[CONF_ID]}") - image = Image.open(io.BytesIO(r.content)) + a = urlparse(conf[CONF_URL]) + path = CORE.relative_config_path(".cache/icons/url/" + os.path.basename(a.path)) + if config[CONF_CACHE] and os.path.isfile(path): + try: + image = openImageFile(path) + logging.info(f" ICONS: Load {conf[CONF_URL]} from cache.") + except Exception as e: + raise core.EsphomeError(f" ICONS: Could not load image file {path}: {e}") + else: + r = requests.get(conf[CONF_URL], timeout=4.0) + if r.status_code != requests.codes.ok: + raise core.EsphomeError(f" ICONS: Could not download image file {conf[CONF_URL]}: {conf[CONF_ID]}") + image = Image.open(io.BytesIO(r.content)) + + if config[CONF_CACHE]: + os.makedirs(os.path.dirname(path), exist_ok=True) + f = open(path,"wb") + f.write(r.content) + f.close() + logging.info(f" ICONS: Save {conf[CONF_URL]} to cache.") elif CONF_RGB565ARRAY in conf: r = list(json.loads(conf[CONF_RGB565ARRAY])) if len(r) == 64: