add-black (#1593)
* Add black Update pre commit Update pre commit add empty line * Format with black
This commit is contained in:
parent
2b60b0f1fa
commit
69879920eb
@ -1,11 +1,27 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.4.0
|
||||
- repo: https://github.com/ambv/black
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
- id: end-of-file-fixer
|
||||
- id: check-yaml
|
||||
- id: check-added-large-files
|
||||
- id: flake8
|
||||
- id: black
|
||||
args:
|
||||
- --safe
|
||||
- --quiet
|
||||
files: ^((esphome|script|tests)/.+)?[^/]+\.py$
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
- flake8-docstrings==1.5.0
|
||||
- pydocstyle==5.1.1
|
||||
files: ^(esphome|tests)/.+\.py$
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.4.0
|
||||
hooks:
|
||||
- id: no-commit-to-branch
|
||||
args:
|
||||
- --branch=dev
|
||||
- --branch=master
|
||||
- --branch=beta
|
||||
|
@ -8,21 +8,36 @@ from datetime import datetime
|
||||
from esphome import const, writer, yaml_util
|
||||
import esphome.codegen as cg
|
||||
from esphome.config import iter_components, read_config, strip_default_ids
|
||||
from esphome.const import CONF_BAUD_RATE, CONF_BROKER, CONF_LOGGER, CONF_OTA, \
|
||||
CONF_PASSWORD, CONF_PORT, CONF_ESPHOME, CONF_PLATFORMIO_OPTIONS
|
||||
from esphome.const import (
|
||||
CONF_BAUD_RATE,
|
||||
CONF_BROKER,
|
||||
CONF_LOGGER,
|
||||
CONF_OTA,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_ESPHOME,
|
||||
CONF_PLATFORMIO_OPTIONS,
|
||||
)
|
||||
from esphome.core import CORE, EsphomeError, coroutine, coroutine_with_priority
|
||||
from esphome.helpers import color, indent
|
||||
from esphome.util import run_external_command, run_external_process, safe_print, list_yaml_files, \
|
||||
get_serial_ports
|
||||
from esphome.util import (
|
||||
run_external_command,
|
||||
run_external_process,
|
||||
safe_print,
|
||||
list_yaml_files,
|
||||
get_serial_ports,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def choose_prompt(options):
|
||||
if not options:
|
||||
raise EsphomeError("Found no valid options for upload/logging, please make sure relevant "
|
||||
"sections (ota, api, mqtt, ...) are in your configuration and/or the "
|
||||
"device is plugged in.")
|
||||
raise EsphomeError(
|
||||
"Found no valid options for upload/logging, please make sure relevant "
|
||||
"sections (ota, api, mqtt, ...) are in your configuration and/or the "
|
||||
"device is plugged in."
|
||||
)
|
||||
|
||||
if len(options) == 1:
|
||||
return options[0][1]
|
||||
@ -32,7 +47,7 @@ def choose_prompt(options):
|
||||
safe_print(f" [{i+1}] {desc}")
|
||||
|
||||
while True:
|
||||
opt = input('(number): ')
|
||||
opt = input("(number): ")
|
||||
if opt in options:
|
||||
opt = options.index(opt)
|
||||
break
|
||||
@ -42,7 +57,7 @@ def choose_prompt(options):
|
||||
raise ValueError
|
||||
break
|
||||
except ValueError:
|
||||
safe_print(color('red', f"Invalid option: '{opt}'"))
|
||||
safe_print(color("red", f"Invalid option: '{opt}'"))
|
||||
return options[opt - 1][1]
|
||||
|
||||
|
||||
@ -50,14 +65,14 @@ def choose_upload_log_host(default, check_default, show_ota, show_mqtt, show_api
|
||||
options = []
|
||||
for port in get_serial_ports():
|
||||
options.append((f"{port.path} ({port.description})", port.path))
|
||||
if (show_ota and 'ota' in CORE.config) or (show_api and 'api' in CORE.config):
|
||||
if (show_ota and "ota" in CORE.config) or (show_api and "api" in CORE.config):
|
||||
options.append((f"Over The Air ({CORE.address})", CORE.address))
|
||||
if default == 'OTA':
|
||||
if default == "OTA":
|
||||
return CORE.address
|
||||
if show_mqtt and 'mqtt' in CORE.config:
|
||||
options.append(("MQTT ({})".format(CORE.config['mqtt'][CONF_BROKER]), 'MQTT'))
|
||||
if default == 'OTA':
|
||||
return 'MQTT'
|
||||
if show_mqtt and "mqtt" in CORE.config:
|
||||
options.append(("MQTT ({})".format(CORE.config["mqtt"][CONF_BROKER]), "MQTT"))
|
||||
if default == "OTA":
|
||||
return "MQTT"
|
||||
if default is not None:
|
||||
return default
|
||||
if check_default is not None and check_default in [opt[1] for opt in options]:
|
||||
@ -66,11 +81,11 @@ def choose_upload_log_host(default, check_default, show_ota, show_mqtt, show_api
|
||||
|
||||
|
||||
def get_port_type(port):
|
||||
if port.startswith('/') or port.startswith('COM'):
|
||||
return 'SERIAL'
|
||||
if port == 'MQTT':
|
||||
return 'MQTT'
|
||||
return 'NETWORK'
|
||||
if port.startswith("/") or port.startswith("COM"):
|
||||
return "SERIAL"
|
||||
if port == "MQTT":
|
||||
return "MQTT"
|
||||
return "NETWORK"
|
||||
|
||||
|
||||
def run_miniterm(config, port):
|
||||
@ -80,7 +95,7 @@ def run_miniterm(config, port):
|
||||
if CONF_LOGGER not in config:
|
||||
_LOGGER.info("Logger is not enabled. Not starting UART logs.")
|
||||
return
|
||||
baud_rate = config['logger'][CONF_BAUD_RATE]
|
||||
baud_rate = config["logger"][CONF_BAUD_RATE]
|
||||
if baud_rate == 0:
|
||||
_LOGGER.info("UART logging is disabled (baud_rate=0). Not starting UART logs.")
|
||||
_LOGGER.info("Starting log output from %s with baud rate %s", port, baud_rate)
|
||||
@ -93,13 +108,18 @@ def run_miniterm(config, port):
|
||||
except serial.SerialException:
|
||||
_LOGGER.error("Serial port closed!")
|
||||
return
|
||||
line = raw.replace(b'\r', b'').replace(b'\n', b'').decode('utf8', 'backslashreplace')
|
||||
time = datetime.now().time().strftime('[%H:%M:%S]')
|
||||
line = (
|
||||
raw.replace(b"\r", b"")
|
||||
.replace(b"\n", b"")
|
||||
.decode("utf8", "backslashreplace")
|
||||
)
|
||||
time = datetime.now().time().strftime("[%H:%M:%S]")
|
||||
message = time + line
|
||||
safe_print(message)
|
||||
|
||||
backtrace_state = platformio_api.process_stacktrace(
|
||||
config, line, backtrace_state=backtrace_state)
|
||||
config, line, backtrace_state=backtrace_state
|
||||
)
|
||||
|
||||
|
||||
def wrap_to_code(name, comp):
|
||||
@ -111,7 +131,7 @@ def wrap_to_code(name, comp):
|
||||
cg.add(cg.LineComment(f"{name}:"))
|
||||
if comp.config_schema is not None:
|
||||
conf_str = yaml_util.dump(conf)
|
||||
conf_str = conf_str.replace('//', '')
|
||||
conf_str = conf_str.replace("//", "")
|
||||
cg.add(cg.LineComment(indent(conf_str)))
|
||||
yield coro(conf)
|
||||
|
||||
@ -151,15 +171,31 @@ def compile_program(args, config):
|
||||
|
||||
def upload_using_esptool(config, port):
|
||||
path = CORE.firmware_bin
|
||||
first_baudrate = config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get('upload_speed', 460800)
|
||||
first_baudrate = config[CONF_ESPHOME][CONF_PLATFORMIO_OPTIONS].get(
|
||||
"upload_speed", 460800
|
||||
)
|
||||
|
||||
def run_esptool(baud_rate):
|
||||
cmd = ['esptool.py', '--before', 'default_reset', '--after', 'hard_reset',
|
||||
'--baud', str(baud_rate),
|
||||
'--chip', 'esp8266', '--port', port, 'write_flash', '0x0', path]
|
||||
cmd = [
|
||||
"esptool.py",
|
||||
"--before",
|
||||
"default_reset",
|
||||
"--after",
|
||||
"hard_reset",
|
||||
"--baud",
|
||||
str(baud_rate),
|
||||
"--chip",
|
||||
"esp8266",
|
||||
"--port",
|
||||
port,
|
||||
"write_flash",
|
||||
"0x0",
|
||||
path,
|
||||
]
|
||||
|
||||
if os.environ.get('ESPHOME_USE_SUBPROCESS') is None:
|
||||
if os.environ.get("ESPHOME_USE_SUBPROCESS") is None:
|
||||
import esptool
|
||||
|
||||
# pylint: disable=protected-access
|
||||
return run_external_command(esptool._main, *cmd)
|
||||
|
||||
@ -169,14 +205,16 @@ def upload_using_esptool(config, port):
|
||||
if rc == 0 or first_baudrate == 115200:
|
||||
return rc
|
||||
# Try with 115200 baud rate, with some serial chips the faster baud rates do not work well
|
||||
_LOGGER.info("Upload with baud rate %s failed. Trying again with baud rate 115200.",
|
||||
first_baudrate)
|
||||
_LOGGER.info(
|
||||
"Upload with baud rate %s failed. Trying again with baud rate 115200.",
|
||||
first_baudrate,
|
||||
)
|
||||
return run_esptool(115200)
|
||||
|
||||
|
||||
def upload_program(config, args, host):
|
||||
# if upload is to a serial port use platformio, otherwise assume ota
|
||||
if get_port_type(host) == 'SERIAL':
|
||||
if get_port_type(host) == "SERIAL":
|
||||
from esphome import platformio_api
|
||||
|
||||
if CORE.is_esp8266:
|
||||
@ -186,8 +224,10 @@ def upload_program(config, args, host):
|
||||
from esphome import espota2
|
||||
|
||||
if CONF_OTA not in config:
|
||||
raise EsphomeError("Cannot upload Over the Air as the config does not include the ota: "
|
||||
"component")
|
||||
raise EsphomeError(
|
||||
"Cannot upload Over the Air as the config does not include the ota: "
|
||||
"component"
|
||||
)
|
||||
|
||||
ota_conf = config[CONF_OTA]
|
||||
remote_port = ota_conf[CONF_PORT]
|
||||
@ -196,19 +236,21 @@ def upload_program(config, args, host):
|
||||
|
||||
|
||||
def show_logs(config, args, port):
|
||||
if 'logger' not in config:
|
||||
if "logger" not in config:
|
||||
raise EsphomeError("Logger is not configured!")
|
||||
if get_port_type(port) == 'SERIAL':
|
||||
if get_port_type(port) == "SERIAL":
|
||||
run_miniterm(config, port)
|
||||
return 0
|
||||
if get_port_type(port) == 'NETWORK' and 'api' in config:
|
||||
if get_port_type(port) == "NETWORK" and "api" in config:
|
||||
from esphome.api.client import run_logs
|
||||
|
||||
return run_logs(config, port)
|
||||
if get_port_type(port) == 'MQTT' and 'mqtt' in config:
|
||||
if get_port_type(port) == "MQTT" and "mqtt" in config:
|
||||
from esphome import mqtt
|
||||
|
||||
return mqtt.show_logs(config, args.topic, args.username, args.password, args.client_id)
|
||||
return mqtt.show_logs(
|
||||
config, args.topic, args.username, args.password, args.client_id
|
||||
)
|
||||
|
||||
raise EsphomeError("No remote or local logging method configured (api/mqtt/logger)")
|
||||
|
||||
@ -216,7 +258,9 @@ def show_logs(config, args, port):
|
||||
def clean_mqtt(config, args):
|
||||
from esphome import mqtt
|
||||
|
||||
return mqtt.clear_topic(config, args.topic, args.username, args.password, args.client_id)
|
||||
return mqtt.clear_topic(
|
||||
config, args.topic, args.username, args.password, args.client_id
|
||||
)
|
||||
|
||||
|
||||
def setup_log(debug=False, quiet=False):
|
||||
@ -230,27 +274,31 @@ def setup_log(debug=False, quiet=False):
|
||||
logging.basicConfig(level=log_level)
|
||||
fmt = "%(levelname)s %(message)s"
|
||||
colorfmt = f"%(log_color)s{fmt}%(reset)s"
|
||||
datefmt = '%H:%M:%S'
|
||||
datefmt = "%H:%M:%S"
|
||||
|
||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||
logging.getLogger("urllib3").setLevel(logging.WARNING)
|
||||
|
||||
try:
|
||||
import colorama
|
||||
|
||||
colorama.init(strip=True)
|
||||
|
||||
from colorlog import ColoredFormatter
|
||||
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
|
||||
colorfmt,
|
||||
datefmt=datefmt,
|
||||
reset=True,
|
||||
log_colors={
|
||||
'DEBUG': 'cyan',
|
||||
'INFO': 'green',
|
||||
'WARNING': 'yellow',
|
||||
'ERROR': 'red',
|
||||
'CRITICAL': 'red',
|
||||
}
|
||||
))
|
||||
|
||||
logging.getLogger().handlers[0].setFormatter(
|
||||
ColoredFormatter(
|
||||
colorfmt,
|
||||
datefmt=datefmt,
|
||||
reset=True,
|
||||
log_colors={
|
||||
"DEBUG": "cyan",
|
||||
"INFO": "green",
|
||||
"WARNING": "yellow",
|
||||
"ERROR": "red",
|
||||
"CRITICAL": "red",
|
||||
},
|
||||
)
|
||||
)
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
@ -291,8 +339,13 @@ def command_compile(args, config):
|
||||
|
||||
|
||||
def command_upload(args, config):
|
||||
port = choose_upload_log_host(default=args.upload_port, check_default=None,
|
||||
show_ota=True, show_mqtt=False, show_api=False)
|
||||
port = choose_upload_log_host(
|
||||
default=args.upload_port,
|
||||
check_default=None,
|
||||
show_ota=True,
|
||||
show_mqtt=False,
|
||||
show_api=False,
|
||||
)
|
||||
exit_code = upload_program(config, args, port)
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
@ -301,8 +354,13 @@ def command_upload(args, config):
|
||||
|
||||
|
||||
def command_logs(args, config):
|
||||
port = choose_upload_log_host(default=args.serial_port, check_default=None,
|
||||
show_ota=False, show_mqtt=True, show_api=True)
|
||||
port = choose_upload_log_host(
|
||||
default=args.serial_port,
|
||||
check_default=None,
|
||||
show_ota=False,
|
||||
show_mqtt=True,
|
||||
show_api=True,
|
||||
)
|
||||
return show_logs(config, args, port)
|
||||
|
||||
|
||||
@ -314,16 +372,26 @@ def command_run(args, config):
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
_LOGGER.info("Successfully compiled program.")
|
||||
port = choose_upload_log_host(default=args.upload_port, check_default=None,
|
||||
show_ota=True, show_mqtt=False, show_api=True)
|
||||
port = choose_upload_log_host(
|
||||
default=args.upload_port,
|
||||
check_default=None,
|
||||
show_ota=True,
|
||||
show_mqtt=False,
|
||||
show_api=True,
|
||||
)
|
||||
exit_code = upload_program(config, args, port)
|
||||
if exit_code != 0:
|
||||
return exit_code
|
||||
_LOGGER.info("Successfully uploaded program.")
|
||||
if args.no_logs:
|
||||
return 0
|
||||
port = choose_upload_log_host(default=args.upload_port, check_default=port,
|
||||
show_ota=False, show_mqtt=True, show_api=True)
|
||||
port = choose_upload_log_host(
|
||||
default=args.upload_port,
|
||||
check_default=port,
|
||||
show_ota=False,
|
||||
show_mqtt=True,
|
||||
show_api=True,
|
||||
)
|
||||
return show_logs(config, args, port)
|
||||
|
||||
|
||||
@ -372,137 +440,189 @@ def command_update_all(args):
|
||||
click.echo(f"{half_line}{middle_text}{half_line}")
|
||||
|
||||
for f in files:
|
||||
print("Updating {}".format(color('cyan', f)))
|
||||
print('-' * twidth)
|
||||
print("Updating {}".format(color("cyan", f)))
|
||||
print("-" * twidth)
|
||||
print()
|
||||
rc = run_external_process('esphome', '--dashboard', f, 'run', '--no-logs', '--upload-port',
|
||||
'OTA')
|
||||
rc = run_external_process(
|
||||
"esphome", "--dashboard", f, "run", "--no-logs", "--upload-port", "OTA"
|
||||
)
|
||||
if rc == 0:
|
||||
print_bar("[{}] {}".format(color('bold_green', 'SUCCESS'), f))
|
||||
print_bar("[{}] {}".format(color("bold_green", "SUCCESS"), f))
|
||||
success[f] = True
|
||||
else:
|
||||
print_bar("[{}] {}".format(color('bold_red', 'ERROR'), f))
|
||||
print_bar("[{}] {}".format(color("bold_red", "ERROR"), f))
|
||||
success[f] = False
|
||||
|
||||
print()
|
||||
print()
|
||||
print()
|
||||
|
||||
print_bar('[{}]'.format(color('bold_white', 'SUMMARY')))
|
||||
print_bar("[{}]".format(color("bold_white", "SUMMARY")))
|
||||
failed = 0
|
||||
for f in files:
|
||||
if success[f]:
|
||||
print(" - {}: {}".format(f, color('green', 'SUCCESS')))
|
||||
print(" - {}: {}".format(f, color("green", "SUCCESS")))
|
||||
else:
|
||||
print(" - {}: {}".format(f, color('bold_red', 'FAILED')))
|
||||
print(" - {}: {}".format(f, color("bold_red", "FAILED")))
|
||||
failed += 1
|
||||
return failed
|
||||
|
||||
|
||||
PRE_CONFIG_ACTIONS = {
|
||||
'wizard': command_wizard,
|
||||
'version': command_version,
|
||||
'dashboard': command_dashboard,
|
||||
'vscode': command_vscode,
|
||||
'update-all': command_update_all,
|
||||
"wizard": command_wizard,
|
||||
"version": command_version,
|
||||
"dashboard": command_dashboard,
|
||||
"vscode": command_vscode,
|
||||
"update-all": command_update_all,
|
||||
}
|
||||
|
||||
POST_CONFIG_ACTIONS = {
|
||||
'config': command_config,
|
||||
'compile': command_compile,
|
||||
'upload': command_upload,
|
||||
'logs': command_logs,
|
||||
'run': command_run,
|
||||
'clean-mqtt': command_clean_mqtt,
|
||||
'mqtt-fingerprint': command_mqtt_fingerprint,
|
||||
'clean': command_clean,
|
||||
"config": command_config,
|
||||
"compile": command_compile,
|
||||
"upload": command_upload,
|
||||
"logs": command_logs,
|
||||
"run": command_run,
|
||||
"clean-mqtt": command_clean_mqtt,
|
||||
"mqtt-fingerprint": command_mqtt_fingerprint,
|
||||
"clean": command_clean,
|
||||
}
|
||||
|
||||
|
||||
def parse_args(argv):
|
||||
parser = argparse.ArgumentParser(description=f'ESPHome v{const.__version__}')
|
||||
parser.add_argument('-v', '--verbose', help="Enable verbose esphome logs.",
|
||||
action='store_true')
|
||||
parser.add_argument('-q', '--quiet', help="Disable all esphome logs.",
|
||||
action='store_true')
|
||||
parser.add_argument('--dashboard', help=argparse.SUPPRESS, action='store_true')
|
||||
parser.add_argument('-s', '--substitution', nargs=2, action='append',
|
||||
help='Add a substitution', metavar=('key', 'value'))
|
||||
parser.add_argument('configuration', help='Your YAML configuration file.', nargs='*')
|
||||
parser = argparse.ArgumentParser(description=f"ESPHome v{const.__version__}")
|
||||
parser.add_argument(
|
||||
"-v", "--verbose", help="Enable verbose esphome logs.", action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-q", "--quiet", help="Disable all esphome logs.", action="store_true"
|
||||
)
|
||||
parser.add_argument("--dashboard", help=argparse.SUPPRESS, action="store_true")
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--substitution",
|
||||
nargs=2,
|
||||
action="append",
|
||||
help="Add a substitution",
|
||||
metavar=("key", "value"),
|
||||
)
|
||||
parser.add_argument(
|
||||
"configuration", help="Your YAML configuration file.", nargs="*"
|
||||
)
|
||||
|
||||
subparsers = parser.add_subparsers(help='Commands', dest='command')
|
||||
subparsers = parser.add_subparsers(help="Commands", dest="command")
|
||||
subparsers.required = True
|
||||
subparsers.add_parser('config', help='Validate the configuration and spit it out.')
|
||||
subparsers.add_parser("config", help="Validate the configuration and spit it out.")
|
||||
|
||||
parser_compile = subparsers.add_parser('compile',
|
||||
help='Read the configuration and compile a program.')
|
||||
parser_compile.add_argument('--only-generate',
|
||||
help="Only generate source code, do not compile.",
|
||||
action='store_true')
|
||||
parser_compile = subparsers.add_parser(
|
||||
"compile", help="Read the configuration and compile a program."
|
||||
)
|
||||
parser_compile.add_argument(
|
||||
"--only-generate",
|
||||
help="Only generate source code, do not compile.",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
parser_upload = subparsers.add_parser('upload', help='Validate the configuration '
|
||||
'and upload the latest binary.')
|
||||
parser_upload.add_argument('--upload-port', help="Manually specify the upload port to use. "
|
||||
"For example /dev/cu.SLAB_USBtoUART.")
|
||||
parser_upload = subparsers.add_parser(
|
||||
"upload", help="Validate the configuration " "and upload the latest binary."
|
||||
)
|
||||
parser_upload.add_argument(
|
||||
"--upload-port",
|
||||
help="Manually specify the upload port to use. "
|
||||
"For example /dev/cu.SLAB_USBtoUART.",
|
||||
)
|
||||
|
||||
parser_logs = subparsers.add_parser('logs', help='Validate the configuration '
|
||||
'and show all MQTT logs.')
|
||||
parser_logs.add_argument('--topic', help='Manually set the topic to subscribe to.')
|
||||
parser_logs.add_argument('--username', help='Manually set the username.')
|
||||
parser_logs.add_argument('--password', help='Manually set the password.')
|
||||
parser_logs.add_argument('--client-id', help='Manually set the client id.')
|
||||
parser_logs.add_argument('--serial-port', help="Manually specify a serial port to use"
|
||||
"For example /dev/cu.SLAB_USBtoUART.")
|
||||
parser_logs = subparsers.add_parser(
|
||||
"logs", help="Validate the configuration " "and show all MQTT logs."
|
||||
)
|
||||
parser_logs.add_argument("--topic", help="Manually set the topic to subscribe to.")
|
||||
parser_logs.add_argument("--username", help="Manually set the username.")
|
||||
parser_logs.add_argument("--password", help="Manually set the password.")
|
||||
parser_logs.add_argument("--client-id", help="Manually set the client id.")
|
||||
parser_logs.add_argument(
|
||||
"--serial-port",
|
||||
help="Manually specify a serial port to use"
|
||||
"For example /dev/cu.SLAB_USBtoUART.",
|
||||
)
|
||||
|
||||
parser_run = subparsers.add_parser('run', help='Validate the configuration, create a binary, '
|
||||
'upload it, and start MQTT logs.')
|
||||
parser_run.add_argument('--upload-port', help="Manually specify the upload port/ip to use. "
|
||||
"For example /dev/cu.SLAB_USBtoUART.")
|
||||
parser_run.add_argument('--no-logs', help='Disable starting MQTT logs.',
|
||||
action='store_true')
|
||||
parser_run.add_argument('--topic', help='Manually set the topic to subscribe to for logs.')
|
||||
parser_run.add_argument('--username', help='Manually set the MQTT username for logs.')
|
||||
parser_run.add_argument('--password', help='Manually set the MQTT password for logs.')
|
||||
parser_run.add_argument('--client-id', help='Manually set the client id for logs.')
|
||||
parser_run = subparsers.add_parser(
|
||||
"run",
|
||||
help="Validate the configuration, create a binary, "
|
||||
"upload it, and start MQTT logs.",
|
||||
)
|
||||
parser_run.add_argument(
|
||||
"--upload-port",
|
||||
help="Manually specify the upload port/ip to use. "
|
||||
"For example /dev/cu.SLAB_USBtoUART.",
|
||||
)
|
||||
parser_run.add_argument(
|
||||
"--no-logs", help="Disable starting MQTT logs.", action="store_true"
|
||||
)
|
||||
parser_run.add_argument(
|
||||
"--topic", help="Manually set the topic to subscribe to for logs."
|
||||
)
|
||||
parser_run.add_argument(
|
||||
"--username", help="Manually set the MQTT username for logs."
|
||||
)
|
||||
parser_run.add_argument(
|
||||
"--password", help="Manually set the MQTT password for logs."
|
||||
)
|
||||
parser_run.add_argument("--client-id", help="Manually set the client id for logs.")
|
||||
|
||||
parser_clean = subparsers.add_parser('clean-mqtt', help="Helper to clear an MQTT topic from "
|
||||
"retain messages.")
|
||||
parser_clean.add_argument('--topic', help='Manually set the topic to subscribe to.')
|
||||
parser_clean.add_argument('--username', help='Manually set the username.')
|
||||
parser_clean.add_argument('--password', help='Manually set the password.')
|
||||
parser_clean.add_argument('--client-id', help='Manually set the client id.')
|
||||
parser_clean = subparsers.add_parser(
|
||||
"clean-mqtt", help="Helper to clear an MQTT topic from " "retain messages."
|
||||
)
|
||||
parser_clean.add_argument("--topic", help="Manually set the topic to subscribe to.")
|
||||
parser_clean.add_argument("--username", help="Manually set the username.")
|
||||
parser_clean.add_argument("--password", help="Manually set the password.")
|
||||
parser_clean.add_argument("--client-id", help="Manually set the client id.")
|
||||
|
||||
subparsers.add_parser('wizard', help="A helpful setup wizard that will guide "
|
||||
"you through setting up esphome.")
|
||||
subparsers.add_parser(
|
||||
"wizard",
|
||||
help="A helpful setup wizard that will guide "
|
||||
"you through setting up esphome.",
|
||||
)
|
||||
|
||||
subparsers.add_parser('mqtt-fingerprint', help="Get the SSL fingerprint from a MQTT broker.")
|
||||
subparsers.add_parser(
|
||||
"mqtt-fingerprint", help="Get the SSL fingerprint from a MQTT broker."
|
||||
)
|
||||
|
||||
subparsers.add_parser('version', help="Print the esphome version and exit.")
|
||||
subparsers.add_parser("version", help="Print the esphome version and exit.")
|
||||
|
||||
subparsers.add_parser('clean', help="Delete all temporary build files.")
|
||||
subparsers.add_parser("clean", help="Delete all temporary build files.")
|
||||
|
||||
dashboard = subparsers.add_parser('dashboard',
|
||||
help="Create a simple web server for a dashboard.")
|
||||
dashboard.add_argument("--port", help="The HTTP port to open connections on. Defaults to 6052.",
|
||||
type=int, default=6052)
|
||||
dashboard.add_argument("--username", help="The optional username to require "
|
||||
"for authentication.",
|
||||
type=str, default='')
|
||||
dashboard.add_argument("--password", help="The optional password to require "
|
||||
"for authentication.",
|
||||
type=str, default='')
|
||||
dashboard.add_argument("--open-ui", help="Open the dashboard UI in a browser.",
|
||||
action='store_true')
|
||||
dashboard.add_argument("--hassio",
|
||||
help=argparse.SUPPRESS,
|
||||
action="store_true")
|
||||
dashboard.add_argument("--socket",
|
||||
help="Make the dashboard serve under a unix socket", type=str)
|
||||
dashboard = subparsers.add_parser(
|
||||
"dashboard", help="Create a simple web server for a dashboard."
|
||||
)
|
||||
dashboard.add_argument(
|
||||
"--port",
|
||||
help="The HTTP port to open connections on. Defaults to 6052.",
|
||||
type=int,
|
||||
default=6052,
|
||||
)
|
||||
dashboard.add_argument(
|
||||
"--username",
|
||||
help="The optional username to require " "for authentication.",
|
||||
type=str,
|
||||
default="",
|
||||
)
|
||||
dashboard.add_argument(
|
||||
"--password",
|
||||
help="The optional password to require " "for authentication.",
|
||||
type=str,
|
||||
default="",
|
||||
)
|
||||
dashboard.add_argument(
|
||||
"--open-ui", help="Open the dashboard UI in a browser.", action="store_true"
|
||||
)
|
||||
dashboard.add_argument("--hassio", help=argparse.SUPPRESS, action="store_true")
|
||||
dashboard.add_argument(
|
||||
"--socket", help="Make the dashboard serve under a unix socket", type=str
|
||||
)
|
||||
|
||||
vscode = subparsers.add_parser('vscode', help=argparse.SUPPRESS)
|
||||
vscode.add_argument('--ace', action='store_true')
|
||||
vscode = subparsers.add_parser("vscode", help=argparse.SUPPRESS)
|
||||
vscode.add_argument("--ace", action="store_true")
|
||||
|
||||
subparsers.add_parser('update-all', help=argparse.SUPPRESS)
|
||||
subparsers.add_parser("update-all", help=argparse.SUPPRESS)
|
||||
|
||||
return parser.parse_args(argv[1:])
|
||||
|
||||
@ -512,13 +632,15 @@ def run_esphome(argv):
|
||||
CORE.dashboard = args.dashboard
|
||||
|
||||
setup_log(args.verbose, args.quiet)
|
||||
if args.command != 'version' and not args.configuration:
|
||||
if args.command != "version" and not args.configuration:
|
||||
_LOGGER.error("Missing configuration parameter, see esphome --help.")
|
||||
return 1
|
||||
|
||||
if sys.version_info < (3, 6, 0):
|
||||
_LOGGER.error("You're running ESPHome with Python <3.6. ESPHome is no longer compatible "
|
||||
"with this Python version. Please reinstall ESPHome with Python 3.6+")
|
||||
_LOGGER.error(
|
||||
"You're running ESPHome with Python <3.6. ESPHome is no longer compatible "
|
||||
"with this Python version. Please reinstall ESPHome with Python 3.6+"
|
||||
)
|
||||
return 1
|
||||
|
||||
if args.command in PRE_CONFIG_ACTIONS:
|
||||
|
File diff suppressed because one or more lines are too long
@ -177,10 +177,14 @@ class APIClient(threading.Thread):
|
||||
try:
|
||||
ip = resolve_ip_address(self._address)
|
||||
except EsphomeError as err:
|
||||
_LOGGER.warning("Error resolving IP address of %s. Is it connected to WiFi?",
|
||||
self._address)
|
||||
_LOGGER.warning("(If this error persists, please set a static IP address: "
|
||||
"https://esphome.io/components/wifi.html#manual-ips)")
|
||||
_LOGGER.warning(
|
||||
"Error resolving IP address of %s. Is it connected to WiFi?",
|
||||
self._address,
|
||||
)
|
||||
_LOGGER.warning(
|
||||
"(If this error persists, please set a static IP address: "
|
||||
"https://esphome.io/components/wifi.html#manual-ips)"
|
||||
)
|
||||
raise APIConnectionError(err) from err
|
||||
|
||||
_LOGGER.info("Connecting to %s:%s (%s)", self._address, self._port, ip)
|
||||
@ -198,14 +202,19 @@ class APIClient(threading.Thread):
|
||||
self._socket_open_event.set()
|
||||
|
||||
hello = pb.HelloRequest()
|
||||
hello.client_info = f'ESPHome v{const.__version__}'
|
||||
hello.client_info = f"ESPHome v{const.__version__}"
|
||||
try:
|
||||
resp = self._send_message_await_response(hello, pb.HelloResponse)
|
||||
except APIConnectionError as err:
|
||||
self._fatal_error(err)
|
||||
raise err
|
||||
_LOGGER.debug("Successfully connected to %s ('%s' API=%s.%s)", self._address,
|
||||
resp.server_info, resp.api_version_major, resp.api_version_minor)
|
||||
_LOGGER.debug(
|
||||
"Successfully connected to %s ('%s' API=%s.%s)",
|
||||
self._address,
|
||||
resp.server_info,
|
||||
resp.api_version_major,
|
||||
resp.api_version_minor,
|
||||
)
|
||||
self._connected = True
|
||||
self._refresh_ping()
|
||||
if self.on_connect is not None:
|
||||
@ -270,7 +279,9 @@ class APIClient(threading.Thread):
|
||||
req += encoded
|
||||
self._write(req)
|
||||
|
||||
def _send_message_await_response_complex(self, send_msg, do_append, do_stop, timeout=5):
|
||||
def _send_message_await_response_complex(
|
||||
self, send_msg, do_append, do_stop, timeout=5
|
||||
):
|
||||
event = threading.Event()
|
||||
responses = []
|
||||
|
||||
@ -295,12 +306,15 @@ class APIClient(threading.Thread):
|
||||
def is_response(msg):
|
||||
return isinstance(msg, response_type)
|
||||
|
||||
return self._send_message_await_response_complex(send_msg, is_response, is_response,
|
||||
timeout)[0]
|
||||
return self._send_message_await_response_complex(
|
||||
send_msg, is_response, is_response, timeout
|
||||
)[0]
|
||||
|
||||
def device_info(self):
|
||||
self._check_connected()
|
||||
return self._send_message_await_response(pb.DeviceInfoRequest(), pb.DeviceInfoResponse)
|
||||
return self._send_message_await_response(
|
||||
pb.DeviceInfoRequest(), pb.DeviceInfoResponse
|
||||
)
|
||||
|
||||
def ping(self):
|
||||
self._check_connected()
|
||||
@ -310,7 +324,9 @@ class APIClient(threading.Thread):
|
||||
self._check_connected()
|
||||
|
||||
try:
|
||||
self._send_message_await_response(pb.DisconnectRequest(), pb.DisconnectResponse)
|
||||
self._send_message_await_response(
|
||||
pb.DisconnectRequest(), pb.DisconnectResponse
|
||||
)
|
||||
except APIConnectionError:
|
||||
pass
|
||||
self._close_socket()
|
||||
@ -415,7 +431,7 @@ class APIClient(threading.Thread):
|
||||
|
||||
|
||||
def run_logs(config, address):
|
||||
conf = config['api']
|
||||
conf = config["api"]
|
||||
port = conf[CONF_PORT]
|
||||
password = conf[CONF_PASSWORD]
|
||||
_LOGGER.info("Starting log output from %s using esphome API", address)
|
||||
@ -447,24 +463,35 @@ def run_logs(config, address):
|
||||
_LOGGER.info("Successfully connected to %s", address)
|
||||
return
|
||||
|
||||
wait_time = int(min(1.5**min(tries, 100), 30))
|
||||
wait_time = int(min(1.5 ** min(tries, 100), 30))
|
||||
if not has_connects:
|
||||
_LOGGER.warning("Initial connection failed. The ESP might not be connected "
|
||||
"to WiFi yet (%s). Re-Trying in %s seconds",
|
||||
error, wait_time)
|
||||
_LOGGER.warning(
|
||||
"Initial connection failed. The ESP might not be connected "
|
||||
"to WiFi yet (%s). Re-Trying in %s seconds",
|
||||
error,
|
||||
wait_time,
|
||||
)
|
||||
else:
|
||||
_LOGGER.warning("Couldn't connect to API (%s). Trying to reconnect in %s seconds",
|
||||
error, wait_time)
|
||||
timer = threading.Timer(wait_time, functools.partial(try_connect, None, tries + 1))
|
||||
_LOGGER.warning(
|
||||
"Couldn't connect to API (%s). Trying to reconnect in %s seconds",
|
||||
error,
|
||||
wait_time,
|
||||
)
|
||||
timer = threading.Timer(
|
||||
wait_time, functools.partial(try_connect, None, tries + 1)
|
||||
)
|
||||
timer.start()
|
||||
retry_timer.append(timer)
|
||||
|
||||
def on_log(msg):
|
||||
time_ = datetime.now().time().strftime('[%H:%M:%S]')
|
||||
time_ = datetime.now().time().strftime("[%H:%M:%S]")
|
||||
text = msg.message
|
||||
if msg.send_failed:
|
||||
text = color('white', '(Message skipped because it was too big to fit in '
|
||||
'TCP buffer - This is only cosmetic)')
|
||||
text = color(
|
||||
"white",
|
||||
"(Message skipped because it was too big to fit in "
|
||||
"TCP buffer - This is only cosmetic)",
|
||||
)
|
||||
safe_print(time_ + text)
|
||||
|
||||
def on_login():
|
||||
|
@ -1,7 +1,15 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_AUTOMATION_ID, CONF_CONDITION, CONF_ELSE, CONF_ID, CONF_THEN, \
|
||||
CONF_TRIGGER_ID, CONF_TYPE_ID, CONF_TIME
|
||||
from esphome.const import (
|
||||
CONF_AUTOMATION_ID,
|
||||
CONF_CONDITION,
|
||||
CONF_ELSE,
|
||||
CONF_ID,
|
||||
CONF_THEN,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_TYPE_ID,
|
||||
CONF_TIME,
|
||||
)
|
||||
from esphome.core import coroutine
|
||||
from esphome.util import Registry
|
||||
|
||||
@ -30,36 +38,34 @@ def register_condition(name, condition_type, schema):
|
||||
return CONDITION_REGISTRY.register(name, condition_type, schema)
|
||||
|
||||
|
||||
Action = cg.esphome_ns.class_('Action')
|
||||
Trigger = cg.esphome_ns.class_('Trigger')
|
||||
Action = cg.esphome_ns.class_("Action")
|
||||
Trigger = cg.esphome_ns.class_("Trigger")
|
||||
ACTION_REGISTRY = Registry()
|
||||
Condition = cg.esphome_ns.class_('Condition')
|
||||
Condition = cg.esphome_ns.class_("Condition")
|
||||
CONDITION_REGISTRY = Registry()
|
||||
validate_action = cv.validate_registry_entry('action', ACTION_REGISTRY)
|
||||
validate_action_list = cv.validate_registry('action', ACTION_REGISTRY)
|
||||
validate_condition = cv.validate_registry_entry('condition', CONDITION_REGISTRY)
|
||||
validate_condition_list = cv.validate_registry('condition', CONDITION_REGISTRY)
|
||||
validate_action = cv.validate_registry_entry("action", ACTION_REGISTRY)
|
||||
validate_action_list = cv.validate_registry("action", ACTION_REGISTRY)
|
||||
validate_condition = cv.validate_registry_entry("condition", CONDITION_REGISTRY)
|
||||
validate_condition_list = cv.validate_registry("condition", CONDITION_REGISTRY)
|
||||
|
||||
|
||||
def validate_potentially_and_condition(value):
|
||||
if isinstance(value, list):
|
||||
with cv.remove_prepend_path(['and']):
|
||||
return validate_condition({
|
||||
'and': value
|
||||
})
|
||||
with cv.remove_prepend_path(["and"]):
|
||||
return validate_condition({"and": value})
|
||||
return validate_condition(value)
|
||||
|
||||
|
||||
DelayAction = cg.esphome_ns.class_('DelayAction', Action, cg.Component)
|
||||
LambdaAction = cg.esphome_ns.class_('LambdaAction', Action)
|
||||
IfAction = cg.esphome_ns.class_('IfAction', Action)
|
||||
WhileAction = cg.esphome_ns.class_('WhileAction', Action)
|
||||
WaitUntilAction = cg.esphome_ns.class_('WaitUntilAction', Action, cg.Component)
|
||||
UpdateComponentAction = cg.esphome_ns.class_('UpdateComponentAction', Action)
|
||||
Automation = cg.esphome_ns.class_('Automation')
|
||||
DelayAction = cg.esphome_ns.class_("DelayAction", Action, cg.Component)
|
||||
LambdaAction = cg.esphome_ns.class_("LambdaAction", Action)
|
||||
IfAction = cg.esphome_ns.class_("IfAction", Action)
|
||||
WhileAction = cg.esphome_ns.class_("WhileAction", Action)
|
||||
WaitUntilAction = cg.esphome_ns.class_("WaitUntilAction", Action, cg.Component)
|
||||
UpdateComponentAction = cg.esphome_ns.class_("UpdateComponentAction", Action)
|
||||
Automation = cg.esphome_ns.class_("Automation")
|
||||
|
||||
LambdaCondition = cg.esphome_ns.class_('LambdaCondition', Condition)
|
||||
ForCondition = cg.esphome_ns.class_('ForCondition', Condition, cg.Component)
|
||||
LambdaCondition = cg.esphome_ns.class_("LambdaCondition", Condition)
|
||||
ForCondition = cg.esphome_ns.class_("ForCondition", Condition, cg.Component)
|
||||
|
||||
|
||||
def validate_automation(extra_schema=None, extra_validators=None, single=False):
|
||||
@ -83,10 +89,10 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
|
||||
try:
|
||||
return cv.Schema([schema])(value)
|
||||
except cv.Invalid as err2:
|
||||
if 'extra keys not allowed' in str(err2) and len(err2.path) == 2:
|
||||
if "extra keys not allowed" in str(err2) and len(err2.path) == 2:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise err
|
||||
if 'Unable to find action' in str(err):
|
||||
if "Unable to find action" in str(err):
|
||||
raise err2
|
||||
raise cv.MultipleInvalid([err, err2])
|
||||
elif isinstance(value, dict):
|
||||
@ -110,47 +116,59 @@ def validate_automation(extra_schema=None, extra_validators=None, single=False):
|
||||
return validator
|
||||
|
||||
|
||||
AUTOMATION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(Trigger),
|
||||
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_id(Automation),
|
||||
cv.Required(CONF_THEN): validate_action_list,
|
||||
})
|
||||
AUTOMATION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(Trigger),
|
||||
cv.GenerateID(CONF_AUTOMATION_ID): cv.declare_id(Automation),
|
||||
cv.Required(CONF_THEN): validate_action_list,
|
||||
}
|
||||
)
|
||||
|
||||
AndCondition = cg.esphome_ns.class_('AndCondition', Condition)
|
||||
OrCondition = cg.esphome_ns.class_('OrCondition', Condition)
|
||||
NotCondition = cg.esphome_ns.class_('NotCondition', Condition)
|
||||
AndCondition = cg.esphome_ns.class_("AndCondition", Condition)
|
||||
OrCondition = cg.esphome_ns.class_("OrCondition", Condition)
|
||||
NotCondition = cg.esphome_ns.class_("NotCondition", Condition)
|
||||
|
||||
|
||||
@register_condition('and', AndCondition, validate_condition_list)
|
||||
@register_condition("and", AndCondition, validate_condition_list)
|
||||
def and_condition_to_code(config, condition_id, template_arg, args):
|
||||
conditions = yield build_condition_list(config, template_arg, args)
|
||||
yield cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
|
||||
|
||||
@register_condition('or', OrCondition, validate_condition_list)
|
||||
@register_condition("or", OrCondition, validate_condition_list)
|
||||
def or_condition_to_code(config, condition_id, template_arg, args):
|
||||
conditions = yield build_condition_list(config, template_arg, args)
|
||||
yield cg.new_Pvariable(condition_id, template_arg, conditions)
|
||||
|
||||
|
||||
@register_condition('not', NotCondition, validate_potentially_and_condition)
|
||||
@register_condition("not", NotCondition, validate_potentially_and_condition)
|
||||
def not_condition_to_code(config, condition_id, template_arg, args):
|
||||
condition = yield build_condition(config, template_arg, args)
|
||||
yield cg.new_Pvariable(condition_id, template_arg, condition)
|
||||
|
||||
|
||||
@register_condition('lambda', LambdaCondition, cv.lambda_)
|
||||
@register_condition("lambda", LambdaCondition, cv.lambda_)
|
||||
def lambda_condition_to_code(config, condition_id, template_arg, args):
|
||||
lambda_ = yield cg.process_lambda(config, args, return_type=bool)
|
||||
yield cg.new_Pvariable(condition_id, template_arg, lambda_)
|
||||
|
||||
|
||||
@register_condition('for', ForCondition, cv.Schema({
|
||||
cv.Required(CONF_TIME): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
}).extend(cv.COMPONENT_SCHEMA))
|
||||
@register_condition(
|
||||
"for",
|
||||
ForCondition,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_TIME): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
)
|
||||
def for_condition_to_code(config, condition_id, template_arg, args):
|
||||
condition = yield build_condition(config[CONF_CONDITION], cg.TemplateArguments(), [])
|
||||
condition = yield build_condition(
|
||||
config[CONF_CONDITION], cg.TemplateArguments(), []
|
||||
)
|
||||
var = cg.new_Pvariable(condition_id, template_arg, condition)
|
||||
yield cg.register_component(var, config)
|
||||
templ = yield cg.templatable(config[CONF_TIME], args, cg.uint32)
|
||||
@ -158,7 +176,9 @@ def for_condition_to_code(config, condition_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@register_action('delay', DelayAction, cv.templatable(cv.positive_time_period_milliseconds))
|
||||
@register_action(
|
||||
"delay", DelayAction, cv.templatable(cv.positive_time_period_milliseconds)
|
||||
)
|
||||
def delay_action_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_component(var, {})
|
||||
@ -167,11 +187,18 @@ def delay_action_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@register_action('if', IfAction, cv.All({
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
cv.Optional(CONF_THEN): validate_action_list,
|
||||
cv.Optional(CONF_ELSE): validate_action_list,
|
||||
}, cv.has_at_least_one_key(CONF_THEN, CONF_ELSE)))
|
||||
@register_action(
|
||||
"if",
|
||||
IfAction,
|
||||
cv.All(
|
||||
{
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
cv.Optional(CONF_THEN): validate_action_list,
|
||||
cv.Optional(CONF_ELSE): validate_action_list,
|
||||
},
|
||||
cv.has_at_least_one_key(CONF_THEN, CONF_ELSE),
|
||||
),
|
||||
)
|
||||
def if_action_to_code(config, action_id, template_arg, args):
|
||||
conditions = yield build_condition(config[CONF_CONDITION], template_arg, args)
|
||||
var = cg.new_Pvariable(action_id, template_arg, conditions)
|
||||
@ -184,10 +211,16 @@ def if_action_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@register_action('while', WhileAction, cv.Schema({
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
cv.Required(CONF_THEN): validate_action_list,
|
||||
}))
|
||||
@register_action(
|
||||
"while",
|
||||
WhileAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
cv.Required(CONF_THEN): validate_action_list,
|
||||
}
|
||||
),
|
||||
)
|
||||
def while_action_to_code(config, action_id, template_arg, args):
|
||||
conditions = yield build_condition(config[CONF_CONDITION], template_arg, args)
|
||||
var = cg.new_Pvariable(action_id, template_arg, conditions)
|
||||
@ -197,15 +230,17 @@ def while_action_to_code(config, action_id, template_arg, args):
|
||||
|
||||
|
||||
def validate_wait_until(value):
|
||||
schema = cv.Schema({
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
})
|
||||
schema = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_CONDITION): validate_potentially_and_condition,
|
||||
}
|
||||
)
|
||||
if isinstance(value, dict) and CONF_CONDITION in value:
|
||||
return schema(value)
|
||||
return validate_wait_until({CONF_CONDITION: value})
|
||||
|
||||
|
||||
@register_action('wait_until', WaitUntilAction, validate_wait_until)
|
||||
@register_action("wait_until", WaitUntilAction, validate_wait_until)
|
||||
def wait_until_action_to_code(config, action_id, template_arg, args):
|
||||
conditions = yield build_condition(config[CONF_CONDITION], template_arg, args)
|
||||
var = cg.new_Pvariable(action_id, template_arg, conditions)
|
||||
@ -213,15 +248,21 @@ def wait_until_action_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@register_action('lambda', LambdaAction, cv.lambda_)
|
||||
@register_action("lambda", LambdaAction, cv.lambda_)
|
||||
def lambda_action_to_code(config, action_id, template_arg, args):
|
||||
lambda_ = yield cg.process_lambda(config, args, return_type=cg.void)
|
||||
yield cg.new_Pvariable(action_id, template_arg, lambda_)
|
||||
|
||||
|
||||
@register_action('component.update', UpdateComponentAction, maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
|
||||
}))
|
||||
@register_action(
|
||||
"component.update",
|
||||
UpdateComponentAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(cg.PollingComponent),
|
||||
}
|
||||
),
|
||||
)
|
||||
def component_update_action_to_code(config, action_id, template_arg, args):
|
||||
comp = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, comp)
|
||||
@ -229,7 +270,9 @@ def component_update_action_to_code(config, action_id, template_arg, args):
|
||||
|
||||
@coroutine
|
||||
def build_action(full_config, template_arg, args):
|
||||
registry_entry, config = cg.extract_registry_entry_config(ACTION_REGISTRY, full_config)
|
||||
registry_entry, config = cg.extract_registry_entry_config(
|
||||
ACTION_REGISTRY, full_config
|
||||
)
|
||||
action_id = full_config[CONF_TYPE_ID]
|
||||
builder = registry_entry.coroutine_fun
|
||||
yield builder(config, action_id, template_arg, args)
|
||||
@ -246,7 +289,9 @@ def build_action_list(config, templ, arg_type):
|
||||
|
||||
@coroutine
|
||||
def build_condition(full_config, template_arg, args):
|
||||
registry_entry, config = cg.extract_registry_entry_config(CONDITION_REGISTRY, full_config)
|
||||
registry_entry, config = cg.extract_registry_entry_config(
|
||||
CONDITION_REGISTRY, full_config
|
||||
)
|
||||
action_id = full_config[CONF_TYPE_ID]
|
||||
builder = registry_entry.coroutine_fun
|
||||
yield builder(config, action_id, template_arg, args)
|
||||
|
@ -9,18 +9,70 @@
|
||||
|
||||
# pylint: disable=unused-import
|
||||
from esphome.cpp_generator import ( # noqa
|
||||
Expression, RawExpression, RawStatement, TemplateArguments,
|
||||
StructInitializer, ArrayInitializer, safe_exp, Statement, LineComment,
|
||||
progmem_array, statement, variable, Pvariable, new_Pvariable,
|
||||
add, add_global, add_library, add_build_flag, add_define,
|
||||
get_variable, get_variable_with_full_id, process_lambda, is_template, templatable, MockObj,
|
||||
MockObjClass)
|
||||
Expression,
|
||||
RawExpression,
|
||||
RawStatement,
|
||||
TemplateArguments,
|
||||
StructInitializer,
|
||||
ArrayInitializer,
|
||||
safe_exp,
|
||||
Statement,
|
||||
LineComment,
|
||||
progmem_array,
|
||||
statement,
|
||||
variable,
|
||||
Pvariable,
|
||||
new_Pvariable,
|
||||
add,
|
||||
add_global,
|
||||
add_library,
|
||||
add_build_flag,
|
||||
add_define,
|
||||
get_variable,
|
||||
get_variable_with_full_id,
|
||||
process_lambda,
|
||||
is_template,
|
||||
templatable,
|
||||
MockObj,
|
||||
MockObjClass,
|
||||
)
|
||||
from esphome.cpp_helpers import ( # noqa
|
||||
gpio_pin_expression, register_component, build_registry_entry,
|
||||
build_registry_list, extract_registry_entry_config, register_parented)
|
||||
gpio_pin_expression,
|
||||
register_component,
|
||||
build_registry_entry,
|
||||
build_registry_list,
|
||||
extract_registry_entry_config,
|
||||
register_parented,
|
||||
)
|
||||
from esphome.cpp_types import ( # noqa
|
||||
global_ns, void, nullptr, float_, double, bool_, int_, std_ns, std_string,
|
||||
std_vector, uint8, uint16, uint32, int32, const_char_ptr, NAN,
|
||||
esphome_ns, App, Nameable, Component, ComponentPtr,
|
||||
PollingComponent, Application, optional, arduino_json_ns, JsonObject,
|
||||
JsonObjectRef, JsonObjectConstRef, Controller, GPIOPin)
|
||||
global_ns,
|
||||
void,
|
||||
nullptr,
|
||||
float_,
|
||||
double,
|
||||
bool_,
|
||||
int_,
|
||||
std_ns,
|
||||
std_string,
|
||||
std_vector,
|
||||
uint8,
|
||||
uint16,
|
||||
uint32,
|
||||
int32,
|
||||
const_char_ptr,
|
||||
NAN,
|
||||
esphome_ns,
|
||||
App,
|
||||
Nameable,
|
||||
Component,
|
||||
ComponentPtr,
|
||||
PollingComponent,
|
||||
Application,
|
||||
optional,
|
||||
arduino_json_ns,
|
||||
JsonObject,
|
||||
JsonObjectRef,
|
||||
JsonObjectConstRef,
|
||||
Controller,
|
||||
GPIOPin,
|
||||
)
|
||||
|
@ -5,15 +5,17 @@ import esphome.codegen as cg
|
||||
from esphome.const import CONF_DIR_PIN, CONF_ID, CONF_SLEEP_PIN, CONF_STEP_PIN
|
||||
|
||||
|
||||
a4988_ns = cg.esphome_ns.namespace('a4988')
|
||||
A4988 = a4988_ns.class_('A4988', stepper.Stepper, cg.Component)
|
||||
a4988_ns = cg.esphome_ns.namespace("a4988")
|
||||
A4988 = a4988_ns.class_("A4988", stepper.Stepper, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = stepper.STEPPER_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(A4988),
|
||||
cv.Required(CONF_STEP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_DIR_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_SLEEP_PIN): pins.gpio_output_pin_schema,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = stepper.STEPPER_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(A4988),
|
||||
cv.Required(CONF_STEP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_DIR_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_SLEEP_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,28 +4,32 @@ from esphome import pins
|
||||
from esphome.components import output
|
||||
from esphome.const import CONF_ID, CONF_MIN_POWER, CONF_METHOD
|
||||
|
||||
CODEOWNERS = ['@glmnet']
|
||||
CODEOWNERS = ["@glmnet"]
|
||||
|
||||
ac_dimmer_ns = cg.esphome_ns.namespace('ac_dimmer')
|
||||
AcDimmer = ac_dimmer_ns.class_('AcDimmer', output.FloatOutput, cg.Component)
|
||||
ac_dimmer_ns = cg.esphome_ns.namespace("ac_dimmer")
|
||||
AcDimmer = ac_dimmer_ns.class_("AcDimmer", output.FloatOutput, cg.Component)
|
||||
|
||||
DimMethod = ac_dimmer_ns.enum('DimMethod')
|
||||
DimMethod = ac_dimmer_ns.enum("DimMethod")
|
||||
DIM_METHODS = {
|
||||
'LEADING_PULSE': DimMethod.DIM_METHOD_LEADING_PULSE,
|
||||
'LEADING': DimMethod.DIM_METHOD_LEADING,
|
||||
'TRAILING': DimMethod.DIM_METHOD_TRAILING,
|
||||
"LEADING_PULSE": DimMethod.DIM_METHOD_LEADING_PULSE,
|
||||
"LEADING": DimMethod.DIM_METHOD_LEADING,
|
||||
"TRAILING": DimMethod.DIM_METHOD_TRAILING,
|
||||
}
|
||||
|
||||
CONF_GATE_PIN = 'gate_pin'
|
||||
CONF_ZERO_CROSS_PIN = 'zero_cross_pin'
|
||||
CONF_INIT_WITH_HALF_CYCLE = 'init_with_half_cycle'
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(AcDimmer),
|
||||
cv.Required(CONF_GATE_PIN): pins.internal_gpio_output_pin_schema,
|
||||
cv.Required(CONF_ZERO_CROSS_PIN): pins.internal_gpio_input_pin_schema,
|
||||
cv.Optional(CONF_INIT_WITH_HALF_CYCLE, default=True): cv.boolean,
|
||||
cv.Optional(CONF_METHOD, default='leading pulse'): cv.enum(DIM_METHODS, upper=True, space='_'),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONF_GATE_PIN = "gate_pin"
|
||||
CONF_ZERO_CROSS_PIN = "zero_cross_pin"
|
||||
CONF_INIT_WITH_HALF_CYCLE = "init_with_half_cycle"
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(AcDimmer),
|
||||
cv.Required(CONF_GATE_PIN): pins.internal_gpio_output_pin_schema,
|
||||
cv.Required(CONF_ZERO_CROSS_PIN): pins.internal_gpio_input_pin_schema,
|
||||
cv.Optional(CONF_INIT_WITH_HALF_CYCLE, default=True): cv.boolean,
|
||||
cv.Optional(CONF_METHOD, default="leading pulse"): cv.enum(
|
||||
DIM_METHODS, upper=True, space="_"
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -5,18 +5,22 @@ from esphome.components.light.types import AddressableLightEffect
|
||||
from esphome.components.light.effects import register_addressable_effect
|
||||
from esphome.const import CONF_NAME, CONF_UART_ID
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
adalight_ns = cg.esphome_ns.namespace('adalight')
|
||||
adalight_ns = cg.esphome_ns.namespace("adalight")
|
||||
AdalightLightEffect = adalight_ns.class_(
|
||||
'AdalightLightEffect', uart.UARTDevice, AddressableLightEffect)
|
||||
"AdalightLightEffect", uart.UARTDevice, AddressableLightEffect
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({})
|
||||
|
||||
|
||||
@register_addressable_effect('adalight', AdalightLightEffect, "Adalight", {
|
||||
cv.GenerateID(CONF_UART_ID): cv.use_id(uart.UARTComponent)
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"adalight",
|
||||
AdalightLightEffect,
|
||||
"Adalight",
|
||||
{cv.GenerateID(CONF_UART_ID): cv.use_id(uart.UARTComponent)},
|
||||
)
|
||||
def adalight_light_effect_to_code(config, effect_id):
|
||||
effect = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
yield uart.register_uart_device(effect, config)
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
|
@ -2,37 +2,51 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_ATTENUATION, CONF_ID, CONF_PIN, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, \
|
||||
UNIT_VOLT
|
||||
from esphome.const import (
|
||||
CONF_ATTENUATION,
|
||||
CONF_ID,
|
||||
CONF_PIN,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
|
||||
|
||||
AUTO_LOAD = ['voltage_sampler']
|
||||
AUTO_LOAD = ["voltage_sampler"]
|
||||
|
||||
ATTENUATION_MODES = {
|
||||
'0db': cg.global_ns.ADC_0db,
|
||||
'2.5db': cg.global_ns.ADC_2_5db,
|
||||
'6db': cg.global_ns.ADC_6db,
|
||||
'11db': cg.global_ns.ADC_11db,
|
||||
"0db": cg.global_ns.ADC_0db,
|
||||
"2.5db": cg.global_ns.ADC_2_5db,
|
||||
"6db": cg.global_ns.ADC_6db,
|
||||
"11db": cg.global_ns.ADC_11db,
|
||||
}
|
||||
|
||||
|
||||
def validate_adc_pin(value):
|
||||
vcc = str(value).upper()
|
||||
if vcc == 'VCC':
|
||||
if vcc == "VCC":
|
||||
return cv.only_on_esp8266(vcc)
|
||||
return pins.analog_pin(value)
|
||||
|
||||
|
||||
adc_ns = cg.esphome_ns.namespace('adc')
|
||||
ADCSensor = adc_ns.class_('ADCSensor', sensor.Sensor, cg.PollingComponent,
|
||||
voltage_sampler.VoltageSampler)
|
||||
adc_ns = cg.esphome_ns.namespace("adc")
|
||||
ADCSensor = adc_ns.class_(
|
||||
"ADCSensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE).extend({
|
||||
cv.GenerateID(): cv.declare_id(ADCSensor),
|
||||
cv.Required(CONF_PIN): validate_adc_pin,
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32='0db'):
|
||||
cv.All(cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADCSensor),
|
||||
cv.Required(CONF_PIN): validate_adc_pin,
|
||||
cv.SplitDefault(CONF_ATTENUATION, esp32="0db"): cv.All(
|
||||
cv.only_on_esp32, cv.enum(ATTENUATION_MODES, lower=True)
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -40,8 +54,8 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
yield sensor.register_sensor(var, config)
|
||||
|
||||
if config[CONF_PIN] == 'VCC':
|
||||
cg.add_define('USE_ADC_SENSOR_VCC')
|
||||
if config[CONF_PIN] == "VCC":
|
||||
cg.add_define("USE_ADC_SENSOR_VCC")
|
||||
else:
|
||||
cg.add(var.set_pin(config[CONF_PIN]))
|
||||
|
||||
|
@ -2,33 +2,54 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, i2c
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_ID, CONF_VOLTAGE, DEVICE_CLASS_CURRENT, DEVICE_CLASS_POWER, \
|
||||
DEVICE_CLASS_VOLTAGE, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ade7953_ns = cg.esphome_ns.namespace('ade7953')
|
||||
ADE7953 = ade7953_ns.class_('ADE7953', cg.PollingComponent, i2c.I2CDevice)
|
||||
ade7953_ns = cg.esphome_ns.namespace("ade7953")
|
||||
ADE7953 = ade7953_ns.class_("ADE7953", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
CONF_IRQ_PIN = 'irq_pin'
|
||||
CONF_CURRENT_A = 'current_a'
|
||||
CONF_CURRENT_B = 'current_b'
|
||||
CONF_ACTIVE_POWER_A = 'active_power_a'
|
||||
CONF_ACTIVE_POWER_B = 'active_power_b'
|
||||
CONF_IRQ_PIN = "irq_pin"
|
||||
CONF_CURRENT_A = "current_a"
|
||||
CONF_CURRENT_B = "current_b"
|
||||
CONF_ACTIVE_POWER_A = "active_power_a"
|
||||
CONF_ACTIVE_POWER_B = "active_power_b"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ADE7953),
|
||||
cv.Optional(CONF_IRQ_PIN): pins.input_pin,
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT_A): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_CURRENT_B): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_ACTIVE_POWER_A): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_ACTIVE_POWER_B): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_POWER),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x38))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADE7953),
|
||||
cv.Optional(CONF_IRQ_PIN): pins.input_pin,
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT_A): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_CURRENT_B): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_ACTIVE_POWER_A): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_ACTIVE_POWER_B): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x38))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -39,10 +60,15 @@ def to_code(config):
|
||||
if CONF_IRQ_PIN in config:
|
||||
cg.add(var.set_irq_pin(config[CONF_IRQ_PIN]))
|
||||
|
||||
for key in [CONF_VOLTAGE, CONF_CURRENT_A, CONF_CURRENT_B, CONF_ACTIVE_POWER_A,
|
||||
CONF_ACTIVE_POWER_B]:
|
||||
for key in [
|
||||
CONF_VOLTAGE,
|
||||
CONF_CURRENT_A,
|
||||
CONF_CURRENT_B,
|
||||
CONF_ACTIVE_POWER_A,
|
||||
CONF_ACTIVE_POWER_B,
|
||||
]:
|
||||
if key not in config:
|
||||
continue
|
||||
conf = config[key]
|
||||
sens = yield sensor.new_sensor(conf)
|
||||
cg.add(getattr(var, f'set_{key}_sensor')(sens))
|
||||
cg.add(getattr(var, f"set_{key}_sensor")(sens))
|
||||
|
@ -3,18 +3,24 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ['sensor', 'voltage_sampler']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["sensor", "voltage_sampler"]
|
||||
MULTI_CONF = True
|
||||
|
||||
ads1115_ns = cg.esphome_ns.namespace('ads1115')
|
||||
ADS1115Component = ads1115_ns.class_('ADS1115Component', cg.Component, i2c.I2CDevice)
|
||||
ads1115_ns = cg.esphome_ns.namespace("ads1115")
|
||||
ADS1115Component = ads1115_ns.class_("ADS1115Component", cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONF_CONTINUOUS_MODE = 'continuous_mode'
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ADS1115Component),
|
||||
cv.Optional(CONF_CONTINUOUS_MODE, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(None))
|
||||
CONF_CONTINUOUS_MODE = "continuous_mode"
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADS1115Component),
|
||||
cv.Optional(CONF_CONTINUOUS_MODE, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(None))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,54 +1,67 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_GAIN, CONF_MULTIPLEXER, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, \
|
||||
UNIT_VOLT, CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_GAIN,
|
||||
CONF_MULTIPLEXER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
CONF_ID,
|
||||
)
|
||||
from . import ads1115_ns, ADS1115Component
|
||||
|
||||
DEPENDENCIES = ['ads1115']
|
||||
DEPENDENCIES = ["ads1115"]
|
||||
|
||||
ADS1115Multiplexer = ads1115_ns.enum('ADS1115Multiplexer')
|
||||
ADS1115Multiplexer = ads1115_ns.enum("ADS1115Multiplexer")
|
||||
MUX = {
|
||||
'A0_A1': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
|
||||
'A0_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
|
||||
'A1_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_N3,
|
||||
'A2_A3': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_N3,
|
||||
'A0_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_NG,
|
||||
'A1_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_NG,
|
||||
'A2_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_NG,
|
||||
'A3_GND': ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
|
||||
"A0_A1": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N1,
|
||||
"A0_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_N3,
|
||||
"A1_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_N3,
|
||||
"A2_A3": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_N3,
|
||||
"A0_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P0_NG,
|
||||
"A1_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P1_NG,
|
||||
"A2_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P2_NG,
|
||||
"A3_GND": ADS1115Multiplexer.ADS1115_MULTIPLEXER_P3_NG,
|
||||
}
|
||||
|
||||
ADS1115Gain = ads1115_ns.enum('ADS1115Gain')
|
||||
ADS1115Gain = ads1115_ns.enum("ADS1115Gain")
|
||||
GAIN = {
|
||||
'6.144': ADS1115Gain.ADS1115_GAIN_6P144,
|
||||
'4.096': ADS1115Gain.ADS1115_GAIN_4P096,
|
||||
'2.048': ADS1115Gain.ADS1115_GAIN_2P048,
|
||||
'1.024': ADS1115Gain.ADS1115_GAIN_1P024,
|
||||
'0.512': ADS1115Gain.ADS1115_GAIN_0P512,
|
||||
'0.256': ADS1115Gain.ADS1115_GAIN_0P256,
|
||||
"6.144": ADS1115Gain.ADS1115_GAIN_6P144,
|
||||
"4.096": ADS1115Gain.ADS1115_GAIN_4P096,
|
||||
"2.048": ADS1115Gain.ADS1115_GAIN_2P048,
|
||||
"1.024": ADS1115Gain.ADS1115_GAIN_1P024,
|
||||
"0.512": ADS1115Gain.ADS1115_GAIN_0P512,
|
||||
"0.256": ADS1115Gain.ADS1115_GAIN_0P256,
|
||||
}
|
||||
|
||||
|
||||
def validate_gain(value):
|
||||
if isinstance(value, float):
|
||||
value = f'{value:0.03f}'
|
||||
value = f"{value:0.03f}"
|
||||
elif not isinstance(value, str):
|
||||
raise cv.Invalid(f'invalid gain "{value}"')
|
||||
|
||||
return cv.enum(GAIN)(value)
|
||||
|
||||
|
||||
ADS1115Sensor = ads1115_ns.class_('ADS1115Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
voltage_sampler.VoltageSampler)
|
||||
ADS1115Sensor = ads1115_ns.class_(
|
||||
"ADS1115Sensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||
)
|
||||
|
||||
CONF_ADS1115_ID = 'ads1115_id'
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 3, DEVICE_CLASS_VOLTAGE).extend({
|
||||
cv.GenerateID(): cv.declare_id(ADS1115Sensor),
|
||||
cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component),
|
||||
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space='_'),
|
||||
cv.Required(CONF_GAIN): validate_gain,
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONF_ADS1115_ID = "ads1115_id"
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 3, DEVICE_CLASS_VOLTAGE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ADS1115Sensor),
|
||||
cv.GenerateID(CONF_ADS1115_ID): cv.use_id(ADS1115Component),
|
||||
cv.Required(CONF_MULTIPLEXER): cv.enum(MUX, upper=True, space="_"),
|
||||
cv.Required(CONF_GAIN): validate_gain,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,37 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_HUMIDITY, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
aht10_ns = cg.esphome_ns.namespace('aht10')
|
||||
AHT10Component = aht10_ns.class_('AHT10Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
aht10_ns = cg.esphome_ns.namespace("aht10")
|
||||
AHT10Component = aht10_ns.class_("AHT10Component", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(AHT10Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x38))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AHT10Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 2, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 2, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x38))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,39 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_HUMIDITY, \
|
||||
DEVICE_CLASS_TEMPERATURE, UNIT_CELSIUS, ICON_EMPTY, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
am2320_ns = cg.esphome_ns.namespace('am2320')
|
||||
AM2320Component = am2320_ns.class_('AM2320Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
am2320_ns = cg.esphome_ns.namespace("am2320")
|
||||
AM2320Component = am2320_ns.class_(
|
||||
"AM2320Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(AM2320Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x5C))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AM2320Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x5C))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -10,24 +10,28 @@ from esphome.core import CORE, HexInt
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
DEPENDENCIES = ["display"]
|
||||
MULTI_CONF = True
|
||||
|
||||
Animation_ = display.display_ns.class_('Animation')
|
||||
Animation_ = display.display_ns.class_("Animation")
|
||||
|
||||
CONF_RAW_DATA_ID = 'raw_data_id'
|
||||
CONF_RAW_DATA_ID = "raw_data_id"
|
||||
|
||||
ANIMATION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
||||
cv.Required(CONF_FILE): cv.file_,
|
||||
cv.Optional(CONF_RESIZE): cv.dimensions,
|
||||
cv.Optional(CONF_TYPE, default='BINARY'): cv.enum(espImage.IMAGE_TYPE, upper=True),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
})
|
||||
ANIMATION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(Animation_),
|
||||
cv.Required(CONF_FILE): cv.file_,
|
||||
cv.Optional(CONF_RESIZE): cv.dimensions,
|
||||
cv.Optional(CONF_TYPE, default="BINARY"): cv.enum(
|
||||
espImage.IMAGE_TYPE, upper=True
|
||||
),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(font.validate_pillow_installed, ANIMATION_SCHEMA)
|
||||
|
||||
CODEOWNERS = ['@syndlex']
|
||||
CODEOWNERS = ["@syndlex"]
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -46,26 +50,28 @@ def to_code(config):
|
||||
width, height = image.size
|
||||
else:
|
||||
if width > 500 or height > 500:
|
||||
_LOGGER.warning("The image you requested is very big. Please consider using"
|
||||
" the resize parameter.")
|
||||
_LOGGER.warning(
|
||||
"The image you requested is very big. Please consider using"
|
||||
" the resize parameter."
|
||||
)
|
||||
|
||||
if config[CONF_TYPE] == 'GRAYSCALE':
|
||||
if config[CONF_TYPE] == "GRAYSCALE":
|
||||
data = [0 for _ in range(height * width * frames)]
|
||||
pos = 0
|
||||
for frameIndex in range(frames):
|
||||
image.seek(frameIndex)
|
||||
frame = image.convert('L', dither=Image.NONE)
|
||||
frame = image.convert("L", dither=Image.NONE)
|
||||
pixels = list(frame.getdata())
|
||||
for pix in pixels:
|
||||
data[pos] = pix
|
||||
pos += 1
|
||||
|
||||
elif config[CONF_TYPE] == 'RGB24':
|
||||
elif config[CONF_TYPE] == "RGB24":
|
||||
data = [0 for _ in range(height * width * 3 * frames)]
|
||||
pos = 0
|
||||
for frameIndex in range(frames):
|
||||
image.seek(frameIndex)
|
||||
frame = image.convert('RGB')
|
||||
frame = image.convert("RGB")
|
||||
pixels = list(frame.getdata())
|
||||
for pix in pixels:
|
||||
data[pos] = pix[0]
|
||||
@ -75,12 +81,12 @@ def to_code(config):
|
||||
data[pos] = pix[2]
|
||||
pos += 1
|
||||
|
||||
elif config[CONF_TYPE] == 'BINARY':
|
||||
elif config[CONF_TYPE] == "BINARY":
|
||||
width8 = ((width + 7) // 8) * 8
|
||||
data = [0 for _ in range((height * width8 // 8) * frames)]
|
||||
for frameIndex in range(frames):
|
||||
image.seek(frameIndex)
|
||||
frame = image.convert('1', dither=Image.NONE)
|
||||
frame = image.convert("1", dither=Image.NONE)
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if frame.getpixel((x, y)):
|
||||
@ -90,5 +96,11 @@ def to_code(config):
|
||||
|
||||
rhs = [HexInt(x) for x in data]
|
||||
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height, frames,
|
||||
espImage.IMAGE_TYPE[config[CONF_TYPE]])
|
||||
cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
prog_arr,
|
||||
width,
|
||||
height,
|
||||
frames,
|
||||
espImage.IMAGE_TYPE[config[CONF_TYPE]],
|
||||
)
|
||||
|
@ -3,18 +3,24 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ['sensor', 'binary_sensor']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["sensor", "binary_sensor"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_APDS9960_ID = 'apds9960_id'
|
||||
CONF_APDS9960_ID = "apds9960_id"
|
||||
|
||||
apds9960_nds = cg.esphome_ns.namespace('apds9960')
|
||||
APDS9960 = apds9960_nds.class_('APDS9960', cg.PollingComponent, i2c.I2CDevice)
|
||||
apds9960_nds = cg.esphome_ns.namespace("apds9960")
|
||||
APDS9960 = apds9960_nds.class_("APDS9960", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(APDS9960),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x39))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(APDS9960),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x39))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,20 +4,24 @@ from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_DIRECTION, CONF_DEVICE_CLASS, DEVICE_CLASS_MOVING
|
||||
from . import APDS9960, CONF_APDS9960_ID
|
||||
|
||||
DEPENDENCIES = ['apds9960']
|
||||
DEPENDENCIES = ["apds9960"]
|
||||
|
||||
DIRECTIONS = {
|
||||
'UP': 'set_up_direction',
|
||||
'DOWN': 'set_down_direction',
|
||||
'LEFT': 'set_left_direction',
|
||||
'RIGHT': 'set_right_direction',
|
||||
"UP": "set_up_direction",
|
||||
"DOWN": "set_down_direction",
|
||||
"LEFT": "set_left_direction",
|
||||
"RIGHT": "set_right_direction",
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, upper=True),
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
cv.Optional(CONF_DEVICE_CLASS, default=DEVICE_CLASS_MOVING): binary_sensor.device_class,
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_DIRECTION): cv.one_of(*DIRECTIONS, upper=True),
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
cv.Optional(
|
||||
CONF_DEVICE_CLASS, default=DEVICE_CLASS_MOVING
|
||||
): binary_sensor.device_class,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,20 +4,24 @@ from esphome.components import sensor
|
||||
from esphome.const import CONF_TYPE, DEVICE_CLASS_EMPTY, UNIT_PERCENT, ICON_LIGHTBULB
|
||||
from . import APDS9960, CONF_APDS9960_ID
|
||||
|
||||
DEPENDENCIES = ['apds9960']
|
||||
DEPENDENCIES = ["apds9960"]
|
||||
|
||||
TYPES = {
|
||||
'CLEAR': 'set_clear_channel',
|
||||
'RED': 'set_red_channel',
|
||||
'GREEN': 'set_green_channel',
|
||||
'BLUE': 'set_blue_channel',
|
||||
'PROXIMITY': 'set_proximity',
|
||||
"CLEAR": "set_clear_channel",
|
||||
"RED": "set_red_channel",
|
||||
"GREEN": "set_green_channel",
|
||||
"BLUE": "set_blue_channel",
|
||||
"PROXIMITY": "set_proximity",
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_PERCENT, ICON_LIGHTBULB, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.Required(CONF_TYPE): cv.one_of(*TYPES, upper=True),
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
})
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_LIGHTBULB, 1, DEVICE_CLASS_EMPTY
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_TYPE): cv.one_of(*TYPES, upper=True),
|
||||
cv.GenerateID(CONF_APDS9960_ID): cv.use_id(APDS9960),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,46 +2,69 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import Condition
|
||||
from esphome.const import CONF_DATA, CONF_DATA_TEMPLATE, CONF_ID, CONF_PASSWORD, CONF_PORT, \
|
||||
CONF_REBOOT_TIMEOUT, CONF_SERVICE, CONF_VARIABLES, CONF_SERVICES, CONF_TRIGGER_ID, CONF_EVENT, \
|
||||
CONF_TAG
|
||||
from esphome.const import (
|
||||
CONF_DATA,
|
||||
CONF_DATA_TEMPLATE,
|
||||
CONF_ID,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_REBOOT_TIMEOUT,
|
||||
CONF_SERVICE,
|
||||
CONF_VARIABLES,
|
||||
CONF_SERVICES,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_EVENT,
|
||||
CONF_TAG,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
DEPENDENCIES = ['network']
|
||||
AUTO_LOAD = ['async_tcp']
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
DEPENDENCIES = ["network"]
|
||||
AUTO_LOAD = ["async_tcp"]
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
||||
api_ns = cg.esphome_ns.namespace('api')
|
||||
APIServer = api_ns.class_('APIServer', cg.Component, cg.Controller)
|
||||
HomeAssistantServiceCallAction = api_ns.class_('HomeAssistantServiceCallAction', automation.Action)
|
||||
APIConnectedCondition = api_ns.class_('APIConnectedCondition', Condition)
|
||||
api_ns = cg.esphome_ns.namespace("api")
|
||||
APIServer = api_ns.class_("APIServer", cg.Component, cg.Controller)
|
||||
HomeAssistantServiceCallAction = api_ns.class_(
|
||||
"HomeAssistantServiceCallAction", automation.Action
|
||||
)
|
||||
APIConnectedCondition = api_ns.class_("APIConnectedCondition", Condition)
|
||||
|
||||
UserServiceTrigger = api_ns.class_('UserServiceTrigger', automation.Trigger)
|
||||
ListEntitiesServicesArgument = api_ns.class_('ListEntitiesServicesArgument')
|
||||
UserServiceTrigger = api_ns.class_("UserServiceTrigger", automation.Trigger)
|
||||
ListEntitiesServicesArgument = api_ns.class_("ListEntitiesServicesArgument")
|
||||
SERVICE_ARG_NATIVE_TYPES = {
|
||||
'bool': bool,
|
||||
'int': cg.int32,
|
||||
'float': float,
|
||||
'string': cg.std_string,
|
||||
'bool[]': cg.std_vector.template(bool),
|
||||
'int[]': cg.std_vector.template(cg.int32),
|
||||
'float[]': cg.std_vector.template(float),
|
||||
'string[]': cg.std_vector.template(cg.std_string),
|
||||
"bool": bool,
|
||||
"int": cg.int32,
|
||||
"float": float,
|
||||
"string": cg.std_string,
|
||||
"bool[]": cg.std_vector.template(bool),
|
||||
"int[]": cg.std_vector.template(cg.int32),
|
||||
"float[]": cg.std_vector.template(float),
|
||||
"string[]": cg.std_vector.template(cg.std_string),
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(APIServer),
|
||||
cv.Optional(CONF_PORT, default=6053): cv.port,
|
||||
cv.Optional(CONF_PASSWORD, default=''): cv.string_strict,
|
||||
cv.Optional(CONF_REBOOT_TIMEOUT, default='15min'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SERVICES): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(UserServiceTrigger),
|
||||
cv.Required(CONF_SERVICE): cv.valid_name,
|
||||
cv.Optional(CONF_VARIABLES, default={}): cv.Schema({
|
||||
cv.validate_id_name: cv.one_of(*SERVICE_ARG_NATIVE_TYPES, lower=True),
|
||||
}),
|
||||
}),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(APIServer),
|
||||
cv.Optional(CONF_PORT, default=6053): cv.port,
|
||||
cv.Optional(CONF_PASSWORD, default=""): cv.string_strict,
|
||||
cv.Optional(
|
||||
CONF_REBOOT_TIMEOUT, default="15min"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SERVICES): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(UserServiceTrigger),
|
||||
cv.Required(CONF_SERVICE): cv.valid_name,
|
||||
cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
|
||||
{
|
||||
cv.validate_id_name: cv.one_of(
|
||||
*SERVICE_ARG_NATIVE_TYPES, lower=True
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine_with_priority(40.0)
|
||||
@ -63,28 +86,36 @@ def to_code(config):
|
||||
func_args.append((native, name))
|
||||
service_arg_names.append(name)
|
||||
templ = cg.TemplateArguments(*template_args)
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], templ,
|
||||
conf[CONF_SERVICE], service_arg_names)
|
||||
trigger = cg.new_Pvariable(
|
||||
conf[CONF_TRIGGER_ID], templ, conf[CONF_SERVICE], service_arg_names
|
||||
)
|
||||
cg.add(var.register_user_service(trigger))
|
||||
yield automation.build_automation(trigger, func_args, conf)
|
||||
|
||||
cg.add_define('USE_API')
|
||||
cg.add_define("USE_API")
|
||||
cg.add_global(api_ns.using)
|
||||
|
||||
|
||||
KEY_VALUE_SCHEMA = cv.Schema({cv.string: cv.templatable(cv.string_strict)})
|
||||
|
||||
HOMEASSISTANT_SERVICE_ACTION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_SERVICE): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_VARIABLES, default={}): cv.Schema({cv.string: cv.returning_lambda}),
|
||||
})
|
||||
HOMEASSISTANT_SERVICE_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_SERVICE): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_VARIABLES, default={}): cv.Schema(
|
||||
{cv.string: cv.returning_lambda}
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('homeassistant.service', HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_SERVICE_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"homeassistant.service",
|
||||
HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_SERVICE_ACTION_SCHEMA,
|
||||
)
|
||||
def homeassistant_service_to_code(config, action_id, template_arg, args):
|
||||
serv = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, serv, False)
|
||||
@ -104,23 +135,30 @@ def homeassistant_service_to_code(config, action_id, template_arg, args):
|
||||
|
||||
def validate_homeassistant_event(value):
|
||||
value = cv.string(value)
|
||||
if not value.startswith('esphome.'):
|
||||
raise cv.Invalid("ESPHome can only generate Home Assistant events that begin with "
|
||||
"esphome. For example 'esphome.xyz'")
|
||||
if not value.startswith("esphome."):
|
||||
raise cv.Invalid(
|
||||
"ESPHome can only generate Home Assistant events that begin with "
|
||||
"esphome. For example 'esphome.xyz'"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
HOMEASSISTANT_EVENT_ACTION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_EVENT): validate_homeassistant_event,
|
||||
cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_VARIABLES, default={}): KEY_VALUE_SCHEMA,
|
||||
})
|
||||
HOMEASSISTANT_EVENT_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_EVENT): validate_homeassistant_event,
|
||||
cv.Optional(CONF_DATA, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_DATA_TEMPLATE, default={}): KEY_VALUE_SCHEMA,
|
||||
cv.Optional(CONF_VARIABLES, default={}): KEY_VALUE_SCHEMA,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('homeassistant.event', HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_EVENT_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"homeassistant.event",
|
||||
HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_EVENT_ACTION_SCHEMA,
|
||||
)
|
||||
def homeassistant_event_to_code(config, action_id, template_arg, args):
|
||||
serv = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, serv, True)
|
||||
@ -138,23 +176,29 @@ def homeassistant_event_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA = cv.maybe_simple_value({
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_TAG): cv.templatable(cv.string_strict),
|
||||
}, key=CONF_TAG)
|
||||
HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA = cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(APIServer),
|
||||
cv.Required(CONF_TAG): cv.templatable(cv.string_strict),
|
||||
},
|
||||
key=CONF_TAG,
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('homeassistant.tag_scanned', HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"homeassistant.tag_scanned",
|
||||
HomeAssistantServiceCallAction,
|
||||
HOMEASSISTANT_TAG_SCANNED_ACTION_SCHEMA,
|
||||
)
|
||||
def homeassistant_tag_scanned_to_code(config, action_id, template_arg, args):
|
||||
serv = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, serv, True)
|
||||
cg.add(var.set_service('esphome.tag_scanned'))
|
||||
cg.add(var.set_service("esphome.tag_scanned"))
|
||||
templ = yield cg.templatable(config[CONF_TAG], args, cg.std_string)
|
||||
cg.add(var.add_data('tag_id', templ))
|
||||
cg.add(var.add_data("tag_id", templ))
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_condition('api.connected', APIConnectedCondition, {})
|
||||
@automation.register_condition("api.connected", APIConnectedCondition, {})
|
||||
def api_connected_to_code(config, condition_id, template_arg, args):
|
||||
yield cg.new_Pvariable(condition_id, template_arg)
|
||||
|
@ -1,33 +1,43 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_INDOOR, CONF_WATCHDOG_THRESHOLD, \
|
||||
CONF_NOISE_LEVEL, CONF_SPIKE_REJECTION, CONF_LIGHTNING_THRESHOLD, \
|
||||
CONF_MASK_DISTURBER, CONF_DIV_RATIO, CONF_CAPACITANCE
|
||||
from esphome.const import (
|
||||
CONF_INDOOR,
|
||||
CONF_WATCHDOG_THRESHOLD,
|
||||
CONF_NOISE_LEVEL,
|
||||
CONF_SPIKE_REJECTION,
|
||||
CONF_LIGHTNING_THRESHOLD,
|
||||
CONF_MASK_DISTURBER,
|
||||
CONF_DIV_RATIO,
|
||||
CONF_CAPACITANCE,
|
||||
)
|
||||
from esphome.core import coroutine
|
||||
|
||||
AUTO_LOAD = ['sensor', 'binary_sensor']
|
||||
AUTO_LOAD = ["sensor", "binary_sensor"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_AS3935_ID = 'as3935_id'
|
||||
CONF_AS3935_ID = "as3935_id"
|
||||
|
||||
as3935_ns = cg.esphome_ns.namespace('as3935')
|
||||
AS3935 = as3935_ns.class_('AS3935Component', cg.Component)
|
||||
as3935_ns = cg.esphome_ns.namespace("as3935")
|
||||
AS3935 = as3935_ns.class_("AS3935Component", cg.Component)
|
||||
|
||||
CONF_IRQ_PIN = 'irq_pin'
|
||||
AS3935_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(AS3935),
|
||||
cv.Required(CONF_IRQ_PIN): pins.gpio_input_pin_schema,
|
||||
|
||||
cv.Optional(CONF_INDOOR, default=True): cv.boolean,
|
||||
cv.Optional(CONF_NOISE_LEVEL, default=2): cv.int_range(min=1, max=7),
|
||||
cv.Optional(CONF_WATCHDOG_THRESHOLD, default=2): cv.int_range(min=1, max=10),
|
||||
cv.Optional(CONF_SPIKE_REJECTION, default=2): cv.int_range(min=1, max=11),
|
||||
cv.Optional(CONF_LIGHTNING_THRESHOLD, default=1): cv.one_of(1, 5, 9, 16, int=True),
|
||||
cv.Optional(CONF_MASK_DISTURBER, default=False): cv.boolean,
|
||||
cv.Optional(CONF_DIV_RATIO, default=0): cv.one_of(0, 16, 32, 64, 128, int=True),
|
||||
cv.Optional(CONF_CAPACITANCE, default=0): cv.int_range(min=0, max=15),
|
||||
})
|
||||
CONF_IRQ_PIN = "irq_pin"
|
||||
AS3935_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AS3935),
|
||||
cv.Required(CONF_IRQ_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Optional(CONF_INDOOR, default=True): cv.boolean,
|
||||
cv.Optional(CONF_NOISE_LEVEL, default=2): cv.int_range(min=1, max=7),
|
||||
cv.Optional(CONF_WATCHDOG_THRESHOLD, default=2): cv.int_range(min=1, max=10),
|
||||
cv.Optional(CONF_SPIKE_REJECTION, default=2): cv.int_range(min=1, max=11),
|
||||
cv.Optional(CONF_LIGHTNING_THRESHOLD, default=1): cv.one_of(
|
||||
1, 5, 9, 16, int=True
|
||||
),
|
||||
cv.Optional(CONF_MASK_DISTURBER, default=False): cv.boolean,
|
||||
cv.Optional(CONF_DIV_RATIO, default=0): cv.one_of(0, 16, 32, 64, 128, int=True),
|
||||
cv.Optional(CONF_CAPACITANCE, default=0): cv.int_range(min=0, max=15),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
|
@ -3,11 +3,13 @@ import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from . import AS3935, CONF_AS3935_ID
|
||||
|
||||
DEPENDENCIES = ['as3935']
|
||||
DEPENDENCIES = ["as3935"]
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_AS3935_ID): cv.use_id(AS3935),
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_AS3935_ID): cv.use_id(AS3935),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,19 +1,30 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_DISTANCE, CONF_LIGHTNING_ENERGY, DEVICE_CLASS_EMPTY, \
|
||||
UNIT_KILOMETER, UNIT_EMPTY, ICON_SIGNAL_DISTANCE_VARIANT, ICON_FLASH
|
||||
from esphome.const import (
|
||||
CONF_DISTANCE,
|
||||
CONF_LIGHTNING_ENERGY,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
UNIT_KILOMETER,
|
||||
UNIT_EMPTY,
|
||||
ICON_SIGNAL_DISTANCE_VARIANT,
|
||||
ICON_FLASH,
|
||||
)
|
||||
from . import AS3935, CONF_AS3935_ID
|
||||
|
||||
DEPENDENCIES = ['as3935']
|
||||
DEPENDENCIES = ["as3935"]
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_AS3935_ID): cv.use_id(AS3935),
|
||||
cv.Optional(CONF_DISTANCE):
|
||||
sensor.sensor_schema(UNIT_KILOMETER, ICON_SIGNAL_DISTANCE_VARIANT, 1, DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_LIGHTNING_ENERGY):
|
||||
sensor.sensor_schema(UNIT_EMPTY, ICON_FLASH, 1, DEVICE_CLASS_EMPTY),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_AS3935_ID): cv.use_id(AS3935),
|
||||
cv.Optional(CONF_DISTANCE): sensor.sensor_schema(
|
||||
UNIT_KILOMETER, ICON_SIGNAL_DISTANCE_VARIANT, 1, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_LIGHTNING_ENERGY): sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_FLASH, 1, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,15 +3,21 @@ import esphome.config_validation as cv
|
||||
from esphome.components import as3935, i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['as3935']
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ["as3935"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
as3935_i2c_ns = cg.esphome_ns.namespace('as3935_i2c')
|
||||
I2CAS3935 = as3935_i2c_ns.class_('I2CAS3935Component', as3935.AS3935, i2c.I2CDevice)
|
||||
as3935_i2c_ns = cg.esphome_ns.namespace("as3935_i2c")
|
||||
I2CAS3935 = as3935_i2c_ns.class_("I2CAS3935Component", as3935.AS3935, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(as3935.AS3935_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(I2CAS3935),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x03)))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
as3935.AS3935_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(I2CAS3935),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x03))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,15 +3,21 @@ import esphome.config_validation as cv
|
||||
from esphome.components import as3935, spi
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['as3935']
|
||||
DEPENDENCIES = ['spi']
|
||||
AUTO_LOAD = ["as3935"]
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
as3935_spi_ns = cg.esphome_ns.namespace('as3935_spi')
|
||||
SPIAS3935 = as3935_spi_ns.class_('SPIAS3935Component', as3935.AS3935, spi.SPIDevice)
|
||||
as3935_spi_ns = cg.esphome_ns.namespace("as3935_spi")
|
||||
SPIAS3935 = as3935_spi_ns.class_("SPIAS3935Component", as3935.AS3935, spi.SPIDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(as3935.AS3935_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(SPIAS3935),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema(cs_pin_required=True)))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
as3935.AS3935_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(SPIAS3935),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(spi.spi_device_schema(cs_pin_required=True))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,14 +2,14 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
||||
|
||||
@coroutine_with_priority(200.0)
|
||||
def to_code(config):
|
||||
if CORE.is_esp32:
|
||||
# https://github.com/OttoWinter/AsyncTCP/blob/master/library.json
|
||||
cg.add_library('AsyncTCP-esphome', '1.1.1')
|
||||
cg.add_library("AsyncTCP-esphome", "1.1.1")
|
||||
elif CORE.is_esp8266:
|
||||
# https://github.com/OttoWinter/ESPAsyncTCP
|
||||
cg.add_library('ESPAsyncTCP-esphome', '1.2.3')
|
||||
cg.add_library("ESPAsyncTCP-esphome", "1.2.3")
|
||||
|
@ -1,32 +1,54 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_BATTERY_LEVEL, CONF_BATTERY_VOLTAGE, CONF_MAC_ADDRESS, \
|
||||
CONF_HUMIDITY, CONF_TEMPERATURE, CONF_ID, DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, \
|
||||
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, UNIT_CELSIUS, UNIT_PERCENT, \
|
||||
UNIT_VOLT
|
||||
from esphome.const import (
|
||||
CONF_BATTERY_LEVEL,
|
||||
CONF_BATTERY_VOLTAGE,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_HUMIDITY,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
UNIT_VOLT,
|
||||
)
|
||||
|
||||
CODEOWNERS = ['@ahpohl']
|
||||
CODEOWNERS = ["@ahpohl"]
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
atc_mithermometer_ns = cg.esphome_ns.namespace('atc_mithermometer')
|
||||
ATCMiThermometer = atc_mithermometer_ns.class_('ATCMiThermometer',
|
||||
esp32_ble_tracker.ESPBTDeviceListener,
|
||||
cg.Component)
|
||||
atc_mithermometer_ns = cg.esphome_ns.namespace("atc_mithermometer")
|
||||
ATCMiThermometer = atc_mithermometer_ns.class_(
|
||||
"ATCMiThermometer", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ATCMiThermometer),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_BATTERY),
|
||||
cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 3,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ATCMiThermometer),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 0, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 0, DEVICE_CLASS_BATTERY
|
||||
),
|
||||
cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 3, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,66 +1,106 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, spi
|
||||
from esphome.const import \
|
||||
CONF_ID, CONF_VOLTAGE, CONF_CURRENT, CONF_POWER, CONF_POWER_FACTOR, CONF_FREQUENCY, \
|
||||
DEVICE_CLASS_CURRENT, DEVICE_CLASS_EMPTY, DEVICE_CLASS_POWER, DEVICE_CLASS_POWER_FACTOR, \
|
||||
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, ICON_LIGHTBULB, ICON_CURRENT_AC, \
|
||||
UNIT_HERTZ, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, UNIT_EMPTY, UNIT_CELSIUS, UNIT_VOLT_AMPS_REACTIVE
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_VOLTAGE,
|
||||
CONF_CURRENT,
|
||||
CONF_POWER,
|
||||
CONF_POWER_FACTOR,
|
||||
CONF_FREQUENCY,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_POWER_FACTOR,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
ICON_LIGHTBULB,
|
||||
ICON_CURRENT_AC,
|
||||
UNIT_HERTZ,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
UNIT_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_VOLT_AMPS_REACTIVE,
|
||||
)
|
||||
|
||||
CONF_PHASE_A = 'phase_a'
|
||||
CONF_PHASE_B = 'phase_b'
|
||||
CONF_PHASE_C = 'phase_c'
|
||||
CONF_PHASE_A = "phase_a"
|
||||
CONF_PHASE_B = "phase_b"
|
||||
CONF_PHASE_C = "phase_c"
|
||||
|
||||
CONF_REACTIVE_POWER = 'reactive_power'
|
||||
CONF_LINE_FREQUENCY = 'line_frequency'
|
||||
CONF_CHIP_TEMPERATURE = 'chip_temperature'
|
||||
CONF_GAIN_PGA = 'gain_pga'
|
||||
CONF_CURRENT_PHASES = 'current_phases'
|
||||
CONF_GAIN_VOLTAGE = 'gain_voltage'
|
||||
CONF_GAIN_CT = 'gain_ct'
|
||||
CONF_REACTIVE_POWER = "reactive_power"
|
||||
CONF_LINE_FREQUENCY = "line_frequency"
|
||||
CONF_CHIP_TEMPERATURE = "chip_temperature"
|
||||
CONF_GAIN_PGA = "gain_pga"
|
||||
CONF_CURRENT_PHASES = "current_phases"
|
||||
CONF_GAIN_VOLTAGE = "gain_voltage"
|
||||
CONF_GAIN_CT = "gain_ct"
|
||||
LINE_FREQS = {
|
||||
'50HZ': 50,
|
||||
'60HZ': 60,
|
||||
"50HZ": 50,
|
||||
"60HZ": 60,
|
||||
}
|
||||
CURRENT_PHASES = {
|
||||
'2': 2,
|
||||
'3': 3,
|
||||
"2": 2,
|
||||
"3": 3,
|
||||
}
|
||||
PGA_GAINS = {
|
||||
'1X': 0x0,
|
||||
'2X': 0x15,
|
||||
'4X': 0x2A,
|
||||
"1X": 0x0,
|
||||
"2X": 0x15,
|
||||
"4X": 0x2A,
|
||||
}
|
||||
|
||||
atm90e32_ns = cg.esphome_ns.namespace('atm90e32')
|
||||
ATM90E32Component = atm90e32_ns.class_('ATM90E32Component', cg.PollingComponent, spi.SPIDevice)
|
||||
atm90e32_ns = cg.esphome_ns.namespace("atm90e32")
|
||||
ATM90E32Component = atm90e32_ns.class_(
|
||||
"ATM90E32Component", cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
ATM90E32_PHASE_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_REACTIVE_POWER): sensor.sensor_schema(UNIT_VOLT_AMPS_REACTIVE,
|
||||
ICON_LIGHTBULB, 2, DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_POWER_FACTOR),
|
||||
cv.Optional(CONF_GAIN_VOLTAGE, default=7305): cv.uint16_t,
|
||||
cv.Optional(CONF_GAIN_CT, default=27961): cv.uint16_t,
|
||||
})
|
||||
ATM90E32_PHASE_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_REACTIVE_POWER): sensor.sensor_schema(
|
||||
UNIT_VOLT_AMPS_REACTIVE, ICON_LIGHTBULB, 2, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_EMPTY, 2, DEVICE_CLASS_POWER_FACTOR
|
||||
),
|
||||
cv.Optional(CONF_GAIN_VOLTAGE, default=7305): cv.uint16_t,
|
||||
cv.Optional(CONF_GAIN_CT, default=27961): cv.uint16_t,
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ATM90E32Component),
|
||||
cv.Optional(CONF_PHASE_A): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_PHASE_B): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_PHASE_C): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_HERTZ, ICON_CURRENT_AC, 1,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_CHIP_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Required(CONF_LINE_FREQUENCY): cv.enum(LINE_FREQS, upper=True),
|
||||
cv.Optional(CONF_CURRENT_PHASES, default='3'): cv.enum(CURRENT_PHASES, upper=True),
|
||||
cv.Optional(CONF_GAIN_PGA, default='2X'): cv.enum(PGA_GAINS, upper=True),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ATM90E32Component),
|
||||
cv.Optional(CONF_PHASE_A): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_PHASE_B): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_PHASE_C): ATM90E32_PHASE_SCHEMA,
|
||||
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(
|
||||
UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_CHIP_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Required(CONF_LINE_FREQUENCY): cv.enum(LINE_FREQS, upper=True),
|
||||
cv.Optional(CONF_CURRENT_PHASES, default="3"): cv.enum(
|
||||
CURRENT_PHASES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_GAIN_PGA, default="2X"): cv.enum(PGA_GAINS, upper=True),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
@ -2,27 +2,41 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.components import climate, sensor
|
||||
from esphome.const import CONF_AWAY_CONFIG, CONF_COOL_ACTION, \
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE_HIGH, CONF_DEFAULT_TARGET_TEMPERATURE_LOW, CONF_HEAT_ACTION, \
|
||||
CONF_ID, CONF_IDLE_ACTION, CONF_SENSOR
|
||||
from esphome.const import (
|
||||
CONF_AWAY_CONFIG,
|
||||
CONF_COOL_ACTION,
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE_HIGH,
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE_LOW,
|
||||
CONF_HEAT_ACTION,
|
||||
CONF_ID,
|
||||
CONF_IDLE_ACTION,
|
||||
CONF_SENSOR,
|
||||
)
|
||||
|
||||
bang_bang_ns = cg.esphome_ns.namespace('bang_bang')
|
||||
BangBangClimate = bang_bang_ns.class_('BangBangClimate', climate.Climate, cg.Component)
|
||||
BangBangClimateTargetTempConfig = bang_bang_ns.struct('BangBangClimateTargetTempConfig')
|
||||
bang_bang_ns = cg.esphome_ns.namespace("bang_bang")
|
||||
BangBangClimate = bang_bang_ns.class_("BangBangClimate", climate.Climate, cg.Component)
|
||||
BangBangClimateTargetTempConfig = bang_bang_ns.struct("BangBangClimateTargetTempConfig")
|
||||
|
||||
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(BangBangClimate),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_LOW): cv.temperature,
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_HIGH): cv.temperature,
|
||||
cv.Required(CONF_IDLE_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_COOL_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_HEAT_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_AWAY_CONFIG): cv.Schema({
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_LOW): cv.temperature,
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_HIGH): cv.temperature,
|
||||
}),
|
||||
}).extend(cv.COMPONENT_SCHEMA), cv.has_at_least_one_key(CONF_COOL_ACTION, CONF_HEAT_ACTION))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
climate.CLIMATE_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BangBangClimate),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_LOW): cv.temperature,
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_HIGH): cv.temperature,
|
||||
cv.Required(CONF_IDLE_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_COOL_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_HEAT_ACTION): automation.validate_automation(single=True),
|
||||
cv.Optional(CONF_AWAY_CONFIG): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_LOW): cv.temperature,
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE_HIGH): cv.temperature,
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
cv.has_at_least_one_key(CONF_COOL_ACTION, CONF_HEAT_ACTION),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -35,23 +49,29 @@ def to_code(config):
|
||||
|
||||
normal_config = BangBangClimateTargetTempConfig(
|
||||
config[CONF_DEFAULT_TARGET_TEMPERATURE_LOW],
|
||||
config[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH]
|
||||
config[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH],
|
||||
)
|
||||
cg.add(var.set_normal_config(normal_config))
|
||||
|
||||
yield automation.build_automation(var.get_idle_trigger(), [], config[CONF_IDLE_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_idle_trigger(), [], config[CONF_IDLE_ACTION]
|
||||
)
|
||||
|
||||
if CONF_COOL_ACTION in config:
|
||||
yield automation.build_automation(var.get_cool_trigger(), [], config[CONF_COOL_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_cool_trigger(), [], config[CONF_COOL_ACTION]
|
||||
)
|
||||
cg.add(var.set_supports_cool(True))
|
||||
if CONF_HEAT_ACTION in config:
|
||||
yield automation.build_automation(var.get_heat_trigger(), [], config[CONF_HEAT_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_heat_trigger(), [], config[CONF_HEAT_ACTION]
|
||||
)
|
||||
cg.add(var.set_supports_heat(True))
|
||||
|
||||
if CONF_AWAY_CONFIG in config:
|
||||
away = config[CONF_AWAY_CONFIG]
|
||||
away_config = BangBangClimateTargetTempConfig(
|
||||
away[CONF_DEFAULT_TARGET_TEMPERATURE_LOW],
|
||||
away[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH]
|
||||
away[CONF_DEFAULT_TARGET_TEMPERATURE_HIGH],
|
||||
)
|
||||
cg.add(var.set_away_config(away_config))
|
||||
|
@ -1,26 +1,45 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_RESOLUTION, DEVICE_CLASS_ILLUMINANCE, ICON_EMPTY, UNIT_LUX
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_RESOLUTION,
|
||||
DEVICE_CLASS_ILLUMINANCE,
|
||||
ICON_EMPTY,
|
||||
UNIT_LUX,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bh1750_ns = cg.esphome_ns.namespace('bh1750')
|
||||
BH1750Resolution = bh1750_ns.enum('BH1750Resolution')
|
||||
bh1750_ns = cg.esphome_ns.namespace("bh1750")
|
||||
BH1750Resolution = bh1750_ns.enum("BH1750Resolution")
|
||||
BH1750_RESOLUTIONS = {
|
||||
4.0: BH1750Resolution.BH1750_RESOLUTION_4P0_LX,
|
||||
1.0: BH1750Resolution.BH1750_RESOLUTION_1P0_LX,
|
||||
0.5: BH1750Resolution.BH1750_RESOLUTION_0P5_LX,
|
||||
}
|
||||
|
||||
BH1750Sensor = bh1750_ns.class_('BH1750Sensor', sensor.Sensor, cg.PollingComponent, i2c.I2CDevice)
|
||||
BH1750Sensor = bh1750_ns.class_(
|
||||
"BH1750Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONF_MEASUREMENT_TIME = 'measurement_time'
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_LUX, ICON_EMPTY, 1, DEVICE_CLASS_ILLUMINANCE).extend({
|
||||
cv.GenerateID(): cv.declare_id(BH1750Sensor),
|
||||
cv.Optional(CONF_RESOLUTION, default=0.5): cv.enum(BH1750_RESOLUTIONS, float=True),
|
||||
cv.Optional(CONF_MEASUREMENT_TIME, default=69): cv.int_range(min=31, max=254),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x23))
|
||||
CONF_MEASUREMENT_TIME = "measurement_time"
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_LUX, ICON_EMPTY, 1, DEVICE_CLASS_ILLUMINANCE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BH1750Sensor),
|
||||
cv.Optional(CONF_RESOLUTION, default=0.5): cv.enum(
|
||||
BH1750_RESOLUTIONS, float=True
|
||||
),
|
||||
cv.Optional(CONF_MEASUREMENT_TIME, default=69): cv.int_range(
|
||||
min=31, max=254
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x23))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,3 +1,3 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
binary_ns = cg.esphome_ns.namespace('binary')
|
||||
binary_ns = cg.esphome_ns.namespace("binary")
|
||||
|
@ -1,18 +1,24 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import fan, output
|
||||
from esphome.const import CONF_DIRECTION_OUTPUT, CONF_OSCILLATION_OUTPUT, \
|
||||
CONF_OUTPUT, CONF_OUTPUT_ID
|
||||
from esphome.const import (
|
||||
CONF_DIRECTION_OUTPUT,
|
||||
CONF_OSCILLATION_OUTPUT,
|
||||
CONF_OUTPUT,
|
||||
CONF_OUTPUT_ID,
|
||||
)
|
||||
from .. import binary_ns
|
||||
|
||||
BinaryFan = binary_ns.class_('BinaryFan', cg.Component)
|
||||
BinaryFan = binary_ns.class_("BinaryFan", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = fan.FAN_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(BinaryFan),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_DIRECTION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_OSCILLATION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = fan.FAN_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(BinaryFan),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_DIRECTION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
cv.Optional(CONF_OSCILLATION_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,12 +4,14 @@ from esphome.components import light, output
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_OUTPUT
|
||||
from .. import binary_ns
|
||||
|
||||
BinaryLightOutput = binary_ns.class_('BinaryLightOutput', light.LightOutput)
|
||||
BinaryLightOutput = binary_ns.class_("BinaryLightOutput", light.LightOutput)
|
||||
|
||||
CONFIG_SCHEMA = light.BINARY_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(BinaryLightOutput),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
})
|
||||
CONFIG_SCHEMA = light.BINARY_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(BinaryLightOutput),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,141 +3,214 @@ import esphome.config_validation as cv
|
||||
from esphome import automation, core
|
||||
from esphome.automation import Condition, maybe_simple_id
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import CONF_DEVICE_CLASS, CONF_FILTERS, \
|
||||
CONF_ID, CONF_INTERNAL, CONF_INVALID_COOLDOWN, CONF_INVERTED, \
|
||||
CONF_MAX_LENGTH, CONF_MIN_LENGTH, CONF_ON_CLICK, \
|
||||
CONF_ON_DOUBLE_CLICK, CONF_ON_MULTI_CLICK, CONF_ON_PRESS, CONF_ON_RELEASE, CONF_ON_STATE, \
|
||||
CONF_STATE, CONF_TIMING, CONF_TRIGGER_ID, CONF_FOR, CONF_NAME, CONF_MQTT_ID, \
|
||||
DEVICE_CLASS_EMPTY, DEVICE_CLASS_BATTERY, DEVICE_CLASS_BATTERY_CHARGING, DEVICE_CLASS_COLD, \
|
||||
DEVICE_CLASS_CONNECTIVITY, DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE_DOOR, DEVICE_CLASS_GAS, \
|
||||
DEVICE_CLASS_HEAT, DEVICE_CLASS_LIGHT, DEVICE_CLASS_LOCK, DEVICE_CLASS_MOISTURE, \
|
||||
DEVICE_CLASS_MOTION, DEVICE_CLASS_MOVING, DEVICE_CLASS_OCCUPANCY, DEVICE_CLASS_OPENING, \
|
||||
DEVICE_CLASS_PLUG, DEVICE_CLASS_POWER, DEVICE_CLASS_PRESENCE, DEVICE_CLASS_PROBLEM, \
|
||||
DEVICE_CLASS_SAFETY, DEVICE_CLASS_SMOKE, DEVICE_CLASS_SOUND, DEVICE_CLASS_VIBRATION, \
|
||||
DEVICE_CLASS_WINDOW
|
||||
from esphome.const import (
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_FILTERS,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_INVALID_COOLDOWN,
|
||||
CONF_INVERTED,
|
||||
CONF_MAX_LENGTH,
|
||||
CONF_MIN_LENGTH,
|
||||
CONF_ON_CLICK,
|
||||
CONF_ON_DOUBLE_CLICK,
|
||||
CONF_ON_MULTI_CLICK,
|
||||
CONF_ON_PRESS,
|
||||
CONF_ON_RELEASE,
|
||||
CONF_ON_STATE,
|
||||
CONF_STATE,
|
||||
CONF_TIMING,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_FOR,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_BATTERY_CHARGING,
|
||||
DEVICE_CLASS_COLD,
|
||||
DEVICE_CLASS_CONNECTIVITY,
|
||||
DEVICE_CLASS_DOOR,
|
||||
DEVICE_CLASS_GARAGE_DOOR,
|
||||
DEVICE_CLASS_GAS,
|
||||
DEVICE_CLASS_HEAT,
|
||||
DEVICE_CLASS_LIGHT,
|
||||
DEVICE_CLASS_LOCK,
|
||||
DEVICE_CLASS_MOISTURE,
|
||||
DEVICE_CLASS_MOTION,
|
||||
DEVICE_CLASS_MOVING,
|
||||
DEVICE_CLASS_OCCUPANCY,
|
||||
DEVICE_CLASS_OPENING,
|
||||
DEVICE_CLASS_PLUG,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_PRESENCE,
|
||||
DEVICE_CLASS_PROBLEM,
|
||||
DEVICE_CLASS_SAFETY,
|
||||
DEVICE_CLASS_SMOKE,
|
||||
DEVICE_CLASS_SOUND,
|
||||
DEVICE_CLASS_VIBRATION,
|
||||
DEVICE_CLASS_WINDOW,
|
||||
)
|
||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||
from esphome.util import Registry
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
DEVICE_CLASSES = [
|
||||
DEVICE_CLASS_EMPTY, DEVICE_CLASS_BATTERY, DEVICE_CLASS_BATTERY_CHARGING, DEVICE_CLASS_COLD,
|
||||
DEVICE_CLASS_CONNECTIVITY, DEVICE_CLASS_DOOR, DEVICE_CLASS_GARAGE_DOOR, DEVICE_CLASS_GAS,
|
||||
DEVICE_CLASS_HEAT, DEVICE_CLASS_LIGHT, DEVICE_CLASS_LOCK, DEVICE_CLASS_MOISTURE,
|
||||
DEVICE_CLASS_MOTION, DEVICE_CLASS_MOVING, DEVICE_CLASS_OCCUPANCY, DEVICE_CLASS_OPENING,
|
||||
DEVICE_CLASS_PLUG, DEVICE_CLASS_POWER, DEVICE_CLASS_PRESENCE, DEVICE_CLASS_PROBLEM,
|
||||
DEVICE_CLASS_SAFETY, DEVICE_CLASS_SMOKE, DEVICE_CLASS_SOUND, DEVICE_CLASS_VIBRATION,
|
||||
DEVICE_CLASS_WINDOW
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_BATTERY_CHARGING,
|
||||
DEVICE_CLASS_COLD,
|
||||
DEVICE_CLASS_CONNECTIVITY,
|
||||
DEVICE_CLASS_DOOR,
|
||||
DEVICE_CLASS_GARAGE_DOOR,
|
||||
DEVICE_CLASS_GAS,
|
||||
DEVICE_CLASS_HEAT,
|
||||
DEVICE_CLASS_LIGHT,
|
||||
DEVICE_CLASS_LOCK,
|
||||
DEVICE_CLASS_MOISTURE,
|
||||
DEVICE_CLASS_MOTION,
|
||||
DEVICE_CLASS_MOVING,
|
||||
DEVICE_CLASS_OCCUPANCY,
|
||||
DEVICE_CLASS_OPENING,
|
||||
DEVICE_CLASS_PLUG,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_PRESENCE,
|
||||
DEVICE_CLASS_PROBLEM,
|
||||
DEVICE_CLASS_SAFETY,
|
||||
DEVICE_CLASS_SMOKE,
|
||||
DEVICE_CLASS_SOUND,
|
||||
DEVICE_CLASS_VIBRATION,
|
||||
DEVICE_CLASS_WINDOW,
|
||||
]
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
binary_sensor_ns = cg.esphome_ns.namespace('binary_sensor')
|
||||
BinarySensor = binary_sensor_ns.class_('BinarySensor', cg.Nameable)
|
||||
BinarySensorInitiallyOff = binary_sensor_ns.class_('BinarySensorInitiallyOff', BinarySensor)
|
||||
BinarySensorPtr = BinarySensor.operator('ptr')
|
||||
binary_sensor_ns = cg.esphome_ns.namespace("binary_sensor")
|
||||
BinarySensor = binary_sensor_ns.class_("BinarySensor", cg.Nameable)
|
||||
BinarySensorInitiallyOff = binary_sensor_ns.class_(
|
||||
"BinarySensorInitiallyOff", BinarySensor
|
||||
)
|
||||
BinarySensorPtr = BinarySensor.operator("ptr")
|
||||
|
||||
# Triggers
|
||||
PressTrigger = binary_sensor_ns.class_('PressTrigger', automation.Trigger.template())
|
||||
ReleaseTrigger = binary_sensor_ns.class_('ReleaseTrigger', automation.Trigger.template())
|
||||
ClickTrigger = binary_sensor_ns.class_('ClickTrigger', automation.Trigger.template())
|
||||
DoubleClickTrigger = binary_sensor_ns.class_('DoubleClickTrigger', automation.Trigger.template())
|
||||
MultiClickTrigger = binary_sensor_ns.class_('MultiClickTrigger', automation.Trigger.template(),
|
||||
cg.Component)
|
||||
MultiClickTriggerEvent = binary_sensor_ns.struct('MultiClickTriggerEvent')
|
||||
StateTrigger = binary_sensor_ns.class_('StateTrigger', automation.Trigger.template(bool))
|
||||
BinarySensorPublishAction = binary_sensor_ns.class_('BinarySensorPublishAction', automation.Action)
|
||||
PressTrigger = binary_sensor_ns.class_("PressTrigger", automation.Trigger.template())
|
||||
ReleaseTrigger = binary_sensor_ns.class_(
|
||||
"ReleaseTrigger", automation.Trigger.template()
|
||||
)
|
||||
ClickTrigger = binary_sensor_ns.class_("ClickTrigger", automation.Trigger.template())
|
||||
DoubleClickTrigger = binary_sensor_ns.class_(
|
||||
"DoubleClickTrigger", automation.Trigger.template()
|
||||
)
|
||||
MultiClickTrigger = binary_sensor_ns.class_(
|
||||
"MultiClickTrigger", automation.Trigger.template(), cg.Component
|
||||
)
|
||||
MultiClickTriggerEvent = binary_sensor_ns.struct("MultiClickTriggerEvent")
|
||||
StateTrigger = binary_sensor_ns.class_(
|
||||
"StateTrigger", automation.Trigger.template(bool)
|
||||
)
|
||||
BinarySensorPublishAction = binary_sensor_ns.class_(
|
||||
"BinarySensorPublishAction", automation.Action
|
||||
)
|
||||
|
||||
# Condition
|
||||
BinarySensorCondition = binary_sensor_ns.class_('BinarySensorCondition', Condition)
|
||||
BinarySensorCondition = binary_sensor_ns.class_("BinarySensorCondition", Condition)
|
||||
|
||||
# Filters
|
||||
Filter = binary_sensor_ns.class_('Filter')
|
||||
DelayedOnOffFilter = binary_sensor_ns.class_('DelayedOnOffFilter', Filter, cg.Component)
|
||||
DelayedOnFilter = binary_sensor_ns.class_('DelayedOnFilter', Filter, cg.Component)
|
||||
DelayedOffFilter = binary_sensor_ns.class_('DelayedOffFilter', Filter, cg.Component)
|
||||
InvertFilter = binary_sensor_ns.class_('InvertFilter', Filter)
|
||||
LambdaFilter = binary_sensor_ns.class_('LambdaFilter', Filter)
|
||||
Filter = binary_sensor_ns.class_("Filter")
|
||||
DelayedOnOffFilter = binary_sensor_ns.class_("DelayedOnOffFilter", Filter, cg.Component)
|
||||
DelayedOnFilter = binary_sensor_ns.class_("DelayedOnFilter", Filter, cg.Component)
|
||||
DelayedOffFilter = binary_sensor_ns.class_("DelayedOffFilter", Filter, cg.Component)
|
||||
InvertFilter = binary_sensor_ns.class_("InvertFilter", Filter)
|
||||
LambdaFilter = binary_sensor_ns.class_("LambdaFilter", Filter)
|
||||
|
||||
FILTER_REGISTRY = Registry()
|
||||
validate_filters = cv.validate_registry('filter', FILTER_REGISTRY)
|
||||
validate_filters = cv.validate_registry("filter", FILTER_REGISTRY)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('invert', InvertFilter, {})
|
||||
@FILTER_REGISTRY.register("invert", InvertFilter, {})
|
||||
def invert_filter_to_code(config, filter_id):
|
||||
yield cg.new_Pvariable(filter_id)
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('delayed_on_off', DelayedOnOffFilter,
|
||||
cv.positive_time_period_milliseconds)
|
||||
@FILTER_REGISTRY.register(
|
||||
"delayed_on_off", DelayedOnOffFilter, cv.positive_time_period_milliseconds
|
||||
)
|
||||
def delayed_on_off_filter_to_code(config, filter_id):
|
||||
var = cg.new_Pvariable(filter_id, config)
|
||||
yield cg.register_component(var, {})
|
||||
yield var
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('delayed_on', DelayedOnFilter,
|
||||
cv.positive_time_period_milliseconds)
|
||||
@FILTER_REGISTRY.register(
|
||||
"delayed_on", DelayedOnFilter, cv.positive_time_period_milliseconds
|
||||
)
|
||||
def delayed_on_filter_to_code(config, filter_id):
|
||||
var = cg.new_Pvariable(filter_id, config)
|
||||
yield cg.register_component(var, {})
|
||||
yield var
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('delayed_off', DelayedOffFilter, cv.positive_time_period_milliseconds)
|
||||
@FILTER_REGISTRY.register(
|
||||
"delayed_off", DelayedOffFilter, cv.positive_time_period_milliseconds
|
||||
)
|
||||
def delayed_off_filter_to_code(config, filter_id):
|
||||
var = cg.new_Pvariable(filter_id, config)
|
||||
yield cg.register_component(var, {})
|
||||
yield var
|
||||
|
||||
|
||||
@FILTER_REGISTRY.register('lambda', LambdaFilter, cv.returning_lambda)
|
||||
@FILTER_REGISTRY.register("lambda", LambdaFilter, cv.returning_lambda)
|
||||
def lambda_filter_to_code(config, filter_id):
|
||||
lambda_ = yield cg.process_lambda(config, [(bool, 'x')], return_type=cg.optional.template(bool))
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config, [(bool, "x")], return_type=cg.optional.template(bool)
|
||||
)
|
||||
yield cg.new_Pvariable(filter_id, lambda_)
|
||||
|
||||
|
||||
MULTI_CLICK_TIMING_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_STATE): cv.boolean,
|
||||
cv.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
MULTI_CLICK_TIMING_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_STATE): cv.boolean,
|
||||
cv.Optional(CONF_MIN_LENGTH): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_MAX_LENGTH): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def parse_multi_click_timing_str(value):
|
||||
if not isinstance(value, str):
|
||||
return value
|
||||
|
||||
parts = value.lower().split(' ')
|
||||
parts = value.lower().split(" ")
|
||||
if len(parts) != 5:
|
||||
raise cv.Invalid("Multi click timing grammar consists of exactly 5 words, not {}"
|
||||
"".format(len(parts)))
|
||||
raise cv.Invalid(
|
||||
"Multi click timing grammar consists of exactly 5 words, not {}"
|
||||
"".format(len(parts))
|
||||
)
|
||||
try:
|
||||
state = cv.boolean(parts[0])
|
||||
except cv.Invalid:
|
||||
# pylint: disable=raise-missing-from
|
||||
raise cv.Invalid("First word must either be ON or OFF, not {}".format(parts[0]))
|
||||
|
||||
if parts[1] != 'for':
|
||||
if parts[1] != "for":
|
||||
raise cv.Invalid("Second word must be 'for', got {}".format(parts[1]))
|
||||
|
||||
if parts[2] == 'at':
|
||||
if parts[3] == 'least':
|
||||
if parts[2] == "at":
|
||||
if parts[3] == "least":
|
||||
key = CONF_MIN_LENGTH
|
||||
elif parts[3] == 'most':
|
||||
elif parts[3] == "most":
|
||||
key = CONF_MAX_LENGTH
|
||||
else:
|
||||
raise cv.Invalid("Third word after at must either be 'least' or 'most', got {}"
|
||||
"".format(parts[3]))
|
||||
raise cv.Invalid(
|
||||
"Third word after at must either be 'least' or 'most', got {}"
|
||||
"".format(parts[3])
|
||||
)
|
||||
try:
|
||||
length = cv.positive_time_period_milliseconds(parts[4])
|
||||
except cv.Invalid as err:
|
||||
raise cv.Invalid(f"Multi Click Grammar Parsing length failed: {err}")
|
||||
return {
|
||||
CONF_STATE: state,
|
||||
key: str(length)
|
||||
}
|
||||
return {CONF_STATE: state, key: str(length)}
|
||||
|
||||
if parts[3] != 'to':
|
||||
if parts[3] != "to":
|
||||
raise cv.Invalid("Multi click grammar: 4th word must be 'to'")
|
||||
|
||||
try:
|
||||
@ -153,7 +226,7 @@ def parse_multi_click_timing_str(value):
|
||||
return {
|
||||
CONF_STATE: state,
|
||||
CONF_MIN_LENGTH: str(min_length),
|
||||
CONF_MAX_LENGTH: str(max_length)
|
||||
CONF_MAX_LENGTH: str(max_length),
|
||||
}
|
||||
|
||||
|
||||
@ -173,11 +246,15 @@ def validate_multi_click_timing(value):
|
||||
|
||||
new_state = v_.get(CONF_STATE, not state)
|
||||
if new_state == state:
|
||||
raise cv.Invalid("Timings must have alternating state. Indices {} and {} have "
|
||||
"the same state {}".format(i, i + 1, state))
|
||||
raise cv.Invalid(
|
||||
"Timings must have alternating state. Indices {} and {} have "
|
||||
"the same state {}".format(i, i + 1, state)
|
||||
)
|
||||
if max_length is not None and max_length < min_length:
|
||||
raise cv.Invalid("Max length ({}) must be larger than min length ({})."
|
||||
"".format(max_length, min_length))
|
||||
raise cv.Invalid(
|
||||
"Max length ({}) must be larger than min length ({})."
|
||||
"".format(max_length, min_length)
|
||||
)
|
||||
|
||||
state = new_state
|
||||
tim = {
|
||||
@ -190,46 +267,71 @@ def validate_multi_click_timing(value):
|
||||
return timings
|
||||
|
||||
|
||||
device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space='_')
|
||||
device_class = cv.one_of(*DEVICE_CLASSES, lower=True, space="_")
|
||||
|
||||
BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(BinarySensor),
|
||||
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTBinarySensorComponent),
|
||||
|
||||
cv.Optional(CONF_DEVICE_CLASS): device_class,
|
||||
cv.Optional(CONF_FILTERS): validate_filters,
|
||||
cv.Optional(CONF_ON_PRESS): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PressTrigger),
|
||||
}),
|
||||
cv.Optional(CONF_ON_RELEASE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ReleaseTrigger),
|
||||
}),
|
||||
cv.Optional(CONF_ON_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ClickTrigger),
|
||||
cv.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
|
||||
}),
|
||||
cv.Optional(CONF_ON_DOUBLE_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DoubleClickTrigger),
|
||||
cv.Optional(CONF_MIN_LENGTH, default='50ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_MAX_LENGTH, default='350ms'): cv.positive_time_period_milliseconds,
|
||||
}),
|
||||
cv.Optional(CONF_ON_MULTI_CLICK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MultiClickTrigger),
|
||||
cv.Required(CONF_TIMING): cv.All([parse_multi_click_timing_str],
|
||||
validate_multi_click_timing),
|
||||
cv.Optional(CONF_INVALID_COOLDOWN, default='1s'): cv.positive_time_period_milliseconds,
|
||||
}),
|
||||
cv.Optional(CONF_ON_STATE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
||||
}),
|
||||
|
||||
cv.Optional(CONF_INVERTED): cv.invalid(
|
||||
"The inverted binary_sensor property has been replaced by the "
|
||||
"new 'invert' binary sensor filter. Please see "
|
||||
"https://esphome.io/components/binary_sensor/index.html."
|
||||
),
|
||||
})
|
||||
BINARY_SENSOR_SCHEMA = cv.MQTT_COMPONENT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BinarySensor),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(
|
||||
mqtt.MQTTBinarySensorComponent
|
||||
),
|
||||
cv.Optional(CONF_DEVICE_CLASS): device_class,
|
||||
cv.Optional(CONF_FILTERS): validate_filters,
|
||||
cv.Optional(CONF_ON_PRESS): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PressTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_RELEASE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ReleaseTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_CLICK): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ClickTrigger),
|
||||
cv.Optional(
|
||||
CONF_MIN_LENGTH, default="50ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(
|
||||
CONF_MAX_LENGTH, default="350ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_DOUBLE_CLICK): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DoubleClickTrigger),
|
||||
cv.Optional(
|
||||
CONF_MIN_LENGTH, default="50ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(
|
||||
CONF_MAX_LENGTH, default="350ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_MULTI_CLICK): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MultiClickTrigger),
|
||||
cv.Required(CONF_TIMING): cv.All(
|
||||
[parse_multi_click_timing_str], validate_multi_click_timing
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_INVALID_COOLDOWN, default="1s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_STATE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(StateTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_INVERTED): cv.invalid(
|
||||
"The inverted binary_sensor property has been replaced by the "
|
||||
"new 'invert' binary sensor filter. Please see "
|
||||
"https://esphome.io/components/binary_sensor/index.html."
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -254,24 +356,28 @@ def setup_binary_sensor_core_(var, config):
|
||||
yield automation.build_automation(trigger, [], conf)
|
||||
|
||||
for conf in config.get(CONF_ON_CLICK, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var,
|
||||
conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH])
|
||||
trigger = cg.new_Pvariable(
|
||||
conf[CONF_TRIGGER_ID], var, conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH]
|
||||
)
|
||||
yield automation.build_automation(trigger, [], conf)
|
||||
|
||||
for conf in config.get(CONF_ON_DOUBLE_CLICK, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var,
|
||||
conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH])
|
||||
trigger = cg.new_Pvariable(
|
||||
conf[CONF_TRIGGER_ID], var, conf[CONF_MIN_LENGTH], conf[CONF_MAX_LENGTH]
|
||||
)
|
||||
yield automation.build_automation(trigger, [], conf)
|
||||
|
||||
for conf in config.get(CONF_ON_MULTI_CLICK, []):
|
||||
timings = []
|
||||
for tim in conf[CONF_TIMING]:
|
||||
timings.append(cg.StructInitializer(
|
||||
MultiClickTriggerEvent,
|
||||
('state', tim[CONF_STATE]),
|
||||
('min_length', tim[CONF_MIN_LENGTH]),
|
||||
('max_length', tim.get(CONF_MAX_LENGTH, 4294967294)),
|
||||
))
|
||||
timings.append(
|
||||
cg.StructInitializer(
|
||||
MultiClickTriggerEvent,
|
||||
("state", tim[CONF_STATE]),
|
||||
("min_length", tim[CONF_MIN_LENGTH]),
|
||||
("max_length", tim.get(CONF_MAX_LENGTH, 4294967294)),
|
||||
)
|
||||
)
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var, timings)
|
||||
if CONF_INVALID_COOLDOWN in conf:
|
||||
cg.add(trigger.set_invalid_cooldown(conf[CONF_INVALID_COOLDOWN]))
|
||||
@ -280,7 +386,7 @@ def setup_binary_sensor_core_(var, config):
|
||||
|
||||
for conf in config.get(CONF_ON_STATE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
yield automation.build_automation(trigger, [(bool, 'x')], conf)
|
||||
yield automation.build_automation(trigger, [(bool, "x")], conf)
|
||||
|
||||
if CONF_MQTT_ID in config:
|
||||
mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var)
|
||||
@ -302,22 +408,28 @@ def new_binary_sensor(config):
|
||||
yield var
|
||||
|
||||
|
||||
BINARY_SENSOR_CONDITION_SCHEMA = maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(BinarySensor),
|
||||
cv.Optional(CONF_FOR): cv.invalid("This option has been removed in 1.13, please use the "
|
||||
"'for' condition instead."),
|
||||
})
|
||||
BINARY_SENSOR_CONDITION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(BinarySensor),
|
||||
cv.Optional(CONF_FOR): cv.invalid(
|
||||
"This option has been removed in 1.13, please use the "
|
||||
"'for' condition instead."
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_condition('binary_sensor.is_on', BinarySensorCondition,
|
||||
BINARY_SENSOR_CONDITION_SCHEMA)
|
||||
@automation.register_condition(
|
||||
"binary_sensor.is_on", BinarySensorCondition, BINARY_SENSOR_CONDITION_SCHEMA
|
||||
)
|
||||
def binary_sensor_is_on_to_code(config, condition_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(condition_id, template_arg, paren, True)
|
||||
|
||||
|
||||
@automation.register_condition('binary_sensor.is_off', BinarySensorCondition,
|
||||
BINARY_SENSOR_CONDITION_SCHEMA)
|
||||
@automation.register_condition(
|
||||
"binary_sensor.is_off", BinarySensorCondition, BINARY_SENSOR_CONDITION_SCHEMA
|
||||
)
|
||||
def binary_sensor_is_off_to_code(config, condition_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(condition_id, template_arg, paren, False)
|
||||
@ -325,5 +437,5 @@ def binary_sensor_is_off_to_code(config, condition_id, template_arg, args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_define('USE_BINARY_SENSOR')
|
||||
cg.add_define("USE_BINARY_SENSOR")
|
||||
cg.add_global(binary_sensor_ns.using)
|
||||
|
@ -2,14 +2,25 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
|
||||
from esphome.components import sensor, binary_sensor
|
||||
from esphome.const import CONF_ID, CONF_CHANNELS, CONF_VALUE, CONF_TYPE, DEVICE_CLASS_EMPTY, \
|
||||
UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, CONF_BINARY_SENSOR, CONF_GROUP
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_CHANNELS,
|
||||
CONF_VALUE,
|
||||
CONF_TYPE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
UNIT_EMPTY,
|
||||
ICON_CHECK_CIRCLE_OUTLINE,
|
||||
CONF_BINARY_SENSOR,
|
||||
CONF_GROUP,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['binary_sensor']
|
||||
DEPENDENCIES = ["binary_sensor"]
|
||||
|
||||
binary_sensor_map_ns = cg.esphome_ns.namespace('binary_sensor_map')
|
||||
BinarySensorMap = binary_sensor_map_ns.class_('BinarySensorMap', cg.Component, sensor.Sensor)
|
||||
SensorMapType = binary_sensor_map_ns.enum('SensorMapType')
|
||||
binary_sensor_map_ns = cg.esphome_ns.namespace("binary_sensor_map")
|
||||
BinarySensorMap = binary_sensor_map_ns.class_(
|
||||
"BinarySensorMap", cg.Component, sensor.Sensor
|
||||
)
|
||||
SensorMapType = binary_sensor_map_ns.enum("SensorMapType")
|
||||
|
||||
SENSOR_MAP_TYPES = {
|
||||
CONF_GROUP: SensorMapType.BINARY_SENSOR_MAP_TYPE_GROUP,
|
||||
@ -20,14 +31,21 @@ entry = {
|
||||
cv.Required(CONF_VALUE): cv.float_,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = cv.typed_schema({
|
||||
CONF_GROUP: sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, 0, DEVICE_CLASS_EMPTY
|
||||
).extend({
|
||||
cv.GenerateID(): cv.declare_id(BinarySensorMap),
|
||||
cv.Required(CONF_CHANNELS): cv.All(cv.ensure_list(entry), cv.Length(min=1)),
|
||||
}),
|
||||
}, lower=True)
|
||||
CONFIG_SCHEMA = cv.typed_schema(
|
||||
{
|
||||
CONF_GROUP: sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_CHECK_CIRCLE_OUTLINE, 0, DEVICE_CLASS_EMPTY
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BinarySensorMap),
|
||||
cv.Required(CONF_CHANNELS): cv.All(
|
||||
cv.ensure_list(entry), cv.Length(min=1)
|
||||
),
|
||||
}
|
||||
),
|
||||
},
|
||||
lower=True,
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,18 +3,28 @@ import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_MAC_ADDRESS, CONF_SERVICE_UUID, CONF_ID
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
ble_presence_ns = cg.esphome_ns.namespace('ble_presence')
|
||||
BLEPresenceDevice = ble_presence_ns.class_('BLEPresenceDevice', binary_sensor.BinarySensor,
|
||||
cg.Component, esp32_ble_tracker.ESPBTDeviceListener)
|
||||
ble_presence_ns = cg.esphome_ns.namespace("ble_presence")
|
||||
BLEPresenceDevice = ble_presence_ns.class_(
|
||||
"BLEPresenceDevice",
|
||||
binary_sensor.BinarySensor,
|
||||
cg.Component,
|
||||
esp32_ble_tracker.ESPBTDeviceListener,
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(BLEPresenceDevice),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(
|
||||
cv.COMPONENT_SCHEMA), cv.has_exactly_one_key(CONF_MAC_ADDRESS, CONF_SERVICE_UUID))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLEPresenceDevice),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA),
|
||||
cv.has_exactly_one_key(CONF_MAC_ADDRESS, CONF_SERVICE_UUID),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -28,9 +38,17 @@ def to_code(config):
|
||||
|
||||
if CONF_SERVICE_UUID in config:
|
||||
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])))
|
||||
cg.add(
|
||||
var.set_service_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])))
|
||||
cg.add(
|
||||
var.set_service_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_hex_array(config[CONF_SERVICE_UUID])
|
||||
cg.add(var.set_service_uuid128(uuid128))
|
||||
|
@ -1,23 +1,35 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_SERVICE_UUID, CONF_MAC_ADDRESS, CONF_ID, \
|
||||
DEVICE_CLASS_SIGNAL_STRENGTH, UNIT_DECIBEL, ICON_EMPTY
|
||||
from esphome.const import (
|
||||
CONF_SERVICE_UUID,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_SIGNAL_STRENGTH,
|
||||
UNIT_DECIBEL,
|
||||
ICON_EMPTY,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
ble_rssi_ns = cg.esphome_ns.namespace('ble_rssi')
|
||||
BLERSSISensor = ble_rssi_ns.class_('BLERSSISensor', sensor.Sensor, cg.Component,
|
||||
esp32_ble_tracker.ESPBTDeviceListener)
|
||||
ble_rssi_ns = cg.esphome_ns.namespace("ble_rssi")
|
||||
BLERSSISensor = ble_rssi_ns.class_(
|
||||
"BLERSSISensor", sensor.Sensor, cg.Component, esp32_ble_tracker.ESPBTDeviceListener
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(UNIT_DECIBEL, ICON_EMPTY, 0, DEVICE_CLASS_SIGNAL_STRENGTH).extend({
|
||||
cv.GenerateID(): cv.declare_id(BLERSSISensor),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
}).extend(
|
||||
esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA
|
||||
).extend(cv.COMPONENT_SCHEMA), cv.has_exactly_one_key(CONF_MAC_ADDRESS, CONF_SERVICE_UUID))
|
||||
sensor.sensor_schema(UNIT_DECIBEL, ICON_EMPTY, 0, DEVICE_CLASS_SIGNAL_STRENGTH)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLERSSISensor),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_SERVICE_UUID): esp32_ble_tracker.bt_uuid,
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA),
|
||||
cv.has_exactly_one_key(CONF_MAC_ADDRESS, CONF_SERVICE_UUID),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -31,9 +43,17 @@ def to_code(config):
|
||||
|
||||
if CONF_SERVICE_UUID in config:
|
||||
if len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid16_format):
|
||||
cg.add(var.set_service_uuid16(esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])))
|
||||
cg.add(
|
||||
var.set_service_uuid16(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid32_format):
|
||||
cg.add(var.set_service_uuid32(esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])))
|
||||
cg.add(
|
||||
var.set_service_uuid32(
|
||||
esp32_ble_tracker.as_hex(config[CONF_SERVICE_UUID])
|
||||
)
|
||||
)
|
||||
elif len(config[CONF_SERVICE_UUID]) == len(esp32_ble_tracker.bt_uuid128_format):
|
||||
uuid128 = esp32_ble_tracker.as_hex_array(config[CONF_SERVICE_UUID])
|
||||
cg.add(var.set_service_uuid128(uuid128))
|
||||
|
@ -3,16 +3,25 @@ import esphome.config_validation as cv
|
||||
from esphome.components import text_sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
ble_scanner_ns = cg.esphome_ns.namespace('ble_scanner')
|
||||
BLEScanner = ble_scanner_ns.class_('BLEScanner', text_sensor.TextSensor, cg.Component,
|
||||
esp32_ble_tracker.ESPBTDeviceListener)
|
||||
ble_scanner_ns = cg.esphome_ns.namespace("ble_scanner")
|
||||
BLEScanner = ble_scanner_ns.class_(
|
||||
"BLEScanner",
|
||||
text_sensor.TextSensor,
|
||||
cg.Component,
|
||||
esp32_ble_tracker.ESPBTDeviceListener,
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(BLEScanner),
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(
|
||||
cv.COMPONENT_SCHEMA))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BLEScanner),
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,53 +1,87 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_OVERSAMPLING, \
|
||||
CONF_PRESSURE, CONF_TEMPERATURE, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_PRESSURE, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, UNIT_HECTOPASCAL, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_IIR_FILTER,
|
||||
CONF_OVERSAMPLING,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_HECTOPASCAL,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bme280_ns = cg.esphome_ns.namespace('bme280')
|
||||
BME280Oversampling = bme280_ns.enum('BME280Oversampling')
|
||||
bme280_ns = cg.esphome_ns.namespace("bme280")
|
||||
BME280Oversampling = bme280_ns.enum("BME280Oversampling")
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': BME280Oversampling.BME280_OVERSAMPLING_NONE,
|
||||
'1X': BME280Oversampling.BME280_OVERSAMPLING_1X,
|
||||
'2X': BME280Oversampling.BME280_OVERSAMPLING_2X,
|
||||
'4X': BME280Oversampling.BME280_OVERSAMPLING_4X,
|
||||
'8X': BME280Oversampling.BME280_OVERSAMPLING_8X,
|
||||
'16X': BME280Oversampling.BME280_OVERSAMPLING_16X,
|
||||
"NONE": BME280Oversampling.BME280_OVERSAMPLING_NONE,
|
||||
"1X": BME280Oversampling.BME280_OVERSAMPLING_1X,
|
||||
"2X": BME280Oversampling.BME280_OVERSAMPLING_2X,
|
||||
"4X": BME280Oversampling.BME280_OVERSAMPLING_4X,
|
||||
"8X": BME280Oversampling.BME280_OVERSAMPLING_8X,
|
||||
"16X": BME280Oversampling.BME280_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BME280IIRFilter = bme280_ns.enum('BME280IIRFilter')
|
||||
BME280IIRFilter = bme280_ns.enum("BME280IIRFilter")
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': BME280IIRFilter.BME280_IIR_FILTER_OFF,
|
||||
'2X': BME280IIRFilter.BME280_IIR_FILTER_2X,
|
||||
'4X': BME280IIRFilter.BME280_IIR_FILTER_4X,
|
||||
'8X': BME280IIRFilter.BME280_IIR_FILTER_8X,
|
||||
'16X': BME280IIRFilter.BME280_IIR_FILTER_16X,
|
||||
"OFF": BME280IIRFilter.BME280_IIR_FILTER_OFF,
|
||||
"2X": BME280IIRFilter.BME280_IIR_FILTER_2X,
|
||||
"4X": BME280IIRFilter.BME280_IIR_FILTER_4X,
|
||||
"8X": BME280IIRFilter.BME280_IIR_FILTER_8X,
|
||||
"16X": BME280IIRFilter.BME280_IIR_FILTER_16X,
|
||||
}
|
||||
|
||||
BME280Component = bme280_ns.class_('BME280Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
BME280Component = bme280_ns.class_(
|
||||
"BME280Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(BME280Component),
|
||||
cv.Optional(CONF_TEMPERATURE):
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_PRESSURE):
|
||||
sensor.sensor_schema(UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_HUMIDITY):
|
||||
sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_IIR_FILTER, default='OFF'): cv.enum(IIR_FILTER_OPTIONS, upper=True),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BME280Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(
|
||||
IIR_FILTER_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x77))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,65 +2,116 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import core
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_DURATION, CONF_GAS_RESISTANCE, CONF_HEATER, \
|
||||
CONF_HUMIDITY, CONF_ID, CONF_IIR_FILTER, CONF_OVERSAMPLING, CONF_PRESSURE, \
|
||||
CONF_TEMPERATURE, DEVICE_CLASS_EMPTY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_PRESSURE, \
|
||||
DEVICE_CLASS_TEMPERATURE, UNIT_OHM, ICON_GAS_CYLINDER, UNIT_CELSIUS, ICON_EMPTY, \
|
||||
UNIT_HECTOPASCAL, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_DURATION,
|
||||
CONF_GAS_RESISTANCE,
|
||||
CONF_HEATER,
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_IIR_FILTER,
|
||||
CONF_OVERSAMPLING,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
UNIT_OHM,
|
||||
ICON_GAS_CYLINDER,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
UNIT_HECTOPASCAL,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bme680_ns = cg.esphome_ns.namespace('bme680')
|
||||
BME680Oversampling = bme680_ns.enum('BME680Oversampling')
|
||||
bme680_ns = cg.esphome_ns.namespace("bme680")
|
||||
BME680Oversampling = bme680_ns.enum("BME680Oversampling")
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': BME680Oversampling.BME680_OVERSAMPLING_NONE,
|
||||
'1X': BME680Oversampling.BME680_OVERSAMPLING_1X,
|
||||
'2X': BME680Oversampling.BME680_OVERSAMPLING_2X,
|
||||
'4X': BME680Oversampling.BME680_OVERSAMPLING_4X,
|
||||
'8X': BME680Oversampling.BME680_OVERSAMPLING_8X,
|
||||
'16X': BME680Oversampling.BME680_OVERSAMPLING_16X,
|
||||
"NONE": BME680Oversampling.BME680_OVERSAMPLING_NONE,
|
||||
"1X": BME680Oversampling.BME680_OVERSAMPLING_1X,
|
||||
"2X": BME680Oversampling.BME680_OVERSAMPLING_2X,
|
||||
"4X": BME680Oversampling.BME680_OVERSAMPLING_4X,
|
||||
"8X": BME680Oversampling.BME680_OVERSAMPLING_8X,
|
||||
"16X": BME680Oversampling.BME680_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BME680IIRFilter = bme680_ns.enum('BME680IIRFilter')
|
||||
BME680IIRFilter = bme680_ns.enum("BME680IIRFilter")
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': BME680IIRFilter.BME680_IIR_FILTER_OFF,
|
||||
'1X': BME680IIRFilter.BME680_IIR_FILTER_1X,
|
||||
'3X': BME680IIRFilter.BME680_IIR_FILTER_3X,
|
||||
'7X': BME680IIRFilter.BME680_IIR_FILTER_7X,
|
||||
'15X': BME680IIRFilter.BME680_IIR_FILTER_15X,
|
||||
'31X': BME680IIRFilter.BME680_IIR_FILTER_31X,
|
||||
'63X': BME680IIRFilter.BME680_IIR_FILTER_63X,
|
||||
'127X': BME680IIRFilter.BME680_IIR_FILTER_127X,
|
||||
"OFF": BME680IIRFilter.BME680_IIR_FILTER_OFF,
|
||||
"1X": BME680IIRFilter.BME680_IIR_FILTER_1X,
|
||||
"3X": BME680IIRFilter.BME680_IIR_FILTER_3X,
|
||||
"7X": BME680IIRFilter.BME680_IIR_FILTER_7X,
|
||||
"15X": BME680IIRFilter.BME680_IIR_FILTER_15X,
|
||||
"31X": BME680IIRFilter.BME680_IIR_FILTER_31X,
|
||||
"63X": BME680IIRFilter.BME680_IIR_FILTER_63X,
|
||||
"127X": BME680IIRFilter.BME680_IIR_FILTER_127X,
|
||||
}
|
||||
|
||||
BME680Component = bme680_ns.class_('BME680Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
BME680Component = bme680_ns.class_(
|
||||
"BME680Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(BME680Component),
|
||||
cv.Optional(CONF_TEMPERATURE):
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_PRESSURE):
|
||||
sensor.sensor_schema(UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_HUMIDITY):
|
||||
sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'):
|
||||
cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_GAS_RESISTANCE):
|
||||
sensor.sensor_schema(UNIT_OHM, ICON_GAS_CYLINDER, 1, DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_IIR_FILTER, default='OFF'): cv.enum(IIR_FILTER_OPTIONS, upper=True),
|
||||
cv.Optional(CONF_HEATER): cv.Any(None, cv.All(cv.Schema({
|
||||
cv.Optional(CONF_TEMPERATURE, default=320): cv.int_range(min=200, max=400),
|
||||
cv.Optional(CONF_DURATION, default='150ms'): cv.All(
|
||||
cv.positive_time_period_milliseconds, cv.Range(max=core.TimePeriod(milliseconds=4032)))
|
||||
}), cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_DURATION))),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x76))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BME680Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_GAS_RESISTANCE): sensor.sensor_schema(
|
||||
UNIT_OHM, ICON_GAS_CYLINDER, 1, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(
|
||||
IIR_FILTER_OPTIONS, upper=True
|
||||
),
|
||||
cv.Optional(CONF_HEATER): cv.Any(
|
||||
None,
|
||||
cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_TEMPERATURE, default=320): cv.int_range(
|
||||
min=200, max=400
|
||||
),
|
||||
cv.Optional(CONF_DURATION, default="150ms"): cv.All(
|
||||
cv.positive_time_period_milliseconds,
|
||||
cv.Range(max=core.TimePeriod(milliseconds=4032)),
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.has_at_least_one_key(CONF_TEMPERATURE, CONF_DURATION),
|
||||
),
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x76))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,39 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_PRESSURE, CONF_TEMPERATURE, DEVICE_CLASS_PRESSURE, \
|
||||
DEVICE_CLASS_TEMPERATURE, UNIT_CELSIUS, ICON_EMPTY, UNIT_HECTOPASCAL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
UNIT_HECTOPASCAL,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bmp085_ns = cg.esphome_ns.namespace('bmp085')
|
||||
BMP085Component = bmp085_ns.class_('BMP085Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
bmp085_ns = cg.esphome_ns.namespace("bmp085")
|
||||
BMP085Component = bmp085_ns.class_(
|
||||
"BMP085Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(BMP085Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(UNIT_HECTOPASCAL, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_PRESSURE),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BMP085Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x77))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,48 +1,75 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_PRESSURE, CONF_TEMPERATURE, DEVICE_CLASS_PRESSURE, \
|
||||
DEVICE_CLASS_TEMPERATURE, UNIT_CELSIUS, ICON_EMPTY, UNIT_HECTOPASCAL, CONF_IIR_FILTER, \
|
||||
CONF_OVERSAMPLING
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
UNIT_HECTOPASCAL,
|
||||
CONF_IIR_FILTER,
|
||||
CONF_OVERSAMPLING,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
bmp280_ns = cg.esphome_ns.namespace('bmp280')
|
||||
BMP280Oversampling = bmp280_ns.enum('BMP280Oversampling')
|
||||
bmp280_ns = cg.esphome_ns.namespace("bmp280")
|
||||
BMP280Oversampling = bmp280_ns.enum("BMP280Oversampling")
|
||||
OVERSAMPLING_OPTIONS = {
|
||||
'NONE': BMP280Oversampling.BMP280_OVERSAMPLING_NONE,
|
||||
'1X': BMP280Oversampling.BMP280_OVERSAMPLING_1X,
|
||||
'2X': BMP280Oversampling.BMP280_OVERSAMPLING_2X,
|
||||
'4X': BMP280Oversampling.BMP280_OVERSAMPLING_4X,
|
||||
'8X': BMP280Oversampling.BMP280_OVERSAMPLING_8X,
|
||||
'16X': BMP280Oversampling.BMP280_OVERSAMPLING_16X,
|
||||
"NONE": BMP280Oversampling.BMP280_OVERSAMPLING_NONE,
|
||||
"1X": BMP280Oversampling.BMP280_OVERSAMPLING_1X,
|
||||
"2X": BMP280Oversampling.BMP280_OVERSAMPLING_2X,
|
||||
"4X": BMP280Oversampling.BMP280_OVERSAMPLING_4X,
|
||||
"8X": BMP280Oversampling.BMP280_OVERSAMPLING_8X,
|
||||
"16X": BMP280Oversampling.BMP280_OVERSAMPLING_16X,
|
||||
}
|
||||
|
||||
BMP280IIRFilter = bmp280_ns.enum('BMP280IIRFilter')
|
||||
BMP280IIRFilter = bmp280_ns.enum("BMP280IIRFilter")
|
||||
IIR_FILTER_OPTIONS = {
|
||||
'OFF': BMP280IIRFilter.BMP280_IIR_FILTER_OFF,
|
||||
'2X': BMP280IIRFilter.BMP280_IIR_FILTER_2X,
|
||||
'4X': BMP280IIRFilter.BMP280_IIR_FILTER_4X,
|
||||
'8X': BMP280IIRFilter.BMP280_IIR_FILTER_8X,
|
||||
'16X': BMP280IIRFilter.BMP280_IIR_FILTER_16X,
|
||||
"OFF": BMP280IIRFilter.BMP280_IIR_FILTER_OFF,
|
||||
"2X": BMP280IIRFilter.BMP280_IIR_FILTER_2X,
|
||||
"4X": BMP280IIRFilter.BMP280_IIR_FILTER_4X,
|
||||
"8X": BMP280IIRFilter.BMP280_IIR_FILTER_8X,
|
||||
"16X": BMP280IIRFilter.BMP280_IIR_FILTER_16X,
|
||||
}
|
||||
|
||||
BMP280Component = bmp280_ns.class_('BMP280Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
BMP280Component = bmp280_ns.class_(
|
||||
"BMP280Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(BMP280Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'): cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE
|
||||
).extend({
|
||||
cv.Optional(CONF_OVERSAMPLING, default='16X'): cv.enum(OVERSAMPLING_OPTIONS, upper=True),
|
||||
}),
|
||||
cv.Optional(CONF_IIR_FILTER, default='OFF'): cv.enum(IIR_FILTER_OPTIONS, upper=True),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(BMP280Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_EMPTY, 1, DEVICE_CLASS_PRESSURE
|
||||
).extend(
|
||||
{
|
||||
cv.Optional(CONF_OVERSAMPLING, default="16X"): cv.enum(
|
||||
OVERSAMPLING_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_IIR_FILTER, default="OFF"): cv.enum(
|
||||
IIR_FILTER_OPTIONS, upper=True
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x77))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,68 +4,76 @@ from esphome import automation
|
||||
from esphome.core import CORE, coroutine
|
||||
from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_DATA
|
||||
|
||||
CODEOWNERS = ['@mvturnho', '@danielschramm']
|
||||
CODEOWNERS = ["@mvturnho", "@danielschramm"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
CONF_CAN_ID = 'can_id'
|
||||
CONF_USE_EXTENDED_ID = 'use_extended_id'
|
||||
CONF_CANBUS_ID = 'canbus_id'
|
||||
CONF_BIT_RATE = 'bit_rate'
|
||||
CONF_ON_FRAME = 'on_frame'
|
||||
CONF_CANBUS_SEND = 'canbus.send'
|
||||
CONF_CAN_ID = "can_id"
|
||||
CONF_USE_EXTENDED_ID = "use_extended_id"
|
||||
CONF_CANBUS_ID = "canbus_id"
|
||||
CONF_BIT_RATE = "bit_rate"
|
||||
CONF_ON_FRAME = "on_frame"
|
||||
CONF_CANBUS_SEND = "canbus.send"
|
||||
|
||||
|
||||
def validate_id(id_value, id_ext):
|
||||
if not id_ext:
|
||||
if id_value > 0x7ff:
|
||||
if id_value > 0x7FF:
|
||||
raise cv.Invalid("Standard IDs must be 11 Bit (0x000-0x7ff / 0-2047)")
|
||||
|
||||
|
||||
def validate_raw_data(value):
|
||||
if isinstance(value, str):
|
||||
return value.encode('utf-8')
|
||||
return value.encode("utf-8")
|
||||
if isinstance(value, list):
|
||||
return cv.Schema([cv.hex_uint8_t])(value)
|
||||
raise cv.Invalid("data must either be a string wrapped in quotes or a list of bytes")
|
||||
raise cv.Invalid(
|
||||
"data must either be a string wrapped in quotes or a list of bytes"
|
||||
)
|
||||
|
||||
|
||||
canbus_ns = cg.esphome_ns.namespace('canbus')
|
||||
CanbusComponent = canbus_ns.class_('CanbusComponent', cg.Component)
|
||||
CanbusTrigger = canbus_ns.class_('CanbusTrigger',
|
||||
automation.Trigger.template(cg.std_vector.template(cg.uint8)),
|
||||
cg.Component)
|
||||
CanSpeed = canbus_ns.enum('CAN_SPEED')
|
||||
canbus_ns = cg.esphome_ns.namespace("canbus")
|
||||
CanbusComponent = canbus_ns.class_("CanbusComponent", cg.Component)
|
||||
CanbusTrigger = canbus_ns.class_(
|
||||
"CanbusTrigger",
|
||||
automation.Trigger.template(cg.std_vector.template(cg.uint8)),
|
||||
cg.Component,
|
||||
)
|
||||
CanSpeed = canbus_ns.enum("CAN_SPEED")
|
||||
|
||||
CAN_SPEEDS = {
|
||||
'5KBPS': CanSpeed.CAN_5KBPS,
|
||||
'10KBPS': CanSpeed.CAN_10KBPS,
|
||||
'20KBPS': CanSpeed.CAN_20KBPS,
|
||||
'31K25BPS': CanSpeed.CAN_31K25BPS,
|
||||
'33KBPS': CanSpeed.CAN_33KBPS,
|
||||
'40KBPS': CanSpeed.CAN_40KBPS,
|
||||
'50KBPS': CanSpeed.CAN_50KBPS,
|
||||
'80KBPS': CanSpeed.CAN_80KBPS,
|
||||
'83K3BPS': CanSpeed.CAN_83K3BPS,
|
||||
'95KBPS': CanSpeed.CAN_95KBPS,
|
||||
'100KBPS': CanSpeed.CAN_100KBPS,
|
||||
'125KBPS': CanSpeed.CAN_125KBPS,
|
||||
'200KBPS': CanSpeed.CAN_200KBPS,
|
||||
'250KBPS': CanSpeed.CAN_250KBPS,
|
||||
'500KBPS': CanSpeed.CAN_500KBPS,
|
||||
'1000KBPS': CanSpeed.CAN_1000KBPS,
|
||||
"5KBPS": CanSpeed.CAN_5KBPS,
|
||||
"10KBPS": CanSpeed.CAN_10KBPS,
|
||||
"20KBPS": CanSpeed.CAN_20KBPS,
|
||||
"31K25BPS": CanSpeed.CAN_31K25BPS,
|
||||
"33KBPS": CanSpeed.CAN_33KBPS,
|
||||
"40KBPS": CanSpeed.CAN_40KBPS,
|
||||
"50KBPS": CanSpeed.CAN_50KBPS,
|
||||
"80KBPS": CanSpeed.CAN_80KBPS,
|
||||
"83K3BPS": CanSpeed.CAN_83K3BPS,
|
||||
"95KBPS": CanSpeed.CAN_95KBPS,
|
||||
"100KBPS": CanSpeed.CAN_100KBPS,
|
||||
"125KBPS": CanSpeed.CAN_125KBPS,
|
||||
"200KBPS": CanSpeed.CAN_200KBPS,
|
||||
"250KBPS": CanSpeed.CAN_250KBPS,
|
||||
"500KBPS": CanSpeed.CAN_500KBPS,
|
||||
"1000KBPS": CanSpeed.CAN_1000KBPS,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||
cv.Required(CONF_CAN_ID): cv.int_range(min=0, max=0x1fffffff),
|
||||
cv.Optional(CONF_BIT_RATE, default='125KBPS'): cv.enum(CAN_SPEEDS, upper=True),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
cv.Optional(CONF_ON_FRAME): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1fffffff),
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CanbusComponent),
|
||||
cv.Required(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_BIT_RATE, default="125KBPS"): cv.enum(CAN_SPEEDS, upper=True),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
}),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
cv.Optional(CONF_ON_FRAME): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CanbusTrigger),
|
||||
cv.GenerateID(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -82,7 +90,9 @@ def setup_canbus_core_(var, config):
|
||||
validate_id(can_id, ext_id)
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var, can_id, ext_id)
|
||||
yield cg.register_component(trigger, conf)
|
||||
yield automation.build_automation(trigger, [(cg.std_vector.template(cg.uint8), 'x')], conf)
|
||||
yield automation.build_automation(
|
||||
trigger, [(cg.std_vector.template(cg.uint8), "x")], conf
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -93,14 +103,19 @@ def register_canbus(var, config):
|
||||
|
||||
|
||||
# Actions
|
||||
@automation.register_action(CONF_CANBUS_SEND,
|
||||
canbus_ns.class_('CanbusSendAction', automation.Action),
|
||||
cv.maybe_simple_value({
|
||||
cv.GenerateID(CONF_CANBUS_ID): cv.use_id(CanbusComponent),
|
||||
cv.Optional(CONF_CAN_ID): cv.int_range(min=0, max=0x1fffffff),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
}, key=CONF_DATA))
|
||||
@automation.register_action(
|
||||
CONF_CANBUS_SEND,
|
||||
canbus_ns.class_("CanbusSendAction", automation.Action),
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(CONF_CANBUS_ID): cv.use_id(CanbusComponent),
|
||||
cv.Optional(CONF_CAN_ID): cv.int_range(min=0, max=0x1FFFFFFF),
|
||||
cv.Optional(CONF_USE_EXTENDED_ID, default=False): cv.boolean,
|
||||
cv.Required(CONF_DATA): cv.templatable(validate_raw_data),
|
||||
},
|
||||
key=CONF_DATA,
|
||||
),
|
||||
)
|
||||
def canbus_action_to_code(config, action_id, template_arg, args):
|
||||
validate_id(config[CONF_CAN_ID], config[CONF_USE_EXTENDED_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
@ -110,7 +125,9 @@ def canbus_action_to_code(config, action_id, template_arg, args):
|
||||
can_id = yield cg.templatable(config[CONF_CAN_ID], args, cg.uint32)
|
||||
cg.add(var.set_can_id(can_id))
|
||||
|
||||
use_extended_id = yield cg.templatable(config[CONF_USE_EXTENDED_ID], args, cg.uint32)
|
||||
use_extended_id = yield cg.templatable(
|
||||
config[CONF_USE_EXTENDED_ID], args, cg.uint32
|
||||
)
|
||||
cg.add(var.set_use_extended_id(use_extended_id))
|
||||
|
||||
data = config[CONF_DATA]
|
||||
|
@ -5,17 +5,21 @@ from esphome.components.web_server_base import CONF_WEB_SERVER_BASE_ID
|
||||
from esphome.const import CONF_ID
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
AUTO_LOAD = ['web_server_base']
|
||||
DEPENDENCIES = ['wifi']
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
AUTO_LOAD = ["web_server_base"]
|
||||
DEPENDENCIES = ["wifi"]
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
||||
captive_portal_ns = cg.esphome_ns.namespace('captive_portal')
|
||||
CaptivePortal = captive_portal_ns.class_('CaptivePortal', cg.Component)
|
||||
captive_portal_ns = cg.esphome_ns.namespace("captive_portal")
|
||||
CaptivePortal = captive_portal_ns.class_("CaptivePortal", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CaptivePortal),
|
||||
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(web_server_base.WebServerBase),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CaptivePortal),
|
||||
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(
|
||||
web_server_base.WebServerBase
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine_with_priority(64.0)
|
||||
@ -24,4 +28,4 @@ def to_code(config):
|
||||
|
||||
var = cg.new_Pvariable(config[CONF_ID], paren)
|
||||
yield cg.register_component(var, config)
|
||||
cg.add_define('USE_CAPTIVE_PORTAL')
|
||||
cg.add_define("USE_CAPTIVE_PORTAL")
|
||||
|
@ -1,28 +1,46 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY, ICON_RADIATOR, UNIT_PARTS_PER_MILLION, \
|
||||
UNIT_PARTS_PER_BILLION, CONF_TEMPERATURE, CONF_TVOC, CONF_HUMIDITY, ICON_MOLECULE_CO2
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ICON_RADIATOR,
|
||||
UNIT_PARTS_PER_MILLION,
|
||||
UNIT_PARTS_PER_BILLION,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_TVOC,
|
||||
CONF_HUMIDITY,
|
||||
ICON_MOLECULE_CO2,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ccs811_ns = cg.esphome_ns.namespace('ccs811')
|
||||
CCS811Component = ccs811_ns.class_('CCS811Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
ccs811_ns = cg.esphome_ns.namespace("ccs811")
|
||||
CCS811Component = ccs811_ns.class_(
|
||||
"CCS811Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONF_ECO2 = 'eco2'
|
||||
CONF_BASELINE = 'baseline'
|
||||
CONF_ECO2 = "eco2"
|
||||
CONF_BASELINE = "baseline"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CCS811Component),
|
||||
cv.Required(CONF_ECO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION, ICON_MOLECULE_CO2,
|
||||
0, DEVICE_CLASS_EMPTY),
|
||||
cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR,
|
||||
0, DEVICE_CLASS_EMPTY),
|
||||
|
||||
cv.Optional(CONF_BASELINE): cv.hex_uint16_t,
|
||||
cv.Optional(CONF_TEMPERATURE): cv.use_id(sensor.Sensor),
|
||||
cv.Optional(CONF_HUMIDITY): cv.use_id(sensor.Sensor),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x5A))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CCS811Component),
|
||||
cv.Required(CONF_ECO2): sensor.sensor_schema(
|
||||
UNIT_PARTS_PER_MILLION, ICON_MOLECULE_CO2, 0, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Required(CONF_TVOC): sensor.sensor_schema(
|
||||
UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_BASELINE): cv.hex_uint16_t,
|
||||
cv.Optional(CONF_TEMPERATURE): cv.use_id(sensor.Sensor),
|
||||
cv.Optional(CONF_HUMIDITY): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x5A))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,70 +2,87 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import CONF_AWAY, CONF_ID, CONF_INTERNAL, CONF_MAX_TEMPERATURE, \
|
||||
CONF_MIN_TEMPERATURE, CONF_MODE, CONF_TARGET_TEMPERATURE, \
|
||||
CONF_TARGET_TEMPERATURE_HIGH, CONF_TARGET_TEMPERATURE_LOW, CONF_TEMPERATURE_STEP, CONF_VISUAL, \
|
||||
CONF_MQTT_ID, CONF_NAME, CONF_FAN_MODE, CONF_SWING_MODE
|
||||
from esphome.const import (
|
||||
CONF_AWAY,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_MAX_TEMPERATURE,
|
||||
CONF_MIN_TEMPERATURE,
|
||||
CONF_MODE,
|
||||
CONF_TARGET_TEMPERATURE,
|
||||
CONF_TARGET_TEMPERATURE_HIGH,
|
||||
CONF_TARGET_TEMPERATURE_LOW,
|
||||
CONF_TEMPERATURE_STEP,
|
||||
CONF_VISUAL,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
CONF_FAN_MODE,
|
||||
CONF_SWING_MODE,
|
||||
)
|
||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
climate_ns = cg.esphome_ns.namespace('climate')
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
climate_ns = cg.esphome_ns.namespace("climate")
|
||||
|
||||
Climate = climate_ns.class_('Climate', cg.Nameable)
|
||||
ClimateCall = climate_ns.class_('ClimateCall')
|
||||
ClimateTraits = climate_ns.class_('ClimateTraits')
|
||||
Climate = climate_ns.class_("Climate", cg.Nameable)
|
||||
ClimateCall = climate_ns.class_("ClimateCall")
|
||||
ClimateTraits = climate_ns.class_("ClimateTraits")
|
||||
|
||||
ClimateMode = climate_ns.enum('ClimateMode')
|
||||
ClimateMode = climate_ns.enum("ClimateMode")
|
||||
CLIMATE_MODES = {
|
||||
'OFF': ClimateMode.CLIMATE_MODE_OFF,
|
||||
'AUTO': ClimateMode.CLIMATE_MODE_AUTO,
|
||||
'COOL': ClimateMode.CLIMATE_MODE_COOL,
|
||||
'HEAT': ClimateMode.CLIMATE_MODE_HEAT,
|
||||
'DRY': ClimateMode.CLIMATE_MODE_DRY,
|
||||
'FAN_ONLY': ClimateMode.CLIMATE_MODE_FAN_ONLY,
|
||||
"OFF": ClimateMode.CLIMATE_MODE_OFF,
|
||||
"AUTO": ClimateMode.CLIMATE_MODE_AUTO,
|
||||
"COOL": ClimateMode.CLIMATE_MODE_COOL,
|
||||
"HEAT": ClimateMode.CLIMATE_MODE_HEAT,
|
||||
"DRY": ClimateMode.CLIMATE_MODE_DRY,
|
||||
"FAN_ONLY": ClimateMode.CLIMATE_MODE_FAN_ONLY,
|
||||
}
|
||||
validate_climate_mode = cv.enum(CLIMATE_MODES, upper=True)
|
||||
|
||||
ClimateFanMode = climate_ns.enum('ClimateFanMode')
|
||||
ClimateFanMode = climate_ns.enum("ClimateFanMode")
|
||||
CLIMATE_FAN_MODES = {
|
||||
'ON': ClimateFanMode.CLIMATE_FAN_ON,
|
||||
'OFF': ClimateFanMode.CLIMATE_FAN_OFF,
|
||||
'AUTO': ClimateFanMode.CLIMATE_FAN_AUTO,
|
||||
'LOW': ClimateFanMode.CLIMATE_FAN_LOW,
|
||||
'MEDIUM': ClimateFanMode.CLIMATE_FAN_MEDIUM,
|
||||
'HIGH': ClimateFanMode.CLIMATE_FAN_HIGH,
|
||||
'MIDDLE': ClimateFanMode.CLIMATE_FAN_MIDDLE,
|
||||
'FOCUS': ClimateFanMode.CLIMATE_FAN_FOCUS,
|
||||
'DIFFUSE': ClimateFanMode.CLIMATE_FAN_DIFFUSE,
|
||||
"ON": ClimateFanMode.CLIMATE_FAN_ON,
|
||||
"OFF": ClimateFanMode.CLIMATE_FAN_OFF,
|
||||
"AUTO": ClimateFanMode.CLIMATE_FAN_AUTO,
|
||||
"LOW": ClimateFanMode.CLIMATE_FAN_LOW,
|
||||
"MEDIUM": ClimateFanMode.CLIMATE_FAN_MEDIUM,
|
||||
"HIGH": ClimateFanMode.CLIMATE_FAN_HIGH,
|
||||
"MIDDLE": ClimateFanMode.CLIMATE_FAN_MIDDLE,
|
||||
"FOCUS": ClimateFanMode.CLIMATE_FAN_FOCUS,
|
||||
"DIFFUSE": ClimateFanMode.CLIMATE_FAN_DIFFUSE,
|
||||
}
|
||||
|
||||
validate_climate_fan_mode = cv.enum(CLIMATE_FAN_MODES, upper=True)
|
||||
|
||||
ClimateSwingMode = climate_ns.enum('ClimateSwingMode')
|
||||
ClimateSwingMode = climate_ns.enum("ClimateSwingMode")
|
||||
CLIMATE_SWING_MODES = {
|
||||
'OFF': ClimateSwingMode.CLIMATE_SWING_OFF,
|
||||
'BOTH': ClimateSwingMode.CLIMATE_SWING_BOTH,
|
||||
'VERTICAL': ClimateSwingMode.CLIMATE_SWING_VERTICAL,
|
||||
'HORIZONTAL': ClimateSwingMode.CLIMATE_SWING_HORIZONTAL,
|
||||
"OFF": ClimateSwingMode.CLIMATE_SWING_OFF,
|
||||
"BOTH": ClimateSwingMode.CLIMATE_SWING_BOTH,
|
||||
"VERTICAL": ClimateSwingMode.CLIMATE_SWING_VERTICAL,
|
||||
"HORIZONTAL": ClimateSwingMode.CLIMATE_SWING_HORIZONTAL,
|
||||
}
|
||||
|
||||
validate_climate_swing_mode = cv.enum(CLIMATE_SWING_MODES, upper=True)
|
||||
|
||||
# Actions
|
||||
ControlAction = climate_ns.class_('ControlAction', automation.Action)
|
||||
ControlAction = climate_ns.class_("ControlAction", automation.Action)
|
||||
|
||||
CLIMATE_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(Climate),
|
||||
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTClimateComponent),
|
||||
cv.Optional(CONF_VISUAL, default={}): cv.Schema({
|
||||
cv.Optional(CONF_MIN_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_MAX_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_TEMPERATURE_STEP): cv.temperature,
|
||||
}),
|
||||
# TODO: MQTT topic options
|
||||
})
|
||||
CLIMATE_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Climate),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTClimateComponent),
|
||||
cv.Optional(CONF_VISUAL, default={}): cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_MIN_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_MAX_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_TEMPERATURE_STEP): cv.temperature,
|
||||
}
|
||||
),
|
||||
# TODO: MQTT topic options
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -94,19 +111,23 @@ def register_climate(var, config):
|
||||
yield setup_climate_core_(var, config)
|
||||
|
||||
|
||||
CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(Climate),
|
||||
cv.Optional(CONF_MODE): cv.templatable(validate_climate_mode),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE_LOW): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE_HIGH): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_AWAY): cv.templatable(cv.boolean),
|
||||
cv.Optional(CONF_FAN_MODE): cv.templatable(validate_climate_fan_mode),
|
||||
cv.Optional(CONF_SWING_MODE): cv.templatable(validate_climate_swing_mode),
|
||||
})
|
||||
CLIMATE_CONTROL_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(Climate),
|
||||
cv.Optional(CONF_MODE): cv.templatable(validate_climate_mode),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE_LOW): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_TARGET_TEMPERATURE_HIGH): cv.templatable(cv.temperature),
|
||||
cv.Optional(CONF_AWAY): cv.templatable(cv.boolean),
|
||||
cv.Optional(CONF_FAN_MODE): cv.templatable(validate_climate_fan_mode),
|
||||
cv.Optional(CONF_SWING_MODE): cv.templatable(validate_climate_swing_mode),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('climate.control', ControlAction, CLIMATE_CONTROL_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"climate.control", ControlAction, CLIMATE_CONTROL_ACTION_SCHEMA
|
||||
)
|
||||
def climate_control_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -117,10 +138,14 @@ def climate_control_to_code(config, action_id, template_arg, args):
|
||||
template_ = yield cg.templatable(config[CONF_TARGET_TEMPERATURE], args, float)
|
||||
cg.add(var.set_target_temperature(template_))
|
||||
if CONF_TARGET_TEMPERATURE_LOW in config:
|
||||
template_ = yield cg.templatable(config[CONF_TARGET_TEMPERATURE_LOW], args, float)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_TARGET_TEMPERATURE_LOW], args, float
|
||||
)
|
||||
cg.add(var.set_target_temperature_low(template_))
|
||||
if CONF_TARGET_TEMPERATURE_HIGH in config:
|
||||
template_ = yield cg.templatable(config[CONF_TARGET_TEMPERATURE_HIGH], args, float)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_TARGET_TEMPERATURE_HIGH], args, float
|
||||
)
|
||||
cg.add(var.set_target_temperature_high(template_))
|
||||
if CONF_AWAY in config:
|
||||
template_ = yield cg.templatable(config[CONF_AWAY], args, bool)
|
||||
@ -129,12 +154,14 @@ def climate_control_to_code(config, action_id, template_arg, args):
|
||||
template_ = yield cg.templatable(config[CONF_FAN_MODE], args, ClimateFanMode)
|
||||
cg.add(var.set_fan_mode(template_))
|
||||
if CONF_SWING_MODE in config:
|
||||
template_ = yield cg.templatable(config[CONF_SWING_MODE], args, ClimateSwingMode)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_SWING_MODE], args, ClimateSwingMode
|
||||
)
|
||||
cg.add(var.set_swing_mode(template_))
|
||||
yield var
|
||||
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_define('USE_CLIMATE')
|
||||
cg.add_define("USE_CLIMATE")
|
||||
cg.add_global(climate_ns.using)
|
||||
|
@ -1,27 +1,42 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import climate, remote_transmitter, remote_receiver, sensor, remote_base
|
||||
from esphome.components import (
|
||||
climate,
|
||||
remote_transmitter,
|
||||
remote_receiver,
|
||||
sensor,
|
||||
remote_base,
|
||||
)
|
||||
from esphome.components.remote_base import CONF_RECEIVER_ID, CONF_TRANSMITTER_ID
|
||||
from esphome.const import CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT, CONF_SENSOR
|
||||
from esphome.core import coroutine
|
||||
|
||||
AUTO_LOAD = ['sensor', 'remote_base']
|
||||
CODEOWNERS = ['@glmnet']
|
||||
AUTO_LOAD = ["sensor", "remote_base"]
|
||||
CODEOWNERS = ["@glmnet"]
|
||||
|
||||
climate_ir_ns = cg.esphome_ns.namespace('climate_ir')
|
||||
ClimateIR = climate_ir_ns.class_('ClimateIR', climate.Climate, cg.Component,
|
||||
remote_base.RemoteReceiverListener)
|
||||
climate_ir_ns = cg.esphome_ns.namespace("climate_ir")
|
||||
ClimateIR = climate_ir_ns.class_(
|
||||
"ClimateIR", climate.Climate, cg.Component, remote_base.RemoteReceiverListener
|
||||
)
|
||||
|
||||
CLIMATE_IR_SCHEMA = climate.CLIMATE_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),
|
||||
cv.Optional(CONF_SUPPORTS_COOL, default=True): cv.boolean,
|
||||
cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
|
||||
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CLIMATE_IR_SCHEMA = climate.CLIMATE_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(
|
||||
remote_transmitter.RemoteTransmitterComponent
|
||||
),
|
||||
cv.Optional(CONF_SUPPORTS_COOL, default=True): cv.boolean,
|
||||
cv.Optional(CONF_SUPPORTS_HEAT, default=True): cv.boolean,
|
||||
cv.Optional(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
CLIMATE_IR_WITH_RECEIVER_SCHEMA = CLIMATE_IR_SCHEMA.extend({
|
||||
cv.Optional(CONF_RECEIVER_ID): cv.use_id(remote_receiver.RemoteReceiverComponent),
|
||||
})
|
||||
CLIMATE_IR_WITH_RECEIVER_SCHEMA = CLIMATE_IR_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_RECEIVER_ID): cv.use_id(
|
||||
remote_receiver.RemoteReceiverComponent
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
|
@ -3,25 +3,37 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
|
||||
climate_ir_lg_ns = cg.esphome_ns.namespace('climate_ir_lg')
|
||||
LgIrClimate = climate_ir_lg_ns.class_('LgIrClimate', climate_ir.ClimateIR)
|
||||
climate_ir_lg_ns = cg.esphome_ns.namespace("climate_ir_lg")
|
||||
LgIrClimate = climate_ir_lg_ns.class_("LgIrClimate", climate_ir.ClimateIR)
|
||||
|
||||
CONF_HEADER_HIGH = 'header_high'
|
||||
CONF_HEADER_LOW = 'header_low'
|
||||
CONF_BIT_HIGH = 'bit_high'
|
||||
CONF_BIT_ONE_LOW = 'bit_one_low'
|
||||
CONF_BIT_ZERO_LOW = 'bit_zero_low'
|
||||
CONF_HEADER_HIGH = "header_high"
|
||||
CONF_HEADER_LOW = "header_low"
|
||||
CONF_BIT_HIGH = "bit_high"
|
||||
CONF_BIT_ONE_LOW = "bit_one_low"
|
||||
CONF_BIT_ZERO_LOW = "bit_zero_low"
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(LgIrClimate),
|
||||
cv.Optional(CONF_HEADER_HIGH, default='8000us'): cv.positive_time_period_microseconds,
|
||||
cv.Optional(CONF_HEADER_LOW, default='4000us'): cv.positive_time_period_microseconds,
|
||||
cv.Optional(CONF_BIT_HIGH, default='600us'): cv.positive_time_period_microseconds,
|
||||
cv.Optional(CONF_BIT_ONE_LOW, default='1600us'): cv.positive_time_period_microseconds,
|
||||
cv.Optional(CONF_BIT_ZERO_LOW, default='550us'): cv.positive_time_period_microseconds,
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(LgIrClimate),
|
||||
cv.Optional(
|
||||
CONF_HEADER_HIGH, default="8000us"
|
||||
): cv.positive_time_period_microseconds,
|
||||
cv.Optional(
|
||||
CONF_HEADER_LOW, default="4000us"
|
||||
): cv.positive_time_period_microseconds,
|
||||
cv.Optional(
|
||||
CONF_BIT_HIGH, default="600us"
|
||||
): cv.positive_time_period_microseconds,
|
||||
cv.Optional(
|
||||
CONF_BIT_ONE_LOW, default="1600us"
|
||||
): cv.positive_time_period_microseconds,
|
||||
cv.Optional(
|
||||
CONF_BIT_ZERO_LOW, default="550us"
|
||||
): cv.positive_time_period_microseconds,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -14,14 +14,14 @@ CONF_WHITE_INT = "white_int"
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(ColorStruct),
|
||||
cv.Exclusive(CONF_RED, 'red'): cv.percentage,
|
||||
cv.Exclusive(CONF_RED_INT, 'red'): cv.uint8_t,
|
||||
cv.Exclusive(CONF_GREEN, 'green'): cv.percentage,
|
||||
cv.Exclusive(CONF_GREEN_INT, 'green'): cv.uint8_t,
|
||||
cv.Exclusive(CONF_BLUE, 'blue'): cv.percentage,
|
||||
cv.Exclusive(CONF_BLUE_INT, 'blue'): cv.uint8_t,
|
||||
cv.Exclusive(CONF_WHITE, 'white'): cv.percentage,
|
||||
cv.Exclusive(CONF_WHITE_INT, 'white'): cv.uint8_t,
|
||||
cv.Exclusive(CONF_RED, "red"): cv.percentage,
|
||||
cv.Exclusive(CONF_RED_INT, "red"): cv.uint8_t,
|
||||
cv.Exclusive(CONF_GREEN, "green"): cv.percentage,
|
||||
cv.Exclusive(CONF_GREEN_INT, "green"): cv.uint8_t,
|
||||
cv.Exclusive(CONF_BLUE, "blue"): cv.percentage,
|
||||
cv.Exclusive(CONF_BLUE_INT, "blue"): cv.uint8_t,
|
||||
cv.Exclusive(CONF_WHITE, "white"): cv.percentage,
|
||||
cv.Exclusive(CONF_WHITE_INT, "white"): cv.uint8_t,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
@ -29,31 +29,29 @@ CONFIG_SCHEMA = cv.Schema(
|
||||
def to_code(config):
|
||||
r = 0
|
||||
if CONF_RED in config:
|
||||
r = int(config[CONF_RED]*255)
|
||||
r = int(config[CONF_RED] * 255)
|
||||
elif CONF_RED_INT in config:
|
||||
r = config[CONF_RED_INT]
|
||||
|
||||
g = 0
|
||||
if CONF_GREEN in config:
|
||||
g = int(config[CONF_GREEN]*255)
|
||||
g = int(config[CONF_GREEN] * 255)
|
||||
elif CONF_GREEN_INT in config:
|
||||
g = config[CONF_GREEN_INT]
|
||||
|
||||
b = 0
|
||||
if CONF_BLUE in config:
|
||||
b = int(config[CONF_BLUE]*255)
|
||||
b = int(config[CONF_BLUE] * 255)
|
||||
elif CONF_BLUE_INT in config:
|
||||
b = config[CONF_BLUE_INT]
|
||||
|
||||
w = 0
|
||||
if CONF_WHITE in config:
|
||||
w = int(config[CONF_WHITE]*255)
|
||||
w = int(config[CONF_WHITE] * 255)
|
||||
elif CONF_WHITE_INT in config:
|
||||
w = config[CONF_WHITE_INT]
|
||||
|
||||
cg.variable(config[CONF_ID], cg.StructInitializer(
|
||||
ColorStruct,
|
||||
('r', r),
|
||||
('g', g),
|
||||
('b', b),
|
||||
('w', w)))
|
||||
cg.variable(
|
||||
config[CONF_ID],
|
||||
cg.StructInitializer(ColorStruct, ("r", r), ("g", g), ("b", b), ("w", w)),
|
||||
)
|
||||
|
@ -3,15 +3,17 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
CODEOWNERS = ['@glmnet']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
CODEOWNERS = ["@glmnet"]
|
||||
|
||||
coolix_ns = cg.esphome_ns.namespace('coolix')
|
||||
CoolixClimate = coolix_ns.class_('CoolixClimate', climate_ir.ClimateIR)
|
||||
coolix_ns = cg.esphome_ns.namespace("coolix")
|
||||
CoolixClimate = coolix_ns.class_("CoolixClimate", climate_ir.ClimateIR)
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(CoolixClimate),
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CoolixClimate),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,54 +3,74 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id, Condition
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_DEVICE_CLASS, CONF_STATE, \
|
||||
CONF_POSITION, CONF_TILT, CONF_STOP, CONF_MQTT_ID, CONF_NAME
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_DEVICE_CLASS,
|
||||
CONF_STATE,
|
||||
CONF_POSITION,
|
||||
CONF_TILT,
|
||||
CONF_STOP,
|
||||
CONF_MQTT_ID,
|
||||
CONF_NAME,
|
||||
)
|
||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
DEVICE_CLASSES = [
|
||||
'', 'awning', 'blind', 'curtain', 'damper', 'door', 'garage',
|
||||
'gate', 'shade', 'shutter', 'window'
|
||||
"",
|
||||
"awning",
|
||||
"blind",
|
||||
"curtain",
|
||||
"damper",
|
||||
"door",
|
||||
"garage",
|
||||
"gate",
|
||||
"shade",
|
||||
"shutter",
|
||||
"window",
|
||||
]
|
||||
|
||||
cover_ns = cg.esphome_ns.namespace('cover')
|
||||
cover_ns = cg.esphome_ns.namespace("cover")
|
||||
|
||||
Cover = cover_ns.class_('Cover', cg.Nameable)
|
||||
Cover = cover_ns.class_("Cover", cg.Nameable)
|
||||
|
||||
COVER_OPEN = cover_ns.COVER_OPEN
|
||||
COVER_CLOSED = cover_ns.COVER_CLOSED
|
||||
|
||||
COVER_STATES = {
|
||||
'OPEN': COVER_OPEN,
|
||||
'CLOSED': COVER_CLOSED,
|
||||
"OPEN": COVER_OPEN,
|
||||
"CLOSED": COVER_CLOSED,
|
||||
}
|
||||
validate_cover_state = cv.enum(COVER_STATES, upper=True)
|
||||
|
||||
CoverOperation = cover_ns.enum('CoverOperation')
|
||||
CoverOperation = cover_ns.enum("CoverOperation")
|
||||
COVER_OPERATIONS = {
|
||||
'IDLE': CoverOperation.COVER_OPERATION_IDLE,
|
||||
'OPENING': CoverOperation.COVER_OPERATION_OPENING,
|
||||
'CLOSING': CoverOperation.COVER_OPERATION_CLOSING,
|
||||
"IDLE": CoverOperation.COVER_OPERATION_IDLE,
|
||||
"OPENING": CoverOperation.COVER_OPERATION_OPENING,
|
||||
"CLOSING": CoverOperation.COVER_OPERATION_CLOSING,
|
||||
}
|
||||
validate_cover_operation = cv.enum(COVER_OPERATIONS, upper=True)
|
||||
|
||||
# Actions
|
||||
OpenAction = cover_ns.class_('OpenAction', automation.Action)
|
||||
CloseAction = cover_ns.class_('CloseAction', automation.Action)
|
||||
StopAction = cover_ns.class_('StopAction', automation.Action)
|
||||
ControlAction = cover_ns.class_('ControlAction', automation.Action)
|
||||
CoverPublishAction = cover_ns.class_('CoverPublishAction', automation.Action)
|
||||
CoverIsOpenCondition = cover_ns.class_('CoverIsOpenCondition', Condition)
|
||||
CoverIsClosedCondition = cover_ns.class_('CoverIsClosedCondition', Condition)
|
||||
OpenAction = cover_ns.class_("OpenAction", automation.Action)
|
||||
CloseAction = cover_ns.class_("CloseAction", automation.Action)
|
||||
StopAction = cover_ns.class_("StopAction", automation.Action)
|
||||
ControlAction = cover_ns.class_("ControlAction", automation.Action)
|
||||
CoverPublishAction = cover_ns.class_("CoverPublishAction", automation.Action)
|
||||
CoverIsOpenCondition = cover_ns.class_("CoverIsOpenCondition", Condition)
|
||||
CoverIsClosedCondition = cover_ns.class_("CoverIsClosedCondition", Condition)
|
||||
|
||||
COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(Cover),
|
||||
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTCoverComponent),
|
||||
cv.Optional(CONF_DEVICE_CLASS): cv.one_of(*DEVICE_CLASSES, lower=True),
|
||||
# TODO: MQTT topic options
|
||||
})
|
||||
COVER_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Cover),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTCoverComponent),
|
||||
cv.Optional(CONF_DEVICE_CLASS): cv.one_of(*DEVICE_CLASSES, lower=True),
|
||||
# TODO: MQTT topic options
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -74,39 +94,43 @@ def register_cover(var, config):
|
||||
yield setup_cover_core_(var, config)
|
||||
|
||||
|
||||
COVER_ACTION_SCHEMA = maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(Cover),
|
||||
})
|
||||
COVER_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(Cover),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('cover.open', OpenAction, COVER_ACTION_SCHEMA)
|
||||
@automation.register_action("cover.open", OpenAction, COVER_ACTION_SCHEMA)
|
||||
def cover_open_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('cover.close', CloseAction, COVER_ACTION_SCHEMA)
|
||||
@automation.register_action("cover.close", CloseAction, COVER_ACTION_SCHEMA)
|
||||
def cover_close_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('cover.stop', StopAction, COVER_ACTION_SCHEMA)
|
||||
@automation.register_action("cover.stop", StopAction, COVER_ACTION_SCHEMA)
|
||||
def cover_stop_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
COVER_CONTROL_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(Cover),
|
||||
cv.Optional(CONF_STOP): cv.templatable(cv.boolean),
|
||||
cv.Exclusive(CONF_STATE, 'pos'): cv.templatable(validate_cover_state),
|
||||
cv.Exclusive(CONF_POSITION, 'pos'): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_TILT): cv.templatable(cv.percentage),
|
||||
})
|
||||
COVER_CONTROL_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(Cover),
|
||||
cv.Optional(CONF_STOP): cv.templatable(cv.boolean),
|
||||
cv.Exclusive(CONF_STATE, "pos"): cv.templatable(validate_cover_state),
|
||||
cv.Exclusive(CONF_POSITION, "pos"): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_TILT): cv.templatable(cv.percentage),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('cover.control', ControlAction, COVER_CONTROL_ACTION_SCHEMA)
|
||||
@automation.register_action("cover.control", ControlAction, COVER_CONTROL_ACTION_SCHEMA)
|
||||
def cover_control_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -127,5 +151,5 @@ def cover_control_to_code(config, action_id, template_arg, args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_define('USE_COVER')
|
||||
cg.add_define("USE_COVER")
|
||||
cg.add_global(cover_ns.using)
|
||||
|
@ -1,22 +1,45 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, uart
|
||||
from esphome.const import CONF_CURRENT, CONF_ID, CONF_POWER, CONF_VOLTAGE, DEVICE_CLASS_CURRENT, \
|
||||
DEVICE_CLASS_POWER, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
|
||||
from esphome.const import (
|
||||
CONF_CURRENT,
|
||||
CONF_ID,
|
||||
CONF_POWER,
|
||||
CONF_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
cse7766_ns = cg.esphome_ns.namespace('cse7766')
|
||||
CSE7766Component = cse7766_ns.class_('CSE7766Component', cg.PollingComponent, uart.UARTDevice)
|
||||
cse7766_ns = cg.esphome_ns.namespace("cse7766")
|
||||
CSE7766Component = cse7766_ns.class_(
|
||||
"CSE7766Component", cg.PollingComponent, uart.UARTDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CSE7766Component),
|
||||
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CSE7766Component),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,35 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_SENSOR, CONF_ID, DEVICE_CLASS_CURRENT, ICON_EMPTY, UNIT_AMPERE
|
||||
from esphome.const import (
|
||||
CONF_SENSOR,
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
ICON_EMPTY,
|
||||
UNIT_AMPERE,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['voltage_sampler']
|
||||
CODEOWNERS = ['@jesserockz']
|
||||
AUTO_LOAD = ["voltage_sampler"]
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
||||
CONF_SAMPLE_DURATION = 'sample_duration'
|
||||
CONF_SAMPLE_DURATION = "sample_duration"
|
||||
|
||||
ct_clamp_ns = cg.esphome_ns.namespace('ct_clamp')
|
||||
CTClampSensor = ct_clamp_ns.class_('CTClampSensor', sensor.Sensor, cg.PollingComponent)
|
||||
ct_clamp_ns = cg.esphome_ns.namespace("ct_clamp")
|
||||
CTClampSensor = ct_clamp_ns.class_("CTClampSensor", sensor.Sensor, cg.PollingComponent)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT).extend({
|
||||
cv.GenerateID(): cv.declare_id(CTClampSensor),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(voltage_sampler.VoltageSampler),
|
||||
cv.Optional(CONF_SAMPLE_DURATION, default='200ms'): cv.positive_time_period_milliseconds,
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CTClampSensor),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(voltage_sampler.VoltageSampler),
|
||||
cv.Optional(
|
||||
CONF_SAMPLE_DURATION, default="200ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,3 +1,3 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
custom_ns = cg.esphome_ns.namespace('custom')
|
||||
custom_ns = cg.esphome_ns.namespace("custom")
|
||||
|
@ -4,18 +4,25 @@ from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_BINARY_SENSORS, CONF_ID, CONF_LAMBDA
|
||||
from .. import custom_ns
|
||||
|
||||
CustomBinarySensorConstructor = custom_ns.class_('CustomBinarySensorConstructor')
|
||||
CustomBinarySensorConstructor = custom_ns.class_("CustomBinarySensorConstructor")
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomBinarySensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_BINARY_SENSORS): cv.ensure_list(binary_sensor.BINARY_SENSOR_SCHEMA),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomBinarySensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_BINARY_SENSORS): cv.ensure_list(
|
||||
binary_sensor.BINARY_SENSOR_SCHEMA
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(binary_sensor.BinarySensorPtr))
|
||||
config[CONF_LAMBDA],
|
||||
[],
|
||||
return_type=cg.std_vector.template(binary_sensor.BinarySensorPtr),
|
||||
)
|
||||
|
||||
rhs = CustomBinarySensorConstructor(template_)
|
||||
custom = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,20 +4,24 @@ from esphome.components import climate
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||
from .. import custom_ns
|
||||
|
||||
CustomClimateConstructor = custom_ns.class_('CustomClimateConstructor')
|
||||
CONF_CLIMATES = 'climates'
|
||||
CustomClimateConstructor = custom_ns.class_("CustomClimateConstructor")
|
||||
CONF_CLIMATES = "climates"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomClimateConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_CLIMATES): cv.ensure_list(climate.CLIMATE_SCHEMA),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomClimateConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_CLIMATES): cv.ensure_list(climate.CLIMATE_SCHEMA),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [],
|
||||
return_type=cg.std_vector.template(climate.Climate.operator('ptr')))
|
||||
config[CONF_LAMBDA],
|
||||
[],
|
||||
return_type=cg.std_vector.template(climate.Climate.operator("ptr")),
|
||||
)
|
||||
|
||||
rhs = CustomClimateConstructor(template_)
|
||||
custom = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,20 +4,24 @@ from esphome.components import cover
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||
from .. import custom_ns
|
||||
|
||||
CustomCoverConstructor = custom_ns.class_('CustomCoverConstructor')
|
||||
CONF_COVERS = 'covers'
|
||||
CustomCoverConstructor = custom_ns.class_("CustomCoverConstructor")
|
||||
CONF_COVERS = "covers"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomCoverConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_COVERS): cv.ensure_list(cover.COVER_SCHEMA),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomCoverConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_COVERS): cv.ensure_list(cover.COVER_SCHEMA),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [],
|
||||
return_type=cg.std_vector.template(cover.Cover.operator('ptr')))
|
||||
config[CONF_LAMBDA],
|
||||
[],
|
||||
return_type=cg.std_vector.template(cover.Cover.operator("ptr")),
|
||||
)
|
||||
|
||||
rhs = CustomCoverConstructor(template_)
|
||||
custom = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,20 +4,24 @@ from esphome.components import light
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||
from .. import custom_ns
|
||||
|
||||
CustomLightOutputConstructor = custom_ns.class_('CustomLightOutputConstructor')
|
||||
CONF_LIGHTS = 'lights'
|
||||
CustomLightOutputConstructor = custom_ns.class_("CustomLightOutputConstructor")
|
||||
CONF_LIGHTS = "lights"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomLightOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_LIGHTS): cv.ensure_list(light.ADDRESSABLE_LIGHT_SCHEMA),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomLightOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_LIGHTS): cv.ensure_list(light.ADDRESSABLE_LIGHT_SCHEMA),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [],
|
||||
return_type=cg.std_vector.template(light.LightOutput.operator('ptr')))
|
||||
config[CONF_LAMBDA],
|
||||
[],
|
||||
return_type=cg.std_vector.template(light.LightOutput.operator("ptr")),
|
||||
)
|
||||
|
||||
rhs = CustomLightOutputConstructor(template_)
|
||||
custom = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,41 +4,55 @@ from esphome.components import output
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE, CONF_BINARY
|
||||
from .. import custom_ns
|
||||
|
||||
CustomBinaryOutputConstructor = custom_ns.class_('CustomBinaryOutputConstructor')
|
||||
CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor')
|
||||
CustomBinaryOutputConstructor = custom_ns.class_("CustomBinaryOutputConstructor")
|
||||
CustomFloatOutputConstructor = custom_ns.class_("CustomFloatOutputConstructor")
|
||||
|
||||
CONF_FLOAT = 'float'
|
||||
CONF_FLOAT = "float"
|
||||
|
||||
CONFIG_SCHEMA = cv.typed_schema({
|
||||
CONF_BINARY: cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomBinaryOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_OUTPUTS):
|
||||
cv.ensure_list(output.BINARY_OUTPUT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(output.BinaryOutput),
|
||||
})),
|
||||
}),
|
||||
CONF_FLOAT: cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomFloatOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_OUTPUTS):
|
||||
cv.ensure_list(output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(output.FloatOutput),
|
||||
})),
|
||||
})
|
||||
}, lower=True)
|
||||
CONFIG_SCHEMA = cv.typed_schema(
|
||||
{
|
||||
CONF_BINARY: cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomBinaryOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_OUTPUTS): cv.ensure_list(
|
||||
output.BINARY_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(output.BinaryOutput),
|
||||
}
|
||||
)
|
||||
),
|
||||
}
|
||||
),
|
||||
CONF_FLOAT: cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomFloatOutputConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_OUTPUTS): cv.ensure_list(
|
||||
output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(output.FloatOutput),
|
||||
}
|
||||
)
|
||||
),
|
||||
}
|
||||
),
|
||||
},
|
||||
lower=True,
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
type = config[CONF_TYPE]
|
||||
if type == 'binary':
|
||||
if type == "binary":
|
||||
ret_type = output.BinaryOutputPtr
|
||||
klass = CustomBinaryOutputConstructor
|
||||
else:
|
||||
ret_type = output.FloatOutputPtr
|
||||
klass = CustomFloatOutputConstructor
|
||||
template_ = yield cg.process_lambda(config[CONF_LAMBDA], [],
|
||||
return_type=cg.std_vector.template(ret_type))
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(ret_type)
|
||||
)
|
||||
|
||||
rhs = klass(template_)
|
||||
custom = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,18 +4,21 @@ from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_SENSORS
|
||||
from .. import custom_ns
|
||||
|
||||
CustomSensorConstructor = custom_ns.class_('CustomSensorConstructor')
|
||||
CustomSensorConstructor = custom_ns.class_("CustomSensorConstructor")
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SENSORS): cv.ensure_list(sensor.SENSOR_SCHEMA),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SENSORS): cv.ensure_list(sensor.SENSOR_SCHEMA),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(sensor.SensorPtr))
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(sensor.SensorPtr)
|
||||
)
|
||||
|
||||
rhs = CustomSensorConstructor(template_)
|
||||
var = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,21 +4,27 @@ from esphome.components import switch
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_SWITCHES
|
||||
from .. import custom_ns
|
||||
|
||||
CustomSwitchConstructor = custom_ns.class_('CustomSwitchConstructor')
|
||||
CustomSwitchConstructor = custom_ns.class_("CustomSwitchConstructor")
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomSwitchConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SWITCHES):
|
||||
cv.ensure_list(switch.SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(switch.Switch),
|
||||
})),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomSwitchConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_SWITCHES): cv.ensure_list(
|
||||
switch.SWITCH_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(switch.Switch),
|
||||
}
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(switch.SwitchPtr))
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(switch.SwitchPtr)
|
||||
)
|
||||
|
||||
rhs = CustomSwitchConstructor(template_)
|
||||
var = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -4,21 +4,29 @@ from esphome.components import text_sensor
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_TEXT_SENSORS
|
||||
from .. import custom_ns
|
||||
|
||||
CustomTextSensorConstructor = custom_ns.class_('CustomTextSensorConstructor')
|
||||
CustomTextSensorConstructor = custom_ns.class_("CustomTextSensorConstructor")
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomTextSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_TEXT_SENSORS):
|
||||
cv.ensure_list(text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
})),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomTextSensorConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Required(CONF_TEXT_SENSORS): cv.ensure_list(
|
||||
text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(text_sensor.TextSensor),
|
||||
}
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(text_sensor.TextSensorPtr))
|
||||
config[CONF_LAMBDA],
|
||||
[],
|
||||
return_type=cg.std_vector.template(text_sensor.TextSensorPtr),
|
||||
)
|
||||
|
||||
rhs = CustomTextSensorConstructor(template_)
|
||||
var = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -2,22 +2,27 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_COMPONENTS, CONF_ID, CONF_LAMBDA
|
||||
|
||||
custom_component_ns = cg.esphome_ns.namespace('custom_component')
|
||||
CustomComponentConstructor = custom_component_ns.class_('CustomComponentConstructor')
|
||||
custom_component_ns = cg.esphome_ns.namespace("custom_component")
|
||||
CustomComponentConstructor = custom_component_ns.class_("CustomComponentConstructor")
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(CustomComponentConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Optional(CONF_COMPONENTS): cv.ensure_list(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(cg.Component)
|
||||
}).extend(cv.COMPONENT_SCHEMA)),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(CustomComponentConstructor),
|
||||
cv.Required(CONF_LAMBDA): cv.returning_lambda,
|
||||
cv.Optional(CONF_COMPONENTS): cv.ensure_list(
|
||||
cv.Schema({cv.GenerateID(): cv.declare_id(cg.Component)}).extend(
|
||||
cv.COMPONENT_SCHEMA
|
||||
)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
template_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(cg.ComponentPtr))
|
||||
config[CONF_LAMBDA], [], return_type=cg.std_vector.template(cg.ComponentPtr)
|
||||
)
|
||||
|
||||
rhs = CustomComponentConstructor(template_)
|
||||
var = cg.variable(config[CONF_ID], rhs)
|
||||
|
@ -1,22 +1,29 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_COLD_WHITE, CONF_WARM_WHITE, \
|
||||
CONF_COLD_WHITE_COLOR_TEMPERATURE, CONF_WARM_WHITE_COLOR_TEMPERATURE
|
||||
from esphome.const import (
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_COLD_WHITE,
|
||||
CONF_WARM_WHITE,
|
||||
CONF_COLD_WHITE_COLOR_TEMPERATURE,
|
||||
CONF_WARM_WHITE_COLOR_TEMPERATURE,
|
||||
)
|
||||
|
||||
cwww_ns = cg.esphome_ns.namespace('cwww')
|
||||
CWWWLightOutput = cwww_ns.class_('CWWWLightOutput', light.LightOutput)
|
||||
cwww_ns = cg.esphome_ns.namespace("cwww")
|
||||
CWWWLightOutput = cwww_ns.class_("CWWWLightOutput", light.LightOutput)
|
||||
|
||||
CONF_CONSTANT_BRIGHTNESS = 'constant_brightness'
|
||||
CONF_CONSTANT_BRIGHTNESS = "constant_brightness"
|
||||
|
||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CWWWLightOutput),
|
||||
cv.Required(CONF_COLD_WHITE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Optional(CONF_CONSTANT_BRIGHTNESS, default=False): cv.boolean,
|
||||
})
|
||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(CWWWLightOutput),
|
||||
cv.Required(CONF_COLD_WHITE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_WARM_WHITE): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_COLD_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Required(CONF_WARM_WHITE_COLOR_TEMPERATURE): cv.color_temperature,
|
||||
cv.Optional(CONF_CONSTANT_BRIGHTNESS, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,14 +3,16 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
|
||||
daikin_ns = cg.esphome_ns.namespace('daikin')
|
||||
DaikinClimate = daikin_ns.class_('DaikinClimate', climate_ir.ClimateIR)
|
||||
daikin_ns = cg.esphome_ns.namespace("daikin")
|
||||
DaikinClimate = daikin_ns.class_("DaikinClimate", climate_ir.ClimateIR)
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(DaikinClimate),
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DaikinClimate),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,18 +4,20 @@ from esphome import pins
|
||||
from esphome.const import CONF_ID, CONF_PIN
|
||||
|
||||
MULTI_CONF = True
|
||||
AUTO_LOAD = ['sensor']
|
||||
AUTO_LOAD = ["sensor"]
|
||||
|
||||
CONF_ONE_WIRE_ID = 'one_wire_id'
|
||||
dallas_ns = cg.esphome_ns.namespace('dallas')
|
||||
DallasComponent = dallas_ns.class_('DallasComponent', cg.PollingComponent)
|
||||
ESPOneWire = dallas_ns.class_('ESPOneWire')
|
||||
CONF_ONE_WIRE_ID = "one_wire_id"
|
||||
dallas_ns = cg.esphome_ns.namespace("dallas")
|
||||
DallasComponent = dallas_ns.class_("DallasComponent", cg.PollingComponent)
|
||||
ESPOneWire = dallas_ns.class_("ESPOneWire")
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DallasComponent),
|
||||
cv.GenerateID(CONF_ONE_WIRE_ID): cv.declare_id(ESPOneWire),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema,
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DallasComponent),
|
||||
cv.GenerateID(CONF_ONE_WIRE_ID): cv.declare_id(ESPOneWire),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema,
|
||||
}
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,22 +1,32 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ADDRESS, CONF_DALLAS_ID, CONF_INDEX, CONF_RESOLUTION, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_DALLAS_ID,
|
||||
CONF_INDEX,
|
||||
CONF_RESOLUTION,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
CONF_ID,
|
||||
)
|
||||
from . import DallasComponent, dallas_ns
|
||||
|
||||
DallasTemperatureSensor = dallas_ns.class_('DallasTemperatureSensor', sensor.Sensor)
|
||||
DallasTemperatureSensor = dallas_ns.class_("DallasTemperatureSensor", sensor.Sensor)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
).extend({
|
||||
cv.GenerateID(): cv.declare_id(DallasTemperatureSensor),
|
||||
cv.GenerateID(CONF_DALLAS_ID): cv.use_id(DallasComponent),
|
||||
|
||||
cv.Optional(CONF_ADDRESS): cv.hex_int,
|
||||
cv.Optional(CONF_INDEX): cv.positive_int,
|
||||
cv.Optional(CONF_RESOLUTION, default=12): cv.int_range(min=9, max=12),
|
||||
}), cv.has_exactly_one_key(CONF_ADDRESS, CONF_INDEX))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DallasTemperatureSensor),
|
||||
cv.GenerateID(CONF_DALLAS_ID): cv.use_id(DallasComponent),
|
||||
cv.Optional(CONF_ADDRESS): cv.hex_int,
|
||||
cv.Optional(CONF_INDEX): cv.positive_int,
|
||||
cv.Optional(CONF_RESOLUTION, default=12): cv.int_range(min=9, max=12),
|
||||
}
|
||||
),
|
||||
cv.has_exactly_one_key(CONF_ADDRESS, CONF_INDEX),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,14 +2,16 @@ import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
DEPENDENCIES = ['logger']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
DEPENDENCIES = ["logger"]
|
||||
|
||||
debug_ns = cg.esphome_ns.namespace('debug')
|
||||
DebugComponent = debug_ns.class_('DebugComponent', cg.Component)
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DebugComponent),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
debug_ns = cg.esphome_ns.namespace("debug")
|
||||
DebugComponent = debug_ns.class_("DebugComponent", cg.Component)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DebugComponent),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,58 +1,81 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins, automation
|
||||
from esphome.const import CONF_ID, CONF_MODE, CONF_NUMBER, CONF_PINS, CONF_RUN_CYCLES, \
|
||||
CONF_RUN_DURATION, CONF_SLEEP_DURATION, CONF_WAKEUP_PIN
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_MODE,
|
||||
CONF_NUMBER,
|
||||
CONF_PINS,
|
||||
CONF_RUN_CYCLES,
|
||||
CONF_RUN_DURATION,
|
||||
CONF_SLEEP_DURATION,
|
||||
CONF_WAKEUP_PIN,
|
||||
)
|
||||
|
||||
|
||||
def validate_pin_number(value):
|
||||
valid_pins = [0, 2, 4, 12, 13, 14, 15, 25, 26, 27, 32, 33, 34, 35, 36, 37, 38, 39]
|
||||
if value[CONF_NUMBER] not in valid_pins:
|
||||
raise cv.Invalid("Only pins {} support wakeup"
|
||||
"".format(', '.join(str(x) for x in valid_pins)))
|
||||
raise cv.Invalid(
|
||||
"Only pins {} support wakeup"
|
||||
"".format(", ".join(str(x) for x in valid_pins))
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
deep_sleep_ns = cg.esphome_ns.namespace('deep_sleep')
|
||||
DeepSleepComponent = deep_sleep_ns.class_('DeepSleepComponent', cg.Component)
|
||||
EnterDeepSleepAction = deep_sleep_ns.class_('EnterDeepSleepAction', automation.Action)
|
||||
PreventDeepSleepAction = deep_sleep_ns.class_('PreventDeepSleepAction', automation.Action)
|
||||
deep_sleep_ns = cg.esphome_ns.namespace("deep_sleep")
|
||||
DeepSleepComponent = deep_sleep_ns.class_("DeepSleepComponent", cg.Component)
|
||||
EnterDeepSleepAction = deep_sleep_ns.class_("EnterDeepSleepAction", automation.Action)
|
||||
PreventDeepSleepAction = deep_sleep_ns.class_(
|
||||
"PreventDeepSleepAction", automation.Action
|
||||
)
|
||||
|
||||
WakeupPinMode = deep_sleep_ns.enum('WakeupPinMode')
|
||||
WakeupPinMode = deep_sleep_ns.enum("WakeupPinMode")
|
||||
WAKEUP_PIN_MODES = {
|
||||
'IGNORE': WakeupPinMode.WAKEUP_PIN_MODE_IGNORE,
|
||||
'KEEP_AWAKE': WakeupPinMode.WAKEUP_PIN_MODE_KEEP_AWAKE,
|
||||
'INVERT_WAKEUP': WakeupPinMode.WAKEUP_PIN_MODE_INVERT_WAKEUP,
|
||||
"IGNORE": WakeupPinMode.WAKEUP_PIN_MODE_IGNORE,
|
||||
"KEEP_AWAKE": WakeupPinMode.WAKEUP_PIN_MODE_KEEP_AWAKE,
|
||||
"INVERT_WAKEUP": WakeupPinMode.WAKEUP_PIN_MODE_INVERT_WAKEUP,
|
||||
}
|
||||
|
||||
esp_sleep_ext1_wakeup_mode_t = cg.global_ns.enum('esp_sleep_ext1_wakeup_mode_t')
|
||||
Ext1Wakeup = deep_sleep_ns.struct('Ext1Wakeup')
|
||||
esp_sleep_ext1_wakeup_mode_t = cg.global_ns.enum("esp_sleep_ext1_wakeup_mode_t")
|
||||
Ext1Wakeup = deep_sleep_ns.struct("Ext1Wakeup")
|
||||
EXT1_WAKEUP_MODES = {
|
||||
'ALL_LOW': esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ALL_LOW,
|
||||
'ANY_HIGH': esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ANY_HIGH,
|
||||
"ALL_LOW": esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ALL_LOW,
|
||||
"ANY_HIGH": esp_sleep_ext1_wakeup_mode_t.ESP_EXT1_WAKEUP_ANY_HIGH,
|
||||
}
|
||||
|
||||
CONF_WAKEUP_PIN_MODE = 'wakeup_pin_mode'
|
||||
CONF_ESP32_EXT1_WAKEUP = 'esp32_ext1_wakeup'
|
||||
CONF_WAKEUP_PIN_MODE = "wakeup_pin_mode"
|
||||
CONF_ESP32_EXT1_WAKEUP = "esp32_ext1_wakeup"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DeepSleepComponent),
|
||||
cv.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
|
||||
|
||||
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_WAKEUP_PIN): cv.All(cv.only_on_esp32, pins.internal_gpio_input_pin_schema,
|
||||
validate_pin_number),
|
||||
cv.Optional(CONF_WAKEUP_PIN_MODE): cv.All(cv.only_on_esp32,
|
||||
cv.enum(WAKEUP_PIN_MODES), upper=True),
|
||||
cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All(cv.only_on_esp32, cv.Schema({
|
||||
cv.Required(CONF_PINS): cv.ensure_list(pins.shorthand_input_pin, validate_pin_number),
|
||||
cv.Required(CONF_MODE): cv.enum(EXT1_WAKEUP_MODES, upper=True),
|
||||
})),
|
||||
|
||||
cv.Optional(CONF_RUN_CYCLES): cv.invalid("The run_cycles option has been removed in 1.11.0 as "
|
||||
"it was essentially the same as a run_duration of 0s."
|
||||
"Please use run_duration now.")
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DeepSleepComponent),
|
||||
cv.Optional(CONF_RUN_DURATION): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_WAKEUP_PIN): cv.All(
|
||||
cv.only_on_esp32, pins.internal_gpio_input_pin_schema, validate_pin_number
|
||||
),
|
||||
cv.Optional(CONF_WAKEUP_PIN_MODE): cv.All(
|
||||
cv.only_on_esp32, cv.enum(WAKEUP_PIN_MODES), upper=True
|
||||
),
|
||||
cv.Optional(CONF_ESP32_EXT1_WAKEUP): cv.All(
|
||||
cv.only_on_esp32,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_PINS): cv.ensure_list(
|
||||
pins.shorthand_input_pin, validate_pin_number
|
||||
),
|
||||
cv.Required(CONF_MODE): cv.enum(EXT1_WAKEUP_MODES, upper=True),
|
||||
}
|
||||
),
|
||||
),
|
||||
cv.Optional(CONF_RUN_CYCLES): cv.invalid(
|
||||
"The run_cycles option has been removed in 1.11.0 as "
|
||||
"it was essentially the same as a run_duration of 0s."
|
||||
"Please use run_duration now."
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -75,27 +98,31 @@ def to_code(config):
|
||||
for pin in conf[CONF_PINS]:
|
||||
mask |= 1 << pin[CONF_NUMBER]
|
||||
struct = cg.StructInitializer(
|
||||
Ext1Wakeup,
|
||||
('mask', mask),
|
||||
('wakeup_mode', conf[CONF_MODE])
|
||||
Ext1Wakeup, ("mask", mask), ("wakeup_mode", conf[CONF_MODE])
|
||||
)
|
||||
cg.add(var.set_ext1_wakeup(struct))
|
||||
|
||||
cg.add_define('USE_DEEP_SLEEP')
|
||||
cg.add_define("USE_DEEP_SLEEP")
|
||||
|
||||
|
||||
DEEP_SLEEP_ENTER_SCHEMA = automation.maybe_simple_id({
|
||||
cv.GenerateID(): cv.use_id(DeepSleepComponent),
|
||||
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
DEEP_SLEEP_ENTER_SCHEMA = automation.maybe_simple_id(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DeepSleepComponent),
|
||||
cv.Optional(CONF_SLEEP_DURATION): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
DEEP_SLEEP_PREVENT_SCHEMA = automation.maybe_simple_id({
|
||||
cv.GenerateID(): cv.use_id(DeepSleepComponent),
|
||||
})
|
||||
DEEP_SLEEP_PREVENT_SCHEMA = automation.maybe_simple_id(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DeepSleepComponent),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('deep_sleep.enter', EnterDeepSleepAction, DEEP_SLEEP_ENTER_SCHEMA)
|
||||
@automation.register_action(
|
||||
"deep_sleep.enter", EnterDeepSleepAction, DEEP_SLEEP_ENTER_SCHEMA
|
||||
)
|
||||
def deep_sleep_enter_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -105,7 +132,9 @@ def deep_sleep_enter_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('deep_sleep.prevent', PreventDeepSleepAction, DEEP_SLEEP_PREVENT_SCHEMA)
|
||||
@automation.register_action(
|
||||
"deep_sleep.prevent", PreventDeepSleepAction, DEEP_SLEEP_PREVENT_SCHEMA
|
||||
)
|
||||
def deep_sleep_prevent_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -4,57 +4,68 @@ from esphome import automation
|
||||
from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_FILE, CONF_DEVICE
|
||||
from esphome.components import uart
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
CODEOWNERS = ['@glmnet']
|
||||
DEPENDENCIES = ["uart"]
|
||||
CODEOWNERS = ["@glmnet"]
|
||||
|
||||
dfplayer_ns = cg.esphome_ns.namespace('dfplayer')
|
||||
DFPlayer = dfplayer_ns.class_('DFPlayer', cg.Component)
|
||||
DFPlayerFinishedPlaybackTrigger = dfplayer_ns.class_('DFPlayerFinishedPlaybackTrigger',
|
||||
automation.Trigger.template())
|
||||
DFPlayerIsPlayingCondition = dfplayer_ns.class_('DFPlayerIsPlayingCondition', automation.Condition)
|
||||
dfplayer_ns = cg.esphome_ns.namespace("dfplayer")
|
||||
DFPlayer = dfplayer_ns.class_("DFPlayer", cg.Component)
|
||||
DFPlayerFinishedPlaybackTrigger = dfplayer_ns.class_(
|
||||
"DFPlayerFinishedPlaybackTrigger", automation.Trigger.template()
|
||||
)
|
||||
DFPlayerIsPlayingCondition = dfplayer_ns.class_(
|
||||
"DFPlayerIsPlayingCondition", automation.Condition
|
||||
)
|
||||
|
||||
MULTI_CONF = True
|
||||
CONF_FOLDER = 'folder'
|
||||
CONF_LOOP = 'loop'
|
||||
CONF_VOLUME = 'volume'
|
||||
CONF_EQ_PRESET = 'eq_preset'
|
||||
CONF_ON_FINISHED_PLAYBACK = 'on_finished_playback'
|
||||
CONF_FOLDER = "folder"
|
||||
CONF_LOOP = "loop"
|
||||
CONF_VOLUME = "volume"
|
||||
CONF_EQ_PRESET = "eq_preset"
|
||||
CONF_ON_FINISHED_PLAYBACK = "on_finished_playback"
|
||||
|
||||
EqPreset = dfplayer_ns.enum("EqPreset")
|
||||
EQ_PRESET = {
|
||||
'NORMAL': EqPreset.NORMAL,
|
||||
'POP': EqPreset.POP,
|
||||
'ROCK': EqPreset.ROCK,
|
||||
'JAZZ': EqPreset.JAZZ,
|
||||
'CLASSIC': EqPreset.CLASSIC,
|
||||
'BASS': EqPreset.BASS,
|
||||
"NORMAL": EqPreset.NORMAL,
|
||||
"POP": EqPreset.POP,
|
||||
"ROCK": EqPreset.ROCK,
|
||||
"JAZZ": EqPreset.JAZZ,
|
||||
"CLASSIC": EqPreset.CLASSIC,
|
||||
"BASS": EqPreset.BASS,
|
||||
}
|
||||
Device = dfplayer_ns.enum("Device")
|
||||
DEVICE = {
|
||||
'USB': Device.USB,
|
||||
'TF_CARD': Device.TF_CARD,
|
||||
"USB": Device.USB,
|
||||
"TF_CARD": Device.TF_CARD,
|
||||
}
|
||||
|
||||
NextAction = dfplayer_ns.class_('NextAction', automation.Action)
|
||||
PreviousAction = dfplayer_ns.class_('PreviousAction', automation.Action)
|
||||
PlayFileAction = dfplayer_ns.class_('PlayFileAction', automation.Action)
|
||||
PlayFolderAction = dfplayer_ns.class_('PlayFolderAction', automation.Action)
|
||||
SetVolumeAction = dfplayer_ns.class_('SetVolumeAction', automation.Action)
|
||||
SetEqAction = dfplayer_ns.class_('SetEqAction', automation.Action)
|
||||
SleepAction = dfplayer_ns.class_('SleepAction', automation.Action)
|
||||
ResetAction = dfplayer_ns.class_('ResetAction', automation.Action)
|
||||
StartAction = dfplayer_ns.class_('StartAction', automation.Action)
|
||||
PauseAction = dfplayer_ns.class_('PauseAction', automation.Action)
|
||||
StopAction = dfplayer_ns.class_('StopAction', automation.Action)
|
||||
RandomAction = dfplayer_ns.class_('RandomAction', automation.Action)
|
||||
SetDeviceAction = dfplayer_ns.class_('SetDeviceAction', automation.Action)
|
||||
NextAction = dfplayer_ns.class_("NextAction", automation.Action)
|
||||
PreviousAction = dfplayer_ns.class_("PreviousAction", automation.Action)
|
||||
PlayFileAction = dfplayer_ns.class_("PlayFileAction", automation.Action)
|
||||
PlayFolderAction = dfplayer_ns.class_("PlayFolderAction", automation.Action)
|
||||
SetVolumeAction = dfplayer_ns.class_("SetVolumeAction", automation.Action)
|
||||
SetEqAction = dfplayer_ns.class_("SetEqAction", automation.Action)
|
||||
SleepAction = dfplayer_ns.class_("SleepAction", automation.Action)
|
||||
ResetAction = dfplayer_ns.class_("ResetAction", automation.Action)
|
||||
StartAction = dfplayer_ns.class_("StartAction", automation.Action)
|
||||
PauseAction = dfplayer_ns.class_("PauseAction", automation.Action)
|
||||
StopAction = dfplayer_ns.class_("StopAction", automation.Action)
|
||||
RandomAction = dfplayer_ns.class_("RandomAction", automation.Action)
|
||||
SetDeviceAction = dfplayer_ns.class_("SetDeviceAction", automation.Action)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DFPlayer),
|
||||
cv.Optional(CONF_ON_FINISHED_PLAYBACK): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(DFPlayerFinishedPlaybackTrigger),
|
||||
}),
|
||||
}).extend(uart.UART_DEVICE_SCHEMA))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DFPlayer),
|
||||
cv.Optional(CONF_ON_FINISHED_PLAYBACK): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
DFPlayerFinishedPlaybackTrigger
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -67,29 +78,48 @@ def to_code(config):
|
||||
yield automation.build_automation(trigger, [], conf)
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.play_next', NextAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.play_next",
|
||||
NextAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_next_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.play_previous', PreviousAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.play_previous",
|
||||
PreviousAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_previous_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.play', PlayFileAction, cv.maybe_simple_value({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_FILE): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_LOOP): cv.templatable(cv.boolean),
|
||||
}, key=CONF_FILE))
|
||||
@automation.register_action(
|
||||
"dfplayer.play",
|
||||
PlayFileAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_FILE): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_LOOP): cv.templatable(cv.boolean),
|
||||
},
|
||||
key=CONF_FILE,
|
||||
),
|
||||
)
|
||||
def dfplayer_play_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
@ -101,12 +131,18 @@ def dfplayer_play_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.play_folder', PlayFolderAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_FOLDER): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_FILE): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_LOOP): cv.templatable(cv.boolean),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.play_folder",
|
||||
PlayFolderAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_FOLDER): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_FILE): cv.templatable(cv.int_),
|
||||
cv.Optional(CONF_LOOP): cv.templatable(cv.boolean),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_play_folder_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
@ -121,10 +157,17 @@ def dfplayer_play_folder_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.set_device', SetDeviceAction, cv.maybe_simple_value({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_DEVICE): cv.enum(DEVICE, upper=True),
|
||||
}, key=CONF_DEVICE))
|
||||
@automation.register_action(
|
||||
"dfplayer.set_device",
|
||||
SetDeviceAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_DEVICE): cv.enum(DEVICE, upper=True),
|
||||
},
|
||||
key=CONF_DEVICE,
|
||||
),
|
||||
)
|
||||
def dfplayer_set_device_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
@ -133,10 +176,17 @@ def dfplayer_set_device_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.set_volume', SetVolumeAction, cv.maybe_simple_value({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_VOLUME): cv.templatable(cv.int_),
|
||||
}, key=CONF_VOLUME))
|
||||
@automation.register_action(
|
||||
"dfplayer.set_volume",
|
||||
SetVolumeAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_VOLUME): cv.templatable(cv.int_),
|
||||
},
|
||||
key=CONF_VOLUME,
|
||||
),
|
||||
)
|
||||
def dfplayer_set_volume_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
@ -145,10 +195,17 @@ def dfplayer_set_volume_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.set_eq', SetEqAction, cv.maybe_simple_value({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_EQ_PRESET): cv.templatable(cv.enum(EQ_PRESET, upper=True)),
|
||||
}, key=CONF_EQ_PRESET))
|
||||
@automation.register_action(
|
||||
"dfplayer.set_eq",
|
||||
SetEqAction,
|
||||
cv.maybe_simple_value(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
cv.Required(CONF_EQ_PRESET): cv.templatable(cv.enum(EQ_PRESET, upper=True)),
|
||||
},
|
||||
key=CONF_EQ_PRESET,
|
||||
),
|
||||
)
|
||||
def dfplayer_set_eq_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
@ -157,63 +214,105 @@ def dfplayer_set_eq_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.sleep', SleepAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.sleep",
|
||||
SleepAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_sleep_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.reset', ResetAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.reset",
|
||||
ResetAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_reset_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.start', StartAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.start",
|
||||
StartAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_start_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.pause', PauseAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.pause",
|
||||
PauseAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_pause_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.stop', StopAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.stop",
|
||||
StopAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_stop_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('dfplayer.random', RandomAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"dfplayer.random",
|
||||
RandomAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplayer_random_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_condition('dfplayer.is_playing', DFPlayerIsPlayingCondition, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}))
|
||||
@automation.register_condition(
|
||||
"dfplayer.is_playing",
|
||||
DFPlayerIsPlayingCondition,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DFPlayer),
|
||||
}
|
||||
),
|
||||
)
|
||||
def dfplyaer_is_playing_to_code(config, condition_id, template_arg, args):
|
||||
var = cg.new_Pvariable(condition_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
@ -2,33 +2,49 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_MODEL, CONF_PIN, CONF_TEMPERATURE, \
|
||||
ICON_EMPTY, UNIT_CELSIUS, UNIT_PERCENT, DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_HUMIDITY
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_MODEL,
|
||||
CONF_PIN,
|
||||
CONF_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
)
|
||||
|
||||
from esphome.cpp_helpers import gpio_pin_expression
|
||||
|
||||
dht_ns = cg.esphome_ns.namespace('dht')
|
||||
DHTModel = dht_ns.enum('DHTModel')
|
||||
dht_ns = cg.esphome_ns.namespace("dht")
|
||||
DHTModel = dht_ns.enum("DHTModel")
|
||||
DHT_MODELS = {
|
||||
'AUTO_DETECT': DHTModel.DHT_MODEL_AUTO_DETECT,
|
||||
'DHT11': DHTModel.DHT_MODEL_DHT11,
|
||||
'DHT22': DHTModel.DHT_MODEL_DHT22,
|
||||
'AM2302': DHTModel.DHT_MODEL_AM2302,
|
||||
'RHT03': DHTModel.DHT_MODEL_RHT03,
|
||||
'SI7021': DHTModel.DHT_MODEL_SI7021,
|
||||
'DHT22_TYPE2': DHTModel.DHT_MODEL_DHT22_TYPE2,
|
||||
"AUTO_DETECT": DHTModel.DHT_MODEL_AUTO_DETECT,
|
||||
"DHT11": DHTModel.DHT_MODEL_DHT11,
|
||||
"DHT22": DHTModel.DHT_MODEL_DHT22,
|
||||
"AM2302": DHTModel.DHT_MODEL_AM2302,
|
||||
"RHT03": DHTModel.DHT_MODEL_RHT03,
|
||||
"SI7021": DHTModel.DHT_MODEL_SI7021,
|
||||
"DHT22_TYPE2": DHTModel.DHT_MODEL_DHT22_TYPE2,
|
||||
}
|
||||
DHT = dht_ns.class_('DHT', cg.PollingComponent)
|
||||
DHT = dht_ns.class_("DHT", cg.PollingComponent)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DHT),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
cv.Optional(CONF_MODEL, default='auto detect'): cv.enum(DHT_MODELS, upper=True, space='_'),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DHT),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 0, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
cv.Optional(CONF_MODEL, default="auto detect"): cv.enum(
|
||||
DHT_MODELS, upper=True, space="_"
|
||||
),
|
||||
}
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,37 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_TEMPERATURE, \
|
||||
UNIT_CELSIUS, ICON_EMPTY, UNIT_PERCENT, DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_HUMIDITY
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
UNIT_PERCENT,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
dht12_ns = cg.esphome_ns.namespace('dht12')
|
||||
DHT12Component = dht12_ns.class_('DHT12Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
dht12_ns = cg.esphome_ns.namespace("dht12")
|
||||
DHT12Component = dht12_ns.class_("DHT12Component", cg.PollingComponent, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(DHT12Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x5C))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DHT12Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x5C))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -7,14 +7,18 @@ from esphome.core import coroutine, coroutine_with_priority
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
display_ns = cg.esphome_ns.namespace('display')
|
||||
DisplayBuffer = display_ns.class_('DisplayBuffer')
|
||||
DisplayPage = display_ns.class_('DisplayPage')
|
||||
DisplayPagePtr = DisplayPage.operator('ptr')
|
||||
DisplayBufferRef = DisplayBuffer.operator('ref')
|
||||
DisplayPageShowAction = display_ns.class_('DisplayPageShowAction', automation.Action)
|
||||
DisplayPageShowNextAction = display_ns.class_('DisplayPageShowNextAction', automation.Action)
|
||||
DisplayPageShowPrevAction = display_ns.class_('DisplayPageShowPrevAction', automation.Action)
|
||||
display_ns = cg.esphome_ns.namespace("display")
|
||||
DisplayBuffer = display_ns.class_("DisplayBuffer")
|
||||
DisplayPage = display_ns.class_("DisplayPage")
|
||||
DisplayPagePtr = DisplayPage.operator("ptr")
|
||||
DisplayBufferRef = DisplayBuffer.operator("ref")
|
||||
DisplayPageShowAction = display_ns.class_("DisplayPageShowAction", automation.Action)
|
||||
DisplayPageShowNextAction = display_ns.class_(
|
||||
"DisplayPageShowNextAction", automation.Action
|
||||
)
|
||||
DisplayPageShowPrevAction = display_ns.class_(
|
||||
"DisplayPageShowPrevAction", automation.Action
|
||||
)
|
||||
|
||||
DISPLAY_ROTATIONS = {
|
||||
0: display_ns.DISPLAY_ROTATION_0_DEGREES,
|
||||
@ -31,17 +35,26 @@ def validate_rotation(value):
|
||||
return cv.enum(DISPLAY_ROTATIONS, int=True)(value)
|
||||
|
||||
|
||||
BASIC_DISPLAY_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
})
|
||||
BASIC_DISPLAY_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_LAMBDA): cv.lambda_,
|
||||
}
|
||||
)
|
||||
|
||||
FULL_DISPLAY_SCHEMA = BASIC_DISPLAY_SCHEMA.extend({
|
||||
cv.Optional(CONF_ROTATION): validate_rotation,
|
||||
cv.Optional(CONF_PAGES): cv.All(cv.ensure_list({
|
||||
cv.GenerateID(): cv.declare_id(DisplayPage),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
}), cv.Length(min=1)),
|
||||
})
|
||||
FULL_DISPLAY_SCHEMA = BASIC_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_ROTATION): validate_rotation,
|
||||
cv.Optional(CONF_PAGES): cv.All(
|
||||
cv.ensure_list(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DisplayPage),
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
}
|
||||
),
|
||||
cv.Length(min=1),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -51,8 +64,9 @@ def setup_display_core_(var, config):
|
||||
if CONF_PAGES in config:
|
||||
pages = []
|
||||
for conf in config[CONF_PAGES]:
|
||||
lambda_ = yield cg.process_lambda(conf[CONF_LAMBDA], [(DisplayBufferRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
conf[CONF_LAMBDA], [(DisplayBufferRef, "it")], return_type=cg.void
|
||||
)
|
||||
page = cg.new_Pvariable(conf[CONF_ID], lambda_)
|
||||
pages.append(page)
|
||||
cg.add(var.set_pages(pages))
|
||||
@ -63,9 +77,15 @@ def register_display(var, config):
|
||||
yield setup_display_core_(var, config)
|
||||
|
||||
|
||||
@automation.register_action('display.page.show', DisplayPageShowAction, maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayPage)),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"display.page.show",
|
||||
DisplayPageShowAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayPage)),
|
||||
}
|
||||
),
|
||||
)
|
||||
def display_page_show_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
if isinstance(config[CONF_ID], core.Lambda):
|
||||
@ -77,18 +97,29 @@ def display_page_show_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('display.page.show_next', DisplayPageShowNextAction, maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"display.page.show_next",
|
||||
DisplayPageShowNextAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
}
|
||||
),
|
||||
)
|
||||
def display_page_show_next_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('display.page.show_previous', DisplayPageShowPrevAction,
|
||||
maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"display.page.show_previous",
|
||||
DisplayPageShowPrevAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.templatable(cv.use_id(DisplayBuffer)),
|
||||
}
|
||||
),
|
||||
)
|
||||
def display_page_show_previous_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -5,31 +5,45 @@ from esphome.components import i2c, time
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
|
||||
CODEOWNERS = ['@badbadc0ffee']
|
||||
DEPENDENCIES = ['i2c']
|
||||
ds1307_ns = cg.esphome_ns.namespace('ds1307')
|
||||
DS1307Component = ds1307_ns.class_('DS1307Component', time.RealTimeClock, i2c.I2CDevice)
|
||||
WriteAction = ds1307_ns.class_('WriteAction', automation.Action)
|
||||
ReadAction = ds1307_ns.class_('ReadAction', automation.Action)
|
||||
CODEOWNERS = ["@badbadc0ffee"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
ds1307_ns = cg.esphome_ns.namespace("ds1307")
|
||||
DS1307Component = ds1307_ns.class_("DS1307Component", time.RealTimeClock, i2c.I2CDevice)
|
||||
WriteAction = ds1307_ns.class_("WriteAction", automation.Action)
|
||||
ReadAction = ds1307_ns.class_("ReadAction", automation.Action)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = time.TIME_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(DS1307Component),
|
||||
}).extend(i2c.i2c_device_schema(0x68))
|
||||
CONFIG_SCHEMA = time.TIME_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DS1307Component),
|
||||
}
|
||||
).extend(i2c.i2c_device_schema(0x68))
|
||||
|
||||
|
||||
@automation.register_action('ds1307.write_time', WriteAction, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(DS1307Component),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"ds1307.write_time",
|
||||
WriteAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DS1307Component),
|
||||
}
|
||||
),
|
||||
)
|
||||
def ds1307_write_time_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_action('ds1307.read_time', ReadAction, automation.maybe_simple_id({
|
||||
cv.GenerateID(): cv.use_id(DS1307Component),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"ds1307.read_time",
|
||||
ReadAction,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(DS1307Component),
|
||||
}
|
||||
),
|
||||
)
|
||||
def ds1307_read_time_to_code(config, action_id, template_arg, args):
|
||||
var = cg.new_Pvariable(action_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
|
@ -2,16 +2,31 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, CONF_PIN, DEVICE_CLASS_EMPTY, UNIT_PERCENT, ICON_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_PIN,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
UNIT_PERCENT,
|
||||
ICON_PERCENT,
|
||||
)
|
||||
|
||||
duty_cycle_ns = cg.esphome_ns.namespace('duty_cycle')
|
||||
DutyCycleSensor = duty_cycle_ns.class_('DutyCycleSensor', sensor.Sensor, cg.PollingComponent)
|
||||
duty_cycle_ns = cg.esphome_ns.namespace("duty_cycle")
|
||||
DutyCycleSensor = duty_cycle_ns.class_(
|
||||
"DutyCycleSensor", sensor.Sensor, cg.PollingComponent
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_PERCENT, ICON_PERCENT, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(DutyCycleSensor),
|
||||
cv.Required(CONF_PIN): cv.All(pins.internal_gpio_input_pin_schema,
|
||||
pins.validate_has_interrupt),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_PERCENT, ICON_PERCENT, 1, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(DutyCycleSensor),
|
||||
cv.Required(CONF_PIN): cv.All(
|
||||
pins.internal_gpio_input_pin_schema, pins.validate_has_interrupt
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,28 +4,29 @@ from esphome.components.light.types import AddressableLightEffect
|
||||
from esphome.components.light.effects import register_addressable_effect
|
||||
from esphome.const import CONF_ID, CONF_NAME, CONF_METHOD, CONF_CHANNELS
|
||||
|
||||
e131_ns = cg.esphome_ns.namespace('e131')
|
||||
E131AddressableLightEffect = e131_ns.class_('E131AddressableLightEffect', AddressableLightEffect)
|
||||
E131Component = e131_ns.class_('E131Component', cg.Component)
|
||||
e131_ns = cg.esphome_ns.namespace("e131")
|
||||
E131AddressableLightEffect = e131_ns.class_(
|
||||
"E131AddressableLightEffect", AddressableLightEffect
|
||||
)
|
||||
E131Component = e131_ns.class_("E131Component", cg.Component)
|
||||
|
||||
METHODS = {
|
||||
'UNICAST': e131_ns.E131_UNICAST,
|
||||
'MULTICAST': e131_ns.E131_MULTICAST
|
||||
}
|
||||
METHODS = {"UNICAST": e131_ns.E131_UNICAST, "MULTICAST": e131_ns.E131_MULTICAST}
|
||||
|
||||
CHANNELS = {
|
||||
'MONO': e131_ns.E131_MONO,
|
||||
'RGB': e131_ns.E131_RGB,
|
||||
'RGBW': e131_ns.E131_RGBW
|
||||
"MONO": e131_ns.E131_MONO,
|
||||
"RGB": e131_ns.E131_RGB,
|
||||
"RGBW": e131_ns.E131_RGBW,
|
||||
}
|
||||
|
||||
CONF_UNIVERSE = 'universe'
|
||||
CONF_E131_ID = 'e131_id'
|
||||
CONF_UNIVERSE = "universe"
|
||||
CONF_E131_ID = "e131_id"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(E131Component),
|
||||
cv.Optional(CONF_METHOD, default='MULTICAST'): cv.one_of(*METHODS, upper=True),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(E131Component),
|
||||
cv.Optional(CONF_METHOD, default="MULTICAST"): cv.one_of(*METHODS, upper=True),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -34,11 +35,16 @@ def to_code(config):
|
||||
cg.add(var.set_method(METHODS[config[CONF_METHOD]]))
|
||||
|
||||
|
||||
@register_addressable_effect('e131', E131AddressableLightEffect, "E1.31", {
|
||||
cv.GenerateID(CONF_E131_ID): cv.use_id(E131Component),
|
||||
cv.Required(CONF_UNIVERSE): cv.int_range(min=1, max=512),
|
||||
cv.Optional(CONF_CHANNELS, default='RGB'): cv.one_of(*CHANNELS, upper=True)
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"e131",
|
||||
E131AddressableLightEffect,
|
||||
"E1.31",
|
||||
{
|
||||
cv.GenerateID(CONF_E131_ID): cv.use_id(E131Component),
|
||||
cv.Required(CONF_UNIVERSE): cv.int_range(min=1, max=512),
|
||||
cv.Optional(CONF_CHANNELS, default="RGB"): cv.one_of(*CHANNELS, upper=True),
|
||||
},
|
||||
)
|
||||
def e131_light_effect_to_code(config, effect_id):
|
||||
parent = yield cg.get_variable(config[CONF_E131_ID])
|
||||
|
||||
|
@ -2,27 +2,34 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.components import binary_sensor, cover
|
||||
from esphome.const import CONF_CLOSE_ACTION, CONF_CLOSE_DURATION, \
|
||||
CONF_CLOSE_ENDSTOP, CONF_ID, CONF_OPEN_ACTION, CONF_OPEN_DURATION, \
|
||||
CONF_OPEN_ENDSTOP, CONF_STOP_ACTION, CONF_MAX_DURATION
|
||||
from esphome.const import (
|
||||
CONF_CLOSE_ACTION,
|
||||
CONF_CLOSE_DURATION,
|
||||
CONF_CLOSE_ENDSTOP,
|
||||
CONF_ID,
|
||||
CONF_OPEN_ACTION,
|
||||
CONF_OPEN_DURATION,
|
||||
CONF_OPEN_ENDSTOP,
|
||||
CONF_STOP_ACTION,
|
||||
CONF_MAX_DURATION,
|
||||
)
|
||||
|
||||
endstop_ns = cg.esphome_ns.namespace('endstop')
|
||||
EndstopCover = endstop_ns.class_('EndstopCover', cover.Cover, cg.Component)
|
||||
endstop_ns = cg.esphome_ns.namespace("endstop")
|
||||
EndstopCover = endstop_ns.class_("EndstopCover", cover.Cover, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(EndstopCover),
|
||||
cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
|
||||
|
||||
cv.Required(CONF_OPEN_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
||||
cv.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True),
|
||||
cv.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds,
|
||||
|
||||
cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
|
||||
cv.Required(CONF_CLOSE_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
||||
cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
|
||||
|
||||
cv.Optional(CONF_MAX_DURATION): cv.positive_time_period_milliseconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cover.COVER_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EndstopCover),
|
||||
cv.Required(CONF_STOP_ACTION): automation.validate_automation(single=True),
|
||||
cv.Required(CONF_OPEN_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
||||
cv.Required(CONF_OPEN_ACTION): automation.validate_automation(single=True),
|
||||
cv.Required(CONF_OPEN_DURATION): cv.positive_time_period_milliseconds,
|
||||
cv.Required(CONF_CLOSE_ACTION): automation.validate_automation(single=True),
|
||||
cv.Required(CONF_CLOSE_ENDSTOP): cv.use_id(binary_sensor.BinarySensor),
|
||||
cv.Required(CONF_CLOSE_DURATION): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_MAX_DURATION): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -30,17 +37,23 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
yield cover.register_cover(var, config)
|
||||
|
||||
yield automation.build_automation(var.get_stop_trigger(), [], config[CONF_STOP_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_stop_trigger(), [], config[CONF_STOP_ACTION]
|
||||
)
|
||||
|
||||
bin = yield cg.get_variable(config[CONF_OPEN_ENDSTOP])
|
||||
cg.add(var.set_open_endstop(bin))
|
||||
cg.add(var.set_open_duration(config[CONF_OPEN_DURATION]))
|
||||
yield automation.build_automation(var.get_open_trigger(), [], config[CONF_OPEN_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_open_trigger(), [], config[CONF_OPEN_ACTION]
|
||||
)
|
||||
|
||||
bin = yield cg.get_variable(config[CONF_CLOSE_ENDSTOP])
|
||||
cg.add(var.set_close_endstop(bin))
|
||||
cg.add(var.set_close_duration(config[CONF_CLOSE_DURATION]))
|
||||
yield automation.build_automation(var.get_close_trigger(), [], config[CONF_CLOSE_ACTION])
|
||||
yield automation.build_automation(
|
||||
var.get_close_trigger(), [], config[CONF_CLOSE_ACTION]
|
||||
)
|
||||
|
||||
if CONF_MAX_DURATION in config:
|
||||
cg.add(var.set_max_duration(config[CONF_MAX_DURATION]))
|
||||
|
@ -3,26 +3,30 @@ import esphome.config_validation as cv
|
||||
from esphome.const import CONF_ID, CONF_TYPE, CONF_UUID, ESP_PLATFORM_ESP32
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
CONFLICTS_WITH = ['esp32_ble_tracker']
|
||||
CONFLICTS_WITH = ["esp32_ble_tracker"]
|
||||
|
||||
esp32_ble_beacon_ns = cg.esphome_ns.namespace('esp32_ble_beacon')
|
||||
ESP32BLEBeacon = esp32_ble_beacon_ns.class_('ESP32BLEBeacon', cg.Component)
|
||||
esp32_ble_beacon_ns = cg.esphome_ns.namespace("esp32_ble_beacon")
|
||||
ESP32BLEBeacon = esp32_ble_beacon_ns.class_("ESP32BLEBeacon", cg.Component)
|
||||
|
||||
CONF_MAJOR = 'major'
|
||||
CONF_MINOR = 'minor'
|
||||
CONF_MAJOR = "major"
|
||||
CONF_MINOR = "minor"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ESP32BLEBeacon),
|
||||
cv.Required(CONF_TYPE): cv.one_of('IBEACON', upper=True),
|
||||
cv.Required(CONF_UUID): cv.uuid,
|
||||
cv.Optional(CONF_MAJOR, default=10167): cv.uint16_t,
|
||||
cv.Optional(CONF_MINOR, default=61958): cv.uint16_t,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32BLEBeacon),
|
||||
cv.Required(CONF_TYPE): cv.one_of("IBEACON", upper=True),
|
||||
cv.Required(CONF_UUID): cv.uuid,
|
||||
cv.Optional(CONF_MAJOR, default=10167): cv.uint16_t,
|
||||
cv.Optional(CONF_MINOR, default=61958): cv.uint16_t,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
uuid = config[CONF_UUID].hex
|
||||
uuid_arr = [cg.RawExpression('0x{}'.format(uuid[i:i + 2])) for i in range(0, len(uuid), 2)]
|
||||
uuid_arr = [
|
||||
cg.RawExpression("0x{}".format(uuid[i : i + 2])) for i in range(0, len(uuid), 2)
|
||||
]
|
||||
var = cg.new_Pvariable(config[CONF_ID], uuid_arr)
|
||||
yield cg.register_component(var, config)
|
||||
cg.add(var.set_major(config[CONF_MAJOR]))
|
||||
|
@ -2,33 +2,46 @@ import re
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.const import CONF_ID, ESP_PLATFORM_ESP32, CONF_INTERVAL, \
|
||||
CONF_DURATION, CONF_TRIGGER_ID, CONF_MAC_ADDRESS, CONF_SERVICE_UUID, CONF_MANUFACTURER_ID, \
|
||||
CONF_ON_BLE_ADVERTISE, CONF_ON_BLE_SERVICE_DATA_ADVERTISE, \
|
||||
CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
ESP_PLATFORM_ESP32,
|
||||
CONF_INTERVAL,
|
||||
CONF_DURATION,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_SERVICE_UUID,
|
||||
CONF_MANUFACTURER_ID,
|
||||
CONF_ON_BLE_ADVERTISE,
|
||||
CONF_ON_BLE_SERVICE_DATA_ADVERTISE,
|
||||
CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE,
|
||||
)
|
||||
from esphome.core import coroutine
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
AUTO_LOAD = ['xiaomi_ble', 'ruuvi_ble']
|
||||
AUTO_LOAD = ["xiaomi_ble", "ruuvi_ble"]
|
||||
|
||||
CONF_ESP32_BLE_ID = 'esp32_ble_id'
|
||||
CONF_SCAN_PARAMETERS = 'scan_parameters'
|
||||
CONF_WINDOW = 'window'
|
||||
CONF_ACTIVE = 'active'
|
||||
esp32_ble_tracker_ns = cg.esphome_ns.namespace('esp32_ble_tracker')
|
||||
ESP32BLETracker = esp32_ble_tracker_ns.class_('ESP32BLETracker', cg.Component)
|
||||
ESPBTDeviceListener = esp32_ble_tracker_ns.class_('ESPBTDeviceListener')
|
||||
ESPBTDevice = esp32_ble_tracker_ns.class_('ESPBTDevice')
|
||||
ESPBTDeviceConstRef = ESPBTDevice.operator('ref').operator('const')
|
||||
CONF_ESP32_BLE_ID = "esp32_ble_id"
|
||||
CONF_SCAN_PARAMETERS = "scan_parameters"
|
||||
CONF_WINDOW = "window"
|
||||
CONF_ACTIVE = "active"
|
||||
esp32_ble_tracker_ns = cg.esphome_ns.namespace("esp32_ble_tracker")
|
||||
ESP32BLETracker = esp32_ble_tracker_ns.class_("ESP32BLETracker", cg.Component)
|
||||
ESPBTDeviceListener = esp32_ble_tracker_ns.class_("ESPBTDeviceListener")
|
||||
ESPBTDevice = esp32_ble_tracker_ns.class_("ESPBTDevice")
|
||||
ESPBTDeviceConstRef = ESPBTDevice.operator("ref").operator("const")
|
||||
adv_data_t = cg.std_vector.template(cg.uint8)
|
||||
adv_data_t_const_ref = adv_data_t.operator('ref').operator('const')
|
||||
adv_data_t_const_ref = adv_data_t.operator("ref").operator("const")
|
||||
# Triggers
|
||||
ESPBTAdvertiseTrigger = esp32_ble_tracker_ns.class_(
|
||||
'ESPBTAdvertiseTrigger', automation.Trigger.template(ESPBTDeviceConstRef))
|
||||
"ESPBTAdvertiseTrigger", automation.Trigger.template(ESPBTDeviceConstRef)
|
||||
)
|
||||
BLEServiceDataAdvertiseTrigger = esp32_ble_tracker_ns.class_(
|
||||
'BLEServiceDataAdvertiseTrigger', automation.Trigger.template(adv_data_t_const_ref))
|
||||
"BLEServiceDataAdvertiseTrigger", automation.Trigger.template(adv_data_t_const_ref)
|
||||
)
|
||||
BLEManufacturerDataAdvertiseTrigger = esp32_ble_tracker_ns.class_(
|
||||
'BLEManufacturerDataAdvertiseTrigger', automation.Trigger.template(adv_data_t_const_ref))
|
||||
"BLEManufacturerDataAdvertiseTrigger",
|
||||
automation.Trigger.template(adv_data_t_const_ref),
|
||||
)
|
||||
|
||||
|
||||
def validate_scan_parameters(config):
|
||||
@ -37,19 +50,23 @@ def validate_scan_parameters(config):
|
||||
window = config[CONF_WINDOW]
|
||||
|
||||
if window > interval:
|
||||
raise cv.Invalid("Scan window ({}) needs to be smaller than scan interval ({})"
|
||||
"".format(window, interval))
|
||||
raise cv.Invalid(
|
||||
"Scan window ({}) needs to be smaller than scan interval ({})"
|
||||
"".format(window, interval)
|
||||
)
|
||||
|
||||
if interval.total_milliseconds * 3 > duration.total_milliseconds:
|
||||
raise cv.Invalid("Scan duration needs to be at least three times the scan interval to"
|
||||
"cover all BLE channels.")
|
||||
raise cv.Invalid(
|
||||
"Scan duration needs to be at least three times the scan interval to"
|
||||
"cover all BLE channels."
|
||||
)
|
||||
|
||||
return config
|
||||
|
||||
|
||||
bt_uuid16_format = 'XXXX'
|
||||
bt_uuid32_format = 'XXXXXXXX'
|
||||
bt_uuid128_format = 'XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'
|
||||
bt_uuid16_format = "XXXX"
|
||||
bt_uuid32_format = "XXXXXXXX"
|
||||
bt_uuid128_format = "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
|
||||
|
||||
|
||||
def bt_uuid(value):
|
||||
@ -60,67 +77,103 @@ def bt_uuid(value):
|
||||
pattern = re.compile("^[A-F|0-9]{4,}$")
|
||||
if not pattern.match(value):
|
||||
raise cv.Invalid(
|
||||
f"Invalid hexadecimal value for 16 bit UUID format: '{in_value}'")
|
||||
f"Invalid hexadecimal value for 16 bit UUID format: '{in_value}'"
|
||||
)
|
||||
return value
|
||||
if len(value) == len(bt_uuid32_format):
|
||||
pattern = re.compile("^[A-F|0-9]{8,}$")
|
||||
if not pattern.match(value):
|
||||
raise cv.Invalid(
|
||||
f"Invalid hexadecimal value for 32 bit UUID format: '{in_value}'")
|
||||
f"Invalid hexadecimal value for 32 bit UUID format: '{in_value}'"
|
||||
)
|
||||
return value
|
||||
if len(value) == len(bt_uuid128_format):
|
||||
pattern = re.compile(
|
||||
"^[A-F|0-9]{8,}-[A-F|0-9]{4,}-[A-F|0-9]{4,}-[A-F|0-9]{4,}-[A-F|0-9]{12,}$")
|
||||
"^[A-F|0-9]{8,}-[A-F|0-9]{4,}-[A-F|0-9]{4,}-[A-F|0-9]{4,}-[A-F|0-9]{12,}$"
|
||||
)
|
||||
if not pattern.match(value):
|
||||
raise cv.Invalid(
|
||||
f"Invalid hexadecimal value for 128 UUID format: '{in_value}'")
|
||||
f"Invalid hexadecimal value for 128 UUID format: '{in_value}'"
|
||||
)
|
||||
return value
|
||||
raise cv.Invalid(
|
||||
"Service UUID must be in 16 bit '{}', 32 bit '{}', or 128 bit '{}' format".format(
|
||||
bt_uuid16_format, bt_uuid32_format, bt_uuid128_format))
|
||||
bt_uuid16_format, bt_uuid32_format, bt_uuid128_format
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def as_hex(value):
|
||||
return cg.RawExpression(f'0x{value}ULL')
|
||||
return cg.RawExpression(f"0x{value}ULL")
|
||||
|
||||
|
||||
def as_hex_array(value):
|
||||
value = value.replace("-", "")
|
||||
cpp_array = [f'0x{part}' for part in [value[i:i+2] for i in range(0, len(value), 2)]]
|
||||
cpp_array = [
|
||||
f"0x{part}" for part in [value[i : i + 2] for i in range(0, len(value), 2)]
|
||||
]
|
||||
return cg.RawExpression(
|
||||
'(uint8_t*)(const uint8_t[16]){{{}}}'.format(','.join(reversed(cpp_array))))
|
||||
"(uint8_t*)(const uint8_t[16]){{{}}}".format(",".join(reversed(cpp_array)))
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ESP32BLETracker),
|
||||
cv.Optional(CONF_SCAN_PARAMETERS, default={}): cv.All(cv.Schema({
|
||||
cv.Optional(CONF_DURATION, default='5min'): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_INTERVAL, default='320ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_WINDOW, default='30ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
|
||||
}), validate_scan_parameters),
|
||||
cv.Optional(CONF_ON_BLE_ADVERTISE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPBTAdvertiseTrigger),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
}),
|
||||
cv.Optional(CONF_ON_BLE_SERVICE_DATA_ADVERTISE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BLEServiceDataAdvertiseTrigger),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Required(CONF_SERVICE_UUID): bt_uuid,
|
||||
}),
|
||||
cv.Optional(CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BLEManufacturerDataAdvertiseTrigger),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Required(CONF_MANUFACTURER_ID): bt_uuid,
|
||||
}),
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32BLETracker),
|
||||
cv.Optional(CONF_SCAN_PARAMETERS, default={}): cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_DURATION, default="5min"
|
||||
): cv.positive_time_period_seconds,
|
||||
cv.Optional(
|
||||
CONF_INTERVAL, default="320ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(
|
||||
CONF_WINDOW, default="30ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_ACTIVE, default=True): cv.boolean,
|
||||
}
|
||||
),
|
||||
validate_scan_parameters,
|
||||
),
|
||||
cv.Optional(CONF_ON_BLE_ADVERTISE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ESPBTAdvertiseTrigger),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_BLE_SERVICE_DATA_ADVERTISE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
BLEServiceDataAdvertiseTrigger
|
||||
),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Required(CONF_SERVICE_UUID): bt_uuid,
|
||||
}
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE
|
||||
): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
BLEManufacturerDataAdvertiseTrigger
|
||||
),
|
||||
cv.Optional(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Required(CONF_MANUFACTURER_ID): bt_uuid,
|
||||
}
|
||||
),
|
||||
cv.Optional("scan_interval"): cv.invalid(
|
||||
"This option has been removed in 1.14 (Reason: " "it never had an effect)"
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
cv.Optional('scan_interval'): cv.invalid("This option has been removed in 1.14 (Reason: "
|
||||
"it never had an effect)"),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
ESP_BLE_DEVICE_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_id(ESP32BLETracker),
|
||||
})
|
||||
ESP_BLE_DEVICE_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_ESP32_BLE_ID): cv.use_id(ESP32BLETracker),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -135,7 +188,7 @@ def to_code(config):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if CONF_MAC_ADDRESS in conf:
|
||||
cg.add(trigger.set_address(conf[CONF_MAC_ADDRESS].as_hex))
|
||||
yield automation.build_automation(trigger, [(ESPBTDeviceConstRef, 'x')], conf)
|
||||
yield automation.build_automation(trigger, [(ESPBTDeviceConstRef, "x")], conf)
|
||||
for conf in config.get(CONF_ON_BLE_SERVICE_DATA_ADVERTISE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if len(conf[CONF_SERVICE_UUID]) == len(bt_uuid16_format):
|
||||
@ -147,7 +200,7 @@ def to_code(config):
|
||||
cg.add(trigger.set_service_uuid128(uuid128))
|
||||
if CONF_MAC_ADDRESS in conf:
|
||||
cg.add(trigger.set_address(conf[CONF_MAC_ADDRESS].as_hex))
|
||||
yield automation.build_automation(trigger, [(adv_data_t_const_ref, 'x')], conf)
|
||||
yield automation.build_automation(trigger, [(adv_data_t_const_ref, "x")], conf)
|
||||
for conf in config.get(CONF_ON_BLE_MANUFACTURER_DATA_ADVERTISE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
if len(conf[CONF_MANUFACTURER_ID]) == len(bt_uuid16_format):
|
||||
@ -159,7 +212,7 @@ def to_code(config):
|
||||
cg.add(trigger.set_manufacturer_uuid128(uuid128))
|
||||
if CONF_MAC_ADDRESS in conf:
|
||||
cg.add(trigger.set_address(conf[CONF_MAC_ADDRESS].as_hex))
|
||||
yield automation.build_automation(trigger, [(adv_data_t_const_ref, 'x')], conf)
|
||||
yield automation.build_automation(trigger, [(adv_data_t_const_ref, "x")], conf)
|
||||
|
||||
|
||||
@coroutine
|
||||
|
@ -1,105 +1,126 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NAME, CONF_PIN, CONF_SCL, CONF_SDA, \
|
||||
ESP_PLATFORM_ESP32, CONF_DATA_PINS, CONF_RESET_PIN, CONF_RESOLUTION, CONF_BRIGHTNESS, \
|
||||
CONF_CONTRAST
|
||||
from esphome.const import (
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_NAME,
|
||||
CONF_PIN,
|
||||
CONF_SCL,
|
||||
CONF_SDA,
|
||||
ESP_PLATFORM_ESP32,
|
||||
CONF_DATA_PINS,
|
||||
CONF_RESET_PIN,
|
||||
CONF_RESOLUTION,
|
||||
CONF_BRIGHTNESS,
|
||||
CONF_CONTRAST,
|
||||
)
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
DEPENDENCIES = ['api']
|
||||
DEPENDENCIES = ["api"]
|
||||
|
||||
esp32_camera_ns = cg.esphome_ns.namespace('esp32_camera')
|
||||
ESP32Camera = esp32_camera_ns.class_('ESP32Camera', cg.PollingComponent, cg.Nameable)
|
||||
ESP32CameraFrameSize = esp32_camera_ns.enum('ESP32CameraFrameSize')
|
||||
esp32_camera_ns = cg.esphome_ns.namespace("esp32_camera")
|
||||
ESP32Camera = esp32_camera_ns.class_("ESP32Camera", cg.PollingComponent, cg.Nameable)
|
||||
ESP32CameraFrameSize = esp32_camera_ns.enum("ESP32CameraFrameSize")
|
||||
FRAME_SIZES = {
|
||||
'160X120': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
|
||||
'QQVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
|
||||
'128X160': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
|
||||
'QQVGA2': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
|
||||
'176X144': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
|
||||
'QCIF': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
|
||||
'240X176': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
|
||||
'HQVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
|
||||
'320X240': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
|
||||
'QVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
|
||||
'400X296': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
|
||||
'CIF': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
|
||||
'640X480': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
|
||||
'VGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
|
||||
'800X600': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
|
||||
'SVGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
|
||||
'1024X768': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
|
||||
'XGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
|
||||
'1280X1024': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
|
||||
'SXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
|
||||
'1600X1200': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
|
||||
'UXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
|
||||
"160X120": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
|
||||
"QQVGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_160X120,
|
||||
"128X160": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
|
||||
"QQVGA2": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_128X160,
|
||||
"176X144": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
|
||||
"QCIF": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_176X144,
|
||||
"240X176": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
|
||||
"HQVGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_240X176,
|
||||
"320X240": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
|
||||
"QVGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_320X240,
|
||||
"400X296": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
|
||||
"CIF": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_400X296,
|
||||
"640X480": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
|
||||
"VGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_640X480,
|
||||
"800X600": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
|
||||
"SVGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_800X600,
|
||||
"1024X768": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
|
||||
"XGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1024X768,
|
||||
"1280X1024": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
|
||||
"SXGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1280X1024,
|
||||
"1600X1200": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
|
||||
"UXGA": ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
|
||||
}
|
||||
|
||||
CONF_VSYNC_PIN = 'vsync_pin'
|
||||
CONF_HREF_PIN = 'href_pin'
|
||||
CONF_PIXEL_CLOCK_PIN = 'pixel_clock_pin'
|
||||
CONF_EXTERNAL_CLOCK = 'external_clock'
|
||||
CONF_I2C_PINS = 'i2c_pins'
|
||||
CONF_POWER_DOWN_PIN = 'power_down_pin'
|
||||
CONF_VSYNC_PIN = "vsync_pin"
|
||||
CONF_HREF_PIN = "href_pin"
|
||||
CONF_PIXEL_CLOCK_PIN = "pixel_clock_pin"
|
||||
CONF_EXTERNAL_CLOCK = "external_clock"
|
||||
CONF_I2C_PINS = "i2c_pins"
|
||||
CONF_POWER_DOWN_PIN = "power_down_pin"
|
||||
|
||||
CONF_MAX_FRAMERATE = 'max_framerate'
|
||||
CONF_IDLE_FRAMERATE = 'idle_framerate'
|
||||
CONF_JPEG_QUALITY = 'jpeg_quality'
|
||||
CONF_VERTICAL_FLIP = 'vertical_flip'
|
||||
CONF_HORIZONTAL_MIRROR = 'horizontal_mirror'
|
||||
CONF_SATURATION = 'saturation'
|
||||
CONF_TEST_PATTERN = 'test_pattern'
|
||||
CONF_MAX_FRAMERATE = "max_framerate"
|
||||
CONF_IDLE_FRAMERATE = "idle_framerate"
|
||||
CONF_JPEG_QUALITY = "jpeg_quality"
|
||||
CONF_VERTICAL_FLIP = "vertical_flip"
|
||||
CONF_HORIZONTAL_MIRROR = "horizontal_mirror"
|
||||
CONF_SATURATION = "saturation"
|
||||
CONF_TEST_PATTERN = "test_pattern"
|
||||
|
||||
camera_range_param = cv.int_range(min=-2, max=2)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ESP32Camera),
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
cv.Required(CONF_DATA_PINS): cv.All([pins.input_pin], cv.Length(min=8, max=8)),
|
||||
cv.Required(CONF_VSYNC_PIN): pins.input_pin,
|
||||
cv.Required(CONF_HREF_PIN): pins.input_pin,
|
||||
cv.Required(CONF_PIXEL_CLOCK_PIN): pins.input_pin,
|
||||
cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema({
|
||||
cv.Required(CONF_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_FREQUENCY, default='20MHz'): cv.All(cv.frequency, cv.one_of(20e6, 10e6)),
|
||||
}),
|
||||
cv.Required(CONF_I2C_PINS): cv.Schema({
|
||||
cv.Required(CONF_SDA): pins.output_pin,
|
||||
cv.Required(CONF_SCL): pins.output_pin,
|
||||
}),
|
||||
cv.Optional(CONF_RESET_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_POWER_DOWN_PIN): pins.output_pin,
|
||||
|
||||
cv.Optional(CONF_MAX_FRAMERATE, default='10 fps'): cv.All(cv.framerate,
|
||||
cv.Range(min=0, min_included=False,
|
||||
max=60)),
|
||||
cv.Optional(CONF_IDLE_FRAMERATE, default='0.1 fps'): cv.All(cv.framerate,
|
||||
cv.Range(min=0, max=1)),
|
||||
cv.Optional(CONF_RESOLUTION, default='640X480'): cv.enum(FRAME_SIZES, upper=True),
|
||||
cv.Optional(CONF_JPEG_QUALITY, default=10): cv.int_range(min=10, max=63),
|
||||
cv.Optional(CONF_CONTRAST, default=0): camera_range_param,
|
||||
cv.Optional(CONF_BRIGHTNESS, default=0): camera_range_param,
|
||||
cv.Optional(CONF_SATURATION, default=0): camera_range_param,
|
||||
cv.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
|
||||
cv.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
|
||||
cv.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32Camera),
|
||||
cv.Required(CONF_NAME): cv.string,
|
||||
cv.Required(CONF_DATA_PINS): cv.All([pins.input_pin], cv.Length(min=8, max=8)),
|
||||
cv.Required(CONF_VSYNC_PIN): pins.input_pin,
|
||||
cv.Required(CONF_HREF_PIN): pins.input_pin,
|
||||
cv.Required(CONF_PIXEL_CLOCK_PIN): pins.input_pin,
|
||||
cv.Required(CONF_EXTERNAL_CLOCK): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_FREQUENCY, default="20MHz"): cv.All(
|
||||
cv.frequency, cv.one_of(20e6, 10e6)
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.Required(CONF_I2C_PINS): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_SDA): pins.output_pin,
|
||||
cv.Required(CONF_SCL): pins.output_pin,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_RESET_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_POWER_DOWN_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_MAX_FRAMERATE, default="10 fps"): cv.All(
|
||||
cv.framerate, cv.Range(min=0, min_included=False, max=60)
|
||||
),
|
||||
cv.Optional(CONF_IDLE_FRAMERATE, default="0.1 fps"): cv.All(
|
||||
cv.framerate, cv.Range(min=0, max=1)
|
||||
),
|
||||
cv.Optional(CONF_RESOLUTION, default="640X480"): cv.enum(
|
||||
FRAME_SIZES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_JPEG_QUALITY, default=10): cv.int_range(min=10, max=63),
|
||||
cv.Optional(CONF_CONTRAST, default=0): camera_range_param,
|
||||
cv.Optional(CONF_BRIGHTNESS, default=0): camera_range_param,
|
||||
cv.Optional(CONF_SATURATION, default=0): camera_range_param,
|
||||
cv.Optional(CONF_VERTICAL_FLIP, default=True): cv.boolean,
|
||||
cv.Optional(CONF_HORIZONTAL_MIRROR, default=True): cv.boolean,
|
||||
cv.Optional(CONF_TEST_PATTERN, default=False): cv.boolean,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
SETTERS = {
|
||||
CONF_DATA_PINS: 'set_data_pins',
|
||||
CONF_VSYNC_PIN: 'set_vsync_pin',
|
||||
CONF_HREF_PIN: 'set_href_pin',
|
||||
CONF_PIXEL_CLOCK_PIN: 'set_pixel_clock_pin',
|
||||
CONF_RESET_PIN: 'set_reset_pin',
|
||||
CONF_POWER_DOWN_PIN: 'set_power_down_pin',
|
||||
CONF_JPEG_QUALITY: 'set_jpeg_quality',
|
||||
CONF_VERTICAL_FLIP: 'set_vertical_flip',
|
||||
CONF_HORIZONTAL_MIRROR: 'set_horizontal_mirror',
|
||||
CONF_CONTRAST: 'set_contrast',
|
||||
CONF_BRIGHTNESS: 'set_brightness',
|
||||
CONF_SATURATION: 'set_saturation',
|
||||
CONF_TEST_PATTERN: 'set_test_pattern',
|
||||
CONF_DATA_PINS: "set_data_pins",
|
||||
CONF_VSYNC_PIN: "set_vsync_pin",
|
||||
CONF_HREF_PIN: "set_href_pin",
|
||||
CONF_PIXEL_CLOCK_PIN: "set_pixel_clock_pin",
|
||||
CONF_RESET_PIN: "set_reset_pin",
|
||||
CONF_POWER_DOWN_PIN: "set_power_down_pin",
|
||||
CONF_JPEG_QUALITY: "set_jpeg_quality",
|
||||
CONF_VERTICAL_FLIP: "set_vertical_flip",
|
||||
CONF_HORIZONTAL_MIRROR: "set_horizontal_mirror",
|
||||
CONF_CONTRAST: "set_contrast",
|
||||
CONF_BRIGHTNESS: "set_brightness",
|
||||
CONF_SATURATION: "set_saturation",
|
||||
CONF_TEST_PATTERN: "set_test_pattern",
|
||||
}
|
||||
|
||||
|
||||
@ -122,5 +143,5 @@ def to_code(config):
|
||||
cg.add(var.set_idle_update_interval(1000 / config[CONF_IDLE_FRAMERATE]))
|
||||
cg.add(var.set_frame_size(config[CONF_RESOLUTION]))
|
||||
|
||||
cg.add_define('USE_ESP32_CAMERA')
|
||||
cg.add_build_flag('-DBOARD_HAS_PSRAM')
|
||||
cg.add_define("USE_ESP32_CAMERA")
|
||||
cg.add_build_flag("-DBOARD_HAS_PSRAM")
|
||||
|
@ -13,13 +13,17 @@ def valid_dac_pin(value):
|
||||
return value
|
||||
|
||||
|
||||
esp32_dac_ns = cg.esphome_ns.namespace('esp32_dac')
|
||||
ESP32DAC = esp32_dac_ns.class_('ESP32DAC', output.FloatOutput, cg.Component)
|
||||
esp32_dac_ns = cg.esphome_ns.namespace("esp32_dac")
|
||||
ESP32DAC = esp32_dac_ns.class_("ESP32DAC", output.FloatOutput, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(ESP32DAC),
|
||||
cv.Required(CONF_PIN): cv.All(pins.internal_gpio_output_pin_schema, valid_dac_pin),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(ESP32DAC),
|
||||
cv.Required(CONF_PIN): cv.All(
|
||||
pins.internal_gpio_output_pin_schema, valid_dac_pin
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,17 +1,30 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY, ESP_PLATFORM_ESP32, UNIT_MICROTESLA, \
|
||||
ICON_MAGNET
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ESP_PLATFORM_ESP32,
|
||||
UNIT_MICROTESLA,
|
||||
ICON_MAGNET,
|
||||
)
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
esp32_hall_ns = cg.esphome_ns.namespace('esp32_hall')
|
||||
ESP32HallSensor = esp32_hall_ns.class_('ESP32HallSensor', sensor.Sensor, cg.PollingComponent)
|
||||
esp32_hall_ns = cg.esphome_ns.namespace("esp32_hall")
|
||||
ESP32HallSensor = esp32_hall_ns.class_(
|
||||
"ESP32HallSensor", sensor.Sensor, cg.PollingComponent
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_MICROTESLA, ICON_MAGNET, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(ESP32HallSensor),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_MICROTESLA, ICON_MAGNET, 1, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32HallSensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,15 +1,23 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import CONF_HIGH_VOLTAGE_REFERENCE, CONF_ID, CONF_IIR_FILTER, \
|
||||
CONF_LOW_VOLTAGE_REFERENCE, CONF_MEASUREMENT_DURATION, CONF_SETUP_MODE, CONF_SLEEP_DURATION, \
|
||||
CONF_VOLTAGE_ATTENUATION, ESP_PLATFORM_ESP32
|
||||
from esphome.const import (
|
||||
CONF_HIGH_VOLTAGE_REFERENCE,
|
||||
CONF_ID,
|
||||
CONF_IIR_FILTER,
|
||||
CONF_LOW_VOLTAGE_REFERENCE,
|
||||
CONF_MEASUREMENT_DURATION,
|
||||
CONF_SETUP_MODE,
|
||||
CONF_SLEEP_DURATION,
|
||||
CONF_VOLTAGE_ATTENUATION,
|
||||
ESP_PLATFORM_ESP32,
|
||||
)
|
||||
from esphome.core import TimePeriod
|
||||
|
||||
AUTO_LOAD = ['binary_sensor']
|
||||
AUTO_LOAD = ["binary_sensor"]
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
esp32_touch_ns = cg.esphome_ns.namespace('esp32_touch')
|
||||
ESP32TouchComponent = esp32_touch_ns.class_('ESP32TouchComponent', cg.Component)
|
||||
esp32_touch_ns = cg.esphome_ns.namespace("esp32_touch")
|
||||
ESP32TouchComponent = esp32_touch_ns.class_("ESP32TouchComponent", cg.Component)
|
||||
|
||||
|
||||
def validate_voltage(values):
|
||||
@ -17,46 +25,56 @@ def validate_voltage(values):
|
||||
if isinstance(value, float) and value.is_integer():
|
||||
value = int(value)
|
||||
value = cv.string(value)
|
||||
if not value.endswith('V'):
|
||||
value += 'V'
|
||||
if not value.endswith("V"):
|
||||
value += "V"
|
||||
return cv.one_of(*values)(value)
|
||||
|
||||
return validator
|
||||
|
||||
|
||||
LOW_VOLTAGE_REFERENCE = {
|
||||
'0.5V': cg.global_ns.TOUCH_LVOLT_0V5,
|
||||
'0.6V': cg.global_ns.TOUCH_LVOLT_0V6,
|
||||
'0.7V': cg.global_ns.TOUCH_LVOLT_0V7,
|
||||
'0.8V': cg.global_ns.TOUCH_LVOLT_0V8,
|
||||
"0.5V": cg.global_ns.TOUCH_LVOLT_0V5,
|
||||
"0.6V": cg.global_ns.TOUCH_LVOLT_0V6,
|
||||
"0.7V": cg.global_ns.TOUCH_LVOLT_0V7,
|
||||
"0.8V": cg.global_ns.TOUCH_LVOLT_0V8,
|
||||
}
|
||||
HIGH_VOLTAGE_REFERENCE = {
|
||||
'2.4V': cg.global_ns.TOUCH_HVOLT_2V4,
|
||||
'2.5V': cg.global_ns.TOUCH_HVOLT_2V5,
|
||||
'2.6V': cg.global_ns.TOUCH_HVOLT_2V6,
|
||||
'2.7V': cg.global_ns.TOUCH_HVOLT_2V7,
|
||||
"2.4V": cg.global_ns.TOUCH_HVOLT_2V4,
|
||||
"2.5V": cg.global_ns.TOUCH_HVOLT_2V5,
|
||||
"2.6V": cg.global_ns.TOUCH_HVOLT_2V6,
|
||||
"2.7V": cg.global_ns.TOUCH_HVOLT_2V7,
|
||||
}
|
||||
VOLTAGE_ATTENUATION = {
|
||||
'1.5V': cg.global_ns.TOUCH_HVOLT_ATTEN_1V5,
|
||||
'1V': cg.global_ns.TOUCH_HVOLT_ATTEN_1V,
|
||||
'0.5V': cg.global_ns.TOUCH_HVOLT_ATTEN_0V5,
|
||||
'0V': cg.global_ns.TOUCH_HVOLT_ATTEN_0V,
|
||||
"1.5V": cg.global_ns.TOUCH_HVOLT_ATTEN_1V5,
|
||||
"1V": cg.global_ns.TOUCH_HVOLT_ATTEN_1V,
|
||||
"0.5V": cg.global_ns.TOUCH_HVOLT_ATTEN_0V5,
|
||||
"0V": cg.global_ns.TOUCH_HVOLT_ATTEN_0V,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(ESP32TouchComponent),
|
||||
cv.Optional(CONF_SETUP_MODE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_IIR_FILTER, default='0ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SLEEP_DURATION, default='27306us'):
|
||||
cv.All(cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=436906))),
|
||||
cv.Optional(CONF_MEASUREMENT_DURATION, default='8192us'):
|
||||
cv.All(cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=8192))),
|
||||
cv.Optional(CONF_LOW_VOLTAGE_REFERENCE, default='0.5V'):
|
||||
validate_voltage(LOW_VOLTAGE_REFERENCE),
|
||||
cv.Optional(CONF_HIGH_VOLTAGE_REFERENCE, default='2.7V'):
|
||||
validate_voltage(HIGH_VOLTAGE_REFERENCE),
|
||||
cv.Optional(CONF_VOLTAGE_ATTENUATION, default='0V'): validate_voltage(VOLTAGE_ATTENUATION),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32TouchComponent),
|
||||
cv.Optional(CONF_SETUP_MODE, default=False): cv.boolean,
|
||||
cv.Optional(
|
||||
CONF_IIR_FILTER, default="0ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SLEEP_DURATION, default="27306us"): cv.All(
|
||||
cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=436906))
|
||||
),
|
||||
cv.Optional(CONF_MEASUREMENT_DURATION, default="8192us"): cv.All(
|
||||
cv.positive_time_period, cv.Range(max=TimePeriod(microseconds=8192))
|
||||
),
|
||||
cv.Optional(CONF_LOW_VOLTAGE_REFERENCE, default="0.5V"): validate_voltage(
|
||||
LOW_VOLTAGE_REFERENCE
|
||||
),
|
||||
cv.Optional(CONF_HIGH_VOLTAGE_REFERENCE, default="2.7V"): validate_voltage(
|
||||
HIGH_VOLTAGE_REFERENCE
|
||||
),
|
||||
cv.Optional(CONF_VOLTAGE_ATTENUATION, default="0V"): validate_voltage(
|
||||
VOLTAGE_ATTENUATION
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -69,12 +87,23 @@ def to_code(config):
|
||||
sleep_duration = int(round(config[CONF_SLEEP_DURATION].total_microseconds * 0.15))
|
||||
cg.add(touch.set_sleep_duration(sleep_duration))
|
||||
|
||||
measurement_duration = int(round(config[CONF_MEASUREMENT_DURATION].total_microseconds *
|
||||
7.99987793))
|
||||
measurement_duration = int(
|
||||
round(config[CONF_MEASUREMENT_DURATION].total_microseconds * 7.99987793)
|
||||
)
|
||||
cg.add(touch.set_measurement_duration(measurement_duration))
|
||||
|
||||
cg.add(touch.set_low_voltage_reference(
|
||||
LOW_VOLTAGE_REFERENCE[config[CONF_LOW_VOLTAGE_REFERENCE]]))
|
||||
cg.add(touch.set_high_voltage_reference(
|
||||
HIGH_VOLTAGE_REFERENCE[config[CONF_HIGH_VOLTAGE_REFERENCE]]))
|
||||
cg.add(touch.set_voltage_attenuation(VOLTAGE_ATTENUATION[config[CONF_VOLTAGE_ATTENUATION]]))
|
||||
cg.add(
|
||||
touch.set_low_voltage_reference(
|
||||
LOW_VOLTAGE_REFERENCE[config[CONF_LOW_VOLTAGE_REFERENCE]]
|
||||
)
|
||||
)
|
||||
cg.add(
|
||||
touch.set_high_voltage_reference(
|
||||
HIGH_VOLTAGE_REFERENCE[config[CONF_HIGH_VOLTAGE_REFERENCE]]
|
||||
)
|
||||
)
|
||||
cg.add(
|
||||
touch.set_voltage_attenuation(
|
||||
VOLTAGE_ATTENUATION[config[CONF_VOLTAGE_ATTENUATION]]
|
||||
)
|
||||
)
|
||||
|
@ -1,14 +1,20 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_NAME, CONF_PIN, CONF_THRESHOLD, ESP_PLATFORM_ESP32, CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_NAME,
|
||||
CONF_PIN,
|
||||
CONF_THRESHOLD,
|
||||
ESP_PLATFORM_ESP32,
|
||||
CONF_ID,
|
||||
)
|
||||
from esphome.pins import validate_gpio_pin
|
||||
from . import esp32_touch_ns, ESP32TouchComponent
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
DEPENDENCIES = ['esp32_touch']
|
||||
DEPENDENCIES = ["esp32_touch"]
|
||||
|
||||
CONF_ESP32_TOUCH_ID = 'esp32_touch_id'
|
||||
CONF_ESP32_TOUCH_ID = "esp32_touch_id"
|
||||
|
||||
TOUCH_PADS = {
|
||||
4: cg.global_ns.TOUCH_PAD_NUM0,
|
||||
@ -31,19 +37,27 @@ def validate_touch_pad(value):
|
||||
return value
|
||||
|
||||
|
||||
ESP32TouchBinarySensor = esp32_touch_ns.class_('ESP32TouchBinarySensor', binary_sensor.BinarySensor)
|
||||
ESP32TouchBinarySensor = esp32_touch_ns.class_(
|
||||
"ESP32TouchBinarySensor", binary_sensor.BinarySensor
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(ESP32TouchBinarySensor),
|
||||
cv.GenerateID(CONF_ESP32_TOUCH_ID): cv.use_id(ESP32TouchComponent),
|
||||
cv.Required(CONF_PIN): validate_touch_pad,
|
||||
cv.Required(CONF_THRESHOLD): cv.uint16_t,
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ESP32TouchBinarySensor),
|
||||
cv.GenerateID(CONF_ESP32_TOUCH_ID): cv.use_id(ESP32TouchComponent),
|
||||
cv.Required(CONF_PIN): validate_touch_pad,
|
||||
cv.Required(CONF_THRESHOLD): cv.uint16_t,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
hub = yield cg.get_variable(config[CONF_ESP32_TOUCH_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], config[CONF_NAME], TOUCH_PADS[config[CONF_PIN]],
|
||||
config[CONF_THRESHOLD])
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
config[CONF_NAME],
|
||||
TOUCH_PADS[config[CONF_PIN]],
|
||||
config[CONF_THRESHOLD],
|
||||
)
|
||||
yield binary_sensor.register_binary_sensor(var, config)
|
||||
cg.add(hub.register_touch_pad(var))
|
||||
|
@ -2,7 +2,13 @@ from esphome import pins, automation
|
||||
from esphome.components import output
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NUMBER, CONF_PIN, ESP_PLATFORM_ESP8266
|
||||
from esphome.const import (
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_NUMBER,
|
||||
CONF_PIN,
|
||||
ESP_PLATFORM_ESP8266,
|
||||
)
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP8266]
|
||||
|
||||
@ -13,16 +19,20 @@ def valid_pwm_pin(value):
|
||||
return value
|
||||
|
||||
|
||||
esp8266_pwm_ns = cg.esphome_ns.namespace('esp8266_pwm')
|
||||
ESP8266PWM = esp8266_pwm_ns.class_('ESP8266PWM', output.FloatOutput, cg.Component)
|
||||
SetFrequencyAction = esp8266_pwm_ns.class_('SetFrequencyAction', automation.Action)
|
||||
esp8266_pwm_ns = cg.esphome_ns.namespace("esp8266_pwm")
|
||||
ESP8266PWM = esp8266_pwm_ns.class_("ESP8266PWM", output.FloatOutput, cg.Component)
|
||||
SetFrequencyAction = esp8266_pwm_ns.class_("SetFrequencyAction", automation.Action)
|
||||
validate_frequency = cv.All(cv.frequency, cv.Range(min=1.0e-6))
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(ESP8266PWM),
|
||||
cv.Required(CONF_PIN): cv.All(pins.internal_gpio_output_pin_schema, valid_pwm_pin),
|
||||
cv.Optional(CONF_FREQUENCY, default='1kHz'): validate_frequency,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(ESP8266PWM),
|
||||
cv.Required(CONF_PIN): cv.All(
|
||||
pins.internal_gpio_output_pin_schema, valid_pwm_pin
|
||||
),
|
||||
cv.Optional(CONF_FREQUENCY, default="1kHz"): validate_frequency,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -36,10 +46,16 @@ def to_code(config):
|
||||
cg.add(var.set_frequency(config[CONF_FREQUENCY]))
|
||||
|
||||
|
||||
@automation.register_action('output.esp8266_pwm.set_frequency', SetFrequencyAction, cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(ESP8266PWM),
|
||||
cv.Required(CONF_FREQUENCY): cv.templatable(validate_frequency),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"output.esp8266_pwm.set_frequency",
|
||||
SetFrequencyAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(ESP8266PWM),
|
||||
cv.Required(CONF_FREQUENCY): cv.templatable(validate_frequency),
|
||||
}
|
||||
),
|
||||
)
|
||||
def esp8266_set_frequency_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -1,47 +1,60 @@
|
||||
from esphome import pins
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import CONF_DOMAIN, CONF_ID, CONF_MANUAL_IP, CONF_STATIC_IP, CONF_TYPE, \
|
||||
CONF_USE_ADDRESS, ESP_PLATFORM_ESP32, CONF_GATEWAY, CONF_SUBNET, CONF_DNS1, CONF_DNS2
|
||||
from esphome.const import (
|
||||
CONF_DOMAIN,
|
||||
CONF_ID,
|
||||
CONF_MANUAL_IP,
|
||||
CONF_STATIC_IP,
|
||||
CONF_TYPE,
|
||||
CONF_USE_ADDRESS,
|
||||
ESP_PLATFORM_ESP32,
|
||||
CONF_GATEWAY,
|
||||
CONF_SUBNET,
|
||||
CONF_DNS1,
|
||||
CONF_DNS2,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
|
||||
CONFLICTS_WITH = ['wifi']
|
||||
CONFLICTS_WITH = ["wifi"]
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
AUTO_LOAD = ['network']
|
||||
AUTO_LOAD = ["network"]
|
||||
|
||||
ethernet_ns = cg.esphome_ns.namespace('ethernet')
|
||||
CONF_PHY_ADDR = 'phy_addr'
|
||||
CONF_MDC_PIN = 'mdc_pin'
|
||||
CONF_MDIO_PIN = 'mdio_pin'
|
||||
CONF_CLK_MODE = 'clk_mode'
|
||||
CONF_POWER_PIN = 'power_pin'
|
||||
ethernet_ns = cg.esphome_ns.namespace("ethernet")
|
||||
CONF_PHY_ADDR = "phy_addr"
|
||||
CONF_MDC_PIN = "mdc_pin"
|
||||
CONF_MDIO_PIN = "mdio_pin"
|
||||
CONF_CLK_MODE = "clk_mode"
|
||||
CONF_POWER_PIN = "power_pin"
|
||||
|
||||
EthernetType = ethernet_ns.enum('EthernetType')
|
||||
EthernetType = ethernet_ns.enum("EthernetType")
|
||||
ETHERNET_TYPES = {
|
||||
'LAN8720': EthernetType.ETHERNET_TYPE_LAN8720,
|
||||
'TLK110': EthernetType.ETHERNET_TYPE_TLK110,
|
||||
"LAN8720": EthernetType.ETHERNET_TYPE_LAN8720,
|
||||
"TLK110": EthernetType.ETHERNET_TYPE_TLK110,
|
||||
}
|
||||
|
||||
eth_clock_mode_t = cg.global_ns.enum('eth_clock_mode_t')
|
||||
eth_clock_mode_t = cg.global_ns.enum("eth_clock_mode_t")
|
||||
CLK_MODES = {
|
||||
'GPIO0_IN': eth_clock_mode_t.ETH_CLOCK_GPIO0_IN,
|
||||
'GPIO0_OUT': eth_clock_mode_t.ETH_CLOCK_GPIO0_OUT,
|
||||
'GPIO16_OUT': eth_clock_mode_t.ETH_CLOCK_GPIO16_OUT,
|
||||
'GPIO17_OUT': eth_clock_mode_t.ETH_CLOCK_GPIO17_OUT,
|
||||
"GPIO0_IN": eth_clock_mode_t.ETH_CLOCK_GPIO0_IN,
|
||||
"GPIO0_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO0_OUT,
|
||||
"GPIO16_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO16_OUT,
|
||||
"GPIO17_OUT": eth_clock_mode_t.ETH_CLOCK_GPIO17_OUT,
|
||||
}
|
||||
|
||||
|
||||
MANUAL_IP_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_STATIC_IP): cv.ipv4,
|
||||
cv.Required(CONF_GATEWAY): cv.ipv4,
|
||||
cv.Required(CONF_SUBNET): cv.ipv4,
|
||||
cv.Optional(CONF_DNS1, default="0.0.0.0"): cv.ipv4,
|
||||
cv.Optional(CONF_DNS2, default="0.0.0.0"): cv.ipv4,
|
||||
})
|
||||
MANUAL_IP_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_STATIC_IP): cv.ipv4,
|
||||
cv.Required(CONF_GATEWAY): cv.ipv4,
|
||||
cv.Required(CONF_SUBNET): cv.ipv4,
|
||||
cv.Optional(CONF_DNS1, default="0.0.0.0"): cv.ipv4,
|
||||
cv.Optional(CONF_DNS2, default="0.0.0.0"): cv.ipv4,
|
||||
}
|
||||
)
|
||||
|
||||
EthernetComponent = ethernet_ns.class_('EthernetComponent', cg.Component)
|
||||
IPAddress = cg.global_ns.class_('IPAddress')
|
||||
ManualIP = ethernet_ns.struct('ManualIP')
|
||||
EthernetComponent = ethernet_ns.class_("EthernetComponent", cg.Component)
|
||||
IPAddress = cg.global_ns.class_("IPAddress")
|
||||
ManualIP = ethernet_ns.struct("ManualIP")
|
||||
|
||||
|
||||
def validate(config):
|
||||
@ -54,30 +67,38 @@ def validate(config):
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(EthernetComponent),
|
||||
cv.Required(CONF_TYPE): cv.enum(ETHERNET_TYPES, upper=True),
|
||||
cv.Required(CONF_MDC_PIN): pins.output_pin,
|
||||
cv.Required(CONF_MDIO_PIN): pins.input_output_pin,
|
||||
cv.Optional(CONF_CLK_MODE, default='GPIO0_IN'): cv.enum(CLK_MODES, upper=True, space='_'),
|
||||
cv.Optional(CONF_PHY_ADDR, default=0): cv.int_range(min=0, max=31),
|
||||
cv.Optional(CONF_POWER_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_MANUAL_IP): MANUAL_IP_SCHEMA,
|
||||
cv.Optional(CONF_DOMAIN, default='.local'): cv.domain_name,
|
||||
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||
|
||||
cv.Optional('hostname'): cv.invalid("The hostname option has been removed in 1.11.0"),
|
||||
}).extend(cv.COMPONENT_SCHEMA), validate)
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EthernetComponent),
|
||||
cv.Required(CONF_TYPE): cv.enum(ETHERNET_TYPES, upper=True),
|
||||
cv.Required(CONF_MDC_PIN): pins.output_pin,
|
||||
cv.Required(CONF_MDIO_PIN): pins.input_output_pin,
|
||||
cv.Optional(CONF_CLK_MODE, default="GPIO0_IN"): cv.enum(
|
||||
CLK_MODES, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_PHY_ADDR, default=0): cv.int_range(min=0, max=31),
|
||||
cv.Optional(CONF_POWER_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_MANUAL_IP): MANUAL_IP_SCHEMA,
|
||||
cv.Optional(CONF_DOMAIN, default=".local"): cv.domain_name,
|
||||
cv.Optional(CONF_USE_ADDRESS): cv.string_strict,
|
||||
cv.Optional("hostname"): cv.invalid(
|
||||
"The hostname option has been removed in 1.11.0"
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
validate,
|
||||
)
|
||||
|
||||
|
||||
def manual_ip(config):
|
||||
return cg.StructInitializer(
|
||||
ManualIP,
|
||||
('static_ip', IPAddress(*config[CONF_STATIC_IP].args)),
|
||||
('gateway', IPAddress(*config[CONF_GATEWAY].args)),
|
||||
('subnet', IPAddress(*config[CONF_SUBNET].args)),
|
||||
('dns1', IPAddress(*config[CONF_DNS1].args)),
|
||||
('dns2', IPAddress(*config[CONF_DNS2].args)),
|
||||
("static_ip", IPAddress(*config[CONF_STATIC_IP].args)),
|
||||
("gateway", IPAddress(*config[CONF_GATEWAY].args)),
|
||||
("subnet", IPAddress(*config[CONF_SUBNET].args)),
|
||||
("dns1", IPAddress(*config[CONF_DNS1].args)),
|
||||
("dns2", IPAddress(*config[CONF_DNS2].args)),
|
||||
)
|
||||
|
||||
|
||||
@ -100,4 +121,4 @@ def to_code(config):
|
||||
if CONF_MANUAL_IP in config:
|
||||
cg.add(var.set_manual_ip(manual_ip(config[CONF_MANUAL_IP])))
|
||||
|
||||
cg.add_define('USE_ETHERNET')
|
||||
cg.add_define("USE_ETHERNET")
|
||||
|
@ -4,26 +4,36 @@ import esphome.config_validation as cv
|
||||
from esphome.components import esp32_ble_tracker
|
||||
from esphome.const import CONF_TRIGGER_ID
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
exposure_notifications_ns = cg.esphome_ns.namespace('exposure_notifications')
|
||||
ExposureNotification = exposure_notifications_ns.struct('ExposureNotification')
|
||||
exposure_notifications_ns = cg.esphome_ns.namespace("exposure_notifications")
|
||||
ExposureNotification = exposure_notifications_ns.struct("ExposureNotification")
|
||||
ExposureNotificationTrigger = exposure_notifications_ns.class_(
|
||||
'ExposureNotificationTrigger', esp32_ble_tracker.ESPBTDeviceListener,
|
||||
automation.Trigger.template(ExposureNotification))
|
||||
"ExposureNotificationTrigger",
|
||||
esp32_ble_tracker.ESPBTDeviceListener,
|
||||
automation.Trigger.template(ExposureNotification),
|
||||
)
|
||||
|
||||
CONF_ON_EXPOSURE_NOTIFICATION = 'on_exposure_notification'
|
||||
CONF_ON_EXPOSURE_NOTIFICATION = "on_exposure_notification"
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ON_EXPOSURE_NOTIFICATION): automation.validate_automation(cv.Schema({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(ExposureNotificationTrigger),
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)),
|
||||
})
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ON_EXPOSURE_NOTIFICATION): automation.validate_automation(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
ExposureNotificationTrigger
|
||||
),
|
||||
}
|
||||
).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
for conf in config.get(CONF_ON_EXPOSURE_NOTIFICATION, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
|
||||
yield automation.build_automation(trigger, [(ExposureNotification, 'x')], conf)
|
||||
yield automation.build_automation(trigger, [(ExposureNotification, "x")], conf)
|
||||
yield esp32_ble_tracker.register_ble_device(trigger, conf)
|
||||
|
@ -3,17 +3,25 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
CODEOWNERS = ['@ssieb']
|
||||
CODEOWNERS = ["@ssieb"]
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ezo_ns = cg.esphome_ns.namespace('ezo')
|
||||
ezo_ns = cg.esphome_ns.namespace("ezo")
|
||||
|
||||
EZOSensor = ezo_ns.class_('EZOSensor', sensor.Sensor, cg.PollingComponent, i2c.I2CDevice)
|
||||
EZOSensor = ezo_ns.class_(
|
||||
"EZOSensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(EZOSensor),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(None))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(EZOSensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(None))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,42 +3,57 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.components import mqtt
|
||||
from esphome.const import CONF_ID, CONF_INTERNAL, CONF_MQTT_ID, CONF_OSCILLATING, \
|
||||
CONF_OSCILLATION_COMMAND_TOPIC, CONF_OSCILLATION_STATE_TOPIC, CONF_SPEED, \
|
||||
CONF_SPEED_COMMAND_TOPIC, CONF_SPEED_STATE_TOPIC, CONF_NAME
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_MQTT_ID,
|
||||
CONF_OSCILLATING,
|
||||
CONF_OSCILLATION_COMMAND_TOPIC,
|
||||
CONF_OSCILLATION_STATE_TOPIC,
|
||||
CONF_SPEED,
|
||||
CONF_SPEED_COMMAND_TOPIC,
|
||||
CONF_SPEED_STATE_TOPIC,
|
||||
CONF_NAME,
|
||||
)
|
||||
from esphome.core import CORE, coroutine, coroutine_with_priority
|
||||
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
fan_ns = cg.esphome_ns.namespace('fan')
|
||||
FanState = fan_ns.class_('FanState', cg.Nameable, cg.Component)
|
||||
MakeFan = cg.Application.struct('MakeFan')
|
||||
fan_ns = cg.esphome_ns.namespace("fan")
|
||||
FanState = fan_ns.class_("FanState", cg.Nameable, cg.Component)
|
||||
MakeFan = cg.Application.struct("MakeFan")
|
||||
|
||||
# Actions
|
||||
TurnOnAction = fan_ns.class_('TurnOnAction', automation.Action)
|
||||
TurnOffAction = fan_ns.class_('TurnOffAction', automation.Action)
|
||||
ToggleAction = fan_ns.class_('ToggleAction', automation.Action)
|
||||
TurnOnAction = fan_ns.class_("TurnOnAction", automation.Action)
|
||||
TurnOffAction = fan_ns.class_("TurnOffAction", automation.Action)
|
||||
ToggleAction = fan_ns.class_("ToggleAction", automation.Action)
|
||||
|
||||
FanSpeed = fan_ns.enum('FanSpeed')
|
||||
FanSpeed = fan_ns.enum("FanSpeed")
|
||||
FAN_SPEEDS = {
|
||||
'OFF': FanSpeed.FAN_SPEED_OFF,
|
||||
'LOW': FanSpeed.FAN_SPEED_LOW,
|
||||
'MEDIUM': FanSpeed.FAN_SPEED_MEDIUM,
|
||||
'HIGH': FanSpeed.FAN_SPEED_HIGH,
|
||||
"OFF": FanSpeed.FAN_SPEED_OFF,
|
||||
"LOW": FanSpeed.FAN_SPEED_LOW,
|
||||
"MEDIUM": FanSpeed.FAN_SPEED_MEDIUM,
|
||||
"HIGH": FanSpeed.FAN_SPEED_HIGH,
|
||||
}
|
||||
|
||||
FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(FanState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTFanComponent),
|
||||
cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(cv.requires_component('mqtt'),
|
||||
cv.publish_topic),
|
||||
cv.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.All(cv.requires_component('mqtt'),
|
||||
cv.subscribe_topic),
|
||||
cv.Optional(CONF_SPEED_STATE_TOPIC): cv.All(cv.requires_component('mqtt'),
|
||||
cv.publish_topic),
|
||||
cv.Optional(CONF_SPEED_COMMAND_TOPIC): cv.All(cv.requires_component('mqtt'),
|
||||
cv.subscribe_topic),
|
||||
})
|
||||
FAN_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(FanState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTFanComponent),
|
||||
cv.Optional(CONF_OSCILLATION_STATE_TOPIC): cv.All(
|
||||
cv.requires_component("mqtt"), cv.publish_topic
|
||||
),
|
||||
cv.Optional(CONF_OSCILLATION_COMMAND_TOPIC): cv.All(
|
||||
cv.requires_component("mqtt"), cv.subscribe_topic
|
||||
),
|
||||
cv.Optional(CONF_SPEED_STATE_TOPIC): cv.All(
|
||||
cv.requires_component("mqtt"), cv.publish_topic
|
||||
),
|
||||
cv.Optional(CONF_SPEED_COMMAND_TOPIC): cv.All(
|
||||
cv.requires_component("mqtt"), cv.subscribe_topic
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -52,14 +67,23 @@ def setup_fan_core_(var, config):
|
||||
yield mqtt.register_mqtt_component(mqtt_, config)
|
||||
|
||||
if CONF_OSCILLATION_STATE_TOPIC in config:
|
||||
cg.add(mqtt_.set_custom_oscillation_state_topic(config[CONF_OSCILLATION_STATE_TOPIC]))
|
||||
cg.add(
|
||||
mqtt_.set_custom_oscillation_state_topic(
|
||||
config[CONF_OSCILLATION_STATE_TOPIC]
|
||||
)
|
||||
)
|
||||
if CONF_OSCILLATION_COMMAND_TOPIC in config:
|
||||
cg.add(mqtt_.set_custom_oscillation_command_topic(
|
||||
config[CONF_OSCILLATION_COMMAND_TOPIC]))
|
||||
cg.add(
|
||||
mqtt_.set_custom_oscillation_command_topic(
|
||||
config[CONF_OSCILLATION_COMMAND_TOPIC]
|
||||
)
|
||||
)
|
||||
if CONF_SPEED_STATE_TOPIC in config:
|
||||
cg.add(mqtt_.set_custom_speed_state_topic(config[CONF_SPEED_STATE_TOPIC]))
|
||||
if CONF_SPEED_COMMAND_TOPIC in config:
|
||||
cg.add(mqtt_.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC]))
|
||||
cg.add(
|
||||
mqtt_.set_custom_speed_command_topic(config[CONF_SPEED_COMMAND_TOPIC])
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -78,28 +102,36 @@ def create_fan_state(config):
|
||||
yield var
|
||||
|
||||
|
||||
FAN_ACTION_SCHEMA = maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(FanState),
|
||||
})
|
||||
FAN_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(FanState),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('fan.toggle', ToggleAction, FAN_ACTION_SCHEMA)
|
||||
@automation.register_action("fan.toggle", ToggleAction, FAN_ACTION_SCHEMA)
|
||||
def fan_toggle_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('fan.turn_off', TurnOffAction, FAN_ACTION_SCHEMA)
|
||||
@automation.register_action("fan.turn_off", TurnOffAction, FAN_ACTION_SCHEMA)
|
||||
def fan_turn_off_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('fan.turn_on', TurnOnAction, maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(FanState),
|
||||
cv.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
||||
cv.Optional(CONF_SPEED): cv.templatable(cv.enum(FAN_SPEEDS, upper=True)),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"fan.turn_on",
|
||||
TurnOnAction,
|
||||
maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(FanState),
|
||||
cv.Optional(CONF_OSCILLATING): cv.templatable(cv.boolean),
|
||||
cv.Optional(CONF_SPEED): cv.templatable(cv.enum(FAN_SPEEDS, upper=True)),
|
||||
}
|
||||
),
|
||||
)
|
||||
def fan_turn_on_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -114,5 +146,5 @@ def fan_turn_on_to_code(config, action_id, template_arg, args):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_define('USE_FAN')
|
||||
cg.add_define("USE_FAN")
|
||||
cg.add_global(fan_ns.using)
|
||||
|
@ -1,29 +1,37 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import light
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_NUM_LEDS, CONF_RGB_ORDER, CONF_MAX_REFRESH_RATE
|
||||
from esphome.const import (
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_NUM_LEDS,
|
||||
CONF_RGB_ORDER,
|
||||
CONF_MAX_REFRESH_RATE,
|
||||
)
|
||||
from esphome.core import coroutine
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
fastled_base_ns = cg.esphome_ns.namespace('fastled_base')
|
||||
FastLEDLightOutput = fastled_base_ns.class_('FastLEDLightOutput', light.AddressableLight)
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
fastled_base_ns = cg.esphome_ns.namespace("fastled_base")
|
||||
FastLEDLightOutput = fastled_base_ns.class_(
|
||||
"FastLEDLightOutput", light.AddressableLight
|
||||
)
|
||||
|
||||
RGB_ORDERS = [
|
||||
'RGB',
|
||||
'RBG',
|
||||
'GRB',
|
||||
'GBR',
|
||||
'BRG',
|
||||
'BGR',
|
||||
"RGB",
|
||||
"RBG",
|
||||
"GRB",
|
||||
"GBR",
|
||||
"BRG",
|
||||
"BGR",
|
||||
]
|
||||
|
||||
BASE_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(FastLEDLightOutput),
|
||||
|
||||
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||
cv.Optional(CONF_RGB_ORDER): cv.one_of(*RGB_ORDERS, upper=True),
|
||||
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
BASE_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(FastLEDLightOutput),
|
||||
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||
cv.Optional(CONF_RGB_ORDER): cv.one_of(*RGB_ORDERS, upper=True),
|
||||
cv.Optional(CONF_MAX_REFRESH_RATE): cv.positive_time_period_microseconds,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -38,5 +46,5 @@ def new_fastled_light(config):
|
||||
# https://github.com/FastLED/FastLED/blob/master/library.json
|
||||
# 3.3.3 has an issue on ESP32 with RMT and fastled_clockless:
|
||||
# https://github.com/esphome/issues/issues/1375
|
||||
cg.add_library('FastLED', '3.3.2')
|
||||
cg.add_library("FastLED", "3.3.2")
|
||||
yield var
|
||||
|
@ -4,46 +4,51 @@ from esphome import pins
|
||||
from esphome.components import fastled_base
|
||||
from esphome.const import CONF_CHIPSET, CONF_NUM_LEDS, CONF_PIN, CONF_RGB_ORDER
|
||||
|
||||
AUTO_LOAD = ['fastled_base']
|
||||
AUTO_LOAD = ["fastled_base"]
|
||||
|
||||
CHIPSETS = [
|
||||
'NEOPIXEL',
|
||||
'TM1829',
|
||||
'TM1809',
|
||||
'TM1804',
|
||||
'TM1803',
|
||||
'UCS1903',
|
||||
'UCS1903B',
|
||||
'UCS1904',
|
||||
'UCS2903',
|
||||
'WS2812',
|
||||
'WS2852',
|
||||
'WS2812B',
|
||||
'SK6812',
|
||||
'SK6822',
|
||||
'APA106',
|
||||
'PL9823',
|
||||
'WS2811',
|
||||
'WS2813',
|
||||
'APA104',
|
||||
'WS2811_400',
|
||||
'GW6205',
|
||||
'GW6205_400',
|
||||
'LPD1886',
|
||||
'LPD1886_8BIT',
|
||||
"NEOPIXEL",
|
||||
"TM1829",
|
||||
"TM1809",
|
||||
"TM1804",
|
||||
"TM1803",
|
||||
"UCS1903",
|
||||
"UCS1903B",
|
||||
"UCS1904",
|
||||
"UCS2903",
|
||||
"WS2812",
|
||||
"WS2852",
|
||||
"WS2812B",
|
||||
"SK6812",
|
||||
"SK6822",
|
||||
"APA106",
|
||||
"PL9823",
|
||||
"WS2811",
|
||||
"WS2813",
|
||||
"APA104",
|
||||
"WS2811_400",
|
||||
"GW6205",
|
||||
"GW6205_400",
|
||||
"LPD1886",
|
||||
"LPD1886_8BIT",
|
||||
]
|
||||
|
||||
|
||||
def validate(value):
|
||||
if value[CONF_CHIPSET] == 'NEOPIXEL' and CONF_RGB_ORDER in value:
|
||||
if value[CONF_CHIPSET] == "NEOPIXEL" and CONF_RGB_ORDER in value:
|
||||
raise cv.Invalid("NEOPIXEL doesn't support RGB order")
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(fastled_base.BASE_SCHEMA.extend({
|
||||
cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||
cv.Required(CONF_PIN): pins.output_pin,
|
||||
}), validate)
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
fastled_base.BASE_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||
cv.Required(CONF_PIN): pins.output_pin,
|
||||
}
|
||||
),
|
||||
validate,
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -52,6 +57,7 @@ def to_code(config):
|
||||
rgb_order = None
|
||||
if CONF_RGB_ORDER in config:
|
||||
rgb_order = cg.RawExpression(config[CONF_RGB_ORDER])
|
||||
template_args = cg.TemplateArguments(cg.RawExpression(config[CONF_CHIPSET]),
|
||||
config[CONF_PIN], rgb_order)
|
||||
template_args = cg.TemplateArguments(
|
||||
cg.RawExpression(config[CONF_CHIPSET]), config[CONF_PIN], rgb_order
|
||||
)
|
||||
cg.add(var.add_leds(template_args, config[CONF_NUM_LEDS]))
|
||||
|
@ -2,34 +2,44 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import fastled_base
|
||||
from esphome.const import CONF_CHIPSET, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_DATA_RATE, \
|
||||
CONF_NUM_LEDS, CONF_RGB_ORDER
|
||||
from esphome.const import (
|
||||
CONF_CHIPSET,
|
||||
CONF_CLOCK_PIN,
|
||||
CONF_DATA_PIN,
|
||||
CONF_DATA_RATE,
|
||||
CONF_NUM_LEDS,
|
||||
CONF_RGB_ORDER,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['fastled_base']
|
||||
AUTO_LOAD = ["fastled_base"]
|
||||
|
||||
CHIPSETS = [
|
||||
'LPD8806',
|
||||
'WS2801',
|
||||
'WS2803',
|
||||
'SM16716',
|
||||
'P9813',
|
||||
'APA102',
|
||||
'SK9822',
|
||||
'DOTSTAR',
|
||||
"LPD8806",
|
||||
"WS2801",
|
||||
"WS2803",
|
||||
"SM16716",
|
||||
"P9813",
|
||||
"APA102",
|
||||
"SK9822",
|
||||
"DOTSTAR",
|
||||
]
|
||||
|
||||
CONFIG_SCHEMA = fastled_base.BASE_SCHEMA.extend({
|
||||
cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||
cv.Required(CONF_DATA_PIN): pins.output_pin,
|
||||
cv.Required(CONF_CLOCK_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_DATA_RATE): cv.frequency,
|
||||
})
|
||||
CONFIG_SCHEMA = fastled_base.BASE_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_CHIPSET): cv.one_of(*CHIPSETS, upper=True),
|
||||
cv.Required(CONF_DATA_PIN): pins.output_pin,
|
||||
cv.Required(CONF_CLOCK_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_DATA_RATE): cv.frequency,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
var = yield fastled_base.new_fastled_light(config)
|
||||
|
||||
rgb_order = cg.RawExpression(config[CONF_RGB_ORDER] if CONF_RGB_ORDER in config else "RGB")
|
||||
rgb_order = cg.RawExpression(
|
||||
config[CONF_RGB_ORDER] if CONF_RGB_ORDER in config else "RGB"
|
||||
)
|
||||
data_rate = None
|
||||
|
||||
if CONF_DATA_RATE in config:
|
||||
@ -39,7 +49,11 @@ def to_code(config):
|
||||
else:
|
||||
data_rate_mhz = int(data_rate_khz / 1000)
|
||||
data_rate = cg.RawExpression(f"DATA_RATE_MHZ({data_rate_mhz})")
|
||||
template_args = cg.TemplateArguments(cg.RawExpression(config[CONF_CHIPSET]),
|
||||
config[CONF_DATA_PIN], config[CONF_CLOCK_PIN], rgb_order,
|
||||
data_rate)
|
||||
template_args = cg.TemplateArguments(
|
||||
cg.RawExpression(config[CONF_CHIPSET]),
|
||||
config[CONF_DATA_PIN],
|
||||
config[CONF_CLOCK_PIN],
|
||||
rgb_order,
|
||||
data_rate,
|
||||
)
|
||||
cg.add(var.add_leds(template_args, config[CONF_NUM_LEDS]))
|
||||
|
@ -7,11 +7,11 @@ import esphome.codegen as cg
|
||||
from esphome.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE
|
||||
from esphome.core import CORE, HexInt
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
DEPENDENCIES = ["display"]
|
||||
MULTI_CONF = True
|
||||
|
||||
Font = display.display_ns.class_('Font')
|
||||
Glyph = display.display_ns.class_('Glyph')
|
||||
Font = display.display_ns.class_("Font")
|
||||
Glyph = display.display_ns.class_("Glyph")
|
||||
|
||||
|
||||
def validate_glyphs(value):
|
||||
@ -20,8 +20,8 @@ def validate_glyphs(value):
|
||||
value = cv.Schema([cv.string])(list(value))
|
||||
|
||||
def comparator(x, y):
|
||||
x_ = x.encode('utf-8')
|
||||
y_ = y.encode('utf-8')
|
||||
x_ = x.encode("utf-8")
|
||||
y_ = y.encode("utf-8")
|
||||
|
||||
for c in range(min(len(x_), len(y_))):
|
||||
if x_[c] < y_[c]:
|
||||
@ -43,36 +43,48 @@ def validate_pillow_installed(value):
|
||||
try:
|
||||
import PIL
|
||||
except ImportError as err:
|
||||
raise cv.Invalid("Please install the pillow python package to use this feature. "
|
||||
"(pip install pillow)") from err
|
||||
raise cv.Invalid(
|
||||
"Please install the pillow python package to use this feature. "
|
||||
"(pip install pillow)"
|
||||
) from err
|
||||
|
||||
if PIL.__version__[0] < '4':
|
||||
raise cv.Invalid("Please update your pillow installation to at least 4.0.x. "
|
||||
"(pip install -U pillow)")
|
||||
if PIL.__version__[0] < "4":
|
||||
raise cv.Invalid(
|
||||
"Please update your pillow installation to at least 4.0.x. "
|
||||
"(pip install -U pillow)"
|
||||
)
|
||||
|
||||
return value
|
||||
|
||||
|
||||
def validate_truetype_file(value):
|
||||
if value.endswith('.zip'): # for Google Fonts downloads
|
||||
raise cv.Invalid("Please unzip the font archive '{}' first and then use the .ttf files "
|
||||
"inside.".format(value))
|
||||
if not value.endswith('.ttf'):
|
||||
raise cv.Invalid("Only truetype (.ttf) files are supported. Please make sure you're "
|
||||
"using the correct format or rename the extension to .ttf")
|
||||
if value.endswith(".zip"): # for Google Fonts downloads
|
||||
raise cv.Invalid(
|
||||
"Please unzip the font archive '{}' first and then use the .ttf files "
|
||||
"inside.".format(value)
|
||||
)
|
||||
if not value.endswith(".ttf"):
|
||||
raise cv.Invalid(
|
||||
"Only truetype (.ttf) files are supported. Please make sure you're "
|
||||
"using the correct format or rename the extension to .ttf"
|
||||
)
|
||||
return cv.file_(value)
|
||||
|
||||
|
||||
DEFAULT_GLYPHS = ' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°'
|
||||
CONF_RAW_DATA_ID = 'raw_data_id'
|
||||
DEFAULT_GLYPHS = (
|
||||
' !"%()+,-.:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz°'
|
||||
)
|
||||
CONF_RAW_DATA_ID = "raw_data_id"
|
||||
|
||||
FONT_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(Font),
|
||||
cv.Required(CONF_FILE): validate_truetype_file,
|
||||
cv.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
|
||||
cv.Optional(CONF_SIZE, default=20): cv.int_range(min=1),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
})
|
||||
FONT_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(Font),
|
||||
cv.Required(CONF_FILE): validate_truetype_file,
|
||||
cv.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
|
||||
cv.Optional(CONF_SIZE, default=20): cv.int_range(min=1),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(validate_pillow_installed, FONT_SCHEMA)
|
||||
|
||||
@ -91,7 +103,7 @@ def to_code(config):
|
||||
glyph_args = {}
|
||||
data = []
|
||||
for glyph in config[CONF_GLYPHS]:
|
||||
mask = font.getmask(glyph, mode='1')
|
||||
mask = font.getmask(glyph, mode="1")
|
||||
_, (offset_x, offset_y) = font.font.getsize(glyph)
|
||||
width, height = mask.size
|
||||
width8 = ((width + 7) // 8) * 8
|
||||
|
@ -3,14 +3,18 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
|
||||
fujitsu_general_ns = cg.esphome_ns.namespace('fujitsu_general')
|
||||
FujitsuGeneralClimate = fujitsu_general_ns.class_('FujitsuGeneralClimate', climate_ir.ClimateIR)
|
||||
fujitsu_general_ns = cg.esphome_ns.namespace("fujitsu_general")
|
||||
FujitsuGeneralClimate = fujitsu_general_ns.class_(
|
||||
"FujitsuGeneralClimate", climate_ir.ClimateIR
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(FujitsuGeneralClimate),
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(FujitsuGeneralClimate),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,21 +2,29 @@ import hashlib
|
||||
|
||||
from esphome import config_validation as cv, automation
|
||||
from esphome import codegen as cg
|
||||
from esphome.const import CONF_ID, CONF_INITIAL_VALUE, CONF_RESTORE_VALUE, CONF_TYPE, CONF_VALUE
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INITIAL_VALUE,
|
||||
CONF_RESTORE_VALUE,
|
||||
CONF_TYPE,
|
||||
CONF_VALUE,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
globals_ns = cg.esphome_ns.namespace('globals')
|
||||
GlobalsComponent = globals_ns.class_('GlobalsComponent', cg.Component)
|
||||
GlobalVarSetAction = globals_ns.class_('GlobalVarSetAction', automation.Action)
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
globals_ns = cg.esphome_ns.namespace("globals")
|
||||
GlobalsComponent = globals_ns.class_("GlobalsComponent", cg.Component)
|
||||
GlobalVarSetAction = globals_ns.class_("GlobalVarSetAction", automation.Action)
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(GlobalsComponent),
|
||||
cv.Required(CONF_TYPE): cv.string_strict,
|
||||
cv.Optional(CONF_INITIAL_VALUE): cv.string_strict,
|
||||
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(GlobalsComponent),
|
||||
cv.Required(CONF_TYPE): cv.string_strict,
|
||||
cv.Optional(CONF_INITIAL_VALUE): cv.string_strict,
|
||||
cv.Optional(CONF_RESTORE_VALUE, default=False): cv.boolean,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
# Run with low priority so that namespaces are registered first
|
||||
@ -42,15 +50,22 @@ def to_code(config):
|
||||
cg.add(glob.set_restore_value(hash_))
|
||||
|
||||
|
||||
@automation.register_action('globals.set', GlobalVarSetAction, cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(GlobalsComponent),
|
||||
cv.Required(CONF_VALUE): cv.templatable(cv.string_strict),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"globals.set",
|
||||
GlobalVarSetAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(GlobalsComponent),
|
||||
cv.Required(CONF_VALUE): cv.templatable(cv.string_strict),
|
||||
}
|
||||
),
|
||||
)
|
||||
def globals_set_to_code(config, action_id, template_arg, args):
|
||||
full_id, paren = yield cg.get_variable_with_full_id(config[CONF_ID])
|
||||
template_arg = cg.TemplateArguments(full_id.type, *template_arg)
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
templ = yield cg.templatable(config[CONF_VALUE], args, None,
|
||||
to_exp=cg.RawExpression)
|
||||
templ = yield cg.templatable(
|
||||
config[CONF_VALUE], args, None, to_exp=cg.RawExpression
|
||||
)
|
||||
cg.add(var.set_value(templ))
|
||||
yield var
|
||||
|
@ -1,4 +1,4 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
gpio_ns = cg.esphome_ns.namespace('gpio')
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
gpio_ns = cg.esphome_ns.namespace("gpio")
|
||||
|
@ -5,12 +5,16 @@ from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_ID, CONF_PIN
|
||||
from .. import gpio_ns
|
||||
|
||||
GPIOBinarySensor = gpio_ns.class_('GPIOBinarySensor', binary_sensor.BinarySensor, cg.Component)
|
||||
GPIOBinarySensor = gpio_ns.class_(
|
||||
"GPIOBinarySensor", binary_sensor.BinarySensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(GPIOBinarySensor),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(GPIOBinarySensor),
|
||||
cv.Required(CONF_PIN): pins.gpio_input_pin_schema,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -5,13 +5,14 @@ from esphome.components import output
|
||||
from esphome.const import CONF_ID, CONF_PIN
|
||||
from .. import gpio_ns
|
||||
|
||||
GPIOBinaryOutput = gpio_ns.class_('GPIOBinaryOutput', output.BinaryOutput,
|
||||
cg.Component)
|
||||
GPIOBinaryOutput = gpio_ns.class_("GPIOBinaryOutput", output.BinaryOutput, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(GPIOBinaryOutput),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(GPIOBinaryOutput),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -5,25 +5,30 @@ from esphome.components import switch
|
||||
from esphome.const import CONF_ID, CONF_INTERLOCK, CONF_PIN, CONF_RESTORE_MODE
|
||||
from .. import gpio_ns
|
||||
|
||||
GPIOSwitch = gpio_ns.class_('GPIOSwitch', switch.Switch, cg.Component)
|
||||
GPIOSwitchRestoreMode = gpio_ns.enum('GPIOSwitchRestoreMode')
|
||||
GPIOSwitch = gpio_ns.class_("GPIOSwitch", switch.Switch, cg.Component)
|
||||
GPIOSwitchRestoreMode = gpio_ns.enum("GPIOSwitchRestoreMode")
|
||||
|
||||
RESTORE_MODES = {
|
||||
'RESTORE_DEFAULT_OFF': GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_OFF,
|
||||
'RESTORE_DEFAULT_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_ON,
|
||||
'ALWAYS_OFF': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_OFF,
|
||||
'ALWAYS_ON': GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON,
|
||||
"RESTORE_DEFAULT_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_OFF,
|
||||
"RESTORE_DEFAULT_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_RESTORE_DEFAULT_ON,
|
||||
"ALWAYS_OFF": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_OFF,
|
||||
"ALWAYS_ON": GPIOSwitchRestoreMode.GPIO_SWITCH_ALWAYS_ON,
|
||||
}
|
||||
|
||||
CONF_INTERLOCK_WAIT_TIME = 'interlock_wait_time'
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(GPIOSwitch),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RESTORE_MODE, default='RESTORE_DEFAULT_OFF'):
|
||||
cv.enum(RESTORE_MODES, upper=True, space='_'),
|
||||
cv.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_id(switch.Switch)),
|
||||
cv.Optional(CONF_INTERLOCK_WAIT_TIME, default='0ms'): cv.positive_time_period_milliseconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONF_INTERLOCK_WAIT_TIME = "interlock_wait_time"
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(GPIOSwitch),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RESTORE_MODE, default="RESTORE_DEFAULT_OFF"): cv.enum(
|
||||
RESTORE_MODES, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_INTERLOCK): cv.ensure_list(cv.use_id(switch.Switch)),
|
||||
cv.Optional(
|
||||
CONF_INTERLOCK_WAIT_TIME, default="0ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,17 +3,23 @@ import esphome.config_validation as cv
|
||||
from esphome.components import uart
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
gps_ns = cg.esphome_ns.namespace('gps')
|
||||
GPS = gps_ns.class_('GPS', cg.Component, uart.UARTDevice)
|
||||
GPSListener = gps_ns.class_('GPSListener')
|
||||
gps_ns = cg.esphome_ns.namespace("gps")
|
||||
GPS = gps_ns.class_("GPS", cg.Component, uart.UARTDevice)
|
||||
GPSListener = gps_ns.class_("GPSListener")
|
||||
|
||||
CONF_GPS_ID = 'gps_id'
|
||||
CONF_GPS_ID = "gps_id"
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(GPS),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(GPS),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -22,4 +28,4 @@ def to_code(config):
|
||||
yield uart.register_uart_device(var, config)
|
||||
|
||||
# https://platformio.org/lib/show/1655/TinyGPSPlus
|
||||
cg.add_library('1655', '1.0.2') # TinyGPSPlus, has name conflict
|
||||
cg.add_library("1655", "1.0.2") # TinyGPSPlus, has name conflict
|
||||
|
@ -4,14 +4,18 @@ import esphome.codegen as cg
|
||||
from esphome.const import CONF_ID
|
||||
from .. import gps_ns, GPSListener, CONF_GPS_ID, GPS
|
||||
|
||||
DEPENDENCIES = ['gps']
|
||||
DEPENDENCIES = ["gps"]
|
||||
|
||||
GPSTime = gps_ns.class_('GPSTime', cg.PollingComponent, time_.RealTimeClock, GPSListener)
|
||||
GPSTime = gps_ns.class_(
|
||||
"GPSTime", cg.PollingComponent, time_.RealTimeClock, GPSListener
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = time_.TIME_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(GPSTime),
|
||||
cv.GenerateID(CONF_GPS_ID): cv.use_id(GPS),
|
||||
}).extend(cv.polling_component_schema('5min'))
|
||||
CONFIG_SCHEMA = time_.TIME_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(GPSTime),
|
||||
cv.GenerateID(CONF_GPS_ID): cv.use_id(GPS),
|
||||
}
|
||||
).extend(cv.polling_component_schema("5min"))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,14 +3,18 @@ import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_PIN_A, CONF_PIN_B
|
||||
|
||||
hbridge_ns = cg.esphome_ns.namespace('hbridge')
|
||||
HBridgeLightOutput = hbridge_ns.class_('HBridgeLightOutput', cg.PollingComponent, light.LightOutput)
|
||||
hbridge_ns = cg.esphome_ns.namespace("hbridge")
|
||||
HBridgeLightOutput = hbridge_ns.class_(
|
||||
"HBridgeLightOutput", cg.PollingComponent, light.LightOutput
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(HBridgeLightOutput),
|
||||
cv.Required(CONF_PIN_A): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_PIN_B): cv.use_id(output.FloatOutput),
|
||||
})
|
||||
CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(HBridgeLightOutput),
|
||||
cv.Required(CONF_PIN_A): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_PIN_B): cv.use_id(output.FloatOutput),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,21 +1,39 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_HUMIDITY, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
hdc1080_ns = cg.esphome_ns.namespace('hdc1080')
|
||||
HDC1080Component = hdc1080_ns.class_('HDC1080Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
hdc1080_ns = cg.esphome_ns.namespace("hdc1080")
|
||||
HDC1080Component = hdc1080_ns.class_(
|
||||
"HDC1080Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HDC1080Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HDC1080Component),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 0, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,14 +3,16 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
|
||||
hitachi_ac344_ns = cg.esphome_ns.namespace('hitachi_ac344')
|
||||
HitachiClimate = hitachi_ac344_ns.class_('HitachiClimate', climate_ir.ClimateIR)
|
||||
hitachi_ac344_ns = cg.esphome_ns.namespace("hitachi_ac344")
|
||||
HitachiClimate = hitachi_ac344_ns.class_("HitachiClimate", climate_ir.ClimateIR)
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(HitachiClimate),
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_WITH_RECEIVER_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HitachiClimate),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,43 +2,72 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_CHANGE_MODE_EVERY, CONF_INITIAL_MODE, CONF_CURRENT, \
|
||||
CONF_CURRENT_RESISTOR, CONF_ID, CONF_POWER, CONF_ENERGY, CONF_SEL_PIN, CONF_VOLTAGE, \
|
||||
CONF_VOLTAGE_DIVIDER, DEVICE_CLASS_CURRENT, DEVICE_CLASS_ENERGY, DEVICE_CLASS_POWER, \
|
||||
DEVICE_CLASS_VOLTAGE, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, UNIT_WATT_HOURS
|
||||
from esphome.const import (
|
||||
CONF_CHANGE_MODE_EVERY,
|
||||
CONF_INITIAL_MODE,
|
||||
CONF_CURRENT,
|
||||
CONF_CURRENT_RESISTOR,
|
||||
CONF_ID,
|
||||
CONF_POWER,
|
||||
CONF_ENERGY,
|
||||
CONF_SEL_PIN,
|
||||
CONF_VOLTAGE,
|
||||
CONF_VOLTAGE_DIVIDER,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
UNIT_WATT_HOURS,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['pulse_counter']
|
||||
AUTO_LOAD = ["pulse_counter"]
|
||||
|
||||
hlw8012_ns = cg.esphome_ns.namespace('hlw8012')
|
||||
HLW8012Component = hlw8012_ns.class_('HLW8012Component', cg.PollingComponent)
|
||||
HLW8012InitialMode = hlw8012_ns.enum('HLW8012InitialMode')
|
||||
hlw8012_ns = cg.esphome_ns.namespace("hlw8012")
|
||||
HLW8012Component = hlw8012_ns.class_("HLW8012Component", cg.PollingComponent)
|
||||
HLW8012InitialMode = hlw8012_ns.enum("HLW8012InitialMode")
|
||||
INITIAL_MODES = {
|
||||
CONF_CURRENT: HLW8012InitialMode.HLW8012_INITIAL_MODE_CURRENT,
|
||||
CONF_VOLTAGE: HLW8012InitialMode.HLW8012_INITIAL_MODE_VOLTAGE,
|
||||
}
|
||||
|
||||
CONF_CF1_PIN = 'cf1_pin'
|
||||
CONF_CF_PIN = 'cf_pin'
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HLW8012Component),
|
||||
cv.Required(CONF_SEL_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CF_PIN): cv.All(pins.internal_gpio_input_pullup_pin_schema,
|
||||
pins.validate_has_interrupt),
|
||||
cv.Required(CONF_CF1_PIN): cv.All(pins.internal_gpio_input_pullup_pin_schema,
|
||||
pins.validate_has_interrupt),
|
||||
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(UNIT_WATT_HOURS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_ENERGY),
|
||||
|
||||
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
|
||||
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
|
||||
cv.Optional(CONF_CHANGE_MODE_EVERY, default=8): cv.All(cv.uint32_t, cv.Range(min=1)),
|
||||
cv.Optional(CONF_INITIAL_MODE, default=CONF_VOLTAGE): cv.one_of(*INITIAL_MODES, lower=True),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONF_CF1_PIN = "cf1_pin"
|
||||
CONF_CF_PIN = "cf_pin"
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HLW8012Component),
|
||||
cv.Required(CONF_SEL_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CF_PIN): cv.All(
|
||||
pins.internal_gpio_input_pullup_pin_schema, pins.validate_has_interrupt
|
||||
),
|
||||
cv.Required(CONF_CF1_PIN): cv.All(
|
||||
pins.internal_gpio_input_pullup_pin_schema, pins.validate_has_interrupt
|
||||
),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 1, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 1, DEVICE_CLASS_ENERGY
|
||||
),
|
||||
cv.Optional(CONF_CURRENT_RESISTOR, default=0.001): cv.resistance,
|
||||
cv.Optional(CONF_VOLTAGE_DIVIDER, default=2351): cv.positive_float,
|
||||
cv.Optional(CONF_CHANGE_MODE_EVERY, default=8): cv.All(
|
||||
cv.uint32_t, cv.Range(min=1)
|
||||
),
|
||||
cv.Optional(CONF_INITIAL_MODE, default=CONF_VOLTAGE): cv.one_of(
|
||||
*INITIAL_MODES, lower=True
|
||||
),
|
||||
}
|
||||
).extend(cv.polling_component_schema("60s"))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,22 +1,31 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_PM_2_5, CONF_PM_10_0, CONF_PM_1_0, DEVICE_CLASS_EMPTY, \
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_PM_2_5,
|
||||
CONF_PM_10_0,
|
||||
CONF_PM_1_0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
hm3301_ns = cg.esphome_ns.namespace('hm3301')
|
||||
HM3301Component = hm3301_ns.class_('HM3301Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
AQICalculatorType = hm3301_ns.enum('AQICalculatorType')
|
||||
hm3301_ns = cg.esphome_ns.namespace("hm3301")
|
||||
HM3301Component = hm3301_ns.class_(
|
||||
"HM3301Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
AQICalculatorType = hm3301_ns.enum("AQICalculatorType")
|
||||
|
||||
CONF_AQI = 'aqi'
|
||||
CONF_CALCULATION_TYPE = 'calculation_type'
|
||||
UNIT_INDEX = 'index'
|
||||
CONF_AQI = "aqi"
|
||||
CONF_CALCULATION_TYPE = "calculation_type"
|
||||
UNIT_INDEX = "index"
|
||||
|
||||
AQI_CALCULATION_TYPE = {
|
||||
'CAQI': AQICalculatorType.CAQI_TYPE,
|
||||
'AQI': AQICalculatorType.AQI_TYPE
|
||||
"CAQI": AQICalculatorType.CAQI_TYPE,
|
||||
"AQI": AQICalculatorType.AQI_TYPE,
|
||||
}
|
||||
|
||||
|
||||
@ -28,23 +37,43 @@ def validate(config):
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HM3301Component),
|
||||
|
||||
cv.Optional(CONF_PM_1_0):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_PM_2_5):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_PM_10_0):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_AQI):
|
||||
sensor.sensor_schema(UNIT_INDEX, ICON_CHEMICAL_WEAPON, 0, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.Required(CONF_CALCULATION_TYPE): cv.enum(AQI_CALCULATION_TYPE, upper=True),
|
||||
})
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40)), validate)
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HM3301Component),
|
||||
cv.Optional(CONF_PM_1_0): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_PM_2_5): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_PM_10_0): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_AQI): sensor.sensor_schema(
|
||||
UNIT_INDEX, ICON_CHEMICAL_WEAPON, 0, DEVICE_CLASS_EMPTY
|
||||
).extend(
|
||||
{
|
||||
cv.Required(CONF_CALCULATION_TYPE): cv.enum(
|
||||
AQI_CALCULATION_TYPE, upper=True
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40)),
|
||||
validate,
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -70,4 +99,4 @@ def to_code(config):
|
||||
cg.add(var.set_aqi_calculation_type(config[CONF_AQI][CONF_CALCULATION_TYPE]))
|
||||
|
||||
# https://platformio.org/lib/show/6306/Grove%20-%20Laser%20PM2.5%20Sensor%20HM3301
|
||||
cg.add_library('6306', '1.0.3')
|
||||
cg.add_library("6306", "1.0.3")
|
||||
|
@ -1,22 +1,33 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ADDRESS, CONF_ID, CONF_OVERSAMPLING, CONF_RANGE, \
|
||||
DEVICE_CLASS_EMPTY, ICON_MAGNET, UNIT_MICROTESLA, UNIT_DEGREES, ICON_SCREEN_ROTATION, \
|
||||
CONF_UPDATE_INTERVAL
|
||||
from esphome.const import (
|
||||
CONF_ADDRESS,
|
||||
CONF_ID,
|
||||
CONF_OVERSAMPLING,
|
||||
CONF_RANGE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ICON_MAGNET,
|
||||
UNIT_MICROTESLA,
|
||||
UNIT_DEGREES,
|
||||
ICON_SCREEN_ROTATION,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
hmc5883l_ns = cg.esphome_ns.namespace('hmc5883l')
|
||||
hmc5883l_ns = cg.esphome_ns.namespace("hmc5883l")
|
||||
|
||||
CONF_FIELD_STRENGTH_X = 'field_strength_x'
|
||||
CONF_FIELD_STRENGTH_Y = 'field_strength_y'
|
||||
CONF_FIELD_STRENGTH_Z = 'field_strength_z'
|
||||
CONF_HEADING = 'heading'
|
||||
CONF_FIELD_STRENGTH_X = "field_strength_x"
|
||||
CONF_FIELD_STRENGTH_Y = "field_strength_y"
|
||||
CONF_FIELD_STRENGTH_Z = "field_strength_z"
|
||||
CONF_HEADING = "heading"
|
||||
|
||||
HMC5883LComponent = hmc5883l_ns.class_('HMC5883LComponent', cg.PollingComponent, i2c.I2CDevice)
|
||||
HMC5883LComponent = hmc5883l_ns.class_(
|
||||
"HMC5883LComponent", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
HMC5883LOversampling = hmc5883l_ns.enum('HMC5883LOversampling')
|
||||
HMC5883LOversampling = hmc5883l_ns.enum("HMC5883LOversampling")
|
||||
HMC5883LOversamplings = {
|
||||
1: HMC5883LOversampling.HMC5883L_OVERSAMPLING_1,
|
||||
2: HMC5883LOversampling.HMC5883L_OVERSAMPLING_2,
|
||||
@ -24,7 +35,7 @@ HMC5883LOversamplings = {
|
||||
8: HMC5883LOversampling.HMC5883L_OVERSAMPLING_8,
|
||||
}
|
||||
|
||||
HMC5883LDatarate = hmc5883l_ns.enum('HMC5883LDatarate')
|
||||
HMC5883LDatarate = hmc5883l_ns.enum("HMC5883LDatarate")
|
||||
HMC5883LDatarates = {
|
||||
0.75: HMC5883LDatarate.HMC5883L_DATARATE_0_75_HZ,
|
||||
1.5: HMC5883LDatarate.HMC5883L_DATARATE_1_5_HZ,
|
||||
@ -35,7 +46,7 @@ HMC5883LDatarates = {
|
||||
75: HMC5883LDatarate.HMC5883L_DATARATE_75_0_HZ,
|
||||
}
|
||||
|
||||
HMC5883LRange = hmc5883l_ns.enum('HMC5883LRange')
|
||||
HMC5883LRange = hmc5883l_ns.enum("HMC5883LRange")
|
||||
HMC5883L_RANGES = {
|
||||
88: HMC5883LRange.HMC5883L_RANGE_88_UT,
|
||||
130: HMC5883LRange.HMC5883L_RANGE_130_UT,
|
||||
@ -59,30 +70,45 @@ def validate_enum(enum_values, units=None, int=True):
|
||||
value = cv.string(value)
|
||||
for unit in _units:
|
||||
if value.endswith(unit):
|
||||
value = value[:-len(unit)]
|
||||
value = value[: -len(unit)]
|
||||
break
|
||||
return enum_bound(value)
|
||||
|
||||
return validate_enum_bound
|
||||
|
||||
|
||||
field_strength_schema = sensor.sensor_schema(UNIT_MICROTESLA, ICON_MAGNET, 1, DEVICE_CLASS_EMPTY)
|
||||
heading_schema = sensor.sensor_schema(UNIT_DEGREES, ICON_SCREEN_ROTATION, 1, DEVICE_CLASS_EMPTY)
|
||||
field_strength_schema = sensor.sensor_schema(
|
||||
UNIT_MICROTESLA, ICON_MAGNET, 1, DEVICE_CLASS_EMPTY
|
||||
)
|
||||
heading_schema = sensor.sensor_schema(
|
||||
UNIT_DEGREES, ICON_SCREEN_ROTATION, 1, DEVICE_CLASS_EMPTY
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HMC5883LComponent),
|
||||
cv.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||
cv.Optional(CONF_OVERSAMPLING, default='1x'): validate_enum(HMC5883LOversamplings, units="x"),
|
||||
cv.Optional(CONF_RANGE, default='130µT'): validate_enum(HMC5883L_RANGES, units=["uT", "µT"]),
|
||||
cv.Optional(CONF_FIELD_STRENGTH_X): field_strength_schema,
|
||||
cv.Optional(CONF_FIELD_STRENGTH_Y): field_strength_schema,
|
||||
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
||||
cv.Optional(CONF_HEADING): heading_schema,
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x1E))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HMC5883LComponent),
|
||||
cv.Optional(CONF_ADDRESS): cv.i2c_address,
|
||||
cv.Optional(CONF_OVERSAMPLING, default="1x"): validate_enum(
|
||||
HMC5883LOversamplings, units="x"
|
||||
),
|
||||
cv.Optional(CONF_RANGE, default="130µT"): validate_enum(
|
||||
HMC5883L_RANGES, units=["uT", "µT"]
|
||||
),
|
||||
cv.Optional(CONF_FIELD_STRENGTH_X): field_strength_schema,
|
||||
cv.Optional(CONF_FIELD_STRENGTH_Y): field_strength_schema,
|
||||
cv.Optional(CONF_FIELD_STRENGTH_Z): field_strength_schema,
|
||||
cv.Optional(CONF_HEADING): heading_schema,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x1E))
|
||||
)
|
||||
|
||||
|
||||
def auto_data_rate(config):
|
||||
interval_sec = config[CONF_UPDATE_INTERVAL].seconds
|
||||
interval_hz = 1.0/interval_sec
|
||||
interval_hz = 1.0 / interval_sec
|
||||
for datarate in sorted(HMC5883LDatarates.keys()):
|
||||
if float(datarate) >= interval_hz:
|
||||
return HMC5883LDatarates[datarate]
|
||||
|
@ -1,4 +1,4 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
homeassistant_ns = cg.esphome_ns.namespace('homeassistant')
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
homeassistant_ns = cg.esphome_ns.namespace("homeassistant")
|
||||
|
@ -4,15 +4,17 @@ from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_ENTITY_ID, CONF_ID
|
||||
from .. import homeassistant_ns
|
||||
|
||||
DEPENDENCIES = ['api']
|
||||
HomeassistantBinarySensor = homeassistant_ns.class_('HomeassistantBinarySensor',
|
||||
binary_sensor.BinarySensor,
|
||||
cg.Component)
|
||||
DEPENDENCIES = ["api"]
|
||||
HomeassistantBinarySensor = homeassistant_ns.class_(
|
||||
"HomeassistantBinarySensor", binary_sensor.BinarySensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantBinarySensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantBinarySensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,18 +1,29 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ENTITY_ID, CONF_ID, ICON_EMPTY, UNIT_EMPTY, DEVICE_CLASS_EMPTY
|
||||
from esphome.const import (
|
||||
CONF_ENTITY_ID,
|
||||
CONF_ID,
|
||||
ICON_EMPTY,
|
||||
UNIT_EMPTY,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
)
|
||||
from .. import homeassistant_ns
|
||||
|
||||
DEPENDENCIES = ['api']
|
||||
DEPENDENCIES = ["api"]
|
||||
|
||||
HomeassistantSensor = homeassistant_ns.class_('HomeassistantSensor', sensor.Sensor,
|
||||
cg.Component)
|
||||
HomeassistantSensor = homeassistant_ns.class_(
|
||||
"HomeassistantSensor", sensor.Sensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantSensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
})
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY
|
||||
).extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantSensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,15 +4,18 @@ from esphome.components import text_sensor
|
||||
from esphome.const import CONF_ENTITY_ID, CONF_ID
|
||||
from .. import homeassistant_ns
|
||||
|
||||
DEPENDENCIES = ['api']
|
||||
DEPENDENCIES = ["api"]
|
||||
|
||||
HomeassistantTextSensor = homeassistant_ns.class_('HomeassistantTextSensor',
|
||||
text_sensor.TextSensor, cg.Component)
|
||||
HomeassistantTextSensor = homeassistant_ns.class_(
|
||||
"HomeassistantTextSensor", text_sensor.TextSensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantTextSensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
})
|
||||
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantTextSensor),
|
||||
cv.Required(CONF_ENTITY_ID): cv.entity_id,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,17 +4,19 @@ import esphome.codegen as cg
|
||||
from esphome.const import CONF_ID
|
||||
from .. import homeassistant_ns
|
||||
|
||||
DEPENDENCIES = ['api']
|
||||
DEPENDENCIES = ["api"]
|
||||
|
||||
HomeassistantTime = homeassistant_ns.class_('HomeassistantTime', time_.RealTimeClock)
|
||||
HomeassistantTime = homeassistant_ns.class_("HomeassistantTime", time_.RealTimeClock)
|
||||
|
||||
CONFIG_SCHEMA = time_.TIME_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantTime),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = time_.TIME_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HomeassistantTime),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
var = cg.new_Pvariable(config[CONF_ID])
|
||||
yield time_.register_time(var, config)
|
||||
yield cg.register_component(var, config)
|
||||
cg.add_define('USE_HOMEASSISTANT_TIME')
|
||||
cg.add_define("USE_HOMEASSISTANT_TIME")
|
||||
|
@ -3,39 +3,54 @@ import urllib.parse as urlparse
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.const import CONF_ID, CONF_TIMEOUT, CONF_ESPHOME, CONF_METHOD, \
|
||||
CONF_ARDUINO_VERSION, ARDUINO_VERSION_ESP8266, CONF_URL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_TIMEOUT,
|
||||
CONF_ESPHOME,
|
||||
CONF_METHOD,
|
||||
CONF_ARDUINO_VERSION,
|
||||
ARDUINO_VERSION_ESP8266,
|
||||
CONF_URL,
|
||||
)
|
||||
from esphome.core import CORE, Lambda
|
||||
from esphome.core_config import PLATFORMIO_ESP8266_LUT
|
||||
|
||||
DEPENDENCIES = ['network']
|
||||
AUTO_LOAD = ['json']
|
||||
DEPENDENCIES = ["network"]
|
||||
AUTO_LOAD = ["json"]
|
||||
|
||||
http_request_ns = cg.esphome_ns.namespace('http_request')
|
||||
HttpRequestComponent = http_request_ns.class_('HttpRequestComponent', cg.Component)
|
||||
HttpRequestSendAction = http_request_ns.class_('HttpRequestSendAction', automation.Action)
|
||||
http_request_ns = cg.esphome_ns.namespace("http_request")
|
||||
HttpRequestComponent = http_request_ns.class_("HttpRequestComponent", cg.Component)
|
||||
HttpRequestSendAction = http_request_ns.class_(
|
||||
"HttpRequestSendAction", automation.Action
|
||||
)
|
||||
|
||||
CONF_HEADERS = 'headers'
|
||||
CONF_USERAGENT = 'useragent'
|
||||
CONF_BODY = 'body'
|
||||
CONF_JSON = 'json'
|
||||
CONF_VERIFY_SSL = 'verify_ssl'
|
||||
CONF_HEADERS = "headers"
|
||||
CONF_USERAGENT = "useragent"
|
||||
CONF_BODY = "body"
|
||||
CONF_JSON = "json"
|
||||
CONF_VERIFY_SSL = "verify_ssl"
|
||||
|
||||
|
||||
def validate_framework(config):
|
||||
if CORE.is_esp32:
|
||||
return config
|
||||
|
||||
version = 'RECOMMENDED'
|
||||
version = "RECOMMENDED"
|
||||
if CONF_ARDUINO_VERSION in CORE.raw_config[CONF_ESPHOME]:
|
||||
version = CORE.raw_config[CONF_ESPHOME][CONF_ARDUINO_VERSION]
|
||||
|
||||
if version in ['LATEST', 'DEV']:
|
||||
if version in ["LATEST", "DEV"]:
|
||||
return config
|
||||
|
||||
framework = PLATFORMIO_ESP8266_LUT[version] if version in PLATFORMIO_ESP8266_LUT else version
|
||||
if framework < ARDUINO_VERSION_ESP8266['2.5.1']:
|
||||
raise cv.Invalid('This component is not supported on arduino framework version below 2.5.1')
|
||||
framework = (
|
||||
PLATFORMIO_ESP8266_LUT[version]
|
||||
if version in PLATFORMIO_ESP8266_LUT
|
||||
else version
|
||||
)
|
||||
if framework < ARDUINO_VERSION_ESP8266["2.5.1"]:
|
||||
raise cv.Invalid(
|
||||
"This component is not supported on arduino framework version below 2.5.1"
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
@ -44,34 +59,47 @@ def validate_url(value):
|
||||
try:
|
||||
parsed = list(urlparse.urlparse(value))
|
||||
except Exception as err:
|
||||
raise cv.Invalid('Invalid URL') from err
|
||||
raise cv.Invalid("Invalid URL") from err
|
||||
|
||||
if not parsed[0] or not parsed[1]:
|
||||
raise cv.Invalid('URL must have a URL scheme and host')
|
||||
raise cv.Invalid("URL must have a URL scheme and host")
|
||||
|
||||
if parsed[0] not in ['http', 'https']:
|
||||
raise cv.Invalid('Scheme must be http or https')
|
||||
if parsed[0] not in ["http", "https"]:
|
||||
raise cv.Invalid("Scheme must be http or https")
|
||||
|
||||
if not parsed[2]:
|
||||
parsed[2] = '/'
|
||||
parsed[2] = "/"
|
||||
|
||||
return urlparse.urlunparse(parsed)
|
||||
|
||||
|
||||
def validate_secure_url(config):
|
||||
url_ = config[CONF_URL]
|
||||
if config.get(CONF_VERIFY_SSL) and not isinstance(url_, Lambda) \
|
||||
and url_.lower().startswith('https:'):
|
||||
raise cv.Invalid('Currently ESPHome doesn\'t support SSL verification. '
|
||||
'Set \'verify_ssl: false\' to make insecure HTTPS requests.')
|
||||
if (
|
||||
config.get(CONF_VERIFY_SSL)
|
||||
and not isinstance(url_, Lambda)
|
||||
and url_.lower().startswith("https:")
|
||||
):
|
||||
raise cv.Invalid(
|
||||
"Currently ESPHome doesn't support SSL verification. "
|
||||
"Set 'verify_ssl: false' to make insecure HTTPS requests."
|
||||
)
|
||||
return config
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HttpRequestComponent),
|
||||
cv.Optional(CONF_USERAGENT, 'ESPHome'): cv.string,
|
||||
cv.Optional(CONF_TIMEOUT, default='5s'): cv.positive_time_period_milliseconds,
|
||||
}).add_extra(validate_framework).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HttpRequestComponent),
|
||||
cv.Optional(CONF_USERAGENT, "ESPHome"): cv.string,
|
||||
cv.Optional(
|
||||
CONF_TIMEOUT, default="5s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
)
|
||||
.add_extra(validate_framework)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -81,41 +109,60 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
|
||||
HTTP_REQUEST_ACTION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(HttpRequestComponent),
|
||||
cv.Required(CONF_URL): cv.templatable(validate_url),
|
||||
cv.Optional(CONF_HEADERS): cv.All(cv.Schema({cv.string: cv.templatable(cv.string)})),
|
||||
cv.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
|
||||
}).add_extra(validate_secure_url)
|
||||
HTTP_REQUEST_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(HttpRequestComponent),
|
||||
cv.Required(CONF_URL): cv.templatable(validate_url),
|
||||
cv.Optional(CONF_HEADERS): cv.All(
|
||||
cv.Schema({cv.string: cv.templatable(cv.string)})
|
||||
),
|
||||
cv.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
|
||||
}
|
||||
).add_extra(validate_secure_url)
|
||||
HTTP_REQUEST_GET_ACTION_SCHEMA = automation.maybe_conf(
|
||||
CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend({
|
||||
cv.Optional(CONF_METHOD, default='GET'): cv.one_of('GET', upper=True),
|
||||
})
|
||||
CONF_URL,
|
||||
HTTP_REQUEST_ACTION_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_METHOD, default="GET"): cv.one_of("GET", upper=True),
|
||||
}
|
||||
),
|
||||
)
|
||||
HTTP_REQUEST_POST_ACTION_SCHEMA = automation.maybe_conf(
|
||||
CONF_URL, HTTP_REQUEST_ACTION_SCHEMA.extend({
|
||||
cv.Optional(CONF_METHOD, default='POST'): cv.one_of('POST', upper=True),
|
||||
cv.Exclusive(CONF_BODY, 'body'): cv.templatable(cv.string),
|
||||
cv.Exclusive(CONF_JSON, 'body'): cv.Any(
|
||||
cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})),
|
||||
),
|
||||
})
|
||||
)
|
||||
HTTP_REQUEST_SEND_ACTION_SCHEMA = HTTP_REQUEST_ACTION_SCHEMA.extend({
|
||||
cv.Required(CONF_METHOD): cv.one_of('GET', 'POST', 'PUT', 'DELETE', 'PATCH', upper=True),
|
||||
cv.Exclusive(CONF_BODY, 'body'): cv.templatable(cv.string),
|
||||
cv.Exclusive(CONF_JSON, 'body'): cv.Any(
|
||||
cv.lambda_, cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})),
|
||||
CONF_URL,
|
||||
HTTP_REQUEST_ACTION_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_METHOD, default="POST"): cv.one_of("POST", upper=True),
|
||||
cv.Exclusive(CONF_BODY, "body"): cv.templatable(cv.string),
|
||||
cv.Exclusive(CONF_JSON, "body"): cv.Any(
|
||||
cv.lambda_,
|
||||
cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})),
|
||||
),
|
||||
}
|
||||
),
|
||||
})
|
||||
)
|
||||
HTTP_REQUEST_SEND_ACTION_SCHEMA = HTTP_REQUEST_ACTION_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_METHOD): cv.one_of(
|
||||
"GET", "POST", "PUT", "DELETE", "PATCH", upper=True
|
||||
),
|
||||
cv.Exclusive(CONF_BODY, "body"): cv.templatable(cv.string),
|
||||
cv.Exclusive(CONF_JSON, "body"): cv.Any(
|
||||
cv.lambda_,
|
||||
cv.All(cv.Schema({cv.string: cv.templatable(cv.string_strict)})),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('http_request.get', HttpRequestSendAction,
|
||||
HTTP_REQUEST_GET_ACTION_SCHEMA)
|
||||
@automation.register_action('http_request.post', HttpRequestSendAction,
|
||||
HTTP_REQUEST_POST_ACTION_SCHEMA)
|
||||
@automation.register_action('http_request.send', HttpRequestSendAction,
|
||||
HTTP_REQUEST_SEND_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"http_request.get", HttpRequestSendAction, HTTP_REQUEST_GET_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"http_request.post", HttpRequestSendAction, HTTP_REQUEST_POST_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"http_request.send", HttpRequestSendAction, HTTP_REQUEST_SEND_ACTION_SCHEMA
|
||||
)
|
||||
def http_request_action_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -129,7 +176,7 @@ def http_request_action_to_code(config, action_id, template_arg, args):
|
||||
if CONF_JSON in config:
|
||||
json_ = config[CONF_JSON]
|
||||
if isinstance(json_, Lambda):
|
||||
args_ = args + [(cg.JsonObjectRef, 'root')]
|
||||
args_ = args + [(cg.JsonObjectRef, "root")]
|
||||
lambda_ = yield cg.process_lambda(json_, args_, return_type=cg.void)
|
||||
cg.add(var.set_json(lambda_))
|
||||
else:
|
||||
@ -137,7 +184,9 @@ def http_request_action_to_code(config, action_id, template_arg, args):
|
||||
template_ = yield cg.templatable(json_[key], args, cg.std_string)
|
||||
cg.add(var.add_json(key, template_))
|
||||
for key in config.get(CONF_HEADERS, []):
|
||||
template_ = yield cg.templatable(config[CONF_HEADERS][key], args, cg.const_char_ptr)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_HEADERS][key], args, cg.const_char_ptr
|
||||
)
|
||||
cg.add(var.add_header(key, template_))
|
||||
|
||||
yield var
|
||||
|
@ -1,21 +1,39 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_HUMIDITY, CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_HUMIDITY, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
htu21d_ns = cg.esphome_ns.namespace('htu21d')
|
||||
HTU21DComponent = htu21d_ns.class_('HTU21DComponent', cg.PollingComponent, i2c.I2CDevice)
|
||||
htu21d_ns = cg.esphome_ns.namespace("htu21d")
|
||||
HTU21DComponent = htu21d_ns.class_(
|
||||
"HTU21DComponent", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(HTU21DComponent),
|
||||
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Required(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HTU21DComponent),
|
||||
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Required(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,27 +2,39 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_CLK_PIN, CONF_GAIN, CONF_ID, DEVICE_CLASS_EMPTY, ICON_SCALE, \
|
||||
UNIT_EMPTY
|
||||
from esphome.const import (
|
||||
CONF_CLK_PIN,
|
||||
CONF_GAIN,
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ICON_SCALE,
|
||||
UNIT_EMPTY,
|
||||
)
|
||||
|
||||
hx711_ns = cg.esphome_ns.namespace('hx711')
|
||||
HX711Sensor = hx711_ns.class_('HX711Sensor', sensor.Sensor, cg.PollingComponent)
|
||||
hx711_ns = cg.esphome_ns.namespace("hx711")
|
||||
HX711Sensor = hx711_ns.class_("HX711Sensor", sensor.Sensor, cg.PollingComponent)
|
||||
|
||||
CONF_DOUT_PIN = 'dout_pin'
|
||||
CONF_DOUT_PIN = "dout_pin"
|
||||
|
||||
HX711Gain = hx711_ns.enum('HX711Gain')
|
||||
HX711Gain = hx711_ns.enum("HX711Gain")
|
||||
GAINS = {
|
||||
128: HX711Gain.HX711_GAIN_128,
|
||||
32: HX711Gain.HX711_GAIN_32,
|
||||
64: HX711Gain.HX711_GAIN_64,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_EMPTY, ICON_SCALE, 0, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(HX711Sensor),
|
||||
cv.Required(CONF_DOUT_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_GAIN, default=128): cv.enum(GAINS, int=True),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_EMPTY, ICON_SCALE, 0, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(HX711Sensor),
|
||||
cv.Required(CONF_DOUT_PIN): pins.gpio_input_pin_schema,
|
||||
cv.Required(CONF_CLK_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_GAIN, default=128): cv.enum(GAINS, int=True),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,24 +1,34 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_SCAN, CONF_SCL, CONF_SDA, CONF_ADDRESS, \
|
||||
CONF_I2C_ID
|
||||
from esphome.const import (
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_SCAN,
|
||||
CONF_SCL,
|
||||
CONF_SDA,
|
||||
CONF_ADDRESS,
|
||||
CONF_I2C_ID,
|
||||
)
|
||||
from esphome.core import coroutine, coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
i2c_ns = cg.esphome_ns.namespace('i2c')
|
||||
I2CComponent = i2c_ns.class_('I2CComponent', cg.Component)
|
||||
I2CDevice = i2c_ns.class_('I2CDevice')
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
i2c_ns = cg.esphome_ns.namespace("i2c")
|
||||
I2CComponent = i2c_ns.class_("I2CComponent", cg.Component)
|
||||
I2CDevice = i2c_ns.class_("I2CDevice")
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(I2CComponent),
|
||||
cv.Optional(CONF_SDA, default='SDA'): pins.input_pin,
|
||||
cv.Optional(CONF_SCL, default='SCL'): pins.input_pin,
|
||||
cv.Optional(CONF_FREQUENCY, default='50kHz'):
|
||||
cv.All(cv.frequency, cv.Range(min=0, min_included=False)),
|
||||
cv.Optional(CONF_SCAN, default=True): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(I2CComponent),
|
||||
cv.Optional(CONF_SDA, default="SDA"): pins.input_pin,
|
||||
cv.Optional(CONF_SCL, default="SCL"): pins.input_pin,
|
||||
cv.Optional(CONF_FREQUENCY, default="50kHz"): cv.All(
|
||||
cv.frequency, cv.Range(min=0, min_included=False)
|
||||
),
|
||||
cv.Optional(CONF_SCAN, default=True): cv.boolean,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine_with_priority(1.0)
|
||||
@ -31,7 +41,7 @@ def to_code(config):
|
||||
cg.add(var.set_scl_pin(config[CONF_SCL]))
|
||||
cg.add(var.set_frequency(int(config[CONF_FREQUENCY])))
|
||||
cg.add(var.set_scan(config[CONF_SCAN]))
|
||||
cg.add_library('Wire', None)
|
||||
cg.add_library("Wire", None)
|
||||
|
||||
|
||||
def i2c_device_schema(default_address):
|
||||
|
@ -2,42 +2,55 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import display, spi
|
||||
from esphome.const import CONF_DC_PIN, \
|
||||
CONF_ID, CONF_LAMBDA, CONF_MODEL, CONF_PAGES, CONF_RESET_PIN
|
||||
from esphome.const import (
|
||||
CONF_DC_PIN,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_MODEL,
|
||||
CONF_PAGES,
|
||||
CONF_RESET_PIN,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
CONF_LED_PIN = 'led_pin'
|
||||
CONF_LED_PIN = "led_pin"
|
||||
|
||||
ili9341_ns = cg.esphome_ns.namespace('ili9341')
|
||||
ili9341 = ili9341_ns.class_('ILI9341Display', cg.PollingComponent, spi.SPIDevice,
|
||||
display.DisplayBuffer)
|
||||
ILI9341M5Stack = ili9341_ns.class_('ILI9341M5Stack', ili9341)
|
||||
ILI9341TFT24 = ili9341_ns.class_('ILI9341TFT24', ili9341)
|
||||
ili9341_ns = cg.esphome_ns.namespace("ili9341")
|
||||
ili9341 = ili9341_ns.class_(
|
||||
"ILI9341Display", cg.PollingComponent, spi.SPIDevice, display.DisplayBuffer
|
||||
)
|
||||
ILI9341M5Stack = ili9341_ns.class_("ILI9341M5Stack", ili9341)
|
||||
ILI9341TFT24 = ili9341_ns.class_("ILI9341TFT24", ili9341)
|
||||
|
||||
ILI9341Model = ili9341_ns.enum('ILI9341Model')
|
||||
ILI9341Model = ili9341_ns.enum("ILI9341Model")
|
||||
|
||||
MODELS = {
|
||||
'M5STACK': ILI9341Model.M5STACK,
|
||||
'TFT_2.4': ILI9341Model.TFT_24,
|
||||
"M5STACK": ILI9341Model.M5STACK,
|
||||
"TFT_2.4": ILI9341Model.TFT_24,
|
||||
}
|
||||
|
||||
ILI9341_MODEL = cv.enum(MODELS, upper=True, space="_")
|
||||
|
||||
CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(ili9341),
|
||||
cv.Required(CONF_MODEL): ILI9341_MODEL,
|
||||
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_LED_PIN): pins.gpio_output_pin_schema,
|
||||
}).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
display.FULL_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(ili9341),
|
||||
cv.Required(CONF_MODEL): ILI9341_MODEL,
|
||||
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_LED_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("1s"))
|
||||
.extend(spi.spi_device_schema()),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
if config[CONF_MODEL] == 'M5STACK':
|
||||
if config[CONF_MODEL] == "M5STACK":
|
||||
lcd_type = ILI9341M5Stack
|
||||
if config[CONF_MODEL] == 'TFT_2.4':
|
||||
if config[CONF_MODEL] == "TFT_2.4":
|
||||
lcd_type = ILI9341TFT24
|
||||
rhs = lcd_type.new()
|
||||
var = cg.Pvariable(config[CONF_ID], rhs)
|
||||
@ -50,8 +63,9 @@ def to_code(config):
|
||||
cg.add(var.set_dc_pin(dc))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayBufferRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
if CONF_RESET_PIN in config:
|
||||
reset = yield cg.gpio_pin_expression(config[CONF_RESET_PIN])
|
||||
|
@ -9,28 +9,32 @@ from esphome.core import CORE, HexInt
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
DEPENDENCIES = ["display"]
|
||||
MULTI_CONF = True
|
||||
|
||||
ImageType = display.display_ns.enum('ImageType')
|
||||
ImageType = display.display_ns.enum("ImageType")
|
||||
IMAGE_TYPE = {
|
||||
'BINARY': ImageType.IMAGE_TYPE_BINARY,
|
||||
'GRAYSCALE': ImageType.IMAGE_TYPE_GRAYSCALE,
|
||||
'RGB24': ImageType.IMAGE_TYPE_RGB24,
|
||||
"BINARY": ImageType.IMAGE_TYPE_BINARY,
|
||||
"GRAYSCALE": ImageType.IMAGE_TYPE_GRAYSCALE,
|
||||
"RGB24": ImageType.IMAGE_TYPE_RGB24,
|
||||
}
|
||||
|
||||
Image_ = display.display_ns.class_('Image')
|
||||
Image_ = display.display_ns.class_("Image")
|
||||
|
||||
CONF_RAW_DATA_ID = 'raw_data_id'
|
||||
CONF_RAW_DATA_ID = "raw_data_id"
|
||||
|
||||
IMAGE_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(Image_),
|
||||
cv.Required(CONF_FILE): cv.file_,
|
||||
cv.Optional(CONF_RESIZE): cv.dimensions,
|
||||
cv.Optional(CONF_TYPE, default='BINARY'): cv.enum(IMAGE_TYPE, upper=True),
|
||||
cv.Optional(CONF_DITHER, default='NONE'): cv.one_of("NONE", "FLOYDSTEINBERG", upper=True),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
})
|
||||
IMAGE_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(Image_),
|
||||
cv.Required(CONF_FILE): cv.file_,
|
||||
cv.Optional(CONF_RESIZE): cv.dimensions,
|
||||
cv.Optional(CONF_TYPE, default="BINARY"): cv.enum(IMAGE_TYPE, upper=True),
|
||||
cv.Optional(CONF_DITHER, default="NONE"): cv.one_of(
|
||||
"NONE", "FLOYDSTEINBERG", upper=True
|
||||
),
|
||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_id(cg.uint8),
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(font.validate_pillow_installed, IMAGE_SCHEMA)
|
||||
|
||||
@ -51,12 +55,14 @@ def to_code(config):
|
||||
width, height = image.size
|
||||
else:
|
||||
if width > 500 or height > 500:
|
||||
_LOGGER.warning("The image you requested is very big. Please consider using"
|
||||
" the resize parameter.")
|
||||
_LOGGER.warning(
|
||||
"The image you requested is very big. Please consider using"
|
||||
" the resize parameter."
|
||||
)
|
||||
|
||||
dither = Image.NONE if config[CONF_DITHER] == 'NONE' else Image.FLOYDSTEINBERG
|
||||
if config[CONF_TYPE] == 'GRAYSCALE':
|
||||
image = image.convert('L', dither=dither)
|
||||
dither = Image.NONE if config[CONF_DITHER] == "NONE" else Image.FLOYDSTEINBERG
|
||||
if config[CONF_TYPE] == "GRAYSCALE":
|
||||
image = image.convert("L", dither=dither)
|
||||
pixels = list(image.getdata())
|
||||
data = [0 for _ in range(height * width)]
|
||||
pos = 0
|
||||
@ -64,8 +70,8 @@ def to_code(config):
|
||||
data[pos] = pix
|
||||
pos += 1
|
||||
|
||||
elif config[CONF_TYPE] == 'RGB24':
|
||||
image = image.convert('RGB')
|
||||
elif config[CONF_TYPE] == "RGB24":
|
||||
image = image.convert("RGB")
|
||||
pixels = list(image.getdata())
|
||||
data = [0 for _ in range(height * width * 3)]
|
||||
pos = 0
|
||||
@ -77,8 +83,8 @@ def to_code(config):
|
||||
data[pos] = pix[2]
|
||||
pos += 1
|
||||
|
||||
elif config[CONF_TYPE] == 'BINARY':
|
||||
image = image.convert('1', dither=dither)
|
||||
elif config[CONF_TYPE] == "BINARY":
|
||||
image = image.convert("1", dither=dither)
|
||||
width8 = ((width + 7) // 8) * 8
|
||||
data = [0 for _ in range(height * width8 // 8)]
|
||||
for y in range(height):
|
||||
@ -90,5 +96,6 @@ def to_code(config):
|
||||
|
||||
rhs = [HexInt(x) for x in data]
|
||||
prog_arr = cg.progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||
cg.new_Pvariable(config[CONF_ID], prog_arr, width, height,
|
||||
IMAGE_TYPE[config[CONF_TYPE]])
|
||||
cg.new_Pvariable(
|
||||
config[CONF_ID], prog_arr, width, height, IMAGE_TYPE[config[CONF_TYPE]]
|
||||
)
|
||||
|
@ -1,29 +1,61 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_MAX_CURRENT, \
|
||||
CONF_MAX_VOLTAGE, CONF_POWER, CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, DEVICE_CLASS_CURRENT, \
|
||||
DEVICE_CLASS_POWER, DEVICE_CLASS_VOLTAGE, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
|
||||
from esphome.const import (
|
||||
CONF_BUS_VOLTAGE,
|
||||
CONF_CURRENT,
|
||||
CONF_ID,
|
||||
CONF_MAX_CURRENT,
|
||||
CONF_MAX_VOLTAGE,
|
||||
CONF_POWER,
|
||||
CONF_SHUNT_RESISTANCE,
|
||||
CONF_SHUNT_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ina219_ns = cg.esphome_ns.namespace('ina219')
|
||||
INA219Component = ina219_ns.class_('INA219Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
ina219_ns = cg.esphome_ns.namespace("ina219")
|
||||
INA219Component = ina219_ns.class_(
|
||||
"INA219Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(INA219Component),
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 3,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(cv.resistance,
|
||||
cv.Range(min=0.0, max=32.0)),
|
||||
cv.Optional(CONF_MAX_VOLTAGE, default=32.0): cv.All(cv.voltage, cv.Range(min=0.0, max=32.0)),
|
||||
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(cv.current, cv.Range(min=0.0)),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(INA219Component),
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 3, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(
|
||||
cv.resistance, cv.Range(min=0.0, max=32.0)
|
||||
),
|
||||
cv.Optional(CONF_MAX_VOLTAGE, default=32.0): cv.All(
|
||||
cv.voltage, cv.Range(min=0.0, max=32.0)
|
||||
),
|
||||
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(
|
||||
cv.current, cv.Range(min=0.0)
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,27 +1,57 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_MAX_CURRENT, CONF_POWER, \
|
||||
CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_CURRENT, \
|
||||
DEVICE_CLASS_POWER, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
|
||||
from esphome.const import (
|
||||
CONF_BUS_VOLTAGE,
|
||||
CONF_CURRENT,
|
||||
CONF_ID,
|
||||
CONF_MAX_CURRENT,
|
||||
CONF_POWER,
|
||||
CONF_SHUNT_RESISTANCE,
|
||||
CONF_SHUNT_VOLTAGE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ina226_ns = cg.esphome_ns.namespace('ina226')
|
||||
INA226Component = ina226_ns.class_('INA226Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
ina226_ns = cg.esphome_ns.namespace("ina226")
|
||||
INA226Component = ina226_ns.class_(
|
||||
"INA226Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(INA226Component),
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 3,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(cv.resistance, cv.Range(min=0.0)),
|
||||
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(cv.current, cv.Range(min=0.0)),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(INA226Component),
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 3, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(
|
||||
cv.resistance, cv.Range(min=0.0)
|
||||
),
|
||||
cv.Optional(CONF_MAX_CURRENT, default=3.2): cv.All(
|
||||
cv.current, cv.Range(min=0.0)
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,37 +1,65 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_BUS_VOLTAGE, CONF_CURRENT, CONF_ID, CONF_POWER, \
|
||||
CONF_SHUNT_RESISTANCE, CONF_SHUNT_VOLTAGE, DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_CURRENT, \
|
||||
DEVICE_CLASS_POWER, ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT
|
||||
from esphome.const import (
|
||||
CONF_BUS_VOLTAGE,
|
||||
CONF_CURRENT,
|
||||
CONF_ID,
|
||||
CONF_POWER,
|
||||
CONF_SHUNT_RESISTANCE,
|
||||
CONF_SHUNT_VOLTAGE,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
CONF_CHANNEL_1 = 'channel_1'
|
||||
CONF_CHANNEL_2 = 'channel_2'
|
||||
CONF_CHANNEL_3 = 'channel_3'
|
||||
CONF_CHANNEL_1 = "channel_1"
|
||||
CONF_CHANNEL_2 = "channel_2"
|
||||
CONF_CHANNEL_3 = "channel_3"
|
||||
|
||||
ina3221_ns = cg.esphome_ns.namespace('ina3221')
|
||||
INA3221Component = ina3221_ns.class_('INA3221Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
ina3221_ns = cg.esphome_ns.namespace("ina3221")
|
||||
INA3221Component = ina3221_ns.class_(
|
||||
"INA3221Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
INA3221_CHANNEL_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(cv.resistance,
|
||||
cv.Range(min=0.0, max=32.0)),
|
||||
})
|
||||
INA3221_CHANNEL_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_BUS_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 2, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_SHUNT_RESISTANCE, default=0.1): cv.All(
|
||||
cv.resistance, cv.Range(min=0.0, max=32.0)
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(INA3221Component),
|
||||
cv.Optional(CONF_CHANNEL_1): INA3221_CHANNEL_SCHEMA,
|
||||
cv.Optional(CONF_CHANNEL_2): INA3221_CHANNEL_SCHEMA,
|
||||
cv.Optional(CONF_CHANNEL_3): INA3221_CHANNEL_SCHEMA,
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(INA3221Component),
|
||||
cv.Optional(CONF_CHANNEL_1): INA3221_CHANNEL_SCHEMA,
|
||||
cv.Optional(CONF_CHANNEL_2): INA3221_CHANNEL_SCHEMA,
|
||||
cv.Optional(CONF_CHANNEL_3): INA3221_CHANNEL_SCHEMA,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,27 +1,47 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, esp32_ble_tracker
|
||||
from esphome.const import CONF_BATTERY_LEVEL, CONF_HUMIDITY, CONF_MAC_ADDRESS, CONF_TEMPERATURE, \
|
||||
DEVICE_CLASS_BATTERY, DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, \
|
||||
UNIT_CELSIUS, UNIT_PERCENT, CONF_ID
|
||||
from esphome.const import (
|
||||
CONF_BATTERY_LEVEL,
|
||||
CONF_HUMIDITY,
|
||||
CONF_MAC_ADDRESS,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_BATTERY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
CONF_ID,
|
||||
)
|
||||
|
||||
CODEOWNERS = ['@fkirill']
|
||||
DEPENDENCIES = ['esp32_ble_tracker']
|
||||
CODEOWNERS = ["@fkirill"]
|
||||
DEPENDENCIES = ["esp32_ble_tracker"]
|
||||
|
||||
inkbird_ibsth1_mini_ns = cg.esphome_ns.namespace('inkbird_ibsth1_mini')
|
||||
inkbird_ibsth1_mini_ns = cg.esphome_ns.namespace("inkbird_ibsth1_mini")
|
||||
InkbirdUBSTH1_MINI = inkbird_ibsth1_mini_ns.class_(
|
||||
'InkbirdIBSTH1_MINI', esp32_ble_tracker.ESPBTDeviceListener, cg.Component)
|
||||
"InkbirdIBSTH1_MINI", esp32_ble_tracker.ESPBTDeviceListener, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(InkbirdUBSTH1_MINI),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_HUMIDITY),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_BATTERY),
|
||||
}).extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(InkbirdUBSTH1_MINI),
|
||||
cv.Required(CONF_MAC_ADDRESS): cv.mac_address,
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 0, DEVICE_CLASS_BATTERY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@jesserockz']
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
@ -2,67 +2,94 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import display, i2c
|
||||
from esphome.const import CONF_FULL_UPDATE_EVERY, CONF_ID, CONF_LAMBDA, CONF_PAGES, \
|
||||
CONF_WAKEUP_PIN, ESP_PLATFORM_ESP32
|
||||
from esphome.const import (
|
||||
CONF_FULL_UPDATE_EVERY,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_PAGES,
|
||||
CONF_WAKEUP_PIN,
|
||||
ESP_PLATFORM_ESP32,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
CONF_DISPLAY_DATA_0_PIN = 'display_data_0_pin'
|
||||
CONF_DISPLAY_DATA_1_PIN = 'display_data_1_pin'
|
||||
CONF_DISPLAY_DATA_2_PIN = 'display_data_2_pin'
|
||||
CONF_DISPLAY_DATA_3_PIN = 'display_data_3_pin'
|
||||
CONF_DISPLAY_DATA_4_PIN = 'display_data_4_pin'
|
||||
CONF_DISPLAY_DATA_5_PIN = 'display_data_5_pin'
|
||||
CONF_DISPLAY_DATA_6_PIN = 'display_data_6_pin'
|
||||
CONF_DISPLAY_DATA_7_PIN = 'display_data_7_pin'
|
||||
CONF_DISPLAY_DATA_0_PIN = "display_data_0_pin"
|
||||
CONF_DISPLAY_DATA_1_PIN = "display_data_1_pin"
|
||||
CONF_DISPLAY_DATA_2_PIN = "display_data_2_pin"
|
||||
CONF_DISPLAY_DATA_3_PIN = "display_data_3_pin"
|
||||
CONF_DISPLAY_DATA_4_PIN = "display_data_4_pin"
|
||||
CONF_DISPLAY_DATA_5_PIN = "display_data_5_pin"
|
||||
CONF_DISPLAY_DATA_6_PIN = "display_data_6_pin"
|
||||
CONF_DISPLAY_DATA_7_PIN = "display_data_7_pin"
|
||||
|
||||
CONF_CL_PIN = 'cl_pin'
|
||||
CONF_CKV_PIN = 'ckv_pin'
|
||||
CONF_GREYSCALE = 'greyscale'
|
||||
CONF_GMOD_PIN = 'gmod_pin'
|
||||
CONF_GPIO0_ENABLE_PIN = 'gpio0_enable_pin'
|
||||
CONF_LE_PIN = 'le_pin'
|
||||
CONF_OE_PIN = 'oe_pin'
|
||||
CONF_PARTIAL_UPDATING = 'partial_updating'
|
||||
CONF_POWERUP_PIN = 'powerup_pin'
|
||||
CONF_SPH_PIN = 'sph_pin'
|
||||
CONF_SPV_PIN = 'spv_pin'
|
||||
CONF_VCOM_PIN = 'vcom_pin'
|
||||
CONF_CL_PIN = "cl_pin"
|
||||
CONF_CKV_PIN = "ckv_pin"
|
||||
CONF_GREYSCALE = "greyscale"
|
||||
CONF_GMOD_PIN = "gmod_pin"
|
||||
CONF_GPIO0_ENABLE_PIN = "gpio0_enable_pin"
|
||||
CONF_LE_PIN = "le_pin"
|
||||
CONF_OE_PIN = "oe_pin"
|
||||
CONF_PARTIAL_UPDATING = "partial_updating"
|
||||
CONF_POWERUP_PIN = "powerup_pin"
|
||||
CONF_SPH_PIN = "sph_pin"
|
||||
CONF_SPV_PIN = "spv_pin"
|
||||
CONF_VCOM_PIN = "vcom_pin"
|
||||
|
||||
|
||||
inkplate6_ns = cg.esphome_ns.namespace('inkplate6')
|
||||
Inkplate6 = inkplate6_ns.class_('Inkplate6', cg.PollingComponent, i2c.I2CDevice,
|
||||
display.DisplayBuffer)
|
||||
inkplate6_ns = cg.esphome_ns.namespace("inkplate6")
|
||||
Inkplate6 = inkplate6_ns.class_(
|
||||
"Inkplate6", cg.PollingComponent, i2c.I2CDevice, display.DisplayBuffer
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(Inkplate6),
|
||||
cv.Optional(CONF_GREYSCALE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
|
||||
cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
|
||||
# Control pins
|
||||
cv.Required(CONF_CKV_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_GMOD_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_GPIO0_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_OE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_POWERUP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_SPH_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_SPV_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_VCOM_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_WAKEUP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_CL_PIN, default=0): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_LE_PIN, default=2): pins.internal_gpio_output_pin_schema,
|
||||
# Data pins
|
||||
cv.Optional(CONF_DISPLAY_DATA_0_PIN, default=4): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_1_PIN, default=5): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_2_PIN, default=18): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_3_PIN, default=19): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_4_PIN, default=23): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_5_PIN, default=25): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_6_PIN, default=26): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_DISPLAY_DATA_7_PIN, default=27): pins.internal_gpio_output_pin_schema,
|
||||
}).extend(cv.polling_component_schema('5s').extend(i2c.i2c_device_schema(0x48))),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
display.FULL_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Inkplate6),
|
||||
cv.Optional(CONF_GREYSCALE, default=False): cv.boolean,
|
||||
cv.Optional(CONF_PARTIAL_UPDATING, default=True): cv.boolean,
|
||||
cv.Optional(CONF_FULL_UPDATE_EVERY, default=10): cv.uint32_t,
|
||||
# Control pins
|
||||
cv.Required(CONF_CKV_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_GMOD_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_GPIO0_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_OE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_POWERUP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_SPH_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_SPV_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_VCOM_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_WAKEUP_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_CL_PIN, default=0): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_LE_PIN, default=2): pins.internal_gpio_output_pin_schema,
|
||||
# Data pins
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_0_PIN, default=4
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_1_PIN, default=5
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_2_PIN, default=18
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_3_PIN, default=19
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_4_PIN, default=23
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_5_PIN, default=25
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_6_PIN, default=26
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_DISPLAY_DATA_7_PIN, default=27
|
||||
): pins.internal_gpio_output_pin_schema,
|
||||
}
|
||||
).extend(cv.polling_component_schema("5s").extend(i2c.i2c_device_schema(0x48))),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -73,8 +100,9 @@ def to_code(config):
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayBufferRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
||||
cg.add(var.set_greyscale(config[CONF_GREYSCALE]))
|
||||
@ -138,4 +166,4 @@ def to_code(config):
|
||||
display_data_7 = yield cg.gpio_pin_expression(config[CONF_DISPLAY_DATA_7_PIN])
|
||||
cg.add(var.set_display_data_7_pin(display_data_7))
|
||||
|
||||
cg.add_build_flag('-DBOARD_HAS_PSRAM')
|
||||
cg.add_build_flag("-DBOARD_HAS_PSRAM")
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
@ -4,36 +4,41 @@ from esphome import automation
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, CONF_SENSOR, CONF_RESTORE
|
||||
|
||||
integration_ns = cg.esphome_ns.namespace('integration')
|
||||
IntegrationSensor = integration_ns.class_('IntegrationSensor', sensor.Sensor, cg.Component)
|
||||
ResetAction = integration_ns.class_('ResetAction', automation.Action)
|
||||
integration_ns = cg.esphome_ns.namespace("integration")
|
||||
IntegrationSensor = integration_ns.class_(
|
||||
"IntegrationSensor", sensor.Sensor, cg.Component
|
||||
)
|
||||
ResetAction = integration_ns.class_("ResetAction", automation.Action)
|
||||
|
||||
IntegrationSensorTime = integration_ns.enum('IntegrationSensorTime')
|
||||
IntegrationSensorTime = integration_ns.enum("IntegrationSensorTime")
|
||||
INTEGRATION_TIMES = {
|
||||
'ms': IntegrationSensorTime.INTEGRATION_SENSOR_TIME_MILLISECOND,
|
||||
's': IntegrationSensorTime.INTEGRATION_SENSOR_TIME_SECOND,
|
||||
'min': IntegrationSensorTime.INTEGRATION_SENSOR_TIME_MINUTE,
|
||||
'h': IntegrationSensorTime.INTEGRATION_SENSOR_TIME_HOUR,
|
||||
'd': IntegrationSensorTime.INTEGRATION_SENSOR_TIME_DAY,
|
||||
"ms": IntegrationSensorTime.INTEGRATION_SENSOR_TIME_MILLISECOND,
|
||||
"s": IntegrationSensorTime.INTEGRATION_SENSOR_TIME_SECOND,
|
||||
"min": IntegrationSensorTime.INTEGRATION_SENSOR_TIME_MINUTE,
|
||||
"h": IntegrationSensorTime.INTEGRATION_SENSOR_TIME_HOUR,
|
||||
"d": IntegrationSensorTime.INTEGRATION_SENSOR_TIME_DAY,
|
||||
}
|
||||
IntegrationMethod = integration_ns.enum('IntegrationMethod')
|
||||
IntegrationMethod = integration_ns.enum("IntegrationMethod")
|
||||
INTEGRATION_METHODS = {
|
||||
'trapezoid': IntegrationMethod.INTEGRATION_METHOD_TRAPEZOID,
|
||||
'left': IntegrationMethod.INTEGRATION_METHOD_LEFT,
|
||||
'right': IntegrationMethod.INTEGRATION_METHOD_RIGHT,
|
||||
"trapezoid": IntegrationMethod.INTEGRATION_METHOD_TRAPEZOID,
|
||||
"left": IntegrationMethod.INTEGRATION_METHOD_LEFT,
|
||||
"right": IntegrationMethod.INTEGRATION_METHOD_RIGHT,
|
||||
}
|
||||
|
||||
CONF_TIME_UNIT = 'time_unit'
|
||||
CONF_INTEGRATION_METHOD = 'integration_method'
|
||||
CONF_TIME_UNIT = "time_unit"
|
||||
CONF_INTEGRATION_METHOD = "integration_method"
|
||||
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(IntegrationSensor),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_TIME_UNIT): cv.enum(INTEGRATION_TIMES, lower=True),
|
||||
cv.Optional(CONF_INTEGRATION_METHOD, default='trapezoid'):
|
||||
cv.enum(INTEGRATION_METHODS, lower=True),
|
||||
cv.Optional(CONF_RESTORE, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(IntegrationSensor),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_TIME_UNIT): cv.enum(INTEGRATION_TIMES, lower=True),
|
||||
cv.Optional(CONF_INTEGRATION_METHOD, default="trapezoid"): cv.enum(
|
||||
INTEGRATION_METHODS, lower=True
|
||||
),
|
||||
cv.Optional(CONF_RESTORE, default=False): cv.boolean,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -49,9 +54,15 @@ def to_code(config):
|
||||
cg.add(var.set_restore(config[CONF_RESTORE]))
|
||||
|
||||
|
||||
@automation.register_action('sensor.integration.reset', ResetAction, automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(IntegrationSensor),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"sensor.integration.reset",
|
||||
ResetAction,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(IntegrationSensor),
|
||||
}
|
||||
),
|
||||
)
|
||||
def sensor_integration_reset_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -3,15 +3,20 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.const import CONF_ID, CONF_INTERVAL
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
interval_ns = cg.esphome_ns.namespace('interval')
|
||||
IntervalTrigger = interval_ns.class_('IntervalTrigger', automation.Trigger.template(),
|
||||
cg.PollingComponent)
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
interval_ns = cg.esphome_ns.namespace("interval")
|
||||
IntervalTrigger = interval_ns.class_(
|
||||
"IntervalTrigger", automation.Trigger.template(), cg.PollingComponent
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = automation.validate_automation(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(IntervalTrigger),
|
||||
cv.Required(CONF_INTERVAL): cv.positive_time_period_milliseconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA))
|
||||
CONFIG_SCHEMA = automation.validate_automation(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(IntervalTrigger),
|
||||
cv.Required(CONF_INTERVAL): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,12 +1,12 @@
|
||||
import esphome.codegen as cg
|
||||
from esphome.core import coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
json_ns = cg.esphome_ns.namespace('json')
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
json_ns = cg.esphome_ns.namespace("json")
|
||||
|
||||
|
||||
@coroutine_with_priority(1.0)
|
||||
def to_code(config):
|
||||
cg.add_library('ArduinoJson-esphomelib', '5.13.3')
|
||||
cg.add_define('USE_JSON')
|
||||
cg.add_library("ArduinoJson-esphomelib", "5.13.3")
|
||||
cg.add_define("USE_JSON")
|
||||
cg.add_global(json_ns.using)
|
||||
|
@ -4,8 +4,8 @@ from esphome.components import display
|
||||
from esphome.const import CONF_DIMENSIONS
|
||||
from esphome.core import coroutine
|
||||
|
||||
lcd_base_ns = cg.esphome_ns.namespace('lcd_base')
|
||||
LCDDisplay = lcd_base_ns.class_('LCDDisplay', cg.PollingComponent)
|
||||
lcd_base_ns = cg.esphome_ns.namespace("lcd_base")
|
||||
LCDDisplay = lcd_base_ns.class_("LCDDisplay", cg.PollingComponent)
|
||||
|
||||
|
||||
def validate_lcd_dimensions(value):
|
||||
@ -17,9 +17,11 @@ def validate_lcd_dimensions(value):
|
||||
return value
|
||||
|
||||
|
||||
LCD_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend({
|
||||
cv.Required(CONF_DIMENSIONS): validate_lcd_dimensions,
|
||||
}).extend(cv.polling_component_schema('1s'))
|
||||
LCD_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_DIMENSIONS): validate_lcd_dimensions,
|
||||
}
|
||||
).extend(cv.polling_component_schema("1s"))
|
||||
|
||||
|
||||
@coroutine
|
||||
|
@ -2,29 +2,41 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import lcd_base
|
||||
from esphome.const import CONF_DATA_PINS, CONF_ENABLE_PIN, CONF_RS_PIN, CONF_RW_PIN, CONF_ID, \
|
||||
CONF_LAMBDA
|
||||
from esphome.const import (
|
||||
CONF_DATA_PINS,
|
||||
CONF_ENABLE_PIN,
|
||||
CONF_RS_PIN,
|
||||
CONF_RW_PIN,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['lcd_base']
|
||||
AUTO_LOAD = ["lcd_base"]
|
||||
|
||||
lcd_gpio_ns = cg.esphome_ns.namespace('lcd_gpio')
|
||||
GPIOLCDDisplay = lcd_gpio_ns.class_('GPIOLCDDisplay', lcd_base.LCDDisplay)
|
||||
lcd_gpio_ns = cg.esphome_ns.namespace("lcd_gpio")
|
||||
GPIOLCDDisplay = lcd_gpio_ns.class_("GPIOLCDDisplay", lcd_base.LCDDisplay)
|
||||
|
||||
|
||||
def validate_pin_length(value):
|
||||
if len(value) != 4 and len(value) != 8:
|
||||
raise cv.Invalid("LCD Displays can either operate in 4-pin or 8-pin mode,"
|
||||
"not {}-pin mode".format(len(value)))
|
||||
raise cv.Invalid(
|
||||
"LCD Displays can either operate in 4-pin or 8-pin mode,"
|
||||
"not {}-pin mode".format(len(value))
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = lcd_base.LCD_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(GPIOLCDDisplay),
|
||||
cv.Required(CONF_DATA_PINS): cv.All([pins.gpio_output_pin_schema], validate_pin_length),
|
||||
cv.Required(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_RS_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RW_PIN): pins.gpio_output_pin_schema,
|
||||
})
|
||||
CONFIG_SCHEMA = lcd_base.LCD_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(GPIOLCDDisplay),
|
||||
cv.Required(CONF_DATA_PINS): cv.All(
|
||||
[pins.gpio_output_pin_schema], validate_pin_length
|
||||
),
|
||||
cv.Required(CONF_ENABLE_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_RS_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_RW_PIN): pins.gpio_output_pin_schema,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -45,7 +57,9 @@ def to_code(config):
|
||||
cg.add(var.set_rw_pin(rw))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA],
|
||||
[(GPIOLCDDisplay.operator('ref'), 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA],
|
||||
[(GPIOLCDDisplay.operator("ref"), "it")],
|
||||
return_type=cg.void,
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
@ -3,15 +3,19 @@ import esphome.config_validation as cv
|
||||
from esphome.components import lcd_base, i2c
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ['lcd_base']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["lcd_base"]
|
||||
|
||||
lcd_pcf8574_ns = cg.esphome_ns.namespace('lcd_pcf8574')
|
||||
PCF8574LCDDisplay = lcd_pcf8574_ns.class_('PCF8574LCDDisplay', lcd_base.LCDDisplay, i2c.I2CDevice)
|
||||
lcd_pcf8574_ns = cg.esphome_ns.namespace("lcd_pcf8574")
|
||||
PCF8574LCDDisplay = lcd_pcf8574_ns.class_(
|
||||
"PCF8574LCDDisplay", lcd_base.LCDDisplay, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = lcd_base.LCD_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PCF8574LCDDisplay),
|
||||
}).extend(i2c.i2c_device_schema(0x3F))
|
||||
CONFIG_SCHEMA = lcd_base.LCD_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PCF8574LCDDisplay),
|
||||
}
|
||||
).extend(i2c.i2c_device_schema(0x3F))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -20,7 +24,9 @@ def to_code(config):
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA],
|
||||
[(PCF8574LCDDisplay.operator('ref'), 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA],
|
||||
[(PCF8574LCDDisplay.operator("ref"), "it")],
|
||||
return_type=cg.void,
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
@ -2,19 +2,25 @@ from esphome import pins, automation
|
||||
from esphome.components import output
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.const import CONF_BIT_DEPTH, CONF_CHANNEL, CONF_FREQUENCY, \
|
||||
CONF_ID, CONF_PIN, ESP_PLATFORM_ESP32
|
||||
from esphome.const import (
|
||||
CONF_BIT_DEPTH,
|
||||
CONF_CHANNEL,
|
||||
CONF_FREQUENCY,
|
||||
CONF_ID,
|
||||
CONF_PIN,
|
||||
ESP_PLATFORM_ESP32,
|
||||
)
|
||||
|
||||
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
|
||||
|
||||
|
||||
def calc_max_frequency(bit_depth):
|
||||
return 80e6 / (2**bit_depth)
|
||||
return 80e6 / (2 ** bit_depth)
|
||||
|
||||
|
||||
def calc_min_frequency(bit_depth):
|
||||
max_div_num = ((2**20) - 1) / 256.0
|
||||
return 80e6 / (max_div_num * (2**bit_depth))
|
||||
max_div_num = ((2 ** 20) - 1) / 256.0
|
||||
return 80e6 / (max_div_num * (2 ** bit_depth))
|
||||
|
||||
|
||||
def validate_frequency(value):
|
||||
@ -22,27 +28,34 @@ def validate_frequency(value):
|
||||
min_freq = calc_min_frequency(20)
|
||||
max_freq = calc_max_frequency(1)
|
||||
if value < min_freq:
|
||||
raise cv.Invalid("This frequency setting is not possible, please choose a higher "
|
||||
"frequency (at least {}Hz)".format(int(min_freq)))
|
||||
raise cv.Invalid(
|
||||
"This frequency setting is not possible, please choose a higher "
|
||||
"frequency (at least {}Hz)".format(int(min_freq))
|
||||
)
|
||||
if value > max_freq:
|
||||
raise cv.Invalid("This frequency setting is not possible, please choose a lower "
|
||||
"frequency (at most {}Hz)".format(int(max_freq)))
|
||||
raise cv.Invalid(
|
||||
"This frequency setting is not possible, please choose a lower "
|
||||
"frequency (at most {}Hz)".format(int(max_freq))
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
ledc_ns = cg.esphome_ns.namespace('ledc')
|
||||
LEDCOutput = ledc_ns.class_('LEDCOutput', output.FloatOutput, cg.Component)
|
||||
SetFrequencyAction = ledc_ns.class_('SetFrequencyAction', automation.Action)
|
||||
ledc_ns = cg.esphome_ns.namespace("ledc")
|
||||
LEDCOutput = ledc_ns.class_("LEDCOutput", output.FloatOutput, cg.Component)
|
||||
SetFrequencyAction = ledc_ns.class_("SetFrequencyAction", automation.Action)
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(LEDCOutput),
|
||||
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_FREQUENCY, default='1kHz'): cv.frequency,
|
||||
cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15),
|
||||
|
||||
cv.Optional(CONF_BIT_DEPTH): cv.invalid("The bit_depth option has been removed in v1.14, the "
|
||||
"best bit depth is now automatically calculated."),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(LEDCOutput),
|
||||
cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
|
||||
cv.Optional(CONF_FREQUENCY, default="1kHz"): cv.frequency,
|
||||
cv.Optional(CONF_CHANNEL): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_BIT_DEPTH): cv.invalid(
|
||||
"The bit_depth option has been removed in v1.14, the "
|
||||
"best bit depth is now automatically calculated."
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -55,10 +68,16 @@ def to_code(config):
|
||||
cg.add(var.set_frequency(config[CONF_FREQUENCY]))
|
||||
|
||||
|
||||
@automation.register_action('output.ledc.set_frequency', SetFrequencyAction, cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(LEDCOutput),
|
||||
cv.Required(CONF_FREQUENCY): cv.templatable(validate_frequency),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"output.ledc.set_frequency",
|
||||
SetFrequencyAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LEDCOutput),
|
||||
cv.Required(CONF_FREQUENCY): cv.templatable(validate_frequency),
|
||||
}
|
||||
),
|
||||
)
|
||||
def ledc_set_frequency_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -2,62 +2,104 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
import esphome.automation as auto
|
||||
from esphome.components import mqtt, power_supply
|
||||
from esphome.const import CONF_COLOR_CORRECT, \
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_ID, \
|
||||
CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY, CONF_RESTORE_MODE, \
|
||||
CONF_ON_TURN_OFF, CONF_ON_TURN_ON, CONF_TRIGGER_ID
|
||||
from esphome.const import (
|
||||
CONF_COLOR_CORRECT,
|
||||
CONF_DEFAULT_TRANSITION_LENGTH,
|
||||
CONF_EFFECTS,
|
||||
CONF_GAMMA_CORRECT,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL,
|
||||
CONF_NAME,
|
||||
CONF_MQTT_ID,
|
||||
CONF_POWER_SUPPLY,
|
||||
CONF_RESTORE_MODE,
|
||||
CONF_ON_TURN_OFF,
|
||||
CONF_ON_TURN_ON,
|
||||
CONF_TRIGGER_ID,
|
||||
)
|
||||
from esphome.core import coroutine, coroutine_with_priority
|
||||
from .automation import light_control_to_code # noqa
|
||||
from .effects import validate_effects, BINARY_EFFECTS, \
|
||||
MONOCHROMATIC_EFFECTS, RGB_EFFECTS, ADDRESSABLE_EFFECTS, EFFECTS_REGISTRY
|
||||
from .effects import (
|
||||
validate_effects,
|
||||
BINARY_EFFECTS,
|
||||
MONOCHROMATIC_EFFECTS,
|
||||
RGB_EFFECTS,
|
||||
ADDRESSABLE_EFFECTS,
|
||||
EFFECTS_REGISTRY,
|
||||
)
|
||||
from .types import ( # noqa
|
||||
LightState, AddressableLightState, light_ns, LightOutput, AddressableLight, \
|
||||
LightTurnOnTrigger, LightTurnOffTrigger)
|
||||
LightState,
|
||||
AddressableLightState,
|
||||
light_ns,
|
||||
LightOutput,
|
||||
AddressableLight,
|
||||
LightTurnOnTrigger,
|
||||
LightTurnOffTrigger,
|
||||
)
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
LightRestoreMode = light_ns.enum('LightRestoreMode')
|
||||
LightRestoreMode = light_ns.enum("LightRestoreMode")
|
||||
RESTORE_MODES = {
|
||||
'RESTORE_DEFAULT_OFF': LightRestoreMode.LIGHT_RESTORE_DEFAULT_OFF,
|
||||
'RESTORE_DEFAULT_ON': LightRestoreMode.LIGHT_RESTORE_DEFAULT_ON,
|
||||
'ALWAYS_OFF': LightRestoreMode.LIGHT_ALWAYS_OFF,
|
||||
'ALWAYS_ON': LightRestoreMode.LIGHT_ALWAYS_ON,
|
||||
"RESTORE_DEFAULT_OFF": LightRestoreMode.LIGHT_RESTORE_DEFAULT_OFF,
|
||||
"RESTORE_DEFAULT_ON": LightRestoreMode.LIGHT_RESTORE_DEFAULT_ON,
|
||||
"ALWAYS_OFF": LightRestoreMode.LIGHT_ALWAYS_OFF,
|
||||
"ALWAYS_ON": LightRestoreMode.LIGHT_ALWAYS_ON,
|
||||
}
|
||||
|
||||
LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(LightState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTJSONLightComponent),
|
||||
cv.Optional(CONF_RESTORE_MODE, default='restore_default_off'):
|
||||
cv.enum(RESTORE_MODES, upper=True, space='_'),
|
||||
cv.Optional(CONF_ON_TURN_ON): auto.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOnTrigger),
|
||||
}),
|
||||
cv.Optional(CONF_ON_TURN_OFF): auto.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOffTrigger),
|
||||
}),
|
||||
})
|
||||
LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(LightState),
|
||||
cv.OnlyWith(CONF_MQTT_ID, "mqtt"): cv.declare_id(mqtt.MQTTJSONLightComponent),
|
||||
cv.Optional(CONF_RESTORE_MODE, default="restore_default_off"): cv.enum(
|
||||
RESTORE_MODES, upper=True, space="_"
|
||||
),
|
||||
cv.Optional(CONF_ON_TURN_ON): auto.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOnTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_TURN_OFF): auto.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOffTrigger),
|
||||
}
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
BINARY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(BINARY_EFFECTS),
|
||||
})
|
||||
BINARY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(BINARY_EFFECTS),
|
||||
}
|
||||
)
|
||||
|
||||
BRIGHTNESS_ONLY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({
|
||||
cv.Optional(CONF_GAMMA_CORRECT, default=2.8): cv.positive_float,
|
||||
cv.Optional(CONF_DEFAULT_TRANSITION_LENGTH, default='1s'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(MONOCHROMATIC_EFFECTS),
|
||||
})
|
||||
BRIGHTNESS_ONLY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_GAMMA_CORRECT, default=2.8): cv.positive_float,
|
||||
cv.Optional(
|
||||
CONF_DEFAULT_TRANSITION_LENGTH, default="1s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(MONOCHROMATIC_EFFECTS),
|
||||
}
|
||||
)
|
||||
|
||||
RGB_LIGHT_SCHEMA = BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend({
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(RGB_EFFECTS),
|
||||
})
|
||||
RGB_LIGHT_SCHEMA = BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(RGB_EFFECTS),
|
||||
}
|
||||
)
|
||||
|
||||
ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(AddressableLightState),
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS),
|
||||
cv.Optional(CONF_COLOR_CORRECT): cv.All([cv.percentage], cv.Length(min=3, max=4)),
|
||||
cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
|
||||
})
|
||||
ADDRESSABLE_LIGHT_SCHEMA = RGB_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(AddressableLightState),
|
||||
cv.Optional(CONF_EFFECTS): validate_effects(ADDRESSABLE_EFFECTS),
|
||||
cv.Optional(CONF_COLOR_CORRECT): cv.All(
|
||||
[cv.percentage], cv.Length(min=3, max=4)
|
||||
),
|
||||
cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -66,10 +108,16 @@ def setup_light_core_(light_var, output_var, config):
|
||||
if CONF_INTERNAL in config:
|
||||
cg.add(light_var.set_internal(config[CONF_INTERNAL]))
|
||||
if CONF_DEFAULT_TRANSITION_LENGTH in config:
|
||||
cg.add(light_var.set_default_transition_length(config[CONF_DEFAULT_TRANSITION_LENGTH]))
|
||||
cg.add(
|
||||
light_var.set_default_transition_length(
|
||||
config[CONF_DEFAULT_TRANSITION_LENGTH]
|
||||
)
|
||||
)
|
||||
if CONF_GAMMA_CORRECT in config:
|
||||
cg.add(light_var.set_gamma_correct(config[CONF_GAMMA_CORRECT]))
|
||||
effects = yield cg.build_registry_list(EFFECTS_REGISTRY, config.get(CONF_EFFECTS, []))
|
||||
effects = yield cg.build_registry_list(
|
||||
EFFECTS_REGISTRY, config.get(CONF_EFFECTS, [])
|
||||
)
|
||||
cg.add(light_var.add_effects(effects))
|
||||
|
||||
for conf in config.get(CONF_ON_TURN_ON, []):
|
||||
@ -101,5 +149,5 @@ def register_light(output_var, config):
|
||||
|
||||
@coroutine_with_priority(100.0)
|
||||
def to_code(config):
|
||||
cg.add_define('USE_LIGHT')
|
||||
cg.add_define("USE_LIGHT")
|
||||
cg.add_global(light_ns.using)
|
||||
|
@ -1,54 +1,102 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.const import CONF_ID, CONF_TRANSITION_LENGTH, CONF_STATE, CONF_FLASH_LENGTH, \
|
||||
CONF_EFFECT, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, \
|
||||
CONF_COLOR_TEMPERATURE, CONF_RANGE_FROM, CONF_RANGE_TO
|
||||
from .types import DimRelativeAction, ToggleAction, LightState, LightControlAction, \
|
||||
AddressableLightState, AddressableSet, LightIsOnCondition, LightIsOffCondition
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_TRANSITION_LENGTH,
|
||||
CONF_STATE,
|
||||
CONF_FLASH_LENGTH,
|
||||
CONF_EFFECT,
|
||||
CONF_BRIGHTNESS,
|
||||
CONF_RED,
|
||||
CONF_GREEN,
|
||||
CONF_BLUE,
|
||||
CONF_WHITE,
|
||||
CONF_COLOR_TEMPERATURE,
|
||||
CONF_RANGE_FROM,
|
||||
CONF_RANGE_TO,
|
||||
)
|
||||
from .types import (
|
||||
DimRelativeAction,
|
||||
ToggleAction,
|
||||
LightState,
|
||||
LightControlAction,
|
||||
AddressableLightState,
|
||||
AddressableSet,
|
||||
LightIsOnCondition,
|
||||
LightIsOffCondition,
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('light.toggle', ToggleAction, automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"light.toggle",
|
||||
ToggleAction,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
}
|
||||
),
|
||||
)
|
||||
def light_toggle_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
template_ = yield cg.templatable(config[CONF_TRANSITION_LENGTH], args, cg.uint32)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_TRANSITION_LENGTH], args, cg.uint32
|
||||
)
|
||||
cg.add(var.set_transition_length(template_))
|
||||
yield var
|
||||
|
||||
|
||||
LIGHT_CONTROL_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_STATE): cv.templatable(cv.boolean),
|
||||
cv.Exclusive(CONF_TRANSITION_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
cv.Exclusive(CONF_FLASH_LENGTH, 'transformer'):
|
||||
cv.templatable(cv.positive_time_period_milliseconds),
|
||||
cv.Exclusive(CONF_EFFECT, 'transformer'): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.color_temperature),
|
||||
})
|
||||
LIGHT_TURN_OFF_ACTION_SCHEMA = automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
cv.Optional(CONF_STATE, default=False): False,
|
||||
})
|
||||
LIGHT_TURN_ON_ACTION_SCHEMA = automation.maybe_simple_id(LIGHT_CONTROL_ACTION_SCHEMA.extend({
|
||||
cv.Optional(CONF_STATE, default=True): True,
|
||||
}))
|
||||
LIGHT_CONTROL_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_STATE): cv.templatable(cv.boolean),
|
||||
cv.Exclusive(CONF_TRANSITION_LENGTH, "transformer"): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
cv.Exclusive(CONF_FLASH_LENGTH, "transformer"): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
cv.Exclusive(CONF_EFFECT, "transformer"): cv.templatable(cv.string),
|
||||
cv.Optional(CONF_BRIGHTNESS): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_COLOR_TEMPERATURE): cv.templatable(cv.color_temperature),
|
||||
}
|
||||
)
|
||||
LIGHT_TURN_OFF_ACTION_SCHEMA = automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
cv.Optional(CONF_STATE, default=False): False,
|
||||
}
|
||||
)
|
||||
LIGHT_TURN_ON_ACTION_SCHEMA = automation.maybe_simple_id(
|
||||
LIGHT_CONTROL_ACTION_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_STATE, default=True): True,
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('light.turn_off', LightControlAction, LIGHT_TURN_OFF_ACTION_SCHEMA)
|
||||
@automation.register_action('light.turn_on', LightControlAction, LIGHT_TURN_ON_ACTION_SCHEMA)
|
||||
@automation.register_action('light.control', LightControlAction, LIGHT_CONTROL_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"light.turn_off", LightControlAction, LIGHT_TURN_OFF_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"light.turn_on", LightControlAction, LIGHT_TURN_ON_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"light.control", LightControlAction, LIGHT_CONTROL_ACTION_SCHEMA
|
||||
)
|
||||
def light_control_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -56,7 +104,9 @@ def light_control_to_code(config, action_id, template_arg, args):
|
||||
template_ = yield cg.templatable(config[CONF_STATE], args, bool)
|
||||
cg.add(var.set_state(template_))
|
||||
if CONF_TRANSITION_LENGTH in config:
|
||||
template_ = yield cg.templatable(config[CONF_TRANSITION_LENGTH], args, cg.uint32)
|
||||
template_ = yield cg.templatable(
|
||||
config[CONF_TRANSITION_LENGTH], args, cg.uint32
|
||||
)
|
||||
cg.add(var.set_transition_length(template_))
|
||||
if CONF_FLASH_LENGTH in config:
|
||||
template_ = yield cg.templatable(config[CONF_FLASH_LENGTH], args, cg.uint32)
|
||||
@ -85,16 +135,23 @@ def light_control_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
CONF_RELATIVE_BRIGHTNESS = 'relative_brightness'
|
||||
LIGHT_DIM_RELATIVE_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Required(CONF_RELATIVE_BRIGHTNESS): cv.templatable(cv.possibly_negative_percentage),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(cv.positive_time_period_milliseconds),
|
||||
})
|
||||
CONF_RELATIVE_BRIGHTNESS = "relative_brightness"
|
||||
LIGHT_DIM_RELATIVE_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
cv.Required(CONF_RELATIVE_BRIGHTNESS): cv.templatable(
|
||||
cv.possibly_negative_percentage
|
||||
),
|
||||
cv.Optional(CONF_TRANSITION_LENGTH): cv.templatable(
|
||||
cv.positive_time_period_milliseconds
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('light.dim_relative', DimRelativeAction,
|
||||
LIGHT_DIM_RELATIVE_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"light.dim_relative", DimRelativeAction, LIGHT_DIM_RELATIVE_ACTION_SCHEMA
|
||||
)
|
||||
def light_dim_relative_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -106,19 +163,22 @@ def light_dim_relative_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(AddressableLightState),
|
||||
cv.Optional(CONF_RANGE_FROM): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RANGE_TO): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
})
|
||||
LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(AddressableLightState),
|
||||
cv.Optional(CONF_RANGE_FROM): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RANGE_TO): cv.templatable(cv.positive_int),
|
||||
cv.Optional(CONF_RED): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_GREEN): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_BLUE): cv.templatable(cv.percentage),
|
||||
cv.Optional(CONF_WHITE): cv.templatable(cv.percentage),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('light.addressable_set', AddressableSet,
|
||||
LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"light.addressable_set", AddressableSet, LIGHT_ADDRESSABLE_SET_ACTION_SCHEMA
|
||||
)
|
||||
def light_addressable_set_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -133,28 +193,46 @@ def light_addressable_set_to_code(config, action_id, template_arg, args):
|
||||
return int(round(x * 255))
|
||||
|
||||
if CONF_RED in config:
|
||||
templ = yield cg.templatable(config[CONF_RED], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
templ = yield cg.templatable(
|
||||
config[CONF_RED], args, cg.uint8, to_exp=rgbw_to_exp
|
||||
)
|
||||
cg.add(var.set_red(templ))
|
||||
if CONF_GREEN in config:
|
||||
templ = yield cg.templatable(config[CONF_GREEN], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
templ = yield cg.templatable(
|
||||
config[CONF_GREEN], args, cg.uint8, to_exp=rgbw_to_exp
|
||||
)
|
||||
cg.add(var.set_green(templ))
|
||||
if CONF_BLUE in config:
|
||||
templ = yield cg.templatable(config[CONF_BLUE], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
templ = yield cg.templatable(
|
||||
config[CONF_BLUE], args, cg.uint8, to_exp=rgbw_to_exp
|
||||
)
|
||||
cg.add(var.set_blue(templ))
|
||||
if CONF_WHITE in config:
|
||||
templ = yield cg.templatable(config[CONF_WHITE], args, cg.uint8, to_exp=rgbw_to_exp)
|
||||
templ = yield cg.templatable(
|
||||
config[CONF_WHITE], args, cg.uint8, to_exp=rgbw_to_exp
|
||||
)
|
||||
cg.add(var.set_white(templ))
|
||||
yield var
|
||||
|
||||
|
||||
@automation.register_condition('light.is_on', LightIsOnCondition,
|
||||
automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
}))
|
||||
@automation.register_condition('light.is_off', LightIsOffCondition,
|
||||
automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
}))
|
||||
@automation.register_condition(
|
||||
"light.is_on",
|
||||
LightIsOnCondition,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
}
|
||||
),
|
||||
)
|
||||
@automation.register_condition(
|
||||
"light.is_off",
|
||||
LightIsOffCondition,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(LightState),
|
||||
}
|
||||
),
|
||||
)
|
||||
def light_is_on_off_to_code(config, condition_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(condition_id, template_arg, paren)
|
||||
|
@ -2,38 +2,69 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
|
||||
from esphome.const import CONF_NAME, CONF_LAMBDA, CONF_UPDATE_INTERVAL, CONF_TRANSITION_LENGTH, \
|
||||
CONF_COLORS, CONF_STATE, CONF_DURATION, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE, \
|
||||
CONF_WHITE, CONF_ALPHA, CONF_INTENSITY, CONF_SPEED, CONF_WIDTH, CONF_NUM_LEDS, CONF_RANDOM, \
|
||||
CONF_SEQUENCE
|
||||
from esphome.const import (
|
||||
CONF_NAME,
|
||||
CONF_LAMBDA,
|
||||
CONF_UPDATE_INTERVAL,
|
||||
CONF_TRANSITION_LENGTH,
|
||||
CONF_COLORS,
|
||||
CONF_STATE,
|
||||
CONF_DURATION,
|
||||
CONF_BRIGHTNESS,
|
||||
CONF_RED,
|
||||
CONF_GREEN,
|
||||
CONF_BLUE,
|
||||
CONF_WHITE,
|
||||
CONF_ALPHA,
|
||||
CONF_INTENSITY,
|
||||
CONF_SPEED,
|
||||
CONF_WIDTH,
|
||||
CONF_NUM_LEDS,
|
||||
CONF_RANDOM,
|
||||
CONF_SEQUENCE,
|
||||
)
|
||||
from esphome.util import Registry
|
||||
from .types import LambdaLightEffect, RandomLightEffect, StrobeLightEffect, \
|
||||
StrobeLightEffectColor, LightColorValues, AddressableLightRef, AddressableLambdaLightEffect, \
|
||||
FlickerLightEffect, AddressableRainbowLightEffect, AddressableColorWipeEffect, \
|
||||
AddressableColorWipeEffectColor, AddressableScanEffect, AddressableTwinkleEffect, \
|
||||
AddressableRandomTwinkleEffect, AddressableFireworksEffect, AddressableFlickerEffect, \
|
||||
AutomationLightEffect, Color
|
||||
from .types import (
|
||||
LambdaLightEffect,
|
||||
RandomLightEffect,
|
||||
StrobeLightEffect,
|
||||
StrobeLightEffectColor,
|
||||
LightColorValues,
|
||||
AddressableLightRef,
|
||||
AddressableLambdaLightEffect,
|
||||
FlickerLightEffect,
|
||||
AddressableRainbowLightEffect,
|
||||
AddressableColorWipeEffect,
|
||||
AddressableColorWipeEffectColor,
|
||||
AddressableScanEffect,
|
||||
AddressableTwinkleEffect,
|
||||
AddressableRandomTwinkleEffect,
|
||||
AddressableFireworksEffect,
|
||||
AddressableFlickerEffect,
|
||||
AutomationLightEffect,
|
||||
Color,
|
||||
)
|
||||
|
||||
CONF_ADD_LED_INTERVAL = 'add_led_interval'
|
||||
CONF_REVERSE = 'reverse'
|
||||
CONF_MOVE_INTERVAL = 'move_interval'
|
||||
CONF_SCAN_WIDTH = 'scan_width'
|
||||
CONF_TWINKLE_PROBABILITY = 'twinkle_probability'
|
||||
CONF_PROGRESS_INTERVAL = 'progress_interval'
|
||||
CONF_SPARK_PROBABILITY = 'spark_probability'
|
||||
CONF_USE_RANDOM_COLOR = 'use_random_color'
|
||||
CONF_FADE_OUT_RATE = 'fade_out_rate'
|
||||
CONF_STROBE = 'strobe'
|
||||
CONF_FLICKER = 'flicker'
|
||||
CONF_ADDRESSABLE_LAMBDA = 'addressable_lambda'
|
||||
CONF_ADDRESSABLE_RAINBOW = 'addressable_rainbow'
|
||||
CONF_ADDRESSABLE_COLOR_WIPE = 'addressable_color_wipe'
|
||||
CONF_ADDRESSABLE_SCAN = 'addressable_scan'
|
||||
CONF_ADDRESSABLE_TWINKLE = 'addressable_twinkle'
|
||||
CONF_ADDRESSABLE_RANDOM_TWINKLE = 'addressable_random_twinkle'
|
||||
CONF_ADDRESSABLE_FIREWORKS = 'addressable_fireworks'
|
||||
CONF_ADDRESSABLE_FLICKER = 'addressable_flicker'
|
||||
CONF_AUTOMATION = 'automation'
|
||||
CONF_ADD_LED_INTERVAL = "add_led_interval"
|
||||
CONF_REVERSE = "reverse"
|
||||
CONF_MOVE_INTERVAL = "move_interval"
|
||||
CONF_SCAN_WIDTH = "scan_width"
|
||||
CONF_TWINKLE_PROBABILITY = "twinkle_probability"
|
||||
CONF_PROGRESS_INTERVAL = "progress_interval"
|
||||
CONF_SPARK_PROBABILITY = "spark_probability"
|
||||
CONF_USE_RANDOM_COLOR = "use_random_color"
|
||||
CONF_FADE_OUT_RATE = "fade_out_rate"
|
||||
CONF_STROBE = "strobe"
|
||||
CONF_FLICKER = "flicker"
|
||||
CONF_ADDRESSABLE_LAMBDA = "addressable_lambda"
|
||||
CONF_ADDRESSABLE_RAINBOW = "addressable_rainbow"
|
||||
CONF_ADDRESSABLE_COLOR_WIPE = "addressable_color_wipe"
|
||||
CONF_ADDRESSABLE_SCAN = "addressable_scan"
|
||||
CONF_ADDRESSABLE_TWINKLE = "addressable_twinkle"
|
||||
CONF_ADDRESSABLE_RANDOM_TWINKLE = "addressable_random_twinkle"
|
||||
CONF_ADDRESSABLE_FIREWORKS = "addressable_fireworks"
|
||||
CONF_ADDRESSABLE_FLICKER = "addressable_flicker"
|
||||
CONF_AUTOMATION = "automation"
|
||||
|
||||
BINARY_EFFECTS = []
|
||||
MONOCHROMATIC_EFFECTS = []
|
||||
@ -44,9 +75,11 @@ EFFECTS_REGISTRY = Registry()
|
||||
|
||||
|
||||
def register_effect(name, effect_type, default_name, schema, *extra_validators):
|
||||
schema = cv.Schema(schema).extend({
|
||||
cv.Optional(CONF_NAME, default=default_name): cv.string_strict,
|
||||
})
|
||||
schema = cv.Schema(schema).extend(
|
||||
{
|
||||
cv.Optional(CONF_NAME, default=default_name): cv.string_strict,
|
||||
}
|
||||
)
|
||||
validator = cv.All(schema, *extra_validators)
|
||||
return EFFECTS_REGISTRY.register(name, effect_type, validator)
|
||||
|
||||
@ -61,7 +94,9 @@ def register_binary_effect(name, effect_type, default_name, schema, *extra_valid
|
||||
return register_effect(name, effect_type, default_name, schema, *extra_validators)
|
||||
|
||||
|
||||
def register_monochromatic_effect(name, effect_type, default_name, schema, *extra_validators):
|
||||
def register_monochromatic_effect(
|
||||
name, effect_type, default_name, schema, *extra_validators
|
||||
):
|
||||
# monochromatic effect can be used for all lights expect binary
|
||||
MONOCHROMATIC_EFFECTS.append(name)
|
||||
RGB_EFFECTS.append(name)
|
||||
@ -78,36 +113,58 @@ def register_rgb_effect(name, effect_type, default_name, schema, *extra_validato
|
||||
return register_effect(name, effect_type, default_name, schema, *extra_validators)
|
||||
|
||||
|
||||
def register_addressable_effect(name, effect_type, default_name, schema, *extra_validators):
|
||||
def register_addressable_effect(
|
||||
name, effect_type, default_name, schema, *extra_validators
|
||||
):
|
||||
# addressable effect can be used only in addressable
|
||||
ADDRESSABLE_EFFECTS.append(name)
|
||||
|
||||
return register_effect(name, effect_type, default_name, schema, *extra_validators)
|
||||
|
||||
|
||||
@register_binary_effect('lambda', LambdaLightEffect, "Lambda", {
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.update_interval,
|
||||
})
|
||||
@register_binary_effect(
|
||||
"lambda",
|
||||
LambdaLightEffect,
|
||||
"Lambda",
|
||||
{
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default="0ms"): cv.update_interval,
|
||||
},
|
||||
)
|
||||
def lambda_effect_to_code(config, effect_id):
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [], return_type=cg.void)
|
||||
yield cg.new_Pvariable(effect_id, config[CONF_NAME], lambda_,
|
||||
config[CONF_UPDATE_INTERVAL])
|
||||
yield cg.new_Pvariable(
|
||||
effect_id, config[CONF_NAME], lambda_, config[CONF_UPDATE_INTERVAL]
|
||||
)
|
||||
|
||||
|
||||
@register_binary_effect('automation', AutomationLightEffect, "Automation", {
|
||||
cv.Required(CONF_SEQUENCE): automation.validate_automation(single=True),
|
||||
})
|
||||
@register_binary_effect(
|
||||
"automation",
|
||||
AutomationLightEffect,
|
||||
"Automation",
|
||||
{
|
||||
cv.Required(CONF_SEQUENCE): automation.validate_automation(single=True),
|
||||
},
|
||||
)
|
||||
def automation_effect_to_code(config, effect_id):
|
||||
var = yield cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
yield automation.build_automation(var.get_trig(), [], config[CONF_SEQUENCE])
|
||||
yield var
|
||||
|
||||
|
||||
@register_rgb_effect('random', RandomLightEffect, "Random", {
|
||||
cv.Optional(CONF_TRANSITION_LENGTH, default='7.5s'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default='10s'): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
@register_rgb_effect(
|
||||
"random",
|
||||
RandomLightEffect,
|
||||
"Random",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_TRANSITION_LENGTH, default="7.5s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(
|
||||
CONF_UPDATE_INTERVAL, default="10s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
},
|
||||
)
|
||||
def random_effect_to_code(config, effect_id):
|
||||
effect = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(effect.set_transition_length(config[CONF_TRANSITION_LENGTH]))
|
||||
@ -115,40 +172,79 @@ def random_effect_to_code(config, effect_id):
|
||||
yield effect
|
||||
|
||||
|
||||
@register_binary_effect('strobe', StrobeLightEffect, "Strobe", {
|
||||
cv.Optional(CONF_COLORS, default=[
|
||||
{CONF_STATE: True, CONF_DURATION: '0.5s'},
|
||||
{CONF_STATE: False, CONF_DURATION: '0.5s'},
|
||||
]): cv.All(cv.ensure_list(cv.Schema({
|
||||
cv.Optional(CONF_STATE, default=True): cv.boolean,
|
||||
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_RED, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_GREEN, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_BLUE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_WHITE, default=1.0): cv.percentage,
|
||||
cv.Required(CONF_DURATION): cv.positive_time_period_milliseconds,
|
||||
}), cv.has_at_least_one_key(CONF_STATE, CONF_BRIGHTNESS, CONF_RED, CONF_GREEN, CONF_BLUE,
|
||||
CONF_WHITE)), cv.Length(min=2)),
|
||||
})
|
||||
@register_binary_effect(
|
||||
"strobe",
|
||||
StrobeLightEffect,
|
||||
"Strobe",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_COLORS,
|
||||
default=[
|
||||
{CONF_STATE: True, CONF_DURATION: "0.5s"},
|
||||
{CONF_STATE: False, CONF_DURATION: "0.5s"},
|
||||
],
|
||||
): cv.All(
|
||||
cv.ensure_list(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_STATE, default=True): cv.boolean,
|
||||
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_RED, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_GREEN, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_BLUE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_WHITE, default=1.0): cv.percentage,
|
||||
cv.Required(
|
||||
CONF_DURATION
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
),
|
||||
cv.has_at_least_one_key(
|
||||
CONF_STATE,
|
||||
CONF_BRIGHTNESS,
|
||||
CONF_RED,
|
||||
CONF_GREEN,
|
||||
CONF_BLUE,
|
||||
CONF_WHITE,
|
||||
),
|
||||
),
|
||||
cv.Length(min=2),
|
||||
),
|
||||
},
|
||||
)
|
||||
def strobe_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
colors = []
|
||||
for color in config.get(CONF_COLORS, []):
|
||||
colors.append(cg.StructInitializer(
|
||||
StrobeLightEffectColor,
|
||||
('color', LightColorValues(color[CONF_STATE], color[CONF_BRIGHTNESS],
|
||||
color[CONF_RED], color[CONF_GREEN], color[CONF_BLUE],
|
||||
color[CONF_WHITE])),
|
||||
('duration', color[CONF_DURATION]),
|
||||
))
|
||||
colors.append(
|
||||
cg.StructInitializer(
|
||||
StrobeLightEffectColor,
|
||||
(
|
||||
"color",
|
||||
LightColorValues(
|
||||
color[CONF_STATE],
|
||||
color[CONF_BRIGHTNESS],
|
||||
color[CONF_RED],
|
||||
color[CONF_GREEN],
|
||||
color[CONF_BLUE],
|
||||
color[CONF_WHITE],
|
||||
),
|
||||
),
|
||||
("duration", color[CONF_DURATION]),
|
||||
)
|
||||
)
|
||||
cg.add(var.set_colors(colors))
|
||||
yield var
|
||||
|
||||
|
||||
@register_monochromatic_effect('flicker', FlickerLightEffect, "Flicker", {
|
||||
cv.Optional(CONF_ALPHA, default=0.95): cv.percentage,
|
||||
cv.Optional(CONF_INTENSITY, default=0.015): cv.percentage,
|
||||
})
|
||||
@register_monochromatic_effect(
|
||||
"flicker",
|
||||
FlickerLightEffect,
|
||||
"Flicker",
|
||||
{
|
||||
cv.Optional(CONF_ALPHA, default=0.95): cv.percentage,
|
||||
cv.Optional(CONF_INTENSITY, default=0.015): cv.percentage,
|
||||
},
|
||||
)
|
||||
def flicker_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_alpha(config[CONF_ALPHA]))
|
||||
@ -157,23 +253,38 @@ def flicker_effect_to_code(config, effect_id):
|
||||
|
||||
|
||||
@register_addressable_effect(
|
||||
'addressable_lambda', AddressableLambdaLightEffect, "Addressable Lambda", {
|
||||
"addressable_lambda",
|
||||
AddressableLambdaLightEffect,
|
||||
"Addressable Lambda",
|
||||
{
|
||||
cv.Required(CONF_LAMBDA): cv.lambda_,
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default='0ms'): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
cv.Optional(
|
||||
CONF_UPDATE_INTERVAL, default="0ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
},
|
||||
)
|
||||
def addressable_lambda_effect_to_code(config, effect_id):
|
||||
args = [(AddressableLightRef, 'it'), (Color, 'current_color'), (bool, 'initial_run')]
|
||||
args = [
|
||||
(AddressableLightRef, "it"),
|
||||
(Color, "current_color"),
|
||||
(bool, "initial_run"),
|
||||
]
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], args, return_type=cg.void)
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME], lambda_,
|
||||
config[CONF_UPDATE_INTERVAL])
|
||||
var = cg.new_Pvariable(
|
||||
effect_id, config[CONF_NAME], lambda_, config[CONF_UPDATE_INTERVAL]
|
||||
)
|
||||
yield var
|
||||
|
||||
|
||||
@register_addressable_effect('addressable_rainbow', AddressableRainbowLightEffect, "Rainbow", {
|
||||
cv.Optional(CONF_SPEED, default=10): cv.uint32_t,
|
||||
cv.Optional(CONF_WIDTH, default=50): cv.uint32_t,
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"addressable_rainbow",
|
||||
AddressableRainbowLightEffect,
|
||||
"Rainbow",
|
||||
{
|
||||
cv.Optional(CONF_SPEED, default=10): cv.uint32_t,
|
||||
cv.Optional(CONF_WIDTH, default=50): cv.uint32_t,
|
||||
},
|
||||
)
|
||||
def addressable_rainbow_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_speed(config[CONF_SPEED]))
|
||||
@ -181,41 +292,61 @@ def addressable_rainbow_effect_to_code(config, effect_id):
|
||||
yield var
|
||||
|
||||
|
||||
@register_addressable_effect('addressable_color_wipe', AddressableColorWipeEffect, "Color Wipe", {
|
||||
cv.Optional(CONF_COLORS, default=[{CONF_NUM_LEDS: 1, CONF_RANDOM: True}]): cv.ensure_list({
|
||||
cv.Optional(CONF_RED, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_GREEN, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_BLUE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_WHITE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_RANDOM, default=False): cv.boolean,
|
||||
cv.Required(CONF_NUM_LEDS): cv.All(cv.uint32_t, cv.Range(min=1)),
|
||||
}),
|
||||
cv.Optional(CONF_ADD_LED_INTERVAL, default='0.1s'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_REVERSE, default=False): cv.boolean,
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"addressable_color_wipe",
|
||||
AddressableColorWipeEffect,
|
||||
"Color Wipe",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_COLORS, default=[{CONF_NUM_LEDS: 1, CONF_RANDOM: True}]
|
||||
): cv.ensure_list(
|
||||
{
|
||||
cv.Optional(CONF_RED, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_GREEN, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_BLUE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_WHITE, default=1.0): cv.percentage,
|
||||
cv.Optional(CONF_RANDOM, default=False): cv.boolean,
|
||||
cv.Required(CONF_NUM_LEDS): cv.All(cv.uint32_t, cv.Range(min=1)),
|
||||
}
|
||||
),
|
||||
cv.Optional(
|
||||
CONF_ADD_LED_INTERVAL, default="0.1s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_REVERSE, default=False): cv.boolean,
|
||||
},
|
||||
)
|
||||
def addressable_color_wipe_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_add_led_interval(config[CONF_ADD_LED_INTERVAL]))
|
||||
cg.add(var.set_reverse(config[CONF_REVERSE]))
|
||||
colors = []
|
||||
for color in config.get(CONF_COLORS, []):
|
||||
colors.append(cg.StructInitializer(
|
||||
AddressableColorWipeEffectColor,
|
||||
('r', int(round(color[CONF_RED] * 255))),
|
||||
('g', int(round(color[CONF_GREEN] * 255))),
|
||||
('b', int(round(color[CONF_BLUE] * 255))),
|
||||
('w', int(round(color[CONF_WHITE] * 255))),
|
||||
('random', color[CONF_RANDOM]),
|
||||
('num_leds', color[CONF_NUM_LEDS]),
|
||||
))
|
||||
colors.append(
|
||||
cg.StructInitializer(
|
||||
AddressableColorWipeEffectColor,
|
||||
("r", int(round(color[CONF_RED] * 255))),
|
||||
("g", int(round(color[CONF_GREEN] * 255))),
|
||||
("b", int(round(color[CONF_BLUE] * 255))),
|
||||
("w", int(round(color[CONF_WHITE] * 255))),
|
||||
("random", color[CONF_RANDOM]),
|
||||
("num_leds", color[CONF_NUM_LEDS]),
|
||||
)
|
||||
)
|
||||
cg.add(var.set_colors(colors))
|
||||
yield var
|
||||
|
||||
|
||||
@register_addressable_effect('addressable_scan', AddressableScanEffect, "Scan", {
|
||||
cv.Optional(CONF_MOVE_INTERVAL, default='0.1s'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SCAN_WIDTH, default=1): cv.int_range(min=1),
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"addressable_scan",
|
||||
AddressableScanEffect,
|
||||
"Scan",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_MOVE_INTERVAL, default="0.1s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SCAN_WIDTH, default=1): cv.int_range(min=1),
|
||||
},
|
||||
)
|
||||
def addressable_scan_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_move_interval(config[CONF_MOVE_INTERVAL]))
|
||||
@ -223,10 +354,17 @@ def addressable_scan_effect_to_code(config, effect_id):
|
||||
yield var
|
||||
|
||||
|
||||
@register_addressable_effect('addressable_twinkle', AddressableTwinkleEffect, "Twinkle", {
|
||||
cv.Optional(CONF_TWINKLE_PROBABILITY, default='5%'): cv.percentage,
|
||||
cv.Optional(CONF_PROGRESS_INTERVAL, default='4ms'): cv.positive_time_period_milliseconds,
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"addressable_twinkle",
|
||||
AddressableTwinkleEffect,
|
||||
"Twinkle",
|
||||
{
|
||||
cv.Optional(CONF_TWINKLE_PROBABILITY, default="5%"): cv.percentage,
|
||||
cv.Optional(
|
||||
CONF_PROGRESS_INTERVAL, default="4ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
},
|
||||
)
|
||||
def addressable_twinkle_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_twinkle_probability(config[CONF_TWINKLE_PROBABILITY]))
|
||||
@ -235,10 +373,15 @@ def addressable_twinkle_effect_to_code(config, effect_id):
|
||||
|
||||
|
||||
@register_addressable_effect(
|
||||
'addressable_random_twinkle', AddressableRandomTwinkleEffect, "Random Twinkle", {
|
||||
cv.Optional(CONF_TWINKLE_PROBABILITY, default='5%'): cv.percentage,
|
||||
cv.Optional(CONF_PROGRESS_INTERVAL, default='32ms'): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
"addressable_random_twinkle",
|
||||
AddressableRandomTwinkleEffect,
|
||||
"Random Twinkle",
|
||||
{
|
||||
cv.Optional(CONF_TWINKLE_PROBABILITY, default="5%"): cv.percentage,
|
||||
cv.Optional(
|
||||
CONF_PROGRESS_INTERVAL, default="32ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
},
|
||||
)
|
||||
def addressable_random_twinkle_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
@ -247,12 +390,19 @@ def addressable_random_twinkle_effect_to_code(config, effect_id):
|
||||
yield var
|
||||
|
||||
|
||||
@register_addressable_effect('addressable_fireworks', AddressableFireworksEffect, "Fireworks", {
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default='32ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SPARK_PROBABILITY, default='10%'): cv.percentage,
|
||||
cv.Optional(CONF_USE_RANDOM_COLOR, default=False): cv.boolean,
|
||||
cv.Optional(CONF_FADE_OUT_RATE, default=120): cv.uint8_t,
|
||||
})
|
||||
@register_addressable_effect(
|
||||
"addressable_fireworks",
|
||||
AddressableFireworksEffect,
|
||||
"Fireworks",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_UPDATE_INTERVAL, default="32ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_SPARK_PROBABILITY, default="10%"): cv.percentage,
|
||||
cv.Optional(CONF_USE_RANDOM_COLOR, default=False): cv.boolean,
|
||||
cv.Optional(CONF_FADE_OUT_RATE, default=120): cv.uint8_t,
|
||||
},
|
||||
)
|
||||
def addressable_fireworks_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
cg.add(var.set_update_interval(config[CONF_UPDATE_INTERVAL]))
|
||||
@ -263,10 +413,15 @@ def addressable_fireworks_effect_to_code(config, effect_id):
|
||||
|
||||
|
||||
@register_addressable_effect(
|
||||
'addressable_flicker', AddressableFlickerEffect, "Addressable Flicker", {
|
||||
cv.Optional(CONF_UPDATE_INTERVAL, default='16ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_INTENSITY, default='5%'): cv.percentage,
|
||||
}
|
||||
"addressable_flicker",
|
||||
AddressableFlickerEffect,
|
||||
"Addressable Flicker",
|
||||
{
|
||||
cv.Optional(
|
||||
CONF_UPDATE_INTERVAL, default="16ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_INTENSITY, default="5%"): cv.percentage,
|
||||
},
|
||||
)
|
||||
def addressable_flicker_effect_to_code(config, effect_id):
|
||||
var = cg.new_Pvariable(effect_id, config[CONF_NAME])
|
||||
@ -277,22 +432,28 @@ def addressable_flicker_effect_to_code(config, effect_id):
|
||||
|
||||
def validate_effects(allowed_effects):
|
||||
def validator(value):
|
||||
value = cv.validate_registry('effect', EFFECTS_REGISTRY)(value)
|
||||
value = cv.validate_registry("effect", EFFECTS_REGISTRY)(value)
|
||||
errors = []
|
||||
names = set()
|
||||
for i, x in enumerate(value):
|
||||
key = next(it for it in x.keys())
|
||||
if key not in allowed_effects:
|
||||
errors.append(
|
||||
cv.Invalid("The effect '{}' is not allowed for this "
|
||||
"light type".format(key), [i])
|
||||
cv.Invalid(
|
||||
"The effect '{}' is not allowed for this "
|
||||
"light type".format(key),
|
||||
[i],
|
||||
)
|
||||
)
|
||||
continue
|
||||
name = x[key][CONF_NAME]
|
||||
if name in names:
|
||||
errors.append(
|
||||
cv.Invalid("Found the effect name '{}' twice. All effects must have "
|
||||
"unique names".format(name), [i])
|
||||
cv.Invalid(
|
||||
"Found the effect name '{}' twice. All effects must have "
|
||||
"unique names".format(name),
|
||||
[i],
|
||||
)
|
||||
)
|
||||
continue
|
||||
names.add(name)
|
||||
|
@ -2,47 +2,62 @@ import esphome.codegen as cg
|
||||
from esphome import automation
|
||||
|
||||
# Base
|
||||
light_ns = cg.esphome_ns.namespace('light')
|
||||
LightState = light_ns.class_('LightState', cg.Nameable, cg.Component)
|
||||
light_ns = cg.esphome_ns.namespace("light")
|
||||
LightState = light_ns.class_("LightState", cg.Nameable, cg.Component)
|
||||
# Fake class for addressable lights
|
||||
AddressableLightState = light_ns.class_('LightState', LightState)
|
||||
LightOutput = light_ns.class_('LightOutput')
|
||||
AddressableLight = light_ns.class_('AddressableLight', cg.Component)
|
||||
AddressableLightRef = AddressableLight.operator('ref')
|
||||
AddressableLightState = light_ns.class_("LightState", LightState)
|
||||
LightOutput = light_ns.class_("LightOutput")
|
||||
AddressableLight = light_ns.class_("AddressableLight", cg.Component)
|
||||
AddressableLightRef = AddressableLight.operator("ref")
|
||||
|
||||
Color = cg.esphome_ns.class_('Color')
|
||||
LightColorValues = light_ns.class_('LightColorValues')
|
||||
Color = cg.esphome_ns.class_("Color")
|
||||
LightColorValues = light_ns.class_("LightColorValues")
|
||||
|
||||
# Actions
|
||||
ToggleAction = light_ns.class_('ToggleAction', automation.Action)
|
||||
LightControlAction = light_ns.class_('LightControlAction', automation.Action)
|
||||
DimRelativeAction = light_ns.class_('DimRelativeAction', automation.Action)
|
||||
AddressableSet = light_ns.class_('AddressableSet', automation.Action)
|
||||
LightIsOnCondition = light_ns.class_('LightIsOnCondition', automation.Condition)
|
||||
LightIsOffCondition = light_ns.class_('LightIsOffCondition', automation.Condition)
|
||||
ToggleAction = light_ns.class_("ToggleAction", automation.Action)
|
||||
LightControlAction = light_ns.class_("LightControlAction", automation.Action)
|
||||
DimRelativeAction = light_ns.class_("DimRelativeAction", automation.Action)
|
||||
AddressableSet = light_ns.class_("AddressableSet", automation.Action)
|
||||
LightIsOnCondition = light_ns.class_("LightIsOnCondition", automation.Condition)
|
||||
LightIsOffCondition = light_ns.class_("LightIsOffCondition", automation.Condition)
|
||||
|
||||
# Triggers
|
||||
LightTurnOnTrigger = light_ns.class_('LightTurnOnTrigger', automation.Trigger.template())
|
||||
LightTurnOffTrigger = light_ns.class_('LightTurnOffTrigger', automation.Trigger.template())
|
||||
LightTurnOnTrigger = light_ns.class_(
|
||||
"LightTurnOnTrigger", automation.Trigger.template()
|
||||
)
|
||||
LightTurnOffTrigger = light_ns.class_(
|
||||
"LightTurnOffTrigger", automation.Trigger.template()
|
||||
)
|
||||
|
||||
# Effects
|
||||
LightEffect = light_ns.class_('LightEffect')
|
||||
RandomLightEffect = light_ns.class_('RandomLightEffect', LightEffect)
|
||||
LambdaLightEffect = light_ns.class_('LambdaLightEffect', LightEffect)
|
||||
AutomationLightEffect = light_ns.class_('AutomationLightEffect', LightEffect)
|
||||
StrobeLightEffect = light_ns.class_('StrobeLightEffect', LightEffect)
|
||||
StrobeLightEffectColor = light_ns.class_('StrobeLightEffectColor', LightEffect)
|
||||
FlickerLightEffect = light_ns.class_('FlickerLightEffect', LightEffect)
|
||||
AddressableLightEffect = light_ns.class_('AddressableLightEffect', LightEffect)
|
||||
AddressableLambdaLightEffect = light_ns.class_('AddressableLambdaLightEffect',
|
||||
AddressableLightEffect)
|
||||
AddressableRainbowLightEffect = light_ns.class_('AddressableRainbowLightEffect',
|
||||
AddressableLightEffect)
|
||||
AddressableColorWipeEffect = light_ns.class_('AddressableColorWipeEffect', AddressableLightEffect)
|
||||
AddressableColorWipeEffectColor = light_ns.struct('AddressableColorWipeEffectColor')
|
||||
AddressableScanEffect = light_ns.class_('AddressableScanEffect', AddressableLightEffect)
|
||||
AddressableTwinkleEffect = light_ns.class_('AddressableTwinkleEffect', AddressableLightEffect)
|
||||
AddressableRandomTwinkleEffect = light_ns.class_('AddressableRandomTwinkleEffect',
|
||||
AddressableLightEffect)
|
||||
AddressableFireworksEffect = light_ns.class_('AddressableFireworksEffect', AddressableLightEffect)
|
||||
AddressableFlickerEffect = light_ns.class_('AddressableFlickerEffect', AddressableLightEffect)
|
||||
LightEffect = light_ns.class_("LightEffect")
|
||||
RandomLightEffect = light_ns.class_("RandomLightEffect", LightEffect)
|
||||
LambdaLightEffect = light_ns.class_("LambdaLightEffect", LightEffect)
|
||||
AutomationLightEffect = light_ns.class_("AutomationLightEffect", LightEffect)
|
||||
StrobeLightEffect = light_ns.class_("StrobeLightEffect", LightEffect)
|
||||
StrobeLightEffectColor = light_ns.class_("StrobeLightEffectColor", LightEffect)
|
||||
FlickerLightEffect = light_ns.class_("FlickerLightEffect", LightEffect)
|
||||
AddressableLightEffect = light_ns.class_("AddressableLightEffect", LightEffect)
|
||||
AddressableLambdaLightEffect = light_ns.class_(
|
||||
"AddressableLambdaLightEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableRainbowLightEffect = light_ns.class_(
|
||||
"AddressableRainbowLightEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableColorWipeEffect = light_ns.class_(
|
||||
"AddressableColorWipeEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableColorWipeEffectColor = light_ns.struct("AddressableColorWipeEffectColor")
|
||||
AddressableScanEffect = light_ns.class_("AddressableScanEffect", AddressableLightEffect)
|
||||
AddressableTwinkleEffect = light_ns.class_(
|
||||
"AddressableTwinkleEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableRandomTwinkleEffect = light_ns.class_(
|
||||
"AddressableRandomTwinkleEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableFireworksEffect = light_ns.class_(
|
||||
"AddressableFireworksEffect", AddressableLightEffect
|
||||
)
|
||||
AddressableFlickerEffect = light_ns.class_(
|
||||
"AddressableFlickerEffect", AddressableLightEffect
|
||||
)
|
||||
|
@ -4,49 +4,69 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import LambdaAction
|
||||
from esphome.const import CONF_ARGS, CONF_BAUD_RATE, CONF_FORMAT, CONF_HARDWARE_UART, CONF_ID, \
|
||||
CONF_LEVEL, CONF_LOGS, CONF_ON_MESSAGE, CONF_TAG, CONF_TRIGGER_ID, CONF_TX_BUFFER_SIZE
|
||||
from esphome.const import (
|
||||
CONF_ARGS,
|
||||
CONF_BAUD_RATE,
|
||||
CONF_FORMAT,
|
||||
CONF_HARDWARE_UART,
|
||||
CONF_ID,
|
||||
CONF_LEVEL,
|
||||
CONF_LOGS,
|
||||
CONF_ON_MESSAGE,
|
||||
CONF_TAG,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_TX_BUFFER_SIZE,
|
||||
)
|
||||
from esphome.core import CORE, EsphomeError, Lambda, coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
logger_ns = cg.esphome_ns.namespace('logger')
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
logger_ns = cg.esphome_ns.namespace("logger")
|
||||
LOG_LEVELS = {
|
||||
'NONE': cg.global_ns.ESPHOME_LOG_LEVEL_NONE,
|
||||
'ERROR': cg.global_ns.ESPHOME_LOG_LEVEL_ERROR,
|
||||
'WARN': cg.global_ns.ESPHOME_LOG_LEVEL_WARN,
|
||||
'INFO': cg.global_ns.ESPHOME_LOG_LEVEL_INFO,
|
||||
'DEBUG': cg.global_ns.ESPHOME_LOG_LEVEL_DEBUG,
|
||||
'VERBOSE': cg.global_ns.ESPHOME_LOG_LEVEL_VERBOSE,
|
||||
'VERY_VERBOSE': cg.global_ns.ESPHOME_LOG_LEVEL_VERY_VERBOSE,
|
||||
"NONE": cg.global_ns.ESPHOME_LOG_LEVEL_NONE,
|
||||
"ERROR": cg.global_ns.ESPHOME_LOG_LEVEL_ERROR,
|
||||
"WARN": cg.global_ns.ESPHOME_LOG_LEVEL_WARN,
|
||||
"INFO": cg.global_ns.ESPHOME_LOG_LEVEL_INFO,
|
||||
"DEBUG": cg.global_ns.ESPHOME_LOG_LEVEL_DEBUG,
|
||||
"VERBOSE": cg.global_ns.ESPHOME_LOG_LEVEL_VERBOSE,
|
||||
"VERY_VERBOSE": cg.global_ns.ESPHOME_LOG_LEVEL_VERY_VERBOSE,
|
||||
}
|
||||
|
||||
LOG_LEVEL_TO_ESP_LOG = {
|
||||
'ERROR': cg.global_ns.ESP_LOGE,
|
||||
'WARN': cg.global_ns.ESP_LOGW,
|
||||
'INFO': cg.global_ns.ESP_LOGI,
|
||||
'DEBUG': cg.global_ns.ESP_LOGD,
|
||||
'VERBOSE': cg.global_ns.ESP_LOGV,
|
||||
'VERY_VERBOSE': cg.global_ns.ESP_LOGVV,
|
||||
"ERROR": cg.global_ns.ESP_LOGE,
|
||||
"WARN": cg.global_ns.ESP_LOGW,
|
||||
"INFO": cg.global_ns.ESP_LOGI,
|
||||
"DEBUG": cg.global_ns.ESP_LOGD,
|
||||
"VERBOSE": cg.global_ns.ESP_LOGV,
|
||||
"VERY_VERBOSE": cg.global_ns.ESP_LOGVV,
|
||||
}
|
||||
|
||||
LOG_LEVEL_SEVERITY = ['NONE', 'ERROR', 'WARN', 'INFO', 'CONFIG', 'DEBUG', 'VERBOSE', 'VERY_VERBOSE']
|
||||
LOG_LEVEL_SEVERITY = [
|
||||
"NONE",
|
||||
"ERROR",
|
||||
"WARN",
|
||||
"INFO",
|
||||
"CONFIG",
|
||||
"DEBUG",
|
||||
"VERBOSE",
|
||||
"VERY_VERBOSE",
|
||||
]
|
||||
|
||||
UART_SELECTION_ESP32 = ['UART0', 'UART1', 'UART2']
|
||||
UART_SELECTION_ESP32 = ["UART0", "UART1", "UART2"]
|
||||
|
||||
UART_SELECTION_ESP8266 = ['UART0', 'UART0_SWAP', 'UART1']
|
||||
UART_SELECTION_ESP8266 = ["UART0", "UART0_SWAP", "UART1"]
|
||||
|
||||
HARDWARE_UART_TO_UART_SELECTION = {
|
||||
'UART0': logger_ns.UART_SELECTION_UART0,
|
||||
'UART0_SWAP': logger_ns.UART_SELECTION_UART0_SWAP,
|
||||
'UART1': logger_ns.UART_SELECTION_UART1,
|
||||
'UART2': logger_ns.UART_SELECTION_UART2,
|
||||
"UART0": logger_ns.UART_SELECTION_UART0,
|
||||
"UART0_SWAP": logger_ns.UART_SELECTION_UART0_SWAP,
|
||||
"UART1": logger_ns.UART_SELECTION_UART1,
|
||||
"UART2": logger_ns.UART_SELECTION_UART2,
|
||||
}
|
||||
|
||||
HARDWARE_UART_TO_SERIAL = {
|
||||
'UART0': cg.global_ns.Serial,
|
||||
'UART0_SWAP': cg.global_ns.Serial,
|
||||
'UART1': cg.global_ns.Serial1,
|
||||
'UART2': cg.global_ns.Serial2,
|
||||
"UART0": cg.global_ns.Serial,
|
||||
"UART0_SWAP": cg.global_ns.Serial,
|
||||
"UART1": cg.global_ns.Serial1,
|
||||
"UART2": cg.global_ns.Serial2,
|
||||
}
|
||||
|
||||
is_log_level = cv.one_of(*LOG_LEVELS, upper=True)
|
||||
@ -61,45 +81,59 @@ def uart_selection(value):
|
||||
|
||||
|
||||
def validate_local_no_higher_than_global(value):
|
||||
global_level = value.get(CONF_LEVEL, 'DEBUG')
|
||||
global_level = value.get(CONF_LEVEL, "DEBUG")
|
||||
for tag, level in value.get(CONF_LOGS, {}).items():
|
||||
if LOG_LEVEL_SEVERITY.index(level) > LOG_LEVEL_SEVERITY.index(global_level):
|
||||
raise EsphomeError("The local log level {} for {} must be less severe than the "
|
||||
"global log level {}.".format(level, tag, global_level))
|
||||
raise EsphomeError(
|
||||
"The local log level {} for {} must be less severe than the "
|
||||
"global log level {}.".format(level, tag, global_level)
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
Logger = logger_ns.class_('Logger', cg.Component)
|
||||
LoggerMessageTrigger = logger_ns.class_('LoggerMessageTrigger',
|
||||
automation.Trigger.template(cg.int_, cg.const_char_ptr,
|
||||
cg.const_char_ptr))
|
||||
Logger = logger_ns.class_("Logger", cg.Component)
|
||||
LoggerMessageTrigger = logger_ns.class_(
|
||||
"LoggerMessageTrigger",
|
||||
automation.Trigger.template(cg.int_, cg.const_char_ptr, cg.const_char_ptr),
|
||||
)
|
||||
|
||||
CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH = 'esp8266_store_log_strings_in_flash'
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(Logger),
|
||||
cv.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
||||
cv.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
|
||||
cv.Optional(CONF_HARDWARE_UART, default='UART0'): uart_selection,
|
||||
cv.Optional(CONF_LEVEL, default='DEBUG'): is_log_level,
|
||||
cv.Optional(CONF_LOGS, default={}): cv.Schema({
|
||||
cv.string: is_log_level,
|
||||
}),
|
||||
cv.Optional(CONF_ON_MESSAGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoggerMessageTrigger),
|
||||
cv.Optional(CONF_LEVEL, default='WARN'): is_log_level,
|
||||
}),
|
||||
|
||||
cv.SplitDefault(CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH, esp8266=True):
|
||||
cv.All(cv.only_on_esp8266, cv.boolean),
|
||||
}).extend(cv.COMPONENT_SCHEMA), validate_local_no_higher_than_global)
|
||||
CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH = "esp8266_store_log_strings_in_flash"
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Logger),
|
||||
cv.Optional(CONF_BAUD_RATE, default=115200): cv.positive_int,
|
||||
cv.Optional(CONF_TX_BUFFER_SIZE, default=512): cv.validate_bytes,
|
||||
cv.Optional(CONF_HARDWARE_UART, default="UART0"): uart_selection,
|
||||
cv.Optional(CONF_LEVEL, default="DEBUG"): is_log_level,
|
||||
cv.Optional(CONF_LOGS, default={}): cv.Schema(
|
||||
{
|
||||
cv.string: is_log_level,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_MESSAGE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LoggerMessageTrigger),
|
||||
cv.Optional(CONF_LEVEL, default="WARN"): is_log_level,
|
||||
}
|
||||
),
|
||||
cv.SplitDefault(
|
||||
CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH, esp8266=True
|
||||
): cv.All(cv.only_on_esp8266, cv.boolean),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
validate_local_no_higher_than_global,
|
||||
)
|
||||
|
||||
|
||||
@coroutine_with_priority(90.0)
|
||||
def to_code(config):
|
||||
baud_rate = config[CONF_BAUD_RATE]
|
||||
rhs = Logger.new(baud_rate,
|
||||
config[CONF_TX_BUFFER_SIZE],
|
||||
HARDWARE_UART_TO_UART_SELECTION[config[CONF_HARDWARE_UART]])
|
||||
rhs = Logger.new(
|
||||
baud_rate,
|
||||
config[CONF_TX_BUFFER_SIZE],
|
||||
HARDWARE_UART_TO_UART_SELECTION[config[CONF_HARDWARE_UART]],
|
||||
)
|
||||
log = cg.Pvariable(config[CONF_ID], rhs)
|
||||
cg.add(log.pre_setup())
|
||||
|
||||
@ -107,12 +141,12 @@ def to_code(config):
|
||||
cg.add(log.set_log_level(tag, LOG_LEVELS[level]))
|
||||
|
||||
level = config[CONF_LEVEL]
|
||||
cg.add_define('USE_LOGGER')
|
||||
cg.add_define("USE_LOGGER")
|
||||
this_severity = LOG_LEVEL_SEVERITY.index(level)
|
||||
cg.add_build_flag('-DESPHOME_LOG_LEVEL={}'.format(LOG_LEVELS[level]))
|
||||
cg.add_build_flag("-DESPHOME_LOG_LEVEL={}".format(LOG_LEVELS[level]))
|
||||
|
||||
verbose_severity = LOG_LEVEL_SEVERITY.index('VERBOSE')
|
||||
very_verbose_severity = LOG_LEVEL_SEVERITY.index('VERY_VERBOSE')
|
||||
verbose_severity = LOG_LEVEL_SEVERITY.index("VERBOSE")
|
||||
very_verbose_severity = LOG_LEVEL_SEVERITY.index("VERY_VERBOSE")
|
||||
is_at_least_verbose = this_severity >= verbose_severity
|
||||
is_at_least_very_verbose = this_severity >= very_verbose_severity
|
||||
has_serial_logging = baud_rate != 0
|
||||
@ -122,35 +156,42 @@ def to_code(config):
|
||||
cg.add_build_flag(f"-DDEBUG_ESP_PORT={debug_serial_port}")
|
||||
cg.add_build_flag("-DLWIP_DEBUG")
|
||||
DEBUG_COMPONENTS = {
|
||||
'HTTP_CLIENT',
|
||||
'HTTP_SERVER',
|
||||
'HTTP_UPDATE',
|
||||
'OTA',
|
||||
'SSL',
|
||||
'TLS_MEM',
|
||||
'UPDATER',
|
||||
'WIFI',
|
||||
"HTTP_CLIENT",
|
||||
"HTTP_SERVER",
|
||||
"HTTP_UPDATE",
|
||||
"OTA",
|
||||
"SSL",
|
||||
"TLS_MEM",
|
||||
"UPDATER",
|
||||
"WIFI",
|
||||
# Spams logs too much:
|
||||
# 'MDNS_RESPONDER',
|
||||
}
|
||||
for comp in DEBUG_COMPONENTS:
|
||||
cg.add_build_flag(f"-DDEBUG_ESP_{comp}")
|
||||
if CORE.is_esp32 and is_at_least_verbose:
|
||||
cg.add_build_flag('-DCORE_DEBUG_LEVEL=5')
|
||||
cg.add_build_flag("-DCORE_DEBUG_LEVEL=5")
|
||||
if CORE.is_esp32 and is_at_least_very_verbose:
|
||||
cg.add_build_flag('-DENABLE_I2C_DEBUG_BUFFER')
|
||||
cg.add_build_flag("-DENABLE_I2C_DEBUG_BUFFER")
|
||||
if config.get(CONF_ESP8266_STORE_LOG_STRINGS_IN_FLASH):
|
||||
cg.add_build_flag('-DUSE_STORE_LOG_STR_IN_FLASH')
|
||||
cg.add_build_flag("-DUSE_STORE_LOG_STR_IN_FLASH")
|
||||
|
||||
# Register at end for safe mode
|
||||
yield cg.register_component(log, config)
|
||||
|
||||
for conf in config.get(CONF_ON_MESSAGE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], log,
|
||||
LOG_LEVEL_SEVERITY.index(conf[CONF_LEVEL]))
|
||||
yield automation.build_automation(trigger, [(cg.int_, 'level'),
|
||||
(cg.const_char_ptr, 'tag'),
|
||||
(cg.const_char_ptr, 'message')], conf)
|
||||
trigger = cg.new_Pvariable(
|
||||
conf[CONF_TRIGGER_ID], log, LOG_LEVEL_SEVERITY.index(conf[CONF_LEVEL])
|
||||
)
|
||||
yield automation.build_automation(
|
||||
trigger,
|
||||
[
|
||||
(cg.int_, "level"),
|
||||
(cg.const_char_ptr, "tag"),
|
||||
(cg.const_char_ptr, "message"),
|
||||
],
|
||||
conf,
|
||||
)
|
||||
|
||||
|
||||
def maybe_simple_message(schema):
|
||||
@ -179,18 +220,27 @@ def validate_printf(value):
|
||||
""" # noqa
|
||||
matches = re.findall(cfmt, value[CONF_FORMAT], flags=re.X)
|
||||
if len(matches) != len(value[CONF_ARGS]):
|
||||
raise cv.Invalid("Found {} printf-patterns ({}), but {} args were given!"
|
||||
"".format(len(matches), ', '.join(matches), len(value[CONF_ARGS])))
|
||||
raise cv.Invalid(
|
||||
"Found {} printf-patterns ({}), but {} args were given!"
|
||||
"".format(len(matches), ", ".join(matches), len(value[CONF_ARGS]))
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONF_LOGGER_LOG = 'logger.log'
|
||||
LOGGER_LOG_ACTION_SCHEMA = cv.All(maybe_simple_message({
|
||||
cv.Required(CONF_FORMAT): cv.string,
|
||||
cv.Optional(CONF_ARGS, default=list): cv.ensure_list(cv.lambda_),
|
||||
cv.Optional(CONF_LEVEL, default="DEBUG"): cv.one_of(*LOG_LEVEL_TO_ESP_LOG, upper=True),
|
||||
cv.Optional(CONF_TAG, default="main"): cv.string,
|
||||
}), validate_printf)
|
||||
CONF_LOGGER_LOG = "logger.log"
|
||||
LOGGER_LOG_ACTION_SCHEMA = cv.All(
|
||||
maybe_simple_message(
|
||||
{
|
||||
cv.Required(CONF_FORMAT): cv.string,
|
||||
cv.Optional(CONF_ARGS, default=list): cv.ensure_list(cv.lambda_),
|
||||
cv.Optional(CONF_LEVEL, default="DEBUG"): cv.one_of(
|
||||
*LOG_LEVEL_TO_ESP_LOG, upper=True
|
||||
),
|
||||
cv.Optional(CONF_TAG, default="main"): cv.string,
|
||||
}
|
||||
),
|
||||
validate_printf,
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action(CONF_LOGGER_LOG, LambdaAction, LOGGER_LOG_ACTION_SCHEMA)
|
||||
|
@ -1,18 +1,32 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, spi
|
||||
from esphome.const import CONF_ID, CONF_REFERENCE_TEMPERATURE, DEVICE_CLASS_TEMPERATURE, \
|
||||
ICON_EMPTY, UNIT_CELSIUS
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_REFERENCE_TEMPERATURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
max31855_ns = cg.esphome_ns.namespace('max31855')
|
||||
MAX31855Sensor = max31855_ns.class_('MAX31855Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
spi.SPIDevice)
|
||||
max31855_ns = cg.esphome_ns.namespace("max31855")
|
||||
MAX31855Sensor = max31855_ns.class_(
|
||||
"MAX31855Sensor", sensor.Sensor, cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(MAX31855Sensor),
|
||||
cv.Optional(CONF_REFERENCE_TEMPERATURE):
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 2, DEVICE_CLASS_TEMPERATURE),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX31855Sensor),
|
||||
cv.Optional(CONF_REFERENCE_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 2, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,23 +1,38 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, spi
|
||||
from esphome.const import CONF_ID, CONF_MAINS_FILTER, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, \
|
||||
UNIT_CELSIUS
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_MAINS_FILTER,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
max31856_ns = cg.esphome_ns.namespace('max31856')
|
||||
MAX31856Sensor = max31856_ns.class_('MAX31856Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
spi.SPIDevice)
|
||||
max31856_ns = cg.esphome_ns.namespace("max31856")
|
||||
MAX31856Sensor = max31856_ns.class_(
|
||||
"MAX31856Sensor", sensor.Sensor, cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
MAX31865ConfigFilter = max31856_ns.enum('MAX31856ConfigFilter')
|
||||
MAX31865ConfigFilter = max31856_ns.enum("MAX31856ConfigFilter")
|
||||
FILTER = {
|
||||
'50HZ': MAX31865ConfigFilter.FILTER_50HZ,
|
||||
'60HZ': MAX31865ConfigFilter.FILTER_60HZ,
|
||||
"50HZ": MAX31865ConfigFilter.FILTER_50HZ,
|
||||
"60HZ": MAX31865ConfigFilter.FILTER_60HZ,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(MAX31856Sensor),
|
||||
cv.Optional(CONF_MAINS_FILTER, default='60HZ'): cv.enum(FILTER, upper=True, space=''),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX31856Sensor),
|
||||
cv.Optional(CONF_MAINS_FILTER, default="60HZ"): cv.enum(
|
||||
FILTER, upper=True, space=""
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,26 +1,48 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, spi
|
||||
from esphome.const import CONF_ID, CONF_MAINS_FILTER, CONF_REFERENCE_RESISTANCE, \
|
||||
CONF_RTD_NOMINAL_RESISTANCE, CONF_RTD_WIRES, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_MAINS_FILTER,
|
||||
CONF_REFERENCE_RESISTANCE,
|
||||
CONF_RTD_NOMINAL_RESISTANCE,
|
||||
CONF_RTD_WIRES,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
max31865_ns = cg.esphome_ns.namespace('max31865')
|
||||
MAX31865Sensor = max31865_ns.class_('MAX31865Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
spi.SPIDevice)
|
||||
max31865_ns = cg.esphome_ns.namespace("max31865")
|
||||
MAX31865Sensor = max31865_ns.class_(
|
||||
"MAX31865Sensor", sensor.Sensor, cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
MAX31865ConfigFilter = max31865_ns.enum('MAX31865ConfigFilter')
|
||||
MAX31865ConfigFilter = max31865_ns.enum("MAX31865ConfigFilter")
|
||||
FILTER = {
|
||||
'50HZ': MAX31865ConfigFilter.FILTER_50HZ,
|
||||
'60HZ': MAX31865ConfigFilter.FILTER_60HZ,
|
||||
"50HZ": MAX31865ConfigFilter.FILTER_50HZ,
|
||||
"60HZ": MAX31865ConfigFilter.FILTER_60HZ,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 2, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(MAX31865Sensor),
|
||||
cv.Required(CONF_REFERENCE_RESISTANCE): cv.All(cv.resistance, cv.Range(min=100, max=10000)),
|
||||
cv.Required(CONF_RTD_NOMINAL_RESISTANCE): cv.All(cv.resistance, cv.Range(min=100, max=1000)),
|
||||
cv.Optional(CONF_MAINS_FILTER, default='60HZ'): cv.enum(FILTER, upper=True, space=''),
|
||||
cv.Optional(CONF_RTD_WIRES, default=4): cv.int_range(min=2, max=4),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 2, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX31865Sensor),
|
||||
cv.Required(CONF_REFERENCE_RESISTANCE): cv.All(
|
||||
cv.resistance, cv.Range(min=100, max=10000)
|
||||
),
|
||||
cv.Required(CONF_RTD_NOMINAL_RESISTANCE): cv.All(
|
||||
cv.resistance, cv.Range(min=100, max=1000)
|
||||
),
|
||||
cv.Optional(CONF_MAINS_FILTER, default="60HZ"): cv.enum(
|
||||
FILTER, upper=True, space=""
|
||||
),
|
||||
cv.Optional(CONF_RTD_WIRES, default=4): cv.int_range(min=2, max=4),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,13 +3,21 @@ import esphome.config_validation as cv
|
||||
from esphome.components import sensor, spi
|
||||
from esphome.const import CONF_ID, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS
|
||||
|
||||
max6675_ns = cg.esphome_ns.namespace('max6675')
|
||||
MAX6675Sensor = max6675_ns.class_('MAX6675Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
spi.SPIDevice)
|
||||
max6675_ns = cg.esphome_ns.namespace("max6675")
|
||||
MAX6675Sensor = max6675_ns.class_(
|
||||
"MAX6675Sensor", sensor.Sensor, cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(MAX6675Sensor),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX6675Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,21 +3,28 @@ import esphome.config_validation as cv
|
||||
from esphome.components import display, spi
|
||||
from esphome.const import CONF_ID, CONF_INTENSITY, CONF_LAMBDA, CONF_NUM_CHIPS
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
max7219_ns = cg.esphome_ns.namespace('max7219')
|
||||
MAX7219Component = max7219_ns.class_('MAX7219Component', cg.PollingComponent, spi.SPIDevice)
|
||||
MAX7219ComponentRef = MAX7219Component.operator('ref')
|
||||
max7219_ns = cg.esphome_ns.namespace("max7219")
|
||||
MAX7219Component = max7219_ns.class_(
|
||||
"MAX7219Component", cg.PollingComponent, spi.SPIDevice
|
||||
)
|
||||
MAX7219ComponentRef = MAX7219Component.operator("ref")
|
||||
|
||||
CONF_REVERSE_ENABLE = 'reverse_enable'
|
||||
CONF_REVERSE_ENABLE = "reverse_enable"
|
||||
|
||||
CONFIG_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(MAX7219Component),
|
||||
|
||||
cv.Optional(CONF_NUM_CHIPS, default=1): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_INTENSITY, default=15): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_REVERSE_ENABLE, default=False): cv.boolean,
|
||||
}).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
display.BASIC_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MAX7219Component),
|
||||
cv.Optional(CONF_NUM_CHIPS, default=1): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_INTENSITY, default=15): cv.int_range(min=0, max=15),
|
||||
cv.Optional(CONF_REVERSE_ENABLE, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("1s"))
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -31,6 +38,7 @@ def to_code(config):
|
||||
cg.add(var.set_reverse(config[CONF_REVERSE_ENABLE]))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(MAX7219ComponentRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(MAX7219ComponentRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
@ -2,26 +2,38 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED, CONF_OPEN_DRAIN_INTERRUPT
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_NUMBER,
|
||||
CONF_MODE,
|
||||
CONF_INVERTED,
|
||||
CONF_OPEN_DRAIN_INTERRUPT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
mcp23008_ns = cg.esphome_ns.namespace('mcp23008')
|
||||
MCP23008GPIOMode = mcp23008_ns.enum('MCP23008GPIOMode')
|
||||
mcp23008_ns = cg.esphome_ns.namespace("mcp23008")
|
||||
MCP23008GPIOMode = mcp23008_ns.enum("MCP23008GPIOMode")
|
||||
MCP23008_GPIO_MODES = {
|
||||
'INPUT': MCP23008GPIOMode.MCP23008_INPUT,
|
||||
'INPUT_PULLUP': MCP23008GPIOMode.MCP23008_INPUT_PULLUP,
|
||||
'OUTPUT': MCP23008GPIOMode.MCP23008_OUTPUT,
|
||||
"INPUT": MCP23008GPIOMode.MCP23008_INPUT,
|
||||
"INPUT_PULLUP": MCP23008GPIOMode.MCP23008_INPUT_PULLUP,
|
||||
"OUTPUT": MCP23008GPIOMode.MCP23008_OUTPUT,
|
||||
}
|
||||
|
||||
MCP23008 = mcp23008_ns.class_('MCP23008', cg.Component, i2c.I2CDevice)
|
||||
MCP23008GPIOPin = mcp23008_ns.class_('MCP23008GPIOPin', cg.GPIOPin)
|
||||
MCP23008 = mcp23008_ns.class_("MCP23008", cg.Component, i2c.I2CDevice)
|
||||
MCP23008GPIOPin = mcp23008_ns.class_("MCP23008GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23008),
|
||||
cv.Optional(CONF_OPEN_DRAIN_INTERRUPT, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x20))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23008),
|
||||
cv.Optional(CONF_OPEN_DRAIN_INTERRUPT, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x20))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -31,23 +43,34 @@ def to_code(config):
|
||||
cg.add(var.set_open_drain_ints(config[CONF_OPEN_DRAIN_INTERRUPT]))
|
||||
|
||||
|
||||
CONF_MCP23008 = 'mcp23008'
|
||||
MCP23008_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23008): cv.use_id(MCP23008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(MCP23008_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
MCP23008_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23008): cv.use_id(MCP23008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(MCP23008_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
CONF_MCP23008 = "mcp23008"
|
||||
MCP23008_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23008): cv.use_id(MCP23008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(
|
||||
MCP23008_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
MCP23008_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23008): cv.use_id(MCP23008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(
|
||||
MCP23008_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23008,
|
||||
(MCP23008_OUTPUT_PIN_SCHEMA, MCP23008_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
CONF_MCP23008, (MCP23008_OUTPUT_PIN_SCHEMA, MCP23008_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def mcp23008_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP23008])
|
||||
yield MCP23008GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield MCP23008GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -4,22 +4,28 @@ from esphome import pins
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
mcp23016_ns = cg.esphome_ns.namespace('mcp23016')
|
||||
MCP23016GPIOMode = mcp23016_ns.enum('MCP23016GPIOMode')
|
||||
mcp23016_ns = cg.esphome_ns.namespace("mcp23016")
|
||||
MCP23016GPIOMode = mcp23016_ns.enum("MCP23016GPIOMode")
|
||||
MCP23016_GPIO_MODES = {
|
||||
'INPUT': MCP23016GPIOMode.MCP23016_INPUT,
|
||||
'OUTPUT': MCP23016GPIOMode.MCP23016_OUTPUT,
|
||||
"INPUT": MCP23016GPIOMode.MCP23016_INPUT,
|
||||
"OUTPUT": MCP23016GPIOMode.MCP23016_OUTPUT,
|
||||
}
|
||||
|
||||
MCP23016 = mcp23016_ns.class_('MCP23016', cg.Component, i2c.I2CDevice)
|
||||
MCP23016GPIOPin = mcp23016_ns.class_('MCP23016GPIOPin', cg.GPIOPin)
|
||||
MCP23016 = mcp23016_ns.class_("MCP23016", cg.Component, i2c.I2CDevice)
|
||||
MCP23016GPIOPin = mcp23016_ns.class_("MCP23016GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23016),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x20))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23016),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x20))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -28,23 +34,34 @@ def to_code(config):
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
|
||||
|
||||
CONF_MCP23016 = 'mcp23016'
|
||||
MCP23016_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23016): cv.use_id(MCP23016),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(MCP23016_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
MCP23016_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23016): cv.use_id(MCP23016),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(MCP23016_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
CONF_MCP23016 = "mcp23016"
|
||||
MCP23016_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23016): cv.use_id(MCP23016),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(
|
||||
MCP23016_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
MCP23016_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23016): cv.use_id(MCP23016),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(
|
||||
MCP23016_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23016,
|
||||
(MCP23016_OUTPUT_PIN_SCHEMA, MCP23016_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
CONF_MCP23016, (MCP23016_OUTPUT_PIN_SCHEMA, MCP23016_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def mcp23016_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP23016])
|
||||
yield MCP23016GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield MCP23016GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -2,26 +2,38 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED, CONF_OPEN_DRAIN_INTERRUPT
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_NUMBER,
|
||||
CONF_MODE,
|
||||
CONF_INVERTED,
|
||||
CONF_OPEN_DRAIN_INTERRUPT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
mcp23017_ns = cg.esphome_ns.namespace('mcp23017')
|
||||
MCP23017GPIOMode = mcp23017_ns.enum('MCP23017GPIOMode')
|
||||
mcp23017_ns = cg.esphome_ns.namespace("mcp23017")
|
||||
MCP23017GPIOMode = mcp23017_ns.enum("MCP23017GPIOMode")
|
||||
MCP23017_GPIO_MODES = {
|
||||
'INPUT': MCP23017GPIOMode.MCP23017_INPUT,
|
||||
'INPUT_PULLUP': MCP23017GPIOMode.MCP23017_INPUT_PULLUP,
|
||||
'OUTPUT': MCP23017GPIOMode.MCP23017_OUTPUT,
|
||||
"INPUT": MCP23017GPIOMode.MCP23017_INPUT,
|
||||
"INPUT_PULLUP": MCP23017GPIOMode.MCP23017_INPUT_PULLUP,
|
||||
"OUTPUT": MCP23017GPIOMode.MCP23017_OUTPUT,
|
||||
}
|
||||
|
||||
MCP23017 = mcp23017_ns.class_('MCP23017', cg.Component, i2c.I2CDevice)
|
||||
MCP23017GPIOPin = mcp23017_ns.class_('MCP23017GPIOPin', cg.GPIOPin)
|
||||
MCP23017 = mcp23017_ns.class_("MCP23017", cg.Component, i2c.I2CDevice)
|
||||
MCP23017GPIOPin = mcp23017_ns.class_("MCP23017GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23017),
|
||||
cv.Optional(CONF_OPEN_DRAIN_INTERRUPT, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x20))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP23017),
|
||||
cv.Optional(CONF_OPEN_DRAIN_INTERRUPT, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x20))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -31,23 +43,34 @@ def to_code(config):
|
||||
cg.add(var.set_open_drain_ints(config[CONF_OPEN_DRAIN_INTERRUPT]))
|
||||
|
||||
|
||||
CONF_MCP23017 = 'mcp23017'
|
||||
MCP23017_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23017): cv.use_id(MCP23017),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(MCP23017_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
MCP23017_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23017): cv.use_id(MCP23017),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(MCP23017_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
CONF_MCP23017 = "mcp23017"
|
||||
MCP23017_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23017): cv.use_id(MCP23017),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(
|
||||
MCP23017_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
MCP23017_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23017): cv.use_id(MCP23017),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(
|
||||
MCP23017_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23017,
|
||||
(MCP23017_OUTPUT_PIN_SCHEMA, MCP23017_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
CONF_MCP23017, (MCP23017_OUTPUT_PIN_SCHEMA, MCP23017_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def mcp23017_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP23017])
|
||||
yield MCP23017GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield MCP23017GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -4,28 +4,34 @@ from esphome import pins
|
||||
from esphome.components import spi
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED
|
||||
|
||||
CODEOWNERS = ['@SenexCrenshaw']
|
||||
CODEOWNERS = ["@SenexCrenshaw"]
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
DEPENDENCIES = ["spi"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_DEVICEADDRESS = "deviceaddress"
|
||||
|
||||
mcp23S08_ns = cg.esphome_ns.namespace('mcp23s08')
|
||||
mcp23S08GPIOMode = mcp23S08_ns.enum('MCP23S08GPIOMode')
|
||||
mcp23S08_ns = cg.esphome_ns.namespace("mcp23s08")
|
||||
mcp23S08GPIOMode = mcp23S08_ns.enum("MCP23S08GPIOMode")
|
||||
mcp23S08_GPIO_MODES = {
|
||||
'INPUT': mcp23S08GPIOMode.MCP23S08_INPUT,
|
||||
'INPUT_PULLUP': mcp23S08GPIOMode.MCP23S08_INPUT_PULLUP,
|
||||
'OUTPUT': mcp23S08GPIOMode.MCP23S08_OUTPUT,
|
||||
"INPUT": mcp23S08GPIOMode.MCP23S08_INPUT,
|
||||
"INPUT_PULLUP": mcp23S08GPIOMode.MCP23S08_INPUT_PULLUP,
|
||||
"OUTPUT": mcp23S08GPIOMode.MCP23S08_OUTPUT,
|
||||
}
|
||||
|
||||
mcp23S08 = mcp23S08_ns.class_('MCP23S08', cg.Component, spi.SPIDevice)
|
||||
mcp23S08GPIOPin = mcp23S08_ns.class_('MCP23S08GPIOPin', cg.GPIOPin)
|
||||
mcp23S08 = mcp23S08_ns.class_("MCP23S08", cg.Component, spi.SPIDevice)
|
||||
mcp23S08GPIOPin = mcp23S08_ns.class_("MCP23S08GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(mcp23S08),
|
||||
cv.Optional(CONF_DEVICEADDRESS, default=0): cv.uint8_t,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(mcp23S08),
|
||||
cv.Optional(CONF_DEVICEADDRESS, default=0): cv.uint8_t,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -35,24 +41,35 @@ def to_code(config):
|
||||
yield spi.register_spi_device(var, config)
|
||||
|
||||
|
||||
CONF_MCP23S08 = 'mcp23s08'
|
||||
CONF_MCP23S08 = "mcp23s08"
|
||||
|
||||
mcp23S08_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_MCP23S08): cv.use_id(mcp23S08),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(mcp23S08_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
mcp23S08_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_MCP23S08): cv.use_id(mcp23S08),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(0, 7),
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(mcp23S08_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
mcp23S08_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_MCP23S08): cv.use_id(mcp23S08),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(
|
||||
mcp23S08_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
mcp23S08_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_MCP23S08): cv.use_id(mcp23S08),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(0, 7),
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(
|
||||
mcp23S08_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23S08,
|
||||
(mcp23S08_OUTPUT_PIN_SCHEMA, mcp23S08_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
CONF_MCP23S08, (mcp23S08_OUTPUT_PIN_SCHEMA, mcp23S08_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def mcp23S08_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP23S08])
|
||||
yield mcp23S08GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield mcp23S08GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -4,28 +4,34 @@ from esphome import pins
|
||||
from esphome.components import spi
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED
|
||||
|
||||
CODEOWNERS = ['@SenexCrenshaw']
|
||||
CODEOWNERS = ["@SenexCrenshaw"]
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
DEPENDENCIES = ["spi"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_DEVICEADDRESS = "deviceaddress"
|
||||
|
||||
mcp23S17_ns = cg.esphome_ns.namespace('mcp23s17')
|
||||
mcp23S17GPIOMode = mcp23S17_ns.enum('MCP23S17GPIOMode')
|
||||
mcp23S17_ns = cg.esphome_ns.namespace("mcp23s17")
|
||||
mcp23S17GPIOMode = mcp23S17_ns.enum("MCP23S17GPIOMode")
|
||||
mcp23S17_GPIO_MODES = {
|
||||
'INPUT': mcp23S17GPIOMode.MCP23S17_INPUT,
|
||||
'INPUT_PULLUP': mcp23S17GPIOMode.MCP23S17_INPUT_PULLUP,
|
||||
'OUTPUT': mcp23S17GPIOMode.MCP23S17_OUTPUT,
|
||||
"INPUT": mcp23S17GPIOMode.MCP23S17_INPUT,
|
||||
"INPUT_PULLUP": mcp23S17GPIOMode.MCP23S17_INPUT_PULLUP,
|
||||
"OUTPUT": mcp23S17GPIOMode.MCP23S17_OUTPUT,
|
||||
}
|
||||
|
||||
mcp23S17 = mcp23S17_ns.class_('MCP23S17', cg.Component, spi.SPIDevice)
|
||||
mcp23S17GPIOPin = mcp23S17_ns.class_('MCP23S17GPIOPin', cg.GPIOPin)
|
||||
mcp23S17 = mcp23S17_ns.class_("MCP23S17", cg.Component, spi.SPIDevice)
|
||||
mcp23S17GPIOPin = mcp23S17_ns.class_("MCP23S17GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(mcp23S17),
|
||||
cv.Optional(CONF_DEVICEADDRESS, default=0): cv.uint8_t,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(spi.spi_device_schema())
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(mcp23S17),
|
||||
cv.Optional(CONF_DEVICEADDRESS, default=0): cv.uint8_t,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(spi.spi_device_schema())
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -35,24 +41,35 @@ def to_code(config):
|
||||
yield spi.register_spi_device(var, config)
|
||||
|
||||
|
||||
CONF_MCP23S17 = 'mcp23s17'
|
||||
CONF_MCP23S17 = "mcp23s17"
|
||||
|
||||
mcp23S17_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(CONF_MCP23S17): cv.use_id(mcp23S17),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(mcp23S17_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
mcp23S17_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_MCP23S17): cv.use_id(mcp23S17),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(0, 15),
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(mcp23S17_GPIO_MODES, upper=True),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
mcp23S17_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(CONF_MCP23S17): cv.use_id(mcp23S17),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): cv.enum(
|
||||
mcp23S17_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
mcp23S17_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_MCP23S17): cv.use_id(mcp23S17),
|
||||
cv.Required(CONF_NUMBER): cv.int_range(0, 15),
|
||||
cv.Optional(CONF_MODE, default="INPUT"): cv.enum(
|
||||
mcp23S17_GPIO_MODES, upper=True
|
||||
),
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(CONF_MCP23S17,
|
||||
(mcp23S17_OUTPUT_PIN_SCHEMA, mcp23S17_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
CONF_MCP23S17, (mcp23S17_OUTPUT_PIN_SCHEMA, mcp23S17_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def mcp23S17_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP23S17])
|
||||
yield mcp23S17GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield mcp23S17GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -4,33 +4,35 @@ from esphome.components import spi, canbus
|
||||
from esphome.const import CONF_ID, CONF_MODE
|
||||
from esphome.components.canbus import CanbusComponent
|
||||
|
||||
CODEOWNERS = ['@mvturnho', '@danielschramm']
|
||||
DEPENDENCIES = ['spi']
|
||||
CODEOWNERS = ["@mvturnho", "@danielschramm"]
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
CONF_CLOCK = 'clock'
|
||||
CONF_CLOCK = "clock"
|
||||
|
||||
mcp2515_ns = cg.esphome_ns.namespace('mcp2515')
|
||||
mcp2515 = mcp2515_ns.class_('MCP2515', CanbusComponent, spi.SPIDevice)
|
||||
CanClock = mcp2515_ns.enum('CAN_CLOCK')
|
||||
McpMode = mcp2515_ns.enum('CANCTRL_REQOP_MODE')
|
||||
mcp2515_ns = cg.esphome_ns.namespace("mcp2515")
|
||||
mcp2515 = mcp2515_ns.class_("MCP2515", CanbusComponent, spi.SPIDevice)
|
||||
CanClock = mcp2515_ns.enum("CAN_CLOCK")
|
||||
McpMode = mcp2515_ns.enum("CANCTRL_REQOP_MODE")
|
||||
|
||||
CAN_CLOCK = {
|
||||
'8MHZ': CanClock.MCP_8MHZ,
|
||||
'16MHZ': CanClock.MCP_16MHZ,
|
||||
'20MHZ': CanClock.MCP_20MHZ,
|
||||
"8MHZ": CanClock.MCP_8MHZ,
|
||||
"16MHZ": CanClock.MCP_16MHZ,
|
||||
"20MHZ": CanClock.MCP_20MHZ,
|
||||
}
|
||||
|
||||
MCP_MODE = {
|
||||
'NORMAL': McpMode.CANCTRL_REQOP_NORMAL,
|
||||
'LOOPBACK': McpMode.CANCTRL_REQOP_LOOPBACK,
|
||||
'LISTENONLY': McpMode.CANCTRL_REQOP_LISTENONLY,
|
||||
"NORMAL": McpMode.CANCTRL_REQOP_NORMAL,
|
||||
"LOOPBACK": McpMode.CANCTRL_REQOP_LOOPBACK,
|
||||
"LISTENONLY": McpMode.CANCTRL_REQOP_LISTENONLY,
|
||||
}
|
||||
|
||||
CONFIG_SCHEMA = canbus.CONFIG_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(mcp2515),
|
||||
cv.Optional(CONF_CLOCK, default='8MHZ'): cv.enum(CAN_CLOCK, upper=True),
|
||||
cv.Optional(CONF_MODE, default='NORMAL'): cv.enum(MCP_MODE, upper=True),
|
||||
}).extend(spi.spi_device_schema(True))
|
||||
CONFIG_SCHEMA = canbus.CONFIG_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(mcp2515),
|
||||
cv.Optional(CONF_CLOCK, default="8MHZ"): cv.enum(CAN_CLOCK, upper=True),
|
||||
cv.Optional(CONF_MODE, default="NORMAL"): cv.enum(MCP_MODE, upper=True),
|
||||
}
|
||||
).extend(spi.spi_device_schema(True))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,18 +3,20 @@ import esphome.config_validation as cv
|
||||
from esphome.components import spi
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
AUTO_LOAD = ['sensor']
|
||||
DEPENDENCIES = ["spi"]
|
||||
AUTO_LOAD = ["sensor"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_MCP3008 = 'mcp3008'
|
||||
CONF_MCP3008 = "mcp3008"
|
||||
|
||||
mcp3008_ns = cg.esphome_ns.namespace('mcp3008')
|
||||
MCP3008 = mcp3008_ns.class_('MCP3008', cg.Component, spi.SPIDevice)
|
||||
mcp3008_ns = cg.esphome_ns.namespace("mcp3008")
|
||||
MCP3008 = mcp3008_ns.class_("MCP3008", cg.Component, spi.SPIDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MCP3008),
|
||||
}).extend(spi.spi_device_schema(cs_pin_required=True))
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MCP3008),
|
||||
}
|
||||
).extend(spi.spi_device_schema(cs_pin_required=True))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,26 +4,34 @@ from esphome.components import sensor, voltage_sampler
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_NAME
|
||||
from . import mcp3008_ns, MCP3008
|
||||
|
||||
AUTO_LOAD = ['voltage_sampler']
|
||||
AUTO_LOAD = ["voltage_sampler"]
|
||||
|
||||
DEPENDENCIES = ['mcp3008']
|
||||
DEPENDENCIES = ["mcp3008"]
|
||||
|
||||
MCP3008Sensor = mcp3008_ns.class_('MCP3008Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
voltage_sampler.VoltageSampler)
|
||||
CONF_REFERENCE_VOLTAGE = 'reference_voltage'
|
||||
CONF_MCP3008_ID = 'mcp3008_id'
|
||||
MCP3008Sensor = mcp3008_ns.class_(
|
||||
"MCP3008Sensor", sensor.Sensor, cg.PollingComponent, voltage_sampler.VoltageSampler
|
||||
)
|
||||
CONF_REFERENCE_VOLTAGE = "reference_voltage"
|
||||
CONF_MCP3008_ID = "mcp3008_id"
|
||||
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(MCP3008Sensor),
|
||||
cv.GenerateID(CONF_MCP3008_ID): cv.use_id(MCP3008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_REFERENCE_VOLTAGE, default='3.3V'): cv.voltage,
|
||||
}).extend(cv.polling_component_schema('1s'))
|
||||
CONFIG_SCHEMA = sensor.SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MCP3008Sensor),
|
||||
cv.GenerateID(CONF_MCP3008_ID): cv.use_id(MCP3008),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_REFERENCE_VOLTAGE, default="3.3V"): cv.voltage,
|
||||
}
|
||||
).extend(cv.polling_component_schema("1s"))
|
||||
|
||||
|
||||
def to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_MCP3008_ID])
|
||||
var = cg.new_Pvariable(config[CONF_ID], parent, config[CONF_NAME],
|
||||
config[CONF_NUMBER], config[CONF_REFERENCE_VOLTAGE])
|
||||
var = cg.new_Pvariable(
|
||||
config[CONF_ID],
|
||||
parent,
|
||||
config[CONF_NAME],
|
||||
config[CONF_NUMBER],
|
||||
config[CONF_REFERENCE_VOLTAGE],
|
||||
)
|
||||
yield cg.register_component(var, config)
|
||||
yield sensor.register_sensor(var, config)
|
||||
|
@ -3,14 +3,20 @@ import esphome.codegen as cg
|
||||
from esphome.components import output, i2c
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
mcp4725 = cg.esphome_ns.namespace('mcp4725')
|
||||
MCP4725 = mcp4725.class_('MCP4725', output.FloatOutput, cg.Component, i2c.I2CDevice)
|
||||
mcp4725 = cg.esphome_ns.namespace("mcp4725")
|
||||
MCP4725 = mcp4725.class_("MCP4725", output.FloatOutput, cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP4725),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x60))
|
||||
CONFIG_SCHEMA = (
|
||||
output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(MCP4725),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x60))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,16 +3,24 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS
|
||||
|
||||
CODEOWNERS = ['@k7hpn']
|
||||
DEPENDENCIES = ['i2c']
|
||||
CODEOWNERS = ["@k7hpn"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
mcp9808_ns = cg.esphome_ns.namespace('mcp9808')
|
||||
MCP9808Sensor = mcp9808_ns.class_('MCP9808Sensor', sensor.Sensor, cg.PollingComponent,
|
||||
i2c.I2CDevice)
|
||||
mcp9808_ns = cg.esphome_ns.namespace("mcp9808")
|
||||
MCP9808Sensor = mcp9808_ns.class_(
|
||||
"MCP9808Sensor", sensor.Sensor, cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(MCP9808Sensor),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x18))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MCP9808Sensor),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x18))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,27 +3,46 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.components import sensor, uart
|
||||
from esphome.const import CONF_CO2, CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_EMPTY, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_MOLECULE_CO2, UNIT_PARTS_PER_MILLION, UNIT_CELSIUS, ICON_EMPTY
|
||||
from esphome.const import (
|
||||
CONF_CO2,
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_MOLECULE_CO2,
|
||||
UNIT_PARTS_PER_MILLION,
|
||||
UNIT_CELSIUS,
|
||||
ICON_EMPTY,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
CONF_AUTOMATIC_BASELINE_CALIBRATION = 'automatic_baseline_calibration'
|
||||
CONF_AUTOMATIC_BASELINE_CALIBRATION = "automatic_baseline_calibration"
|
||||
|
||||
mhz19_ns = cg.esphome_ns.namespace('mhz19')
|
||||
MHZ19Component = mhz19_ns.class_('MHZ19Component', cg.PollingComponent, uart.UARTDevice)
|
||||
MHZ19CalibrateZeroAction = mhz19_ns.class_('MHZ19CalibrateZeroAction', automation.Action)
|
||||
MHZ19ABCEnableAction = mhz19_ns.class_('MHZ19ABCEnableAction', automation.Action)
|
||||
MHZ19ABCDisableAction = mhz19_ns.class_('MHZ19ABCDisableAction', automation.Action)
|
||||
mhz19_ns = cg.esphome_ns.namespace("mhz19")
|
||||
MHZ19Component = mhz19_ns.class_("MHZ19Component", cg.PollingComponent, uart.UARTDevice)
|
||||
MHZ19CalibrateZeroAction = mhz19_ns.class_(
|
||||
"MHZ19CalibrateZeroAction", automation.Action
|
||||
)
|
||||
MHZ19ABCEnableAction = mhz19_ns.class_("MHZ19ABCEnableAction", automation.Action)
|
||||
MHZ19ABCDisableAction = mhz19_ns.class_("MHZ19ABCDisableAction", automation.Action)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MHZ19Component),
|
||||
cv.Required(CONF_CO2): sensor.sensor_schema(
|
||||
UNIT_PARTS_PER_MILLION, ICON_MOLECULE_CO2, 0, DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 0, DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_AUTOMATIC_BASELINE_CALIBRATION): cv.boolean,
|
||||
}).extend(cv.polling_component_schema('60s')).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MHZ19Component),
|
||||
cv.Required(CONF_CO2): sensor.sensor_schema(
|
||||
UNIT_PARTS_PER_MILLION, ICON_MOLECULE_CO2, 0, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 0, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_AUTOMATIC_BASELINE_CALIBRATION): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -43,17 +62,22 @@ def to_code(config):
|
||||
cg.add(var.set_abc_enabled(config[CONF_AUTOMATIC_BASELINE_CALIBRATION]))
|
||||
|
||||
|
||||
CALIBRATION_ACTION_SCHEMA = maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(MHZ19Component),
|
||||
})
|
||||
CALIBRATION_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(MHZ19Component),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('mhz19.calibrate_zero', MHZ19CalibrateZeroAction,
|
||||
CALIBRATION_ACTION_SCHEMA)
|
||||
@automation.register_action('mhz19.abc_enable', MHZ19ABCEnableAction,
|
||||
CALIBRATION_ACTION_SCHEMA)
|
||||
@automation.register_action('mhz19.abc_disable', MHZ19ABCDisableAction,
|
||||
CALIBRATION_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"mhz19.calibrate_zero", MHZ19CalibrateZeroAction, CALIBRATION_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"mhz19.abc_enable", MHZ19ABCEnableAction, CALIBRATION_ACTION_SCHEMA
|
||||
)
|
||||
@automation.register_action(
|
||||
"mhz19.abc_disable", MHZ19ABCDisableAction, CALIBRATION_ACTION_SCHEMA
|
||||
)
|
||||
def mhz19_calibration_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -3,14 +3,16 @@ import esphome.config_validation as cv
|
||||
from esphome.components import climate_ir
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['climate_ir']
|
||||
AUTO_LOAD = ["climate_ir"]
|
||||
|
||||
mitsubishi_ns = cg.esphome_ns.namespace('mitsubishi')
|
||||
MitsubishiClimate = mitsubishi_ns.class_('MitsubishiClimate', climate_ir.ClimateIR)
|
||||
mitsubishi_ns = cg.esphome_ns.namespace("mitsubishi")
|
||||
MitsubishiClimate = mitsubishi_ns.class_("MitsubishiClimate", climate_ir.ClimateIR)
|
||||
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(MitsubishiClimate),
|
||||
})
|
||||
CONFIG_SCHEMA = climate_ir.CLIMATE_IR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MitsubishiClimate),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,17 +4,23 @@ from esphome.components import uart
|
||||
from esphome.const import CONF_ID, CONF_ADDRESS
|
||||
from esphome.core import coroutine
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
modbus_ns = cg.esphome_ns.namespace('modbus')
|
||||
Modbus = modbus_ns.class_('Modbus', cg.Component, uart.UARTDevice)
|
||||
ModbusDevice = modbus_ns.class_('ModbusDevice')
|
||||
modbus_ns = cg.esphome_ns.namespace("modbus")
|
||||
Modbus = modbus_ns.class_("Modbus", cg.Component, uart.UARTDevice)
|
||||
ModbusDevice = modbus_ns.class_("ModbusDevice")
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_MODBUS_ID = 'modbus_id'
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(Modbus),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONF_MODBUS_ID = "modbus_id"
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Modbus),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,13 +3,17 @@ import esphome.config_validation as cv
|
||||
from esphome.components import light, output
|
||||
from esphome.const import CONF_OUTPUT_ID, CONF_OUTPUT
|
||||
|
||||
monochromatic_ns = cg.esphome_ns.namespace('monochromatic')
|
||||
MonochromaticLightOutput = monochromatic_ns.class_('MonochromaticLightOutput', light.LightOutput)
|
||||
monochromatic_ns = cg.esphome_ns.namespace("monochromatic")
|
||||
MonochromaticLightOutput = monochromatic_ns.class_(
|
||||
"MonochromaticLightOutput", light.LightOutput
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(MonochromaticLightOutput),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
})
|
||||
CONFIG_SCHEMA = light.BRIGHTNESS_ONLY_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(MonochromaticLightOutput),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -8,21 +8,31 @@ CONF_RELEASE_THRESHOLD = "release_threshold"
|
||||
CONF_TOUCH_DEBOUNCE = "touch_debounce"
|
||||
CONF_RELEASE_DEBOUNCE = "release_debounce"
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ['binary_sensor']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
AUTO_LOAD = ["binary_sensor"]
|
||||
|
||||
mpr121_ns = cg.esphome_ns.namespace('mpr121')
|
||||
CONF_MPR121_ID = 'mpr121_id'
|
||||
MPR121Component = mpr121_ns.class_('MPR121Component', cg.Component, i2c.I2CDevice)
|
||||
mpr121_ns = cg.esphome_ns.namespace("mpr121")
|
||||
CONF_MPR121_ID = "mpr121_id"
|
||||
MPR121Component = mpr121_ns.class_("MPR121Component", cg.Component, i2c.I2CDevice)
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MPR121Component),
|
||||
cv.Optional(CONF_RELEASE_DEBOUNCE, default=0): cv.int_range(min=0, max=7),
|
||||
cv.Optional(CONF_TOUCH_DEBOUNCE, default=0): cv.int_range(min=0, max=7),
|
||||
cv.Optional(CONF_TOUCH_THRESHOLD, default=0x0b): cv.int_range(min=0x05, max=0x30),
|
||||
cv.Optional(CONF_RELEASE_THRESHOLD, default=0x06): cv.int_range(min=0x05, max=0x30),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x5A))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MPR121Component),
|
||||
cv.Optional(CONF_RELEASE_DEBOUNCE, default=0): cv.int_range(min=0, max=7),
|
||||
cv.Optional(CONF_TOUCH_DEBOUNCE, default=0): cv.int_range(min=0, max=7),
|
||||
cv.Optional(CONF_TOUCH_THRESHOLD, default=0x0B): cv.int_range(
|
||||
min=0x05, max=0x30
|
||||
),
|
||||
cv.Optional(CONF_RELEASE_THRESHOLD, default=0x06): cv.int_range(
|
||||
min=0x05, max=0x30
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x5A))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,19 +2,26 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import binary_sensor
|
||||
from esphome.const import CONF_CHANNEL, CONF_ID
|
||||
from . import mpr121_ns, MPR121Component, CONF_MPR121_ID, CONF_TOUCH_THRESHOLD, \
|
||||
CONF_RELEASE_THRESHOLD
|
||||
from . import (
|
||||
mpr121_ns,
|
||||
MPR121Component,
|
||||
CONF_MPR121_ID,
|
||||
CONF_TOUCH_THRESHOLD,
|
||||
CONF_RELEASE_THRESHOLD,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['mpr121']
|
||||
MPR121Channel = mpr121_ns.class_('MPR121Channel', binary_sensor.BinarySensor)
|
||||
DEPENDENCIES = ["mpr121"]
|
||||
MPR121Channel = mpr121_ns.class_("MPR121Channel", binary_sensor.BinarySensor)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(MPR121Channel),
|
||||
cv.GenerateID(CONF_MPR121_ID): cv.use_id(MPR121Component),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=11),
|
||||
cv.Optional(CONF_TOUCH_THRESHOLD): cv.int_range(min=0x05, max=0x30),
|
||||
cv.Optional(CONF_RELEASE_THRESHOLD): cv.int_range(min=0x05, max=0x30),
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MPR121Channel),
|
||||
cv.GenerateID(CONF_MPR121_ID): cv.use_id(MPR121Component),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=11),
|
||||
cv.Optional(CONF_TOUCH_THRESHOLD): cv.int_range(min=0x05, max=0x30),
|
||||
cv.Optional(CONF_RELEASE_THRESHOLD): cv.int_range(min=0x05, max=0x30),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,38 +1,59 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_TEMPERATURE, DEVICE_CLASS_EMPTY, DEVICE_CLASS_TEMPERATURE, \
|
||||
ICON_BRIEFCASE_DOWNLOAD, ICON_EMPTY, UNIT_METER_PER_SECOND_SQUARED, \
|
||||
ICON_SCREEN_ROTATION, UNIT_DEGREE_PER_SECOND, UNIT_CELSIUS
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_BRIEFCASE_DOWNLOAD,
|
||||
ICON_EMPTY,
|
||||
UNIT_METER_PER_SECOND_SQUARED,
|
||||
ICON_SCREEN_ROTATION,
|
||||
UNIT_DEGREE_PER_SECOND,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
CONF_ACCEL_X = 'accel_x'
|
||||
CONF_ACCEL_Y = 'accel_y'
|
||||
CONF_ACCEL_Z = 'accel_z'
|
||||
CONF_GYRO_X = 'gyro_x'
|
||||
CONF_GYRO_Y = 'gyro_y'
|
||||
CONF_GYRO_Z = 'gyro_z'
|
||||
CONF_ACCEL_X = "accel_x"
|
||||
CONF_ACCEL_Y = "accel_y"
|
||||
CONF_ACCEL_Z = "accel_z"
|
||||
CONF_GYRO_X = "gyro_x"
|
||||
CONF_GYRO_Y = "gyro_y"
|
||||
CONF_GYRO_Z = "gyro_z"
|
||||
|
||||
mpu6050_ns = cg.esphome_ns.namespace('mpu6050')
|
||||
MPU6050Component = mpu6050_ns.class_('MPU6050Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
mpu6050_ns = cg.esphome_ns.namespace("mpu6050")
|
||||
MPU6050Component = mpu6050_ns.class_(
|
||||
"MPU6050Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
accel_schema = sensor.sensor_schema(UNIT_METER_PER_SECOND_SQUARED, ICON_BRIEFCASE_DOWNLOAD, 2,
|
||||
DEVICE_CLASS_EMPTY)
|
||||
gyro_schema = sensor.sensor_schema(UNIT_DEGREE_PER_SECOND, ICON_SCREEN_ROTATION, 2,
|
||||
DEVICE_CLASS_EMPTY)
|
||||
temperature_schema = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
accel_schema = sensor.sensor_schema(
|
||||
UNIT_METER_PER_SECOND_SQUARED, ICON_BRIEFCASE_DOWNLOAD, 2, DEVICE_CLASS_EMPTY
|
||||
)
|
||||
gyro_schema = sensor.sensor_schema(
|
||||
UNIT_DEGREE_PER_SECOND, ICON_SCREEN_ROTATION, 2, DEVICE_CLASS_EMPTY
|
||||
)
|
||||
temperature_schema = sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MPU6050Component),
|
||||
cv.Optional(CONF_ACCEL_X): accel_schema,
|
||||
cv.Optional(CONF_ACCEL_Y): accel_schema,
|
||||
cv.Optional(CONF_ACCEL_Z): accel_schema,
|
||||
cv.Optional(CONF_GYRO_X): gyro_schema,
|
||||
cv.Optional(CONF_GYRO_Y): gyro_schema,
|
||||
cv.Optional(CONF_GYRO_Z): gyro_schema,
|
||||
cv.Optional(CONF_TEMPERATURE): temperature_schema,
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x68))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MPU6050Component),
|
||||
cv.Optional(CONF_ACCEL_X): accel_schema,
|
||||
cv.Optional(CONF_ACCEL_Y): accel_schema,
|
||||
cv.Optional(CONF_ACCEL_Z): accel_schema,
|
||||
cv.Optional(CONF_GYRO_X): gyro_schema,
|
||||
cv.Optional(CONF_GYRO_Y): gyro_schema,
|
||||
cv.Optional(CONF_GYRO_Z): gyro_schema,
|
||||
cv.Optional(CONF_TEMPERATURE): temperature_schema,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x68))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -40,15 +61,15 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
yield i2c.register_i2c_device(var, config)
|
||||
|
||||
for d in ['x', 'y', 'z']:
|
||||
accel_key = f'accel_{d}'
|
||||
for d in ["x", "y", "z"]:
|
||||
accel_key = f"accel_{d}"
|
||||
if accel_key in config:
|
||||
sens = yield sensor.new_sensor(config[accel_key])
|
||||
cg.add(getattr(var, f'set_accel_{d}_sensor')(sens))
|
||||
accel_key = f'gyro_{d}'
|
||||
cg.add(getattr(var, f"set_accel_{d}_sensor")(sens))
|
||||
accel_key = f"gyro_{d}"
|
||||
if accel_key in config:
|
||||
sens = yield sensor.new_sensor(config[accel_key])
|
||||
cg.add(getattr(var, f'set_gyro_{d}_sensor')(sens))
|
||||
cg.add(getattr(var, f"set_gyro_{d}_sensor")(sens))
|
||||
|
||||
if CONF_TEMPERATURE in config:
|
||||
sens = yield sensor.new_sensor(config[CONF_TEMPERATURE])
|
||||
|
@ -5,17 +5,42 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import Condition
|
||||
from esphome.components import logger
|
||||
from esphome.const import CONF_AVAILABILITY, CONF_BIRTH_MESSAGE, CONF_BROKER, CONF_CLIENT_ID, \
|
||||
CONF_COMMAND_TOPIC, CONF_DISCOVERY, CONF_DISCOVERY_PREFIX, CONF_DISCOVERY_RETAIN, \
|
||||
CONF_ID, CONF_KEEPALIVE, CONF_LEVEL, CONF_LOG_TOPIC, CONF_ON_JSON_MESSAGE, CONF_ON_MESSAGE, \
|
||||
CONF_PASSWORD, CONF_PAYLOAD, CONF_PAYLOAD_AVAILABLE, CONF_PAYLOAD_NOT_AVAILABLE, CONF_PORT, \
|
||||
CONF_QOS, CONF_REBOOT_TIMEOUT, CONF_RETAIN, CONF_SHUTDOWN_MESSAGE, CONF_SSL_FINGERPRINTS, \
|
||||
CONF_STATE_TOPIC, CONF_TOPIC, CONF_TOPIC_PREFIX, CONF_TRIGGER_ID, CONF_USERNAME, \
|
||||
CONF_WILL_MESSAGE
|
||||
from esphome.const import (
|
||||
CONF_AVAILABILITY,
|
||||
CONF_BIRTH_MESSAGE,
|
||||
CONF_BROKER,
|
||||
CONF_CLIENT_ID,
|
||||
CONF_COMMAND_TOPIC,
|
||||
CONF_DISCOVERY,
|
||||
CONF_DISCOVERY_PREFIX,
|
||||
CONF_DISCOVERY_RETAIN,
|
||||
CONF_ID,
|
||||
CONF_KEEPALIVE,
|
||||
CONF_LEVEL,
|
||||
CONF_LOG_TOPIC,
|
||||
CONF_ON_JSON_MESSAGE,
|
||||
CONF_ON_MESSAGE,
|
||||
CONF_PASSWORD,
|
||||
CONF_PAYLOAD,
|
||||
CONF_PAYLOAD_AVAILABLE,
|
||||
CONF_PAYLOAD_NOT_AVAILABLE,
|
||||
CONF_PORT,
|
||||
CONF_QOS,
|
||||
CONF_REBOOT_TIMEOUT,
|
||||
CONF_RETAIN,
|
||||
CONF_SHUTDOWN_MESSAGE,
|
||||
CONF_SSL_FINGERPRINTS,
|
||||
CONF_STATE_TOPIC,
|
||||
CONF_TOPIC,
|
||||
CONF_TOPIC_PREFIX,
|
||||
CONF_TRIGGER_ID,
|
||||
CONF_USERNAME,
|
||||
CONF_WILL_MESSAGE,
|
||||
)
|
||||
from esphome.core import coroutine_with_priority, coroutine, CORE
|
||||
|
||||
DEPENDENCIES = ['network']
|
||||
AUTO_LOAD = ['json', 'async_tcp']
|
||||
DEPENDENCIES = ["network"]
|
||||
AUTO_LOAD = ["json", "async_tcp"]
|
||||
|
||||
|
||||
def validate_message_just_topic(value):
|
||||
@ -23,39 +48,49 @@ def validate_message_just_topic(value):
|
||||
return MQTT_MESSAGE_BASE({CONF_TOPIC: value})
|
||||
|
||||
|
||||
MQTT_MESSAGE_BASE = cv.Schema({
|
||||
cv.Required(CONF_TOPIC): cv.publish_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
cv.Optional(CONF_RETAIN, default=True): cv.boolean,
|
||||
})
|
||||
MQTT_MESSAGE_BASE = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_TOPIC): cv.publish_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
cv.Optional(CONF_RETAIN, default=True): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
MQTT_MESSAGE_TEMPLATE_SCHEMA = cv.Any(None, MQTT_MESSAGE_BASE, validate_message_just_topic)
|
||||
MQTT_MESSAGE_TEMPLATE_SCHEMA = cv.Any(
|
||||
None, MQTT_MESSAGE_BASE, validate_message_just_topic
|
||||
)
|
||||
|
||||
MQTT_MESSAGE_SCHEMA = cv.Any(None, MQTT_MESSAGE_BASE.extend({
|
||||
cv.Required(CONF_PAYLOAD): cv.mqtt_payload,
|
||||
}))
|
||||
MQTT_MESSAGE_SCHEMA = cv.Any(
|
||||
None,
|
||||
MQTT_MESSAGE_BASE.extend(
|
||||
{
|
||||
cv.Required(CONF_PAYLOAD): cv.mqtt_payload,
|
||||
}
|
||||
),
|
||||
)
|
||||
|
||||
mqtt_ns = cg.esphome_ns.namespace('mqtt')
|
||||
MQTTMessage = mqtt_ns.struct('MQTTMessage')
|
||||
MQTTClientComponent = mqtt_ns.class_('MQTTClientComponent', cg.Component)
|
||||
MQTTPublishAction = mqtt_ns.class_('MQTTPublishAction', automation.Action)
|
||||
MQTTPublishJsonAction = mqtt_ns.class_('MQTTPublishJsonAction', automation.Action)
|
||||
MQTTMessageTrigger = mqtt_ns.class_('MQTTMessageTrigger',
|
||||
automation.Trigger.template(cg.std_string),
|
||||
cg.Component)
|
||||
MQTTJsonMessageTrigger = mqtt_ns.class_('MQTTJsonMessageTrigger',
|
||||
automation.Trigger.template(cg.JsonObjectConstRef))
|
||||
MQTTComponent = mqtt_ns.class_('MQTTComponent', cg.Component)
|
||||
MQTTConnectedCondition = mqtt_ns.class_('MQTTConnectedCondition', Condition)
|
||||
mqtt_ns = cg.esphome_ns.namespace("mqtt")
|
||||
MQTTMessage = mqtt_ns.struct("MQTTMessage")
|
||||
MQTTClientComponent = mqtt_ns.class_("MQTTClientComponent", cg.Component)
|
||||
MQTTPublishAction = mqtt_ns.class_("MQTTPublishAction", automation.Action)
|
||||
MQTTPublishJsonAction = mqtt_ns.class_("MQTTPublishJsonAction", automation.Action)
|
||||
MQTTMessageTrigger = mqtt_ns.class_(
|
||||
"MQTTMessageTrigger", automation.Trigger.template(cg.std_string), cg.Component
|
||||
)
|
||||
MQTTJsonMessageTrigger = mqtt_ns.class_(
|
||||
"MQTTJsonMessageTrigger", automation.Trigger.template(cg.JsonObjectConstRef)
|
||||
)
|
||||
MQTTComponent = mqtt_ns.class_("MQTTComponent", cg.Component)
|
||||
MQTTConnectedCondition = mqtt_ns.class_("MQTTConnectedCondition", Condition)
|
||||
|
||||
MQTTBinarySensorComponent = mqtt_ns.class_('MQTTBinarySensorComponent', MQTTComponent)
|
||||
MQTTClimateComponent = mqtt_ns.class_('MQTTClimateComponent', MQTTComponent)
|
||||
MQTTCoverComponent = mqtt_ns.class_('MQTTCoverComponent', MQTTComponent)
|
||||
MQTTFanComponent = mqtt_ns.class_('MQTTFanComponent', MQTTComponent)
|
||||
MQTTJSONLightComponent = mqtt_ns.class_('MQTTJSONLightComponent', MQTTComponent)
|
||||
MQTTSensorComponent = mqtt_ns.class_('MQTTSensorComponent', MQTTComponent)
|
||||
MQTTSwitchComponent = mqtt_ns.class_('MQTTSwitchComponent', MQTTComponent)
|
||||
MQTTTextSensor = mqtt_ns.class_('MQTTTextSensor', MQTTComponent)
|
||||
MQTTBinarySensorComponent = mqtt_ns.class_("MQTTBinarySensorComponent", MQTTComponent)
|
||||
MQTTClimateComponent = mqtt_ns.class_("MQTTClimateComponent", MQTTComponent)
|
||||
MQTTCoverComponent = mqtt_ns.class_("MQTTCoverComponent", MQTTComponent)
|
||||
MQTTFanComponent = mqtt_ns.class_("MQTTFanComponent", MQTTComponent)
|
||||
MQTTJSONLightComponent = mqtt_ns.class_("MQTTJSONLightComponent", MQTTComponent)
|
||||
MQTTSensorComponent = mqtt_ns.class_("MQTTSensorComponent", MQTTComponent)
|
||||
MQTTSwitchComponent = mqtt_ns.class_("MQTTSwitchComponent", MQTTComponent)
|
||||
MQTTTextSensor = mqtt_ns.class_("MQTTTextSensor", MQTTComponent)
|
||||
|
||||
|
||||
def validate_config(value):
|
||||
@ -64,28 +99,28 @@ def validate_config(value):
|
||||
topic_prefix = value[CONF_TOPIC_PREFIX]
|
||||
if CONF_BIRTH_MESSAGE not in value:
|
||||
out[CONF_BIRTH_MESSAGE] = {
|
||||
CONF_TOPIC: f'{topic_prefix}/status',
|
||||
CONF_PAYLOAD: 'online',
|
||||
CONF_TOPIC: f"{topic_prefix}/status",
|
||||
CONF_PAYLOAD: "online",
|
||||
CONF_QOS: 0,
|
||||
CONF_RETAIN: True,
|
||||
}
|
||||
if CONF_WILL_MESSAGE not in value:
|
||||
out[CONF_WILL_MESSAGE] = {
|
||||
CONF_TOPIC: f'{topic_prefix}/status',
|
||||
CONF_PAYLOAD: 'offline',
|
||||
CONF_TOPIC: f"{topic_prefix}/status",
|
||||
CONF_PAYLOAD: "offline",
|
||||
CONF_QOS: 0,
|
||||
CONF_RETAIN: True,
|
||||
}
|
||||
if CONF_SHUTDOWN_MESSAGE not in value:
|
||||
out[CONF_SHUTDOWN_MESSAGE] = {
|
||||
CONF_TOPIC: f'{topic_prefix}/status',
|
||||
CONF_PAYLOAD: 'offline',
|
||||
CONF_TOPIC: f"{topic_prefix}/status",
|
||||
CONF_PAYLOAD: "offline",
|
||||
CONF_QOS: 0,
|
||||
CONF_RETAIN: True,
|
||||
}
|
||||
if CONF_LOG_TOPIC not in value:
|
||||
out[CONF_LOG_TOPIC] = {
|
||||
CONF_TOPIC: f'{topic_prefix}/debug',
|
||||
CONF_TOPIC: f"{topic_prefix}/debug",
|
||||
CONF_QOS: 0,
|
||||
CONF_RETAIN: True,
|
||||
}
|
||||
@ -94,46 +129,68 @@ def validate_config(value):
|
||||
|
||||
def validate_fingerprint(value):
|
||||
value = cv.string(value)
|
||||
if re.match(r'^[0-9a-f]{40}$', value) is None:
|
||||
if re.match(r"^[0-9a-f]{40}$", value) is None:
|
||||
raise cv.Invalid("fingerprint must be valid SHA1 hash")
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MQTTClientComponent),
|
||||
cv.Required(CONF_BROKER): cv.string_strict,
|
||||
cv.Optional(CONF_PORT, default=1883): cv.port,
|
||||
cv.Optional(CONF_USERNAME, default=''): cv.string,
|
||||
cv.Optional(CONF_PASSWORD, default=''): cv.string,
|
||||
cv.Optional(CONF_CLIENT_ID): cv.string,
|
||||
cv.Optional(CONF_DISCOVERY, default=True): cv.Any(cv.boolean, cv.one_of("CLEAN", upper=True)),
|
||||
cv.Optional(CONF_DISCOVERY_RETAIN, default=True): cv.boolean,
|
||||
cv.Optional(CONF_DISCOVERY_PREFIX, default="homeassistant"): cv.publish_topic,
|
||||
|
||||
cv.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_SHUTDOWN_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_TOPIC_PREFIX, default=lambda: CORE.name): cv.publish_topic,
|
||||
cv.Optional(CONF_LOG_TOPIC): cv.Any(None, MQTT_MESSAGE_BASE.extend({
|
||||
cv.Optional(CONF_LEVEL): logger.is_log_level,
|
||||
}), validate_message_just_topic),
|
||||
|
||||
cv.Optional(CONF_SSL_FINGERPRINTS): cv.All(cv.only_on_esp8266,
|
||||
cv.ensure_list(validate_fingerprint)),
|
||||
cv.Optional(CONF_KEEPALIVE, default='15s'): cv.positive_time_period_seconds,
|
||||
cv.Optional(CONF_REBOOT_TIMEOUT, default='15min'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_ON_MESSAGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MQTTMessageTrigger),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
cv.Optional(CONF_PAYLOAD): cv.string_strict,
|
||||
}),
|
||||
cv.Optional(CONF_ON_JSON_MESSAGE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MQTTJsonMessageTrigger),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}),
|
||||
}), validate_config)
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MQTTClientComponent),
|
||||
cv.Required(CONF_BROKER): cv.string_strict,
|
||||
cv.Optional(CONF_PORT, default=1883): cv.port,
|
||||
cv.Optional(CONF_USERNAME, default=""): cv.string,
|
||||
cv.Optional(CONF_PASSWORD, default=""): cv.string,
|
||||
cv.Optional(CONF_CLIENT_ID): cv.string,
|
||||
cv.Optional(CONF_DISCOVERY, default=True): cv.Any(
|
||||
cv.boolean, cv.one_of("CLEAN", upper=True)
|
||||
),
|
||||
cv.Optional(CONF_DISCOVERY_RETAIN, default=True): cv.boolean,
|
||||
cv.Optional(
|
||||
CONF_DISCOVERY_PREFIX, default="homeassistant"
|
||||
): cv.publish_topic,
|
||||
cv.Optional(CONF_BIRTH_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_WILL_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_SHUTDOWN_MESSAGE): MQTT_MESSAGE_SCHEMA,
|
||||
cv.Optional(CONF_TOPIC_PREFIX, default=lambda: CORE.name): cv.publish_topic,
|
||||
cv.Optional(CONF_LOG_TOPIC): cv.Any(
|
||||
None,
|
||||
MQTT_MESSAGE_BASE.extend(
|
||||
{
|
||||
cv.Optional(CONF_LEVEL): logger.is_log_level,
|
||||
}
|
||||
),
|
||||
validate_message_just_topic,
|
||||
),
|
||||
cv.Optional(CONF_SSL_FINGERPRINTS): cv.All(
|
||||
cv.only_on_esp8266, cv.ensure_list(validate_fingerprint)
|
||||
),
|
||||
cv.Optional(CONF_KEEPALIVE, default="15s"): cv.positive_time_period_seconds,
|
||||
cv.Optional(
|
||||
CONF_REBOOT_TIMEOUT, default="15min"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_ON_MESSAGE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(MQTTMessageTrigger),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
cv.Optional(CONF_PAYLOAD): cv.string_strict,
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_JSON_MESSAGE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
MQTTJsonMessageTrigger
|
||||
),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
validate_config,
|
||||
)
|
||||
|
||||
|
||||
def exp_mqtt_message(config):
|
||||
@ -141,10 +198,10 @@ def exp_mqtt_message(config):
|
||||
return cg.optional(cg.TemplateArguments(MQTTMessage))
|
||||
exp = cg.StructInitializer(
|
||||
MQTTMessage,
|
||||
('topic', config[CONF_TOPIC]),
|
||||
('payload', config.get(CONF_PAYLOAD, "")),
|
||||
('qos', config[CONF_QOS]),
|
||||
('retain', config[CONF_RETAIN])
|
||||
("topic", config[CONF_TOPIC]),
|
||||
("payload", config.get(CONF_PAYLOAD, "")),
|
||||
("qos", config[CONF_QOS]),
|
||||
("retain", config[CONF_RETAIN]),
|
||||
)
|
||||
return exp
|
||||
|
||||
@ -155,8 +212,8 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
# https://github.com/OttoWinter/async-mqtt-client/blob/master/library.json
|
||||
cg.add_library('AsyncMqttClient-esphome', '0.8.4')
|
||||
cg.add_define('USE_MQTT')
|
||||
cg.add_library("AsyncMqttClient-esphome", "0.8.4")
|
||||
cg.add_define("USE_MQTT")
|
||||
cg.add_global(mqtt_ns.using)
|
||||
|
||||
cg.add(var.set_broker_address(config[CONF_BROKER]))
|
||||
@ -206,9 +263,12 @@ def to_code(config):
|
||||
|
||||
if CONF_SSL_FINGERPRINTS in config:
|
||||
for fingerprint in config[CONF_SSL_FINGERPRINTS]:
|
||||
arr = [cg.RawExpression("0x{}".format(fingerprint[i:i + 2])) for i in range(0, 40, 2)]
|
||||
arr = [
|
||||
cg.RawExpression("0x{}".format(fingerprint[i : i + 2]))
|
||||
for i in range(0, 40, 2)
|
||||
]
|
||||
cg.add(var.add_ssl_fingerprint(arr))
|
||||
cg.add_build_flag('-DASYNC_TCP_SSL_ENABLED=1')
|
||||
cg.add_build_flag("-DASYNC_TCP_SSL_ENABLED=1")
|
||||
|
||||
cg.add(var.set_keep_alive(config[CONF_KEEPALIVE]))
|
||||
|
||||
@ -220,23 +280,27 @@ def to_code(config):
|
||||
if CONF_PAYLOAD in conf:
|
||||
cg.add(trig.set_payload(conf[CONF_PAYLOAD]))
|
||||
yield cg.register_component(trig, conf)
|
||||
yield automation.build_automation(trig, [(cg.std_string, 'x')], conf)
|
||||
yield automation.build_automation(trig, [(cg.std_string, "x")], conf)
|
||||
|
||||
for conf in config.get(CONF_ON_JSON_MESSAGE, []):
|
||||
trig = cg.new_Pvariable(conf[CONF_TRIGGER_ID], conf[CONF_TOPIC], conf[CONF_QOS])
|
||||
yield automation.build_automation(trig, [(cg.JsonObjectConstRef, 'x')], conf)
|
||||
yield automation.build_automation(trig, [(cg.JsonObjectConstRef, "x")], conf)
|
||||
|
||||
|
||||
MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
cv.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
||||
cv.Optional(CONF_QOS, default=0): cv.templatable(cv.mqtt_qos),
|
||||
cv.Optional(CONF_RETAIN, default=False): cv.templatable(cv.boolean),
|
||||
})
|
||||
MQTT_PUBLISH_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
cv.Required(CONF_PAYLOAD): cv.templatable(cv.mqtt_payload),
|
||||
cv.Optional(CONF_QOS, default=0): cv.templatable(cv.mqtt_qos),
|
||||
cv.Optional(CONF_RETAIN, default=False): cv.templatable(cv.boolean),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('mqtt.publish', MQTTPublishAction, MQTT_PUBLISH_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"mqtt.publish", MQTTPublishAction, MQTT_PUBLISH_ACTION_SCHEMA
|
||||
)
|
||||
def mqtt_publish_action_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -252,24 +316,27 @@ def mqtt_publish_action_to_code(config, action_id, template_arg, args):
|
||||
yield var
|
||||
|
||||
|
||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
cv.Required(CONF_PAYLOAD): cv.lambda_,
|
||||
cv.Optional(CONF_QOS, default=0): cv.templatable(cv.mqtt_qos),
|
||||
cv.Optional(CONF_RETAIN, default=False): cv.templatable(cv.boolean),
|
||||
})
|
||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.templatable(cv.publish_topic),
|
||||
cv.Required(CONF_PAYLOAD): cv.lambda_,
|
||||
cv.Optional(CONF_QOS, default=0): cv.templatable(cv.mqtt_qos),
|
||||
cv.Optional(CONF_RETAIN, default=False): cv.templatable(cv.boolean),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('mqtt.publish_json', MQTTPublishJsonAction,
|
||||
MQTT_PUBLISH_JSON_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"mqtt.publish_json", MQTTPublishJsonAction, MQTT_PUBLISH_JSON_ACTION_SCHEMA
|
||||
)
|
||||
def mqtt_publish_json_action_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
template_ = yield cg.templatable(config[CONF_TOPIC], args, cg.std_string)
|
||||
cg.add(var.set_topic(template_))
|
||||
|
||||
args_ = args + [(cg.JsonObjectRef, 'root')]
|
||||
args_ = args + [(cg.JsonObjectRef, "root")]
|
||||
lambda_ = yield cg.process_lambda(config[CONF_PAYLOAD], args_, return_type=cg.void)
|
||||
cg.add(var.set_payload(lambda_))
|
||||
template_ = yield cg.templatable(config[CONF_QOS], args, cg.uint8)
|
||||
@ -280,10 +347,13 @@ def mqtt_publish_json_action_to_code(config, action_id, template_arg, args):
|
||||
|
||||
|
||||
def get_default_topic_for(data, component_type, name, suffix):
|
||||
allowlist = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_'
|
||||
sanitized_name = ''.join(x for x in name.lower().replace(' ', '_') if x in allowlist)
|
||||
return '{}/{}/{}/{}'.format(data.topic_prefix, component_type,
|
||||
sanitized_name, suffix)
|
||||
allowlist = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
|
||||
sanitized_name = "".join(
|
||||
x for x in name.lower().replace(" ", "_") if x in allowlist
|
||||
)
|
||||
return "{}/{}/{}/{}".format(
|
||||
data.topic_prefix, component_type, sanitized_name, suffix
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -303,14 +373,24 @@ def register_mqtt_component(var, config):
|
||||
if not availability:
|
||||
cg.add(var.disable_availability())
|
||||
else:
|
||||
cg.add(var.set_availability(availability[CONF_TOPIC],
|
||||
availability[CONF_PAYLOAD_AVAILABLE],
|
||||
availability[CONF_PAYLOAD_NOT_AVAILABLE]))
|
||||
cg.add(
|
||||
var.set_availability(
|
||||
availability[CONF_TOPIC],
|
||||
availability[CONF_PAYLOAD_AVAILABLE],
|
||||
availability[CONF_PAYLOAD_NOT_AVAILABLE],
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@automation.register_condition('mqtt.connected', MQTTConnectedCondition, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
}))
|
||||
@automation.register_condition(
|
||||
"mqtt.connected",
|
||||
MQTTConnectedCondition,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(MQTTClientComponent),
|
||||
}
|
||||
),
|
||||
)
|
||||
def mqtt_connected_to_code(config, condition_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(condition_id, template_arg, paren)
|
||||
|
@ -1,3 +1,3 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
mqtt_subscribe_ns = cg.esphome_ns.namespace('mqtt_subscribe')
|
||||
mqtt_subscribe_ns = cg.esphome_ns.namespace("mqtt_subscribe")
|
||||
|
@ -1,20 +1,35 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import mqtt, sensor
|
||||
from esphome.const import CONF_ID, CONF_QOS, CONF_TOPIC, UNIT_EMPTY, ICON_EMPTY, DEVICE_CLASS_EMPTY
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_QOS,
|
||||
CONF_TOPIC,
|
||||
UNIT_EMPTY,
|
||||
ICON_EMPTY,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
)
|
||||
from .. import mqtt_subscribe_ns
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
DEPENDENCIES = ["mqtt"]
|
||||
|
||||
CONF_MQTT_PARENT_ID = 'mqtt_parent_id'
|
||||
MQTTSubscribeSensor = mqtt_subscribe_ns.class_('MQTTSubscribeSensor', sensor.Sensor, cg.Component)
|
||||
CONF_MQTT_PARENT_ID = "mqtt_parent_id"
|
||||
MQTTSubscribeSensor = mqtt_subscribe_ns.class_(
|
||||
"MQTTSubscribeSensor", sensor.Sensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(MQTTSubscribeSensor),
|
||||
cv.GenerateID(CONF_MQTT_PARENT_ID): cv.use_id(mqtt.MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 1, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MQTTSubscribeSensor),
|
||||
cv.GenerateID(CONF_MQTT_PARENT_ID): cv.use_id(mqtt.MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,18 +4,21 @@ from esphome.components import text_sensor, mqtt
|
||||
from esphome.const import CONF_ID, CONF_QOS, CONF_TOPIC
|
||||
from .. import mqtt_subscribe_ns
|
||||
|
||||
DEPENDENCIES = ['mqtt']
|
||||
DEPENDENCIES = ["mqtt"]
|
||||
|
||||
CONF_MQTT_PARENT_ID = 'mqtt_parent_id'
|
||||
MQTTSubscribeTextSensor = mqtt_subscribe_ns.class_('MQTTSubscribeTextSensor',
|
||||
text_sensor.TextSensor, cg.Component)
|
||||
CONF_MQTT_PARENT_ID = "mqtt_parent_id"
|
||||
MQTTSubscribeTextSensor = mqtt_subscribe_ns.class_(
|
||||
"MQTTSubscribeTextSensor", text_sensor.TextSensor, cg.Component
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(MQTTSubscribeTextSensor),
|
||||
cv.GenerateID(CONF_MQTT_PARENT_ID): cv.use_id(mqtt.MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = text_sensor.TEXT_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MQTTSubscribeTextSensor),
|
||||
cv.GenerateID(CONF_MQTT_PARENT_ID): cv.use_id(mqtt.MQTTClientComponent),
|
||||
cv.Required(CONF_TOPIC): cv.subscribe_topic,
|
||||
cv.Optional(CONF_QOS, default=0): cv.mqtt_qos,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,22 +1,40 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import i2c, sensor
|
||||
from esphome.const import CONF_ID, CONF_PRESSURE, \
|
||||
CONF_TEMPERATURE, DEVICE_CLASS_PRESSURE, DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS, \
|
||||
ICON_GAUGE, UNIT_HECTOPASCAL
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_PRESSURE,
|
||||
CONF_TEMPERATURE,
|
||||
DEVICE_CLASS_PRESSURE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
ICON_GAUGE,
|
||||
UNIT_HECTOPASCAL,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
ms5611_ns = cg.esphome_ns.namespace('ms5611')
|
||||
MS5611Component = ms5611_ns.class_('MS5611Component', cg.PollingComponent, i2c.I2CDevice)
|
||||
ms5611_ns = cg.esphome_ns.namespace("ms5611")
|
||||
MS5611Component = ms5611_ns.class_(
|
||||
"MS5611Component", cg.PollingComponent, i2c.I2CDevice
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MS5611Component),
|
||||
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1,
|
||||
DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Required(CONF_PRESSURE): sensor.sensor_schema(UNIT_HECTOPASCAL, ICON_GAUGE, 1,
|
||||
DEVICE_CLASS_PRESSURE),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MS5611Component),
|
||||
cv.Required(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Required(CONF_PRESSURE): sensor.sensor_schema(
|
||||
UNIT_HECTOPASCAL, ICON_GAUGE, 1, DEVICE_CLASS_PRESSURE
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(i2c.i2c_device_schema(0x77))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,22 +1,30 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import (CONF_BIT_DEPTH, CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_ID,
|
||||
CONF_NUM_CHANNELS, CONF_NUM_CHIPS)
|
||||
from esphome.const import (
|
||||
CONF_BIT_DEPTH,
|
||||
CONF_CLOCK_PIN,
|
||||
CONF_DATA_PIN,
|
||||
CONF_ID,
|
||||
CONF_NUM_CHANNELS,
|
||||
CONF_NUM_CHIPS,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['output']
|
||||
my9231_ns = cg.esphome_ns.namespace('my9231')
|
||||
MY9231OutputComponent = my9231_ns.class_('MY9231OutputComponent', cg.Component)
|
||||
AUTO_LOAD = ["output"]
|
||||
my9231_ns = cg.esphome_ns.namespace("my9231")
|
||||
MY9231OutputComponent = my9231_ns.class_("MY9231OutputComponent", cg.Component)
|
||||
|
||||
MULTI_CONF = True
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(MY9231OutputComponent),
|
||||
cv.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_NUM_CHANNELS, default=6): cv.int_range(min=3, max=1020),
|
||||
cv.Optional(CONF_NUM_CHIPS, default=2): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_BIT_DEPTH, default=16): cv.one_of(8, 12, 14, 16, int=True),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(MY9231OutputComponent),
|
||||
cv.Required(CONF_DATA_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CLOCK_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_NUM_CHANNELS, default=6): cv.int_range(min=3, max=1020),
|
||||
cv.Optional(CONF_NUM_CHIPS, default=2): cv.int_range(min=1, max=255),
|
||||
cv.Optional(CONF_BIT_DEPTH, default=16): cv.one_of(8, 12, 14, 16, int=True),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,17 +4,18 @@ from esphome.components import output
|
||||
from esphome.const import CONF_CHANNEL, CONF_ID
|
||||
from . import MY9231OutputComponent
|
||||
|
||||
DEPENDENCIES = ['my9231']
|
||||
DEPENDENCIES = ["my9231"]
|
||||
|
||||
Channel = MY9231OutputComponent.class_('Channel', output.FloatOutput)
|
||||
Channel = MY9231OutputComponent.class_("Channel", output.FloatOutput)
|
||||
|
||||
CONF_MY9231_ID = 'my9231_id'
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_MY9231_ID): cv.use_id(MY9231OutputComponent),
|
||||
|
||||
cv.Required(CONF_ID): cv.declare_id(Channel),
|
||||
cv.Required(CONF_CHANNEL): cv.uint16_t,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONF_MY9231_ID = "my9231_id"
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_MY9231_ID): cv.use_id(MY9231OutputComponent),
|
||||
cv.Required(CONF_ID): cv.declare_id(Channel),
|
||||
cv.Required(CONF_CHANNEL): cv.uint16_t,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,32 +2,45 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import light
|
||||
from esphome.const import CONF_CLOCK_PIN, CONF_DATA_PIN, CONF_METHOD, CONF_NUM_LEDS, CONF_PIN, \
|
||||
CONF_TYPE, CONF_VARIANT, CONF_OUTPUT_ID, CONF_INVERT
|
||||
from esphome.const import (
|
||||
CONF_CLOCK_PIN,
|
||||
CONF_DATA_PIN,
|
||||
CONF_METHOD,
|
||||
CONF_NUM_LEDS,
|
||||
CONF_PIN,
|
||||
CONF_TYPE,
|
||||
CONF_VARIANT,
|
||||
CONF_OUTPUT_ID,
|
||||
CONF_INVERT,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
|
||||
neopixelbus_ns = cg.esphome_ns.namespace('neopixelbus')
|
||||
NeoPixelBusLightOutputBase = neopixelbus_ns.class_('NeoPixelBusLightOutputBase',
|
||||
light.AddressableLight)
|
||||
NeoPixelRGBLightOutput = neopixelbus_ns.class_('NeoPixelRGBLightOutput', NeoPixelBusLightOutputBase)
|
||||
NeoPixelRGBWLightOutput = neopixelbus_ns.class_('NeoPixelRGBWLightOutput',
|
||||
NeoPixelBusLightOutputBase)
|
||||
ESPNeoPixelOrder = neopixelbus_ns.namespace('ESPNeoPixelOrder')
|
||||
neopixelbus_ns = cg.esphome_ns.namespace("neopixelbus")
|
||||
NeoPixelBusLightOutputBase = neopixelbus_ns.class_(
|
||||
"NeoPixelBusLightOutputBase", light.AddressableLight
|
||||
)
|
||||
NeoPixelRGBLightOutput = neopixelbus_ns.class_(
|
||||
"NeoPixelRGBLightOutput", NeoPixelBusLightOutputBase
|
||||
)
|
||||
NeoPixelRGBWLightOutput = neopixelbus_ns.class_(
|
||||
"NeoPixelRGBWLightOutput", NeoPixelBusLightOutputBase
|
||||
)
|
||||
ESPNeoPixelOrder = neopixelbus_ns.namespace("ESPNeoPixelOrder")
|
||||
NeoRgbFeature = cg.global_ns.NeoRgbFeature
|
||||
NeoRgbwFeature = cg.global_ns.NeoRgbwFeature
|
||||
|
||||
|
||||
def validate_type(value):
|
||||
value = cv.string(value).upper()
|
||||
if 'R' not in value:
|
||||
if "R" not in value:
|
||||
raise cv.Invalid("Must have R in type")
|
||||
if 'G' not in value:
|
||||
if "G" not in value:
|
||||
raise cv.Invalid("Must have G in type")
|
||||
if 'B' not in value:
|
||||
if "B" not in value:
|
||||
raise cv.Invalid("Must have B in type")
|
||||
rest = set(value) - set('RGBW')
|
||||
rest = set(value) - set("RGBW")
|
||||
if rest:
|
||||
raise cv.Invalid("Type has invalid color: {}".format(', '.join(rest)))
|
||||
raise cv.Invalid("Type has invalid color: {}".format(", ".join(rest)))
|
||||
if len(set(value)) != len(value):
|
||||
raise cv.Invalid("Type has duplicate color!")
|
||||
return value
|
||||
@ -35,45 +48,45 @@ def validate_type(value):
|
||||
|
||||
def validate_variant(value):
|
||||
value = cv.string(value).upper()
|
||||
if value == 'WS2813':
|
||||
value = 'WS2812X'
|
||||
if value == 'WS2812':
|
||||
value = '800KBPS'
|
||||
if value == 'LC8812':
|
||||
value = 'SK6812'
|
||||
if value == "WS2813":
|
||||
value = "WS2812X"
|
||||
if value == "WS2812":
|
||||
value = "800KBPS"
|
||||
if value == "LC8812":
|
||||
value = "SK6812"
|
||||
return cv.one_of(*VARIANTS)(value)
|
||||
|
||||
|
||||
def validate_method(value):
|
||||
if value is None:
|
||||
if CORE.is_esp32:
|
||||
return 'ESP32_I2S_1'
|
||||
return "ESP32_I2S_1"
|
||||
if CORE.is_esp8266:
|
||||
return 'ESP8266_DMA'
|
||||
return "ESP8266_DMA"
|
||||
raise NotImplementedError
|
||||
|
||||
if CORE.is_esp32:
|
||||
return cv.one_of(*ESP32_METHODS, upper=True, space='_')(value)
|
||||
return cv.one_of(*ESP32_METHODS, upper=True, space="_")(value)
|
||||
if CORE.is_esp8266:
|
||||
return cv.one_of(*ESP8266_METHODS, upper=True, space='_')(value)
|
||||
return cv.one_of(*ESP8266_METHODS, upper=True, space="_")(value)
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
def validate_method_pin(value):
|
||||
method = value[CONF_METHOD]
|
||||
method_pins = {
|
||||
'ESP8266_DMA': [3],
|
||||
'ESP8266_UART0': [1],
|
||||
'ESP8266_ASYNC_UART0': [1],
|
||||
'ESP8266_UART1': [2],
|
||||
'ESP8266_ASYNC_UART1': [2],
|
||||
'ESP32_I2S_0': list(range(0, 32)),
|
||||
'ESP32_I2S_1': list(range(0, 32)),
|
||||
"ESP8266_DMA": [3],
|
||||
"ESP8266_UART0": [1],
|
||||
"ESP8266_ASYNC_UART0": [1],
|
||||
"ESP8266_UART1": [2],
|
||||
"ESP8266_ASYNC_UART1": [2],
|
||||
"ESP32_I2S_0": list(range(0, 32)),
|
||||
"ESP32_I2S_1": list(range(0, 32)),
|
||||
}
|
||||
if CORE.is_esp8266:
|
||||
method_pins['BIT_BANG'] = list(range(0, 16))
|
||||
method_pins["BIT_BANG"] = list(range(0, 16))
|
||||
elif CORE.is_esp32:
|
||||
method_pins['BIT_BANG'] = list(range(0, 32))
|
||||
method_pins["BIT_BANG"] = list(range(0, 32))
|
||||
pins_ = method_pins.get(method)
|
||||
if pins_ is None:
|
||||
# all pins allowed for this method
|
||||
@ -81,39 +94,42 @@ def validate_method_pin(value):
|
||||
|
||||
for opt in (CONF_PIN, CONF_CLOCK_PIN, CONF_DATA_PIN):
|
||||
if opt in value and value[opt] not in pins_:
|
||||
raise cv.Invalid("Method {} only supports pin(s) {}".format(
|
||||
method, ', '.join(f'GPIO{x}' for x in pins_)
|
||||
), path=[CONF_METHOD])
|
||||
raise cv.Invalid(
|
||||
"Method {} only supports pin(s) {}".format(
|
||||
method, ", ".join(f"GPIO{x}" for x in pins_)
|
||||
),
|
||||
path=[CONF_METHOD],
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
VARIANTS = {
|
||||
'WS2812X': 'Ws2812x',
|
||||
'SK6812': 'Sk6812',
|
||||
'800KBPS': '800Kbps',
|
||||
'400KBPS': '400Kbps',
|
||||
"WS2812X": "Ws2812x",
|
||||
"SK6812": "Sk6812",
|
||||
"800KBPS": "800Kbps",
|
||||
"400KBPS": "400Kbps",
|
||||
}
|
||||
|
||||
ESP8266_METHODS = {
|
||||
'ESP8266_DMA': 'NeoEsp8266Dma{}Method',
|
||||
'ESP8266_UART0': 'NeoEsp8266Uart0{}Method',
|
||||
'ESP8266_UART1': 'NeoEsp8266Uart1{}Method',
|
||||
'ESP8266_ASYNC_UART0': 'NeoEsp8266AsyncUart0{}Method',
|
||||
'ESP8266_ASYNC_UART1': 'NeoEsp8266AsyncUart1{}Method',
|
||||
'BIT_BANG': 'NeoEsp8266BitBang{}Method',
|
||||
"ESP8266_DMA": "NeoEsp8266Dma{}Method",
|
||||
"ESP8266_UART0": "NeoEsp8266Uart0{}Method",
|
||||
"ESP8266_UART1": "NeoEsp8266Uart1{}Method",
|
||||
"ESP8266_ASYNC_UART0": "NeoEsp8266AsyncUart0{}Method",
|
||||
"ESP8266_ASYNC_UART1": "NeoEsp8266AsyncUart1{}Method",
|
||||
"BIT_BANG": "NeoEsp8266BitBang{}Method",
|
||||
}
|
||||
ESP32_METHODS = {
|
||||
'ESP32_I2S_0': 'NeoEsp32I2s0{}Method',
|
||||
'ESP32_I2S_1': 'NeoEsp32I2s1{}Method',
|
||||
'ESP32_RMT_0': 'NeoEsp32Rmt0{}Method',
|
||||
'ESP32_RMT_1': 'NeoEsp32Rmt1{}Method',
|
||||
'ESP32_RMT_2': 'NeoEsp32Rmt2{}Method',
|
||||
'ESP32_RMT_3': 'NeoEsp32Rmt3{}Method',
|
||||
'ESP32_RMT_4': 'NeoEsp32Rmt4{}Method',
|
||||
'ESP32_RMT_5': 'NeoEsp32Rmt5{}Method',
|
||||
'ESP32_RMT_6': 'NeoEsp32Rmt6{}Method',
|
||||
'ESP32_RMT_7': 'NeoEsp32Rmt7{}Method',
|
||||
'BIT_BANG': 'NeoEsp32BitBang{}Method',
|
||||
"ESP32_I2S_0": "NeoEsp32I2s0{}Method",
|
||||
"ESP32_I2S_1": "NeoEsp32I2s1{}Method",
|
||||
"ESP32_RMT_0": "NeoEsp32Rmt0{}Method",
|
||||
"ESP32_RMT_1": "NeoEsp32Rmt1{}Method",
|
||||
"ESP32_RMT_2": "NeoEsp32Rmt2{}Method",
|
||||
"ESP32_RMT_3": "NeoEsp32Rmt3{}Method",
|
||||
"ESP32_RMT_4": "NeoEsp32Rmt4{}Method",
|
||||
"ESP32_RMT_5": "NeoEsp32Rmt5{}Method",
|
||||
"ESP32_RMT_6": "NeoEsp32Rmt6{}Method",
|
||||
"ESP32_RMT_7": "NeoEsp32Rmt7{}Method",
|
||||
"BIT_BANG": "NeoEsp32BitBang{}Method",
|
||||
}
|
||||
|
||||
|
||||
@ -122,10 +138,10 @@ def format_method(config):
|
||||
method = config[CONF_METHOD]
|
||||
|
||||
if config[CONF_INVERT]:
|
||||
if method == 'ESP8266_DMA':
|
||||
variant = 'Inverted' + variant
|
||||
if method == "ESP8266_DMA":
|
||||
variant = "Inverted" + variant
|
||||
else:
|
||||
variant += 'Inverted'
|
||||
variant += "Inverted"
|
||||
|
||||
if CORE.is_esp8266:
|
||||
return ESP8266_METHODS[method].format(variant)
|
||||
@ -146,23 +162,27 @@ def validate(config):
|
||||
raise cv.Invalid("Must specify at least one of 'pin' or 'clock_pin'+'data_pin'")
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(light.ADDRESSABLE_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(NeoPixelBusLightOutputBase),
|
||||
|
||||
cv.Optional(CONF_TYPE, default='GRB'): validate_type,
|
||||
cv.Optional(CONF_VARIANT, default='800KBPS'): validate_variant,
|
||||
cv.Optional(CONF_METHOD, default=None): validate_method,
|
||||
cv.Optional(CONF_INVERT, default='no'): cv.boolean,
|
||||
cv.Optional(CONF_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_CLOCK_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_DATA_PIN): pins.output_pin,
|
||||
|
||||
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||
}).extend(cv.COMPONENT_SCHEMA), validate, validate_method_pin)
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(NeoPixelBusLightOutputBase),
|
||||
cv.Optional(CONF_TYPE, default="GRB"): validate_type,
|
||||
cv.Optional(CONF_VARIANT, default="800KBPS"): validate_variant,
|
||||
cv.Optional(CONF_METHOD, default=None): validate_method,
|
||||
cv.Optional(CONF_INVERT, default="no"): cv.boolean,
|
||||
cv.Optional(CONF_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_CLOCK_PIN): pins.output_pin,
|
||||
cv.Optional(CONF_DATA_PIN): pins.output_pin,
|
||||
cv.Required(CONF_NUM_LEDS): cv.positive_not_null_int,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA),
|
||||
validate,
|
||||
validate_method_pin,
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
has_white = 'W' in config[CONF_TYPE]
|
||||
has_white = "W" in config[CONF_TYPE]
|
||||
template = cg.TemplateArguments(getattr(cg.global_ns, format_method(config)))
|
||||
if has_white:
|
||||
out_type = NeoPixelRGBWLightOutput.template(template)
|
||||
@ -176,9 +196,13 @@ def to_code(config):
|
||||
if CONF_PIN in config:
|
||||
cg.add(var.add_leds(config[CONF_NUM_LEDS], config[CONF_PIN]))
|
||||
else:
|
||||
cg.add(var.add_leds(config[CONF_NUM_LEDS], config[CONF_CLOCK_PIN], config[CONF_DATA_PIN]))
|
||||
cg.add(
|
||||
var.add_leds(
|
||||
config[CONF_NUM_LEDS], config[CONF_CLOCK_PIN], config[CONF_DATA_PIN]
|
||||
)
|
||||
)
|
||||
|
||||
cg.add(var.set_pixel_order(getattr(ESPNeoPixelOrder, config[CONF_TYPE])))
|
||||
|
||||
# https://github.com/Makuna/NeoPixelBus/blob/master/library.json
|
||||
cg.add_library('NeoPixelBus-esphome', '2.5.7')
|
||||
cg.add_library("NeoPixelBus-esphome", "2.5.7")
|
||||
|
@ -1,2 +1,2 @@
|
||||
# Dummy package to allow components to depend on network
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
|
@ -1,3 +1,3 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
nextion_ns = cg.esphome_ns.namespace('nextion')
|
||||
nextion_ns = cg.esphome_ns.namespace("nextion")
|
||||
|
@ -5,19 +5,22 @@ from esphome.const import CONF_COMPONENT_ID, CONF_PAGE_ID, CONF_ID
|
||||
from . import nextion_ns
|
||||
from .display import Nextion
|
||||
|
||||
DEPENDENCIES = ['display']
|
||||
DEPENDENCIES = ["display"]
|
||||
|
||||
CONF_NEXTION_ID = 'nextion_id'
|
||||
CONF_NEXTION_ID = "nextion_id"
|
||||
|
||||
NextionTouchComponent = nextion_ns.class_('NextionTouchComponent', binary_sensor.BinarySensor)
|
||||
NextionTouchComponent = nextion_ns.class_(
|
||||
"NextionTouchComponent", binary_sensor.BinarySensor
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(NextionTouchComponent),
|
||||
cv.GenerateID(CONF_NEXTION_ID): cv.use_id(Nextion),
|
||||
|
||||
cv.Required(CONF_PAGE_ID): cv.uint8_t,
|
||||
cv.Required(CONF_COMPONENT_ID): cv.uint8_t,
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(NextionTouchComponent),
|
||||
cv.GenerateID(CONF_NEXTION_ID): cv.use_id(Nextion),
|
||||
cv.Required(CONF_PAGE_ID): cv.uint8_t,
|
||||
cv.Required(CONF_COMPONENT_ID): cv.uint8_t,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,16 +4,22 @@ from esphome.components import display, uart
|
||||
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_BRIGHTNESS
|
||||
from . import nextion_ns
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
AUTO_LOAD = ['binary_sensor']
|
||||
DEPENDENCIES = ["uart"]
|
||||
AUTO_LOAD = ["binary_sensor"]
|
||||
|
||||
Nextion = nextion_ns.class_('Nextion', cg.PollingComponent, uart.UARTDevice)
|
||||
NextionRef = Nextion.operator('ref')
|
||||
Nextion = nextion_ns.class_("Nextion", cg.PollingComponent, uart.UARTDevice)
|
||||
NextionRef = Nextion.operator("ref")
|
||||
|
||||
CONFIG_SCHEMA = display.BASIC_DISPLAY_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(Nextion),
|
||||
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||
}).extend(cv.polling_component_schema('5s')).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
display.BASIC_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(Nextion),
|
||||
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("5s"))
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -24,8 +30,9 @@ def to_code(config):
|
||||
if CONF_BRIGHTNESS in config:
|
||||
cg.add(var.set_brightness(config[CONF_BRIGHTNESS]))
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(NextionRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(NextionRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
||||
yield display.register_display(var, config)
|
||||
|
@ -1,7 +1,7 @@
|
||||
import esphome.codegen as cg
|
||||
|
||||
CODEOWNERS = ['@jesserockz']
|
||||
CODEOWNERS = ["@jesserockz"]
|
||||
|
||||
nfc_ns = cg.esphome_ns.namespace('nfc')
|
||||
nfc_ns = cg.esphome_ns.namespace("nfc")
|
||||
|
||||
NfcTag = nfc_ns.class_('NfcTag')
|
||||
NfcTag = nfc_ns.class_("NfcTag")
|
||||
|
@ -3,37 +3,50 @@ from math import log
|
||||
import esphome.config_validation as cv
|
||||
import esphome.codegen as cg
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_CALIBRATION, CONF_ID, CONF_REFERENCE_RESISTANCE, \
|
||||
CONF_REFERENCE_TEMPERATURE, CONF_SENSOR, CONF_TEMPERATURE, CONF_VALUE, \
|
||||
DEVICE_CLASS_TEMPERATURE, ICON_EMPTY, UNIT_CELSIUS
|
||||
from esphome.const import (
|
||||
CONF_CALIBRATION,
|
||||
CONF_ID,
|
||||
CONF_REFERENCE_RESISTANCE,
|
||||
CONF_REFERENCE_TEMPERATURE,
|
||||
CONF_SENSOR,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_VALUE,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_EMPTY,
|
||||
UNIT_CELSIUS,
|
||||
)
|
||||
|
||||
ntc_ns = cg.esphome_ns.namespace('ntc')
|
||||
NTC = ntc_ns.class_('NTC', cg.Component, sensor.Sensor)
|
||||
ntc_ns = cg.esphome_ns.namespace("ntc")
|
||||
NTC = ntc_ns.class_("NTC", cg.Component, sensor.Sensor)
|
||||
|
||||
CONF_B_CONSTANT = 'b_constant'
|
||||
CONF_A = 'a'
|
||||
CONF_B = 'b'
|
||||
CONF_C = 'c'
|
||||
CONF_B_CONSTANT = "b_constant"
|
||||
CONF_A = "a"
|
||||
CONF_B = "b"
|
||||
CONF_C = "c"
|
||||
ZERO_POINT = 273.15
|
||||
|
||||
|
||||
def validate_calibration_parameter(value):
|
||||
if isinstance(value, dict):
|
||||
return cv.Schema({
|
||||
cv.Required(CONF_TEMPERATURE): cv.float_,
|
||||
cv.Required(CONF_VALUE): cv.float_,
|
||||
})(value)
|
||||
return cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_TEMPERATURE): cv.float_,
|
||||
cv.Required(CONF_VALUE): cv.float_,
|
||||
}
|
||||
)(value)
|
||||
|
||||
value = cv.string(value)
|
||||
parts = value.split('->')
|
||||
parts = value.split("->")
|
||||
if len(parts) != 2:
|
||||
raise cv.Invalid("Calibration parameter must be of form 3000 -> 23°C")
|
||||
voltage = cv.resistance(parts[0].strip())
|
||||
temperature = cv.temperature(parts[1].strip())
|
||||
return validate_calibration_parameter({
|
||||
CONF_TEMPERATURE: temperature,
|
||||
CONF_VALUE: voltage,
|
||||
})
|
||||
return validate_calibration_parameter(
|
||||
{
|
||||
CONF_TEMPERATURE: temperature,
|
||||
CONF_VALUE: voltage,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def calc_steinhart_hart(value):
|
||||
@ -48,16 +61,16 @@ def calc_steinhart_hart(value):
|
||||
l2 = log(r2)
|
||||
l3 = log(r3)
|
||||
|
||||
y1 = 1/t1
|
||||
y2 = 1/t2
|
||||
y3 = 1/t3
|
||||
y1 = 1 / t1
|
||||
y2 = 1 / t2
|
||||
y3 = 1 / t3
|
||||
|
||||
g2 = (y2-y1)/(l2-l1)
|
||||
g3 = (y3-y1)/(l3-l1)
|
||||
g2 = (y2 - y1) / (l2 - l1)
|
||||
g3 = (y3 - y1) / (l3 - l1)
|
||||
|
||||
c = (g3-g2)/(l3-l2) * 1/(l1+l2+l3)
|
||||
b = g2 - c*(l1*l1 + l1*l2 + l2*l2)
|
||||
a = y1 - (b + l1*l1*c) * l1
|
||||
c = (g3 - g2) / (l3 - l2) * 1 / (l1 + l2 + l3)
|
||||
b = g2 - c * (l1 * l1 + l1 * l2 + l2 * l2)
|
||||
a = y1 - (b + l1 * l1 * c) * l1
|
||||
return a, b, c
|
||||
|
||||
|
||||
@ -66,8 +79,8 @@ def calc_b(value):
|
||||
t0 = value[CONF_REFERENCE_TEMPERATURE] + ZERO_POINT
|
||||
r0 = value[CONF_REFERENCE_RESISTANCE]
|
||||
|
||||
a = (1/t0) - (1/beta) * log(r0)
|
||||
b = 1/beta
|
||||
a = (1 / t0) - (1 / beta) * log(r0)
|
||||
b = 1 / beta
|
||||
c = 0
|
||||
|
||||
return a, b, c
|
||||
@ -75,21 +88,27 @@ def calc_b(value):
|
||||
|
||||
def process_calibration(value):
|
||||
if isinstance(value, dict):
|
||||
value = cv.Schema({
|
||||
cv.Required(CONF_B_CONSTANT): cv.float_,
|
||||
cv.Required(CONF_REFERENCE_TEMPERATURE): cv.temperature,
|
||||
cv.Required(CONF_REFERENCE_RESISTANCE): cv.resistance,
|
||||
})(value)
|
||||
value = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_B_CONSTANT): cv.float_,
|
||||
cv.Required(CONF_REFERENCE_TEMPERATURE): cv.temperature,
|
||||
cv.Required(CONF_REFERENCE_RESISTANCE): cv.resistance,
|
||||
}
|
||||
)(value)
|
||||
a, b, c = calc_b(value)
|
||||
elif isinstance(value, list):
|
||||
if len(value) != 3:
|
||||
raise cv.Invalid("Steinhart–Hart Calibration must consist of exactly three values")
|
||||
raise cv.Invalid(
|
||||
"Steinhart–Hart Calibration must consist of exactly three values"
|
||||
)
|
||||
value = cv.Schema([validate_calibration_parameter])(value)
|
||||
a, b, c = calc_steinhart_hart(value)
|
||||
else:
|
||||
raise cv.Invalid("Calibration parameter accepts either a list for steinhart-hart "
|
||||
"calibration, or mapping for b-constant calibration, "
|
||||
"not {}".format(type(value)))
|
||||
raise cv.Invalid(
|
||||
"Calibration parameter accepts either a list for steinhart-hart "
|
||||
"calibration, or mapping for b-constant calibration, "
|
||||
"not {}".format(type(value))
|
||||
)
|
||||
|
||||
return {
|
||||
CONF_A: a,
|
||||
@ -98,11 +117,17 @@ def process_calibration(value):
|
||||
}
|
||||
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE).extend({
|
||||
cv.GenerateID(): cv.declare_id(NTC),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_CALIBRATION): process_calibration,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(NTC),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_CALIBRATION): process_calibration,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -2,25 +2,33 @@ from esphome.cpp_generator import RawExpression
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.const import (
|
||||
CONF_ID, CONF_NUM_ATTEMPTS, CONF_PASSWORD,
|
||||
CONF_PORT, CONF_REBOOT_TIMEOUT, CONF_SAFE_MODE
|
||||
CONF_ID,
|
||||
CONF_NUM_ATTEMPTS,
|
||||
CONF_PASSWORD,
|
||||
CONF_PORT,
|
||||
CONF_REBOOT_TIMEOUT,
|
||||
CONF_SAFE_MODE,
|
||||
)
|
||||
from esphome.core import CORE, coroutine_with_priority
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
DEPENDENCIES = ['network']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
DEPENDENCIES = ["network"]
|
||||
|
||||
ota_ns = cg.esphome_ns.namespace('ota')
|
||||
OTAComponent = ota_ns.class_('OTAComponent', cg.Component)
|
||||
ota_ns = cg.esphome_ns.namespace("ota")
|
||||
OTAComponent = ota_ns.class_("OTAComponent", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(OTAComponent),
|
||||
cv.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
|
||||
cv.SplitDefault(CONF_PORT, esp8266=8266, esp32=3232): cv.port,
|
||||
cv.Optional(CONF_PASSWORD, default=''): cv.string,
|
||||
cv.Optional(CONF_REBOOT_TIMEOUT, default='5min'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_NUM_ATTEMPTS, default='10'): cv.positive_not_null_int
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(OTAComponent),
|
||||
cv.Optional(CONF_SAFE_MODE, default=True): cv.boolean,
|
||||
cv.SplitDefault(CONF_PORT, esp8266=8266, esp32=3232): cv.port,
|
||||
cv.Optional(CONF_PASSWORD, default=""): cv.string,
|
||||
cv.Optional(
|
||||
CONF_REBOOT_TIMEOUT, default="5min"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_NUM_ATTEMPTS, default="10"): cv.positive_not_null_int,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
@coroutine_with_priority(50.0)
|
||||
@ -32,11 +40,12 @@ def to_code(config):
|
||||
yield cg.register_component(var, config)
|
||||
|
||||
if config[CONF_SAFE_MODE]:
|
||||
condition = var.should_enter_safe_mode(config[CONF_NUM_ATTEMPTS],
|
||||
config[CONF_REBOOT_TIMEOUT])
|
||||
condition = var.should_enter_safe_mode(
|
||||
config[CONF_NUM_ATTEMPTS], config[CONF_REBOOT_TIMEOUT]
|
||||
)
|
||||
cg.add(RawExpression(f"if ({condition}) return"))
|
||||
|
||||
if CORE.is_esp8266:
|
||||
cg.add_library('Update', None)
|
||||
cg.add_library("Update", None)
|
||||
elif CORE.is_esp32:
|
||||
cg.add_library('Hash', None)
|
||||
cg.add_library("Hash", None)
|
||||
|
@ -3,34 +3,44 @@ import esphome.config_validation as cv
|
||||
from esphome import automation
|
||||
from esphome.automation import maybe_simple_id
|
||||
from esphome.components import power_supply
|
||||
from esphome.const import CONF_ID, CONF_INVERTED, CONF_LEVEL, CONF_MAX_POWER, \
|
||||
CONF_MIN_POWER, CONF_POWER_SUPPLY
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
CONF_INVERTED,
|
||||
CONF_LEVEL,
|
||||
CONF_MAX_POWER,
|
||||
CONF_MIN_POWER,
|
||||
CONF_POWER_SUPPLY,
|
||||
)
|
||||
from esphome.core import CORE, coroutine
|
||||
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
IS_PLATFORM_COMPONENT = True
|
||||
|
||||
BINARY_OUTPUT_SCHEMA = cv.Schema({
|
||||
cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
|
||||
cv.Optional(CONF_INVERTED): cv.boolean,
|
||||
})
|
||||
BINARY_OUTPUT_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Optional(CONF_POWER_SUPPLY): cv.use_id(power_supply.PowerSupply),
|
||||
cv.Optional(CONF_INVERTED): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend({
|
||||
cv.Optional(CONF_MAX_POWER): cv.percentage,
|
||||
cv.Optional(CONF_MIN_POWER): cv.percentage,
|
||||
})
|
||||
FLOAT_OUTPUT_SCHEMA = BINARY_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Optional(CONF_MAX_POWER): cv.percentage,
|
||||
cv.Optional(CONF_MIN_POWER): cv.percentage,
|
||||
}
|
||||
)
|
||||
|
||||
output_ns = cg.esphome_ns.namespace('output')
|
||||
BinaryOutput = output_ns.class_('BinaryOutput')
|
||||
BinaryOutputPtr = BinaryOutput.operator('ptr')
|
||||
FloatOutput = output_ns.class_('FloatOutput', BinaryOutput)
|
||||
FloatOutputPtr = FloatOutput.operator('ptr')
|
||||
output_ns = cg.esphome_ns.namespace("output")
|
||||
BinaryOutput = output_ns.class_("BinaryOutput")
|
||||
BinaryOutputPtr = BinaryOutput.operator("ptr")
|
||||
FloatOutput = output_ns.class_("FloatOutput", BinaryOutput)
|
||||
FloatOutputPtr = FloatOutput.operator("ptr")
|
||||
|
||||
# Actions
|
||||
TurnOffAction = output_ns.class_('TurnOffAction', automation.Action)
|
||||
TurnOnAction = output_ns.class_('TurnOnAction', automation.Action)
|
||||
SetLevelAction = output_ns.class_('SetLevelAction', automation.Action)
|
||||
TurnOffAction = output_ns.class_("TurnOffAction", automation.Action)
|
||||
TurnOnAction = output_ns.class_("TurnOnAction", automation.Action)
|
||||
SetLevelAction = output_ns.class_("SetLevelAction", automation.Action)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -53,27 +63,37 @@ def register_output(var, config):
|
||||
yield setup_output_platform_(var, config)
|
||||
|
||||
|
||||
BINARY_OUTPUT_ACTION_SCHEMA = maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(BinaryOutput),
|
||||
})
|
||||
BINARY_OUTPUT_ACTION_SCHEMA = maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(BinaryOutput),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@automation.register_action('output.turn_on', TurnOnAction, BINARY_OUTPUT_ACTION_SCHEMA)
|
||||
@automation.register_action("output.turn_on", TurnOnAction, BINARY_OUTPUT_ACTION_SCHEMA)
|
||||
def output_turn_on_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('output.turn_off', TurnOffAction, BINARY_OUTPUT_ACTION_SCHEMA)
|
||||
@automation.register_action(
|
||||
"output.turn_off", TurnOffAction, BINARY_OUTPUT_ACTION_SCHEMA
|
||||
)
|
||||
def output_turn_off_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('output.set_level', SetLevelAction, cv.Schema({
|
||||
cv.Required(CONF_ID): cv.use_id(FloatOutput),
|
||||
cv.Required(CONF_LEVEL): cv.templatable(cv.percentage),
|
||||
}))
|
||||
@automation.register_action(
|
||||
"output.set_level",
|
||||
SetLevelAction,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(FloatOutput),
|
||||
cv.Required(CONF_LEVEL): cv.templatable(cv.percentage),
|
||||
}
|
||||
),
|
||||
)
|
||||
def output_set_level_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
@ -4,12 +4,14 @@ from esphome.components import output, switch
|
||||
from esphome.const import CONF_ID, CONF_OUTPUT
|
||||
from .. import output_ns
|
||||
|
||||
OutputSwitch = output_ns.class_('OutputSwitch', switch.Switch, cg.Component)
|
||||
OutputSwitch = output_ns.class_("OutputSwitch", switch.Switch, cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(OutputSwitch),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = switch.SWITCH_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(OutputSwitch),
|
||||
cv.Required(CONF_OUTPUT): cv.use_id(output.BinaryOutput),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,7 +4,6 @@ from esphome.const import CONF_PACKAGES
|
||||
|
||||
|
||||
def _merge_package(full_old, full_new):
|
||||
|
||||
def merge(old, new):
|
||||
# pylint: disable=no-else-return
|
||||
if isinstance(new, dict):
|
||||
@ -30,8 +29,10 @@ def do_packages_pass(config: dict):
|
||||
packages = config[CONF_PACKAGES]
|
||||
with cv.prepend_path(CONF_PACKAGES):
|
||||
if not isinstance(packages, dict):
|
||||
raise cv.Invalid("Packages must be a key to value mapping, got {} instead"
|
||||
"".format(type(packages)))
|
||||
raise cv.Invalid(
|
||||
"Packages must be a key to value mapping, got {} instead"
|
||||
"".format(type(packages))
|
||||
)
|
||||
|
||||
for package_name, package_config in packages.items():
|
||||
with cv.prepend_path(package_name):
|
||||
|
@ -3,34 +3,49 @@ import esphome.config_validation as cv
|
||||
from esphome.components import light
|
||||
from esphome.const import CONF_FROM, CONF_ID, CONF_SEGMENTS, CONF_TO, CONF_OUTPUT_ID
|
||||
|
||||
partitions_ns = cg.esphome_ns.namespace('partition')
|
||||
AddressableSegment = partitions_ns.class_('AddressableSegment')
|
||||
PartitionLightOutput = partitions_ns.class_('PartitionLightOutput', light.AddressableLight)
|
||||
partitions_ns = cg.esphome_ns.namespace("partition")
|
||||
AddressableSegment = partitions_ns.class_("AddressableSegment")
|
||||
PartitionLightOutput = partitions_ns.class_(
|
||||
"PartitionLightOutput", light.AddressableLight
|
||||
)
|
||||
|
||||
|
||||
def validate_from_to(value):
|
||||
if value[CONF_FROM] > value[CONF_TO]:
|
||||
raise cv.Invalid("From ({}) must not be larger than to ({})"
|
||||
"".format(value[CONF_FROM], value[CONF_TO]))
|
||||
raise cv.Invalid(
|
||||
"From ({}) must not be larger than to ({})"
|
||||
"".format(value[CONF_FROM], value[CONF_TO])
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend({
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(PartitionLightOutput),
|
||||
cv.Required(CONF_SEGMENTS): cv.All(cv.ensure_list({
|
||||
cv.Required(CONF_ID): cv.use_id(light.AddressableLightState),
|
||||
cv.Required(CONF_FROM): cv.positive_int,
|
||||
cv.Required(CONF_TO): cv.positive_int,
|
||||
}, validate_from_to), cv.Length(min=1)),
|
||||
})
|
||||
CONFIG_SCHEMA = light.ADDRESSABLE_LIGHT_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(PartitionLightOutput),
|
||||
cv.Required(CONF_SEGMENTS): cv.All(
|
||||
cv.ensure_list(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(light.AddressableLightState),
|
||||
cv.Required(CONF_FROM): cv.positive_int,
|
||||
cv.Required(CONF_TO): cv.positive_int,
|
||||
},
|
||||
validate_from_to,
|
||||
),
|
||||
cv.Length(min=1),
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
segments = []
|
||||
for conf in config[CONF_SEGMENTS]:
|
||||
var = yield cg.get_variable(conf[CONF_ID])
|
||||
segments.append(AddressableSegment(var, conf[CONF_FROM],
|
||||
conf[CONF_TO] - conf[CONF_FROM] + 1))
|
||||
segments.append(
|
||||
AddressableSegment(
|
||||
var, conf[CONF_FROM], conf[CONF_TO] - conf[CONF_FROM] + 1
|
||||
)
|
||||
)
|
||||
|
||||
var = cg.new_Pvariable(config[CONF_OUTPUT_ID], segments)
|
||||
yield cg.register_component(var, config)
|
||||
|
@ -3,17 +3,24 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_FREQUENCY, CONF_ID
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
pca9685_ns = cg.esphome_ns.namespace('pca9685')
|
||||
PCA9685Output = pca9685_ns.class_('PCA9685Output', cg.Component, i2c.I2CDevice)
|
||||
pca9685_ns = cg.esphome_ns.namespace("pca9685")
|
||||
PCA9685Output = pca9685_ns.class_("PCA9685Output", cg.Component, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PCA9685Output),
|
||||
cv.Required(CONF_FREQUENCY): cv.All(cv.frequency,
|
||||
cv.Range(min=23.84, max=1525.88)),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x40))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PCA9685Output),
|
||||
cv.Required(CONF_FREQUENCY): cv.All(
|
||||
cv.frequency, cv.Range(min=23.84, max=1525.88)
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x40))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,17 +4,18 @@ from esphome.components import output
|
||||
from esphome.const import CONF_CHANNEL, CONF_ID
|
||||
from . import PCA9685Output, pca9685_ns
|
||||
|
||||
DEPENDENCIES = ['pca9685']
|
||||
DEPENDENCIES = ["pca9685"]
|
||||
|
||||
PCA9685Channel = pca9685_ns.class_('PCA9685Channel', output.FloatOutput)
|
||||
CONF_PCA9685_ID = 'pca9685_id'
|
||||
PCA9685Channel = pca9685_ns.class_("PCA9685Channel", output.FloatOutput)
|
||||
CONF_PCA9685_ID = "pca9685_id"
|
||||
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend({
|
||||
cv.Required(CONF_ID): cv.declare_id(PCA9685Channel),
|
||||
cv.GenerateID(CONF_PCA9685_ID): cv.use_id(PCA9685Output),
|
||||
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=15),
|
||||
})
|
||||
CONFIG_SCHEMA = output.FLOAT_OUTPUT_SCHEMA.extend(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(PCA9685Channel),
|
||||
cv.GenerateID(CONF_PCA9685_ID): cv.use_id(PCA9685Output),
|
||||
cv.Required(CONF_CHANNEL): cv.int_range(min=0, max=15),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,23 +3,37 @@ import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import display, spi
|
||||
from esphome.const import (
|
||||
CONF_DC_PIN, CONF_ID, CONF_LAMBDA, CONF_PAGES, CONF_RESET_PIN, CONF_CS_PIN, CONF_CONTRAST
|
||||
CONF_DC_PIN,
|
||||
CONF_ID,
|
||||
CONF_LAMBDA,
|
||||
CONF_PAGES,
|
||||
CONF_RESET_PIN,
|
||||
CONF_CS_PIN,
|
||||
CONF_CONTRAST,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['spi']
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
pcd8544_ns = cg.esphome_ns.namespace('pcd8544')
|
||||
PCD8544 = pcd8544_ns.class_('PCD8544', cg.PollingComponent, display.DisplayBuffer, spi.SPIDevice)
|
||||
pcd8544_ns = cg.esphome_ns.namespace("pcd8544")
|
||||
PCD8544 = pcd8544_ns.class_(
|
||||
"PCD8544", cg.PollingComponent, display.DisplayBuffer, spi.SPIDevice
|
||||
)
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.All(display.FULL_DISPLAY_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PCD8544),
|
||||
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, # CE
|
||||
cv.Optional(CONF_CONTRAST, default=0x7f): cv.int_,
|
||||
}).extend(cv.polling_component_schema('1s')).extend(spi.spi_device_schema()),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
display.FULL_DISPLAY_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PCD8544),
|
||||
cv.Required(CONF_DC_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_RESET_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Required(CONF_CS_PIN): pins.gpio_output_pin_schema, # CE
|
||||
cv.Optional(CONF_CONTRAST, default=0x7F): cv.int_,
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("1s"))
|
||||
.extend(spi.spi_device_schema()),
|
||||
cv.has_at_most_one_key(CONF_PAGES, CONF_LAMBDA),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -37,6 +51,7 @@ def to_code(config):
|
||||
cg.add(var.set_contrast(config[CONF_CONTRAST]))
|
||||
|
||||
if CONF_LAMBDA in config:
|
||||
lambda_ = yield cg.process_lambda(config[CONF_LAMBDA], [(display.DisplayBufferRef, 'it')],
|
||||
return_type=cg.void)
|
||||
lambda_ = yield cg.process_lambda(
|
||||
config[CONF_LAMBDA], [(display.DisplayBufferRef, "it")], return_type=cg.void
|
||||
)
|
||||
cg.add(var.set_writer(lambda_))
|
||||
|
@ -4,25 +4,31 @@ from esphome import pins
|
||||
from esphome.components import i2c
|
||||
from esphome.const import CONF_ID, CONF_NUMBER, CONF_MODE, CONF_INVERTED
|
||||
|
||||
DEPENDENCIES = ['i2c']
|
||||
DEPENDENCIES = ["i2c"]
|
||||
MULTI_CONF = True
|
||||
|
||||
pcf8574_ns = cg.esphome_ns.namespace('pcf8574')
|
||||
PCF8574GPIOMode = pcf8574_ns.enum('PCF8574GPIOMode')
|
||||
pcf8574_ns = cg.esphome_ns.namespace("pcf8574")
|
||||
PCF8574GPIOMode = pcf8574_ns.enum("PCF8574GPIOMode")
|
||||
PCF8674_GPIO_MODES = {
|
||||
'INPUT': PCF8574GPIOMode.PCF8574_INPUT,
|
||||
'OUTPUT': PCF8574GPIOMode.PCF8574_OUTPUT,
|
||||
"INPUT": PCF8574GPIOMode.PCF8574_INPUT,
|
||||
"OUTPUT": PCF8574GPIOMode.PCF8574_OUTPUT,
|
||||
}
|
||||
|
||||
PCF8574Component = pcf8574_ns.class_('PCF8574Component', cg.Component, i2c.I2CDevice)
|
||||
PCF8574GPIOPin = pcf8574_ns.class_('PCF8574GPIOPin', cg.GPIOPin)
|
||||
PCF8574Component = pcf8574_ns.class_("PCF8574Component", cg.Component, i2c.I2CDevice)
|
||||
PCF8574GPIOPin = pcf8574_ns.class_("PCF8574GPIOPin", cg.GPIOPin)
|
||||
|
||||
CONF_PCF8574 = 'pcf8574'
|
||||
CONF_PCF8575 = 'pcf8575'
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(PCF8574Component),
|
||||
cv.Optional(CONF_PCF8575, default=False): cv.boolean,
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(i2c.i2c_device_schema(0x21))
|
||||
CONF_PCF8574 = "pcf8574"
|
||||
CONF_PCF8575 = "pcf8575"
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(PCF8574Component),
|
||||
cv.Optional(CONF_PCF8575, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(i2c.i2c_device_schema(0x21))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -34,27 +40,37 @@ def to_code(config):
|
||||
|
||||
def validate_pcf8574_gpio_mode(value):
|
||||
value = cv.string(value)
|
||||
if value.upper() == 'INPUT_PULLUP':
|
||||
raise cv.Invalid("INPUT_PULLUP mode has been removed in 1.14 and been combined into "
|
||||
"INPUT mode (they were the same thing). Please use INPUT instead.")
|
||||
if value.upper() == "INPUT_PULLUP":
|
||||
raise cv.Invalid(
|
||||
"INPUT_PULLUP mode has been removed in 1.14 and been combined into "
|
||||
"INPUT mode (they were the same thing). Please use INPUT instead."
|
||||
)
|
||||
return cv.enum(PCF8674_GPIO_MODES, upper=True)(value)
|
||||
|
||||
|
||||
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): validate_pcf8574_gpio_mode,
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
PCF8574_INPUT_PIN_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): validate_pcf8574_gpio_mode,
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
})
|
||||
PCF8574_OUTPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="OUTPUT"): validate_pcf8574_gpio_mode,
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
PCF8574_INPUT_PIN_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_PCF8574): cv.use_id(PCF8574Component),
|
||||
cv.Required(CONF_NUMBER): cv.int_,
|
||||
cv.Optional(CONF_MODE, default="INPUT"): validate_pcf8574_gpio_mode,
|
||||
cv.Optional(CONF_INVERTED, default=False): cv.boolean,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pins.PIN_SCHEMA_REGISTRY.register('pcf8574', (PCF8574_OUTPUT_PIN_SCHEMA, PCF8574_INPUT_PIN_SCHEMA))
|
||||
@pins.PIN_SCHEMA_REGISTRY.register(
|
||||
"pcf8574", (PCF8574_OUTPUT_PIN_SCHEMA, PCF8574_INPUT_PIN_SCHEMA)
|
||||
)
|
||||
def pcf8574_pin_to_code(config):
|
||||
parent = yield cg.get_variable(config[CONF_PCF8574])
|
||||
yield PCF8574GPIOPin.new(parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED])
|
||||
yield PCF8574GPIOPin.new(
|
||||
parent, config[CONF_NUMBER], config[CONF_MODE], config[CONF_INVERTED]
|
||||
)
|
||||
|
@ -1 +1 @@
|
||||
CODEOWNERS = ['@OttoWinter']
|
||||
CODEOWNERS = ["@OttoWinter"]
|
||||
|
@ -4,40 +4,51 @@ from esphome import automation
|
||||
from esphome.components import climate, sensor, output
|
||||
from esphome.const import CONF_ID, CONF_SENSOR
|
||||
|
||||
pid_ns = cg.esphome_ns.namespace('pid')
|
||||
PIDClimate = pid_ns.class_('PIDClimate', climate.Climate, cg.Component)
|
||||
PIDAutotuneAction = pid_ns.class_('PIDAutotuneAction', automation.Action)
|
||||
PIDResetIntegralTermAction = pid_ns.class_('PIDResetIntegralTermAction', automation.Action)
|
||||
PIDSetControlParametersAction = pid_ns.class_('PIDSetControlParametersAction', automation.Action)
|
||||
pid_ns = cg.esphome_ns.namespace("pid")
|
||||
PIDClimate = pid_ns.class_("PIDClimate", climate.Climate, cg.Component)
|
||||
PIDAutotuneAction = pid_ns.class_("PIDAutotuneAction", automation.Action)
|
||||
PIDResetIntegralTermAction = pid_ns.class_(
|
||||
"PIDResetIntegralTermAction", automation.Action
|
||||
)
|
||||
PIDSetControlParametersAction = pid_ns.class_(
|
||||
"PIDSetControlParametersAction", automation.Action
|
||||
)
|
||||
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE = 'default_target_temperature'
|
||||
CONF_DEFAULT_TARGET_TEMPERATURE = "default_target_temperature"
|
||||
|
||||
CONF_KP = 'kp'
|
||||
CONF_KI = 'ki'
|
||||
CONF_KD = 'kd'
|
||||
CONF_CONTROL_PARAMETERS = 'control_parameters'
|
||||
CONF_COOL_OUTPUT = 'cool_output'
|
||||
CONF_HEAT_OUTPUT = 'heat_output'
|
||||
CONF_NOISEBAND = 'noiseband'
|
||||
CONF_POSITIVE_OUTPUT = 'positive_output'
|
||||
CONF_NEGATIVE_OUTPUT = 'negative_output'
|
||||
CONF_MIN_INTEGRAL = 'min_integral'
|
||||
CONF_MAX_INTEGRAL = 'max_integral'
|
||||
CONF_KP = "kp"
|
||||
CONF_KI = "ki"
|
||||
CONF_KD = "kd"
|
||||
CONF_CONTROL_PARAMETERS = "control_parameters"
|
||||
CONF_COOL_OUTPUT = "cool_output"
|
||||
CONF_HEAT_OUTPUT = "heat_output"
|
||||
CONF_NOISEBAND = "noiseband"
|
||||
CONF_POSITIVE_OUTPUT = "positive_output"
|
||||
CONF_NEGATIVE_OUTPUT = "negative_output"
|
||||
CONF_MIN_INTEGRAL = "min_integral"
|
||||
CONF_MAX_INTEGRAL = "max_integral"
|
||||
|
||||
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PIDClimate),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_COOL_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
cv.Optional(CONF_HEAT_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_CONTROL_PARAMETERS): cv.Schema({
|
||||
cv.Required(CONF_KP): cv.float_,
|
||||
cv.Optional(CONF_KI, default=0.0): cv.float_,
|
||||
cv.Optional(CONF_KD, default=0.0): cv.float_,
|
||||
cv.Optional(CONF_MIN_INTEGRAL, default=-1): cv.float_,
|
||||
cv.Optional(CONF_MAX_INTEGRAL, default=1): cv.float_,
|
||||
}),
|
||||
}), cv.has_at_least_one_key(CONF_COOL_OUTPUT, CONF_HEAT_OUTPUT))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
climate.CLIMATE_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PIDClimate),
|
||||
cv.Required(CONF_SENSOR): cv.use_id(sensor.Sensor),
|
||||
cv.Required(CONF_DEFAULT_TARGET_TEMPERATURE): cv.temperature,
|
||||
cv.Optional(CONF_COOL_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
cv.Optional(CONF_HEAT_OUTPUT): cv.use_id(output.FloatOutput),
|
||||
cv.Required(CONF_CONTROL_PARAMETERS): cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_KP): cv.float_,
|
||||
cv.Optional(CONF_KI, default=0.0): cv.float_,
|
||||
cv.Optional(CONF_KD, default=0.0): cv.float_,
|
||||
cv.Optional(CONF_MIN_INTEGRAL, default=-1): cv.float_,
|
||||
cv.Optional(CONF_MAX_INTEGRAL, default=1): cv.float_,
|
||||
}
|
||||
),
|
||||
}
|
||||
),
|
||||
cv.has_at_least_one_key(CONF_COOL_OUTPUT, CONF_HEAT_OUTPUT),
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -67,23 +78,35 @@ def to_code(config):
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
'climate.pid.reset_integral_term',
|
||||
"climate.pid.reset_integral_term",
|
||||
PIDResetIntegralTermAction,
|
||||
automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
})
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
}
|
||||
),
|
||||
)
|
||||
def pid_reset_integral_term(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
yield cg.new_Pvariable(action_id, template_arg, paren)
|
||||
|
||||
|
||||
@automation.register_action('climate.pid.autotune', PIDAutotuneAction, automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
cv.Optional(CONF_NOISEBAND, default=0.25): cv.float_,
|
||||
cv.Optional(CONF_POSITIVE_OUTPUT, default=1.0): cv.possibly_negative_percentage,
|
||||
cv.Optional(CONF_NEGATIVE_OUTPUT, default=-1.0): cv.possibly_negative_percentage,
|
||||
}))
|
||||
@automation.register_action(
|
||||
"climate.pid.autotune",
|
||||
PIDAutotuneAction,
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
cv.Optional(CONF_NOISEBAND, default=0.25): cv.float_,
|
||||
cv.Optional(
|
||||
CONF_POSITIVE_OUTPUT, default=1.0
|
||||
): cv.possibly_negative_percentage,
|
||||
cv.Optional(
|
||||
CONF_NEGATIVE_OUTPUT, default=-1.0
|
||||
): cv.possibly_negative_percentage,
|
||||
}
|
||||
),
|
||||
)
|
||||
def esp8266_set_frequency_to_code(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
var = cg.new_Pvariable(action_id, template_arg, paren)
|
||||
@ -94,14 +117,16 @@ def esp8266_set_frequency_to_code(config, action_id, template_arg, args):
|
||||
|
||||
|
||||
@automation.register_action(
|
||||
'climate.pid.set_control_parameters',
|
||||
"climate.pid.set_control_parameters",
|
||||
PIDSetControlParametersAction,
|
||||
automation.maybe_simple_id({
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
cv.Required(CONF_KP): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KI, default=0.0): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KD, default=0.0): cv.templatable(cv.float_),
|
||||
})
|
||||
automation.maybe_simple_id(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.use_id(PIDClimate),
|
||||
cv.Required(CONF_KP): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KI, default=0.0): cv.templatable(cv.float_),
|
||||
cv.Optional(CONF_KD, default=0.0): cv.templatable(cv.float_),
|
||||
}
|
||||
),
|
||||
)
|
||||
def set_control_parameters(config, action_id, template_arg, args):
|
||||
paren = yield cg.get_variable(config[CONF_ID])
|
||||
|
@ -1,32 +1,43 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY, UNIT_PERCENT, ICON_GAUGE, CONF_TYPE
|
||||
from esphome.const import (
|
||||
CONF_ID,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
UNIT_PERCENT,
|
||||
ICON_GAUGE,
|
||||
CONF_TYPE,
|
||||
)
|
||||
from ..climate import pid_ns, PIDClimate
|
||||
|
||||
PIDClimateSensor = pid_ns.class_('PIDClimateSensor', sensor.Sensor, cg.Component)
|
||||
PIDClimateSensorType = pid_ns.enum('PIDClimateSensorType')
|
||||
PIDClimateSensor = pid_ns.class_("PIDClimateSensor", sensor.Sensor, cg.Component)
|
||||
PIDClimateSensorType = pid_ns.enum("PIDClimateSensorType")
|
||||
|
||||
PID_CLIMATE_SENSOR_TYPES = {
|
||||
'RESULT': PIDClimateSensorType.PID_SENSOR_TYPE_RESULT,
|
||||
'ERROR': PIDClimateSensorType.PID_SENSOR_TYPE_ERROR,
|
||||
'PROPORTIONAL': PIDClimateSensorType.PID_SENSOR_TYPE_PROPORTIONAL,
|
||||
'INTEGRAL': PIDClimateSensorType.PID_SENSOR_TYPE_INTEGRAL,
|
||||
'DERIVATIVE': PIDClimateSensorType.PID_SENSOR_TYPE_DERIVATIVE,
|
||||
'HEAT': PIDClimateSensorType.PID_SENSOR_TYPE_HEAT,
|
||||
'COOL': PIDClimateSensorType.PID_SENSOR_TYPE_COOL,
|
||||
'KP': PIDClimateSensorType.PID_SENSOR_TYPE_KP,
|
||||
'KI': PIDClimateSensorType.PID_SENSOR_TYPE_KI,
|
||||
'KD': PIDClimateSensorType.PID_SENSOR_TYPE_KD,
|
||||
"RESULT": PIDClimateSensorType.PID_SENSOR_TYPE_RESULT,
|
||||
"ERROR": PIDClimateSensorType.PID_SENSOR_TYPE_ERROR,
|
||||
"PROPORTIONAL": PIDClimateSensorType.PID_SENSOR_TYPE_PROPORTIONAL,
|
||||
"INTEGRAL": PIDClimateSensorType.PID_SENSOR_TYPE_INTEGRAL,
|
||||
"DERIVATIVE": PIDClimateSensorType.PID_SENSOR_TYPE_DERIVATIVE,
|
||||
"HEAT": PIDClimateSensorType.PID_SENSOR_TYPE_HEAT,
|
||||
"COOL": PIDClimateSensorType.PID_SENSOR_TYPE_COOL,
|
||||
"KP": PIDClimateSensorType.PID_SENSOR_TYPE_KP,
|
||||
"KI": PIDClimateSensorType.PID_SENSOR_TYPE_KI,
|
||||
"KD": PIDClimateSensorType.PID_SENSOR_TYPE_KD,
|
||||
}
|
||||
|
||||
CONF_CLIMATE_ID = 'climate_id'
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_PERCENT, ICON_GAUGE, 1, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(PIDClimateSensor),
|
||||
cv.GenerateID(CONF_CLIMATE_ID): cv.use_id(PIDClimate),
|
||||
|
||||
cv.Required(CONF_TYPE): cv.enum(PID_CLIMATE_SENSOR_TYPES, upper=True),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONF_CLIMATE_ID = "climate_id"
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_PERCENT, ICON_GAUGE, 1, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PIDClimateSensor),
|
||||
cv.GenerateID(CONF_CLIMATE_ID): cv.use_id(PIDClimate),
|
||||
cv.Required(CONF_TYPE): cv.enum(PID_CLIMATE_SENSOR_TYPES, upper=True),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,22 +1,36 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, uart
|
||||
from esphome.const import CONF_FORMALDEHYDE, CONF_HUMIDITY, CONF_ID, CONF_PM_10_0, \
|
||||
CONF_PM_1_0, CONF_PM_2_5, CONF_TEMPERATURE, CONF_TYPE, DEVICE_CLASS_EMPTY, \
|
||||
DEVICE_CLASS_HUMIDITY, DEVICE_CLASS_TEMPERATURE, ICON_CHEMICAL_WEAPON, ICON_EMPTY, \
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER, UNIT_CELSIUS, UNIT_PERCENT
|
||||
from esphome.const import (
|
||||
CONF_FORMALDEHYDE,
|
||||
CONF_HUMIDITY,
|
||||
CONF_ID,
|
||||
CONF_PM_10_0,
|
||||
CONF_PM_1_0,
|
||||
CONF_PM_2_5,
|
||||
CONF_TEMPERATURE,
|
||||
CONF_TYPE,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_HUMIDITY,
|
||||
DEVICE_CLASS_TEMPERATURE,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
ICON_EMPTY,
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
UNIT_CELSIUS,
|
||||
UNIT_PERCENT,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
pmsx003_ns = cg.esphome_ns.namespace('pmsx003')
|
||||
PMSX003Component = pmsx003_ns.class_('PMSX003Component', uart.UARTDevice, cg.Component)
|
||||
PMSX003Sensor = pmsx003_ns.class_('PMSX003Sensor', sensor.Sensor)
|
||||
pmsx003_ns = cg.esphome_ns.namespace("pmsx003")
|
||||
PMSX003Component = pmsx003_ns.class_("PMSX003Component", uart.UARTDevice, cg.Component)
|
||||
PMSX003Sensor = pmsx003_ns.class_("PMSX003Sensor", sensor.Sensor)
|
||||
|
||||
TYPE_PMSX003 = 'PMSX003'
|
||||
TYPE_PMS5003T = 'PMS5003T'
|
||||
TYPE_PMS5003ST = 'PMS5003ST'
|
||||
TYPE_PMSX003 = "PMSX003"
|
||||
TYPE_PMS5003T = "PMS5003T"
|
||||
TYPE_PMS5003ST = "PMS5003ST"
|
||||
|
||||
PMSX003Type = pmsx003_ns.enum('PMSX003Type')
|
||||
PMSX003Type = pmsx003_ns.enum("PMSX003Type")
|
||||
PMSX003_TYPES = {
|
||||
TYPE_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
|
||||
TYPE_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
|
||||
@ -36,31 +50,52 @@ SENSORS_TO_TYPE = {
|
||||
def validate_pmsx003_sensors(value):
|
||||
for key, types in SENSORS_TO_TYPE.items():
|
||||
if key in value and value[CONF_TYPE] not in types:
|
||||
raise cv.Invalid("{} does not have {} sensor!".format(value[CONF_TYPE], key))
|
||||
raise cv.Invalid(
|
||||
"{} does not have {} sensor!".format(value[CONF_TYPE], key)
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PMSX003Component),
|
||||
cv.Required(CONF_TYPE): cv.enum(PMSX003_TYPES, upper=True),
|
||||
|
||||
cv.Optional(CONF_PM_1_0):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_PM_2_5):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_PM_10_0):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_TEMPERATURE):
|
||||
sensor.sensor_schema(UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE),
|
||||
cv.Optional(CONF_HUMIDITY):
|
||||
sensor.sensor_schema(UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY),
|
||||
cv.Optional(CONF_FORMALDEHYDE):
|
||||
sensor.sensor_schema(UNIT_MICROGRAMS_PER_CUBIC_METER, ICON_CHEMICAL_WEAPON, 0,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
}).extend(cv.COMPONENT_SCHEMA).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PMSX003Component),
|
||||
cv.Required(CONF_TYPE): cv.enum(PMSX003_TYPES, upper=True),
|
||||
cv.Optional(CONF_PM_1_0): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_PM_2_5): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_PM_10_0): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
cv.Optional(CONF_TEMPERATURE): sensor.sensor_schema(
|
||||
UNIT_CELSIUS, ICON_EMPTY, 1, DEVICE_CLASS_TEMPERATURE
|
||||
),
|
||||
cv.Optional(CONF_HUMIDITY): sensor.sensor_schema(
|
||||
UNIT_PERCENT, ICON_EMPTY, 1, DEVICE_CLASS_HUMIDITY
|
||||
),
|
||||
cv.Optional(CONF_FORMALDEHYDE): sensor.sensor_schema(
|
||||
UNIT_MICROGRAMS_PER_CUBIC_METER,
|
||||
ICON_CHEMICAL_WEAPON,
|
||||
0,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.COMPONENT_SCHEMA)
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -5,38 +5,52 @@ from esphome.components import nfc
|
||||
from esphome.const import CONF_ID, CONF_ON_TAG, CONF_TRIGGER_ID
|
||||
from esphome.core import coroutine
|
||||
|
||||
CODEOWNERS = ['@OttoWinter', '@jesserockz']
|
||||
AUTO_LOAD = ['binary_sensor', 'nfc']
|
||||
CODEOWNERS = ["@OttoWinter", "@jesserockz"]
|
||||
AUTO_LOAD = ["binary_sensor", "nfc"]
|
||||
MULTI_CONF = True
|
||||
|
||||
CONF_PN532_ID = 'pn532_id'
|
||||
CONF_ON_FINISHED_WRITE = 'on_finished_write'
|
||||
CONF_PN532_ID = "pn532_id"
|
||||
CONF_ON_FINISHED_WRITE = "on_finished_write"
|
||||
|
||||
pn532_ns = cg.esphome_ns.namespace('pn532')
|
||||
PN532 = pn532_ns.class_('PN532', cg.PollingComponent)
|
||||
pn532_ns = cg.esphome_ns.namespace("pn532")
|
||||
PN532 = pn532_ns.class_("PN532", cg.PollingComponent)
|
||||
|
||||
PN532OnTagTrigger = pn532_ns.class_('PN532OnTagTrigger',
|
||||
automation.Trigger.template(cg.std_string, nfc.NfcTag))
|
||||
PN532OnFinishedWriteTrigger = pn532_ns.class_('PN532OnFinishedWriteTrigger',
|
||||
automation.Trigger.template())
|
||||
PN532OnTagTrigger = pn532_ns.class_(
|
||||
"PN532OnTagTrigger", automation.Trigger.template(cg.std_string, nfc.NfcTag)
|
||||
)
|
||||
PN532OnFinishedWriteTrigger = pn532_ns.class_(
|
||||
"PN532OnFinishedWriteTrigger", automation.Trigger.template()
|
||||
)
|
||||
|
||||
PN532IsWritingCondition = pn532_ns.class_('PN532IsWritingCondition', automation.Condition)
|
||||
PN532IsWritingCondition = pn532_ns.class_(
|
||||
"PN532IsWritingCondition", automation.Condition
|
||||
)
|
||||
|
||||
PN532_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PN532),
|
||||
cv.Optional(CONF_ON_TAG): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PN532OnTagTrigger),
|
||||
}),
|
||||
cv.Optional(CONF_ON_FINISHED_WRITE): automation.validate_automation({
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PN532OnFinishedWriteTrigger),
|
||||
}),
|
||||
}).extend(cv.polling_component_schema('1s'))
|
||||
PN532_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PN532),
|
||||
cv.Optional(CONF_ON_TAG): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(PN532OnTagTrigger),
|
||||
}
|
||||
),
|
||||
cv.Optional(CONF_ON_FINISHED_WRITE): automation.validate_automation(
|
||||
{
|
||||
cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(
|
||||
PN532OnFinishedWriteTrigger
|
||||
),
|
||||
}
|
||||
),
|
||||
}
|
||||
).extend(cv.polling_component_schema("1s"))
|
||||
|
||||
|
||||
def CONFIG_SCHEMA(conf):
|
||||
if conf:
|
||||
raise cv.Invalid("This component has been moved in 1.16, please see the docs for updated "
|
||||
"instructions. https://esphome.io/components/binary_sensor/pn532.html")
|
||||
raise cv.Invalid(
|
||||
"This component has been moved in 1.16, please see the docs for updated "
|
||||
"instructions. https://esphome.io/components/binary_sensor/pn532.html"
|
||||
)
|
||||
|
||||
|
||||
@coroutine
|
||||
@ -46,17 +60,24 @@ def setup_pn532(var, config):
|
||||
for conf in config.get(CONF_ON_TAG, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID])
|
||||
cg.add(var.register_trigger(trigger))
|
||||
yield automation.build_automation(trigger, [(cg.std_string, 'x'), (nfc.NfcTag, 'tag')],
|
||||
conf)
|
||||
yield automation.build_automation(
|
||||
trigger, [(cg.std_string, "x"), (nfc.NfcTag, "tag")], conf
|
||||
)
|
||||
|
||||
for conf in config.get(CONF_ON_FINISHED_WRITE, []):
|
||||
trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var)
|
||||
yield automation.build_automation(trigger, [], conf)
|
||||
|
||||
|
||||
@automation.register_condition('pn532.is_writing', PN532IsWritingCondition, cv.Schema({
|
||||
cv.GenerateID(): cv.use_id(PN532),
|
||||
}))
|
||||
@automation.register_condition(
|
||||
"pn532.is_writing",
|
||||
PN532IsWritingCondition,
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.use_id(PN532),
|
||||
}
|
||||
),
|
||||
)
|
||||
def pn532_is_writing_to_code(config, condition_id, template_arg, args):
|
||||
var = cg.new_Pvariable(condition_id, template_arg)
|
||||
yield cg.register_parented(var, config[CONF_ID])
|
||||
|
@ -5,31 +5,39 @@ from esphome.const import CONF_UID, CONF_ID
|
||||
from esphome.core import HexInt
|
||||
from . import pn532_ns, PN532, CONF_PN532_ID
|
||||
|
||||
DEPENDENCIES = ['pn532']
|
||||
DEPENDENCIES = ["pn532"]
|
||||
|
||||
|
||||
def validate_uid(value):
|
||||
value = cv.string_strict(value)
|
||||
for x in value.split('-'):
|
||||
for x in value.split("-"):
|
||||
if len(x) != 2:
|
||||
raise cv.Invalid("Each part (separated by '-') of the UID must be two characters "
|
||||
"long.")
|
||||
raise cv.Invalid(
|
||||
"Each part (separated by '-') of the UID must be two characters "
|
||||
"long."
|
||||
)
|
||||
try:
|
||||
x = int(x, 16)
|
||||
except ValueError as err:
|
||||
raise cv.Invalid("Valid characters for parts of a UID are 0123456789ABCDEF.") from err
|
||||
raise cv.Invalid(
|
||||
"Valid characters for parts of a UID are 0123456789ABCDEF."
|
||||
) from err
|
||||
if x < 0 or x > 255:
|
||||
raise cv.Invalid("Valid values for UID parts (separated by '-') are 00 to FF")
|
||||
raise cv.Invalid(
|
||||
"Valid values for UID parts (separated by '-') are 00 to FF"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
PN532BinarySensor = pn532_ns.class_('PN532BinarySensor', binary_sensor.BinarySensor)
|
||||
PN532BinarySensor = pn532_ns.class_("PN532BinarySensor", binary_sensor.BinarySensor)
|
||||
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PN532BinarySensor),
|
||||
cv.GenerateID(CONF_PN532_ID): cv.use_id(PN532),
|
||||
cv.Required(CONF_UID): validate_uid,
|
||||
})
|
||||
CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PN532BinarySensor),
|
||||
cv.GenerateID(CONF_PN532_ID): cv.use_id(PN532),
|
||||
cv.Required(CONF_UID): validate_uid,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -38,5 +46,5 @@ def to_code(config):
|
||||
|
||||
hub = yield cg.get_variable(config[CONF_PN532_ID])
|
||||
cg.add(hub.register_tag(var))
|
||||
addr = [HexInt(int(x, 16)) for x in config[CONF_UID].split('-')]
|
||||
addr = [HexInt(int(x, 16)) for x in config[CONF_UID].split("-")]
|
||||
cg.add(var.set_uid(addr))
|
||||
|
@ -3,16 +3,20 @@ import esphome.config_validation as cv
|
||||
from esphome.components import i2c, pn532
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['pn532']
|
||||
CODEOWNERS = ['@OttoWinter', '@jesserockz']
|
||||
DEPENDENCIES = ['i2c']
|
||||
AUTO_LOAD = ["pn532"]
|
||||
CODEOWNERS = ["@OttoWinter", "@jesserockz"]
|
||||
DEPENDENCIES = ["i2c"]
|
||||
|
||||
pn532_i2c_ns = cg.esphome_ns.namespace('pn532_i2c')
|
||||
PN532I2C = pn532_i2c_ns.class_('PN532I2C', pn532.PN532, i2c.I2CDevice)
|
||||
pn532_i2c_ns = cg.esphome_ns.namespace("pn532_i2c")
|
||||
PN532I2C = pn532_i2c_ns.class_("PN532I2C", pn532.PN532, i2c.I2CDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(pn532.PN532_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PN532I2C),
|
||||
}).extend(i2c.i2c_device_schema(0x24)))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
pn532.PN532_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PN532I2C),
|
||||
}
|
||||
).extend(i2c.i2c_device_schema(0x24))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,16 +3,20 @@ import esphome.config_validation as cv
|
||||
from esphome.components import spi, pn532
|
||||
from esphome.const import CONF_ID
|
||||
|
||||
AUTO_LOAD = ['pn532']
|
||||
CODEOWNERS = ['@OttoWinter', '@jesserockz']
|
||||
DEPENDENCIES = ['spi']
|
||||
AUTO_LOAD = ["pn532"]
|
||||
CODEOWNERS = ["@OttoWinter", "@jesserockz"]
|
||||
DEPENDENCIES = ["spi"]
|
||||
|
||||
pn532_spi_ns = cg.esphome_ns.namespace('pn532_spi')
|
||||
PN532Spi = pn532_spi_ns.class_('PN532Spi', pn532.PN532, spi.SPIDevice)
|
||||
pn532_spi_ns = cg.esphome_ns.namespace("pn532_spi")
|
||||
PN532Spi = pn532_spi_ns.class_("PN532Spi", pn532.PN532, spi.SPIDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.All(pn532.PN532_SCHEMA.extend({
|
||||
cv.GenerateID(): cv.declare_id(PN532Spi),
|
||||
}).extend(spi.spi_device_schema(cs_pin_required=True)))
|
||||
CONFIG_SCHEMA = cv.All(
|
||||
pn532.PN532_SCHEMA.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PN532Spi),
|
||||
}
|
||||
).extend(spi.spi_device_schema(cs_pin_required=True))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -3,17 +3,23 @@ import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.const import CONF_ENABLE_TIME, CONF_ID, CONF_KEEP_ON_TIME, CONF_PIN
|
||||
|
||||
CODEOWNERS = ['@esphome/core']
|
||||
power_supply_ns = cg.esphome_ns.namespace('power_supply')
|
||||
PowerSupply = power_supply_ns.class_('PowerSupply', cg.Component)
|
||||
CODEOWNERS = ["@esphome/core"]
|
||||
power_supply_ns = cg.esphome_ns.namespace("power_supply")
|
||||
PowerSupply = power_supply_ns.class_("PowerSupply", cg.Component)
|
||||
MULTI_CONF = True
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.Required(CONF_ID): cv.declare_id(PowerSupply),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(CONF_ENABLE_TIME, default='20ms'): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(CONF_KEEP_ON_TIME, default='10s'): cv.positive_time_period_milliseconds,
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_ID): cv.declare_id(PowerSupply),
|
||||
cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
|
||||
cv.Optional(
|
||||
CONF_ENABLE_TIME, default="20ms"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
cv.Optional(
|
||||
CONF_KEEP_ON_TIME, default="10s"
|
||||
): cv.positive_time_period_milliseconds,
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
@ -25,4 +31,4 @@ def to_code(config):
|
||||
cg.add(var.set_enable_time(config[CONF_ENABLE_TIME]))
|
||||
cg.add(var.set_keep_on_time(config[CONF_KEEP_ON_TIME]))
|
||||
|
||||
cg.add_define('USE_POWER_SUPPLY')
|
||||
cg.add_define("USE_POWER_SUPPLY")
|
||||
|
@ -4,21 +4,25 @@ from esphome.const import CONF_ID
|
||||
from esphome.components.web_server_base import CONF_WEB_SERVER_BASE_ID
|
||||
from esphome.components import web_server_base
|
||||
|
||||
AUTO_LOAD = ['web_server_base']
|
||||
AUTO_LOAD = ["web_server_base"]
|
||||
|
||||
prometheus_ns = cg.esphome_ns.namespace('prometheus')
|
||||
PrometheusHandler = prometheus_ns.class_('PrometheusHandler', cg.Component)
|
||||
prometheus_ns = cg.esphome_ns.namespace("prometheus")
|
||||
PrometheusHandler = prometheus_ns.class_("PrometheusHandler", cg.Component)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PrometheusHandler),
|
||||
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(web_server_base.WebServerBase),
|
||||
}).extend(cv.COMPONENT_SCHEMA)
|
||||
CONFIG_SCHEMA = cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PrometheusHandler),
|
||||
cv.GenerateID(CONF_WEB_SERVER_BASE_ID): cv.use_id(
|
||||
web_server_base.WebServerBase
|
||||
),
|
||||
}
|
||||
).extend(cv.COMPONENT_SCHEMA)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
paren = yield cg.get_variable(config[CONF_WEB_SERVER_BASE_ID])
|
||||
|
||||
cg.add_define('USE_PROMETHEUS')
|
||||
cg.add_define("USE_PROMETHEUS")
|
||||
|
||||
var = cg.new_Pvariable(config[CONF_ID], paren)
|
||||
yield cg.register_component(var, config)
|
||||
|
@ -2,23 +2,35 @@ import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_COUNT_MODE, CONF_FALLING_EDGE, CONF_ID, CONF_INTERNAL_FILTER, \
|
||||
CONF_PIN, CONF_RISING_EDGE, CONF_NUMBER, CONF_TOTAL, DEVICE_CLASS_EMPTY, \
|
||||
ICON_PULSE, UNIT_PULSES_PER_MINUTE, UNIT_PULSES
|
||||
from esphome.const import (
|
||||
CONF_COUNT_MODE,
|
||||
CONF_FALLING_EDGE,
|
||||
CONF_ID,
|
||||
CONF_INTERNAL_FILTER,
|
||||
CONF_PIN,
|
||||
CONF_RISING_EDGE,
|
||||
CONF_NUMBER,
|
||||
CONF_TOTAL,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
ICON_PULSE,
|
||||
UNIT_PULSES_PER_MINUTE,
|
||||
UNIT_PULSES,
|
||||
)
|
||||
from esphome.core import CORE
|
||||
|
||||
pulse_counter_ns = cg.esphome_ns.namespace('pulse_counter')
|
||||
PulseCounterCountMode = pulse_counter_ns.enum('PulseCounterCountMode')
|
||||
pulse_counter_ns = cg.esphome_ns.namespace("pulse_counter")
|
||||
PulseCounterCountMode = pulse_counter_ns.enum("PulseCounterCountMode")
|
||||
COUNT_MODES = {
|
||||
'DISABLE': PulseCounterCountMode.PULSE_COUNTER_DISABLE,
|
||||
'INCREMENT': PulseCounterCountMode.PULSE_COUNTER_INCREMENT,
|
||||
'DECREMENT': PulseCounterCountMode.PULSE_COUNTER_DECREMENT,
|
||||
"DISABLE": PulseCounterCountMode.PULSE_COUNTER_DISABLE,
|
||||
"INCREMENT": PulseCounterCountMode.PULSE_COUNTER_INCREMENT,
|
||||
"DECREMENT": PulseCounterCountMode.PULSE_COUNTER_DECREMENT,
|
||||
}
|
||||
|
||||
COUNT_MODE_SCHEMA = cv.enum(COUNT_MODES, upper=True)
|
||||
|
||||
PulseCounterSensor = pulse_counter_ns.class_('PulseCounterSensor',
|
||||
sensor.Sensor, cg.PollingComponent)
|
||||
PulseCounterSensor = pulse_counter_ns.class_(
|
||||
"PulseCounterSensor", sensor.Sensor, cg.PollingComponent
|
||||
)
|
||||
|
||||
|
||||
def validate_internal_filter(value):
|
||||
@ -34,35 +46,52 @@ def validate_internal_filter(value):
|
||||
def validate_pulse_counter_pin(value):
|
||||
value = pins.internal_gpio_input_pin_schema(value)
|
||||
if CORE.is_esp8266 and value[CONF_NUMBER] >= 16:
|
||||
raise cv.Invalid("Pins GPIO16 and GPIO17 cannot be used as pulse counters on ESP8266.")
|
||||
raise cv.Invalid(
|
||||
"Pins GPIO16 and GPIO17 cannot be used as pulse counters on ESP8266."
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
def validate_count_mode(value):
|
||||
rising_edge = value[CONF_RISING_EDGE]
|
||||
falling_edge = value[CONF_FALLING_EDGE]
|
||||
if rising_edge == 'DISABLE' and falling_edge == 'DISABLE':
|
||||
raise cv.Invalid("Can't set both count modes to DISABLE! This means no counting occurs at "
|
||||
"all!")
|
||||
if rising_edge == "DISABLE" and falling_edge == "DISABLE":
|
||||
raise cv.Invalid(
|
||||
"Can't set both count modes to DISABLE! This means no counting occurs at "
|
||||
"all!"
|
||||
)
|
||||
return value
|
||||
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(
|
||||
UNIT_PULSES_PER_MINUTE, ICON_PULSE, 2, DEVICE_CLASS_EMPTY
|
||||
).extend({
|
||||
cv.GenerateID(): cv.declare_id(PulseCounterSensor),
|
||||
cv.Required(CONF_PIN): validate_pulse_counter_pin,
|
||||
cv.Optional(CONF_COUNT_MODE, default={
|
||||
CONF_RISING_EDGE: 'INCREMENT',
|
||||
CONF_FALLING_EDGE: 'DISABLE',
|
||||
}): cv.All(cv.Schema({
|
||||
cv.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA,
|
||||
cv.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
|
||||
}), validate_count_mode),
|
||||
cv.Optional(CONF_INTERNAL_FILTER, default='13us'): validate_internal_filter,
|
||||
cv.Optional(CONF_TOTAL): sensor.sensor_schema(UNIT_PULSES, ICON_PULSE, 0, DEVICE_CLASS_EMPTY),
|
||||
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_PULSES_PER_MINUTE, ICON_PULSE, 2, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PulseCounterSensor),
|
||||
cv.Required(CONF_PIN): validate_pulse_counter_pin,
|
||||
cv.Optional(
|
||||
CONF_COUNT_MODE,
|
||||
default={
|
||||
CONF_RISING_EDGE: "INCREMENT",
|
||||
CONF_FALLING_EDGE: "DISABLE",
|
||||
},
|
||||
): cv.All(
|
||||
cv.Schema(
|
||||
{
|
||||
cv.Required(CONF_RISING_EDGE): COUNT_MODE_SCHEMA,
|
||||
cv.Required(CONF_FALLING_EDGE): COUNT_MODE_SCHEMA,
|
||||
}
|
||||
),
|
||||
validate_count_mode,
|
||||
),
|
||||
cv.Optional(CONF_INTERNAL_FILTER, default="13us"): validate_internal_filter,
|
||||
cv.Optional(CONF_TOTAL): sensor.sensor_schema(
|
||||
UNIT_PULSES, ICON_PULSE, 0, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -4,15 +4,24 @@ from esphome import pins
|
||||
from esphome.components import sensor
|
||||
from esphome.const import CONF_ID, CONF_PIN, DEVICE_CLASS_EMPTY, UNIT_SECOND, ICON_TIMER
|
||||
|
||||
pulse_width_ns = cg.esphome_ns.namespace('pulse_width')
|
||||
pulse_width_ns = cg.esphome_ns.namespace("pulse_width")
|
||||
|
||||
PulseWidthSensor = pulse_width_ns.class_('PulseWidthSensor', sensor.Sensor, cg.PollingComponent)
|
||||
PulseWidthSensor = pulse_width_ns.class_(
|
||||
"PulseWidthSensor", sensor.Sensor, cg.PollingComponent
|
||||
)
|
||||
|
||||
CONFIG_SCHEMA = sensor.sensor_schema(UNIT_SECOND, ICON_TIMER, 3, DEVICE_CLASS_EMPTY).extend({
|
||||
cv.GenerateID(): cv.declare_id(PulseWidthSensor),
|
||||
cv.Required(CONF_PIN): cv.All(pins.internal_gpio_input_pin_schema,
|
||||
pins.validate_has_interrupt),
|
||||
}).extend(cv.polling_component_schema('60s'))
|
||||
CONFIG_SCHEMA = (
|
||||
sensor.sensor_schema(UNIT_SECOND, ICON_TIMER, 3, DEVICE_CLASS_EMPTY)
|
||||
.extend(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PulseWidthSensor),
|
||||
cv.Required(CONF_PIN): cv.All(
|
||||
pins.internal_gpio_input_pin_schema, pins.validate_has_interrupt
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,25 +1,49 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, uart
|
||||
from esphome.const import CONF_CURRENT, CONF_ID, CONF_POWER, CONF_VOLTAGE, CONF_ENERGY, \
|
||||
DEVICE_CLASS_CURRENT, DEVICE_CLASS_ENERGY, DEVICE_CLASS_POWER, DEVICE_CLASS_VOLTAGE, \
|
||||
ICON_EMPTY, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, UNIT_WATT_HOURS
|
||||
from esphome.const import (
|
||||
CONF_CURRENT,
|
||||
CONF_ID,
|
||||
CONF_POWER,
|
||||
CONF_VOLTAGE,
|
||||
CONF_ENERGY,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
ICON_EMPTY,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
UNIT_WATT_HOURS,
|
||||
)
|
||||
|
||||
DEPENDENCIES = ['uart']
|
||||
DEPENDENCIES = ["uart"]
|
||||
|
||||
pzem004t_ns = cg.esphome_ns.namespace('pzem004t')
|
||||
PZEM004T = pzem004t_ns.class_('PZEM004T', cg.PollingComponent, uart.UARTDevice)
|
||||
pzem004t_ns = cg.esphome_ns.namespace("pzem004t")
|
||||
PZEM004T = pzem004t_ns.class_("PZEM004T", cg.PollingComponent, uart.UARTDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PZEM004T),
|
||||
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 0, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(UNIT_WATT_HOURS, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_ENERGY)
|
||||
}).extend(cv.polling_component_schema('60s')).extend(uart.UART_DEVICE_SCHEMA)
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PZEM004T),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 2, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 0, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 0, DEVICE_CLASS_ENERGY
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(uart.UART_DEVICE_SCHEMA)
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
@ -1,30 +1,62 @@
|
||||
import esphome.codegen as cg
|
||||
import esphome.config_validation as cv
|
||||
from esphome.components import sensor, modbus
|
||||
from esphome.const import CONF_CURRENT, CONF_ENERGY, CONF_ID, CONF_POWER, CONF_VOLTAGE, \
|
||||
CONF_FREQUENCY, CONF_POWER_FACTOR, DEVICE_CLASS_EMPTY, DEVICE_CLASS_POWER_FACTOR, \
|
||||
DEVICE_CLASS_VOLTAGE, DEVICE_CLASS_CURRENT, DEVICE_CLASS_POWER, DEVICE_CLASS_ENERGY, \
|
||||
ICON_EMPTY, ICON_CURRENT_AC, UNIT_HERTZ, UNIT_VOLT, UNIT_AMPERE, UNIT_WATT, UNIT_EMPTY, \
|
||||
UNIT_WATT_HOURS
|
||||
from esphome.const import (
|
||||
CONF_CURRENT,
|
||||
CONF_ENERGY,
|
||||
CONF_ID,
|
||||
CONF_POWER,
|
||||
CONF_VOLTAGE,
|
||||
CONF_FREQUENCY,
|
||||
CONF_POWER_FACTOR,
|
||||
DEVICE_CLASS_EMPTY,
|
||||
DEVICE_CLASS_POWER_FACTOR,
|
||||
DEVICE_CLASS_VOLTAGE,
|
||||
DEVICE_CLASS_CURRENT,
|
||||
DEVICE_CLASS_POWER,
|
||||
DEVICE_CLASS_ENERGY,
|
||||
ICON_EMPTY,
|
||||
ICON_CURRENT_AC,
|
||||
UNIT_HERTZ,
|
||||
UNIT_VOLT,
|
||||
UNIT_AMPERE,
|
||||
UNIT_WATT,
|
||||
UNIT_EMPTY,
|
||||
UNIT_WATT_HOURS,
|
||||
)
|
||||
|
||||
AUTO_LOAD = ['modbus']
|
||||
AUTO_LOAD = ["modbus"]
|
||||
|
||||
pzemac_ns = cg.esphome_ns.namespace('pzemac')
|
||||
PZEMAC = pzemac_ns.class_('PZEMAC', cg.PollingComponent, modbus.ModbusDevice)
|
||||
pzemac_ns = cg.esphome_ns.namespace("pzemac")
|
||||
PZEMAC = pzemac_ns.class_("PZEMAC", cg.PollingComponent, modbus.ModbusDevice)
|
||||
|
||||
CONFIG_SCHEMA = cv.Schema({
|
||||
cv.GenerateID(): cv.declare_id(PZEMAC),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(UNIT_AMPERE, ICON_EMPTY, 3,
|
||||
DEVICE_CLASS_CURRENT),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(UNIT_WATT_HOURS, ICON_EMPTY, 0,
|
||||
DEVICE_CLASS_ENERGY),
|
||||
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(UNIT_HERTZ, ICON_CURRENT_AC, 1,
|
||||
DEVICE_CLASS_EMPTY),
|
||||
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(UNIT_EMPTY, ICON_EMPTY, 2,
|
||||
DEVICE_CLASS_POWER_FACTOR),
|
||||
}).extend(cv.polling_component_schema('60s')).extend(modbus.modbus_device_schema(0x01))
|
||||
CONFIG_SCHEMA = (
|
||||
cv.Schema(
|
||||
{
|
||||
cv.GenerateID(): cv.declare_id(PZEMAC),
|
||||
cv.Optional(CONF_VOLTAGE): sensor.sensor_schema(
|
||||
UNIT_VOLT, ICON_EMPTY, 1, DEVICE_CLASS_VOLTAGE
|
||||
),
|
||||
cv.Optional(CONF_CURRENT): sensor.sensor_schema(
|
||||
UNIT_AMPERE, ICON_EMPTY, 3, DEVICE_CLASS_CURRENT
|
||||
),
|
||||
cv.Optional(CONF_POWER): sensor.sensor_schema(
|
||||
UNIT_WATT, ICON_EMPTY, 2, DEVICE_CLASS_POWER
|
||||
),
|
||||
cv.Optional(CONF_ENERGY): sensor.sensor_schema(
|
||||
UNIT_WATT_HOURS, ICON_EMPTY, 0, DEVICE_CLASS_ENERGY
|
||||
),
|
||||
cv.Optional(CONF_FREQUENCY): sensor.sensor_schema(
|
||||
UNIT_HERTZ, ICON_CURRENT_AC, 1, DEVICE_CLASS_EMPTY
|
||||
),
|
||||
cv.Optional(CONF_POWER_FACTOR): sensor.sensor_schema(
|
||||
UNIT_EMPTY, ICON_EMPTY, 2, DEVICE_CLASS_POWER_FACTOR
|
||||
),
|
||||
}
|
||||
)
|
||||
.extend(cv.polling_component_schema("60s"))
|
||||
.extend(modbus.modbus_device_schema(0x01))
|
||||
)
|
||||
|
||||
|
||||
def to_code(config):
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user