mirror of
https://github.com/esphome/esphome.git
synced 2024-11-12 10:16:02 +01:00
[animation] Allow loading external url at build time (#6876)
This commit is contained in:
parent
3a97244b83
commit
c723fd1f80
@ -3,7 +3,13 @@ import logging
|
|||||||
from esphome import automation, core
|
from esphome import automation, core
|
||||||
from esphome.components import font
|
from esphome.components import font
|
||||||
import esphome.components.image as espImage
|
import esphome.components.image as espImage
|
||||||
from esphome.components.image import CONF_USE_TRANSPARENCY
|
from esphome.components.image import (
|
||||||
|
CONF_USE_TRANSPARENCY,
|
||||||
|
LOCAL_SCHEMA,
|
||||||
|
WEB_SCHEMA,
|
||||||
|
SOURCE_WEB,
|
||||||
|
SOURCE_LOCAL,
|
||||||
|
)
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.const import (
|
from esphome.const import (
|
||||||
@ -13,6 +19,9 @@ from esphome.const import (
|
|||||||
CONF_REPEAT,
|
CONF_REPEAT,
|
||||||
CONF_RESIZE,
|
CONF_RESIZE,
|
||||||
CONF_TYPE,
|
CONF_TYPE,
|
||||||
|
CONF_SOURCE,
|
||||||
|
CONF_PATH,
|
||||||
|
CONF_URL,
|
||||||
)
|
)
|
||||||
from esphome.core import CORE, HexInt
|
from esphome.core import CORE, HexInt
|
||||||
|
|
||||||
@ -43,6 +52,40 @@ SetFrameAction = animation_ns.class_(
|
|||||||
"AnimationSetFrameAction", automation.Action, cg.Parented.template(Animation_)
|
"AnimationSetFrameAction", automation.Action, cg.Parented.template(Animation_)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
TYPED_FILE_SCHEMA = cv.typed_schema(
|
||||||
|
{
|
||||||
|
SOURCE_LOCAL: LOCAL_SCHEMA,
|
||||||
|
SOURCE_WEB: WEB_SCHEMA,
|
||||||
|
},
|
||||||
|
key=CONF_SOURCE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _file_schema(value):
|
||||||
|
if isinstance(value, str):
|
||||||
|
return validate_file_shorthand(value)
|
||||||
|
return TYPED_FILE_SCHEMA(value)
|
||||||
|
|
||||||
|
|
||||||
|
FILE_SCHEMA = cv.Schema(_file_schema)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_file_shorthand(value):
|
||||||
|
value = cv.string_strict(value)
|
||||||
|
if value.startswith("http://") or value.startswith("https://"):
|
||||||
|
return FILE_SCHEMA(
|
||||||
|
{
|
||||||
|
CONF_SOURCE: SOURCE_WEB,
|
||||||
|
CONF_URL: value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return FILE_SCHEMA(
|
||||||
|
{
|
||||||
|
CONF_SOURCE: SOURCE_LOCAL,
|
||||||
|
CONF_PATH: value,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def validate_cross_dependencies(config):
|
def validate_cross_dependencies(config):
|
||||||
"""
|
"""
|
||||||
@ -67,7 +110,7 @@ ANIMATION_SCHEMA = cv.Schema(
|
|||||||
cv.All(
|
cv.All(
|
||||||
{
|
{
|
||||||
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
||||||
cv.Required(CONF_FILE): cv.file_,
|
cv.Required(CONF_FILE): FILE_SCHEMA,
|
||||||
cv.Optional(CONF_RESIZE): cv.dimensions,
|
cv.Optional(CONF_RESIZE): cv.dimensions,
|
||||||
cv.Optional(CONF_TYPE, default="BINARY"): cv.enum(
|
cv.Optional(CONF_TYPE, default="BINARY"): cv.enum(
|
||||||
espImage.IMAGE_TYPE, upper=True
|
espImage.IMAGE_TYPE, upper=True
|
||||||
@ -124,7 +167,11 @@ async def animation_action_to_code(config, action_id, template_arg, args):
|
|||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
path = CORE.relative_config_path(config[CONF_FILE])
|
conf_file = config[CONF_FILE]
|
||||||
|
if conf_file[CONF_SOURCE] == SOURCE_LOCAL:
|
||||||
|
path = CORE.relative_config_path(conf_file[CONF_PATH])
|
||||||
|
elif conf_file[CONF_SOURCE] == SOURCE_WEB:
|
||||||
|
path = espImage.compute_local_image_path(conf_file).as_posix()
|
||||||
try:
|
try:
|
||||||
image = Image.open(path)
|
image = Image.open(path)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -68,7 +68,7 @@ def _compute_local_icon_path(value: dict) -> Path:
|
|||||||
return base_dir / f"{value[CONF_ICON]}.svg"
|
return base_dir / f"{value[CONF_ICON]}.svg"
|
||||||
|
|
||||||
|
|
||||||
def _compute_local_image_path(value: dict) -> Path:
|
def compute_local_image_path(value: dict) -> Path:
|
||||||
url = value[CONF_URL]
|
url = value[CONF_URL]
|
||||||
h = hashlib.new("sha256")
|
h = hashlib.new("sha256")
|
||||||
h.update(url.encode())
|
h.update(url.encode())
|
||||||
@ -117,7 +117,7 @@ def download_mdi(value):
|
|||||||
|
|
||||||
def download_image(value):
|
def download_image(value):
|
||||||
url = value[CONF_URL]
|
url = value[CONF_URL]
|
||||||
path = _compute_local_image_path(value)
|
path = compute_local_image_path(value)
|
||||||
|
|
||||||
download_content(url, path)
|
download_content(url, path)
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ async def to_code(config):
|
|||||||
path = _compute_local_icon_path(conf_file).as_posix()
|
path = _compute_local_icon_path(conf_file).as_posix()
|
||||||
|
|
||||||
elif conf_file[CONF_SOURCE] == SOURCE_WEB:
|
elif conf_file[CONF_SOURCE] == SOURCE_WEB:
|
||||||
path = _compute_local_image_path(conf_file).as_posix()
|
path = compute_local_image_path(conf_file).as_posix()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
|
Loading…
Reference in New Issue
Block a user