Initial commit.
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
"""
|
||||
Helpers functions for HASS-LocalTuya.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
import os.path
|
||||
from enum import Enum
|
||||
from fnmatch import fnmatch
|
||||
from typing import NamedTuple
|
||||
|
||||
from homeassistant.util.yaml import load_yaml, dump
|
||||
from homeassistant.const import CONF_PLATFORM, CONF_ENTITIES
|
||||
|
||||
|
||||
import custom_components.localtuya.templates as templates_dir
|
||||
|
||||
JSON_TYPE = list | dict | str
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
###############################
|
||||
# Templates #
|
||||
###############################
|
||||
class templates:
|
||||
|
||||
def yaml_dump(config, fname: str | None = None) -> JSON_TYPE:
|
||||
"""Save yaml config."""
|
||||
try:
|
||||
with open(fname, "w", encoding="utf-8") as conf_file:
|
||||
return conf_file.write(dump(config))
|
||||
except UnicodeDecodeError as exc:
|
||||
_LOGGER.error("Unable to save file %s: %s", fname, exc)
|
||||
|
||||
def list_templates():
|
||||
"""Return the available templates files."""
|
||||
dir = os.path.dirname(templates_dir.__file__)
|
||||
files = {}
|
||||
for e in sorted(os.scandir(dir), key=lambda e: e.name):
|
||||
file: str = e.name.lower()
|
||||
if e.is_file() and (fnmatch(file, "*yaml") or fnmatch(file, "*yml")):
|
||||
# fn = str(file).replace(".yaml", "").replace("_", " ")
|
||||
files[e.name] = e.name
|
||||
return files
|
||||
|
||||
def import_config(filename):
|
||||
"""Create a data that can be used as config in localtuya."""
|
||||
template_dir = os.path.dirname(templates_dir.__file__)
|
||||
template_file = os.path.join(template_dir, filename)
|
||||
_config = load_yaml(template_file)
|
||||
entities = []
|
||||
for cfg in _config:
|
||||
ent = {}
|
||||
for plat, values in cfg.items():
|
||||
for key, value in values.items():
|
||||
ent[str(key)] = (
|
||||
str(value)
|
||||
if not isinstance(value, (bool, float, dict, list))
|
||||
else value
|
||||
)
|
||||
ent[CONF_PLATFORM] = plat
|
||||
entities.append(ent)
|
||||
if not entities:
|
||||
raise ValueError("No entities found the can be used for localtuya")
|
||||
return entities
|
||||
|
||||
@classmethod
|
||||
def export_config(cls, config: dict, config_name: str):
|
||||
"""Create a yaml config file for localtuya."""
|
||||
export_config = []
|
||||
for cfg in config[CONF_ENTITIES]:
|
||||
# Special case device_classes
|
||||
for k, v in cfg.items():
|
||||
if not type(v) is str and isinstance(v, Enum):
|
||||
cfg[k] = v.value
|
||||
|
||||
ents = {cfg[CONF_PLATFORM]: cfg}
|
||||
export_config.append(ents)
|
||||
fname = (
|
||||
config_name + ".yaml" if not config_name.endswith(".yaml") else config_name
|
||||
)
|
||||
fname = fname.replace(" ", "_")
|
||||
template_dir = os.path.dirname(templates_dir.__file__)
|
||||
template_file = os.path.join(template_dir, fname)
|
||||
|
||||
cls.yaml_dump(export_config, template_file)
|
||||
|
||||
|
||||
################################
|
||||
## config flows ##
|
||||
################################
|
||||
|
||||
from ..const import CONF_LOCAL_KEY, CONF_NODE_ID
|
||||
|
||||
GATEWAY = NamedTuple("Gateway", [("id", str), ("data", dict)])
|
||||
|
||||
|
||||
def get_gateway_by_deviceid(device_id: str, cloud_data: dict) -> GATEWAY:
|
||||
"""Return the gateway (id, data) of the sub-deviceID if existed in cloud_data."""
|
||||
|
||||
if sub_device := cloud_data.get(device_id):
|
||||
for dev_id, dev_data in cloud_data.items():
|
||||
# Get gateway Assuming the LocalKey is the same gateway LocalKey!
|
||||
if (
|
||||
dev_id != device_id
|
||||
and not dev_data.get(CONF_NODE_ID)
|
||||
and dev_data.get(CONF_LOCAL_KEY) == sub_device.get(CONF_LOCAL_KEY)
|
||||
):
|
||||
return GATEWAY(dev_id, dev_data)
|
||||
|
||||
|
||||
###############################
|
||||
# Auto configure device #
|
||||
###############################
|
||||
from .ha_entities import gen_localtuya_entities
|
||||
Reference in New Issue
Block a user