def to_code(config): cg.add_global(cg.global_ns.namespace('esphome').using) cg.add(cg.App.pre_setup(config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'))) for conf in config.get(CONF_ON_BOOT, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], conf.get(CONF_PRIORITY)) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) for conf in config.get(CONF_ON_SHUTDOWN, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID]) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) for conf in config.get(CONF_ON_LOOP, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID]) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) # Build flags if CORE.is_esp8266 and CORE.board in ESP8266_FLASH_SIZES and \ CORE.arduino_version != ARDUINO_VERSION_ESP8266_2_3_0: flash_size = ESP8266_FLASH_SIZES[CORE.board] ld_scripts = ESP8266_LD_SCRIPTS[flash_size] ld_script = None if CORE.arduino_version in ('[email protected]', '[email protected]', '[email protected]'): ld_script = ld_scripts[0] elif CORE.arduino_version in (ARDUINO_VERSION_ESP8266_DEV, ARDUINO_VERSION_ESP8266_2_5_0, ARDUINO_VERSION_ESP8266_2_5_1, ARDUINO_VERSION_ESP8266_2_5_2): ld_script = ld_scripts[1] if ld_script is not None: cg.add_build_flag(f'-Wl,-T{ld_script}') cg.add_build_flag('-fno-exceptions') # Libraries if CORE.is_esp32: cg.add_library('ESPmDNS', None) elif CORE.is_esp8266: cg.add_library('ESP8266WiFi', None) cg.add_library('ESP8266mDNS', None) for lib in config[CONF_LIBRARIES]: if '@' in lib: name, vers = lib.split('@', 1) cg.add_library(name, vers) else: cg.add_library(lib, None) cg.add_build_flag('-Wno-unused-variable') cg.add_build_flag('-Wno-unused-but-set-variable') cg.add_build_flag('-Wno-sign-compare') if config.get(CONF_ESP8266_RESTORE_FROM_FLASH, False): cg.add_define('USE_ESP8266_PREFERENCES_FLASH') if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES])
def generate_cpp_contents(config): _LOGGER.info("Generating C++ source...") for name, component, conf in iter_components(CORE.config): if component.to_code is not None: coro = wrap_to_code(name, component) CORE.add_job(coro, conf) CORE.flush_tasks()
def write_cpp(config): _LOGGER.info("Generating C++ source...") for name, component, conf in iter_components(CORE.config): if component.to_code is not None: coro = wrap_to_code(name, component) CORE.add_job(coro, conf) CORE.flush_tasks() writer.write_platformio_project() code_s = indent(CORE.cpp_main_section) writer.write_cpp(code_s) return 0
def to_code(config): cg.add_global(cg.global_ns.namespace('esphome').using) cg.add(cg.App.pre_setup(config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'))) for conf in config.get(CONF_ON_BOOT, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], conf.get(CONF_PRIORITY)) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) for conf in config.get(CONF_ON_SHUTDOWN, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID]) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) for conf in config.get(CONF_ON_LOOP, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID]) yield cg.register_component(trigger, conf) yield automation.build_automation(trigger, [], conf) # Set LWIP build constants for ESP8266 if CORE.is_esp8266: CORE.add_job(_esp8266_add_lwip_type) cg.add_build_flag('-fno-exceptions') # Libraries if CORE.is_esp32: cg.add_library('ESPmDNS', None) elif CORE.is_esp8266: cg.add_library('ESP8266WiFi', None) cg.add_library('ESP8266mDNS', None) for lib in config[CONF_LIBRARIES]: if '@' in lib: name, vers = lib.split('@', 1) cg.add_library(name, vers) else: cg.add_library(lib, None) cg.add_build_flag('-Wno-unused-variable') cg.add_build_flag('-Wno-unused-but-set-variable') cg.add_build_flag('-Wno-sign-compare') if config.get(CONF_ESP8266_RESTORE_FROM_FLASH, False): cg.add_define('USE_ESP8266_PREFERENCES_FLASH') if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES])
async def to_code(config): cg.add_global(cg.global_ns.namespace("esphome").using) # These can be used by user lambdas, put them to default scope cg.add_global(cg.RawExpression("using std::isnan")) cg.add_global(cg.RawExpression("using std::min")) cg.add_global(cg.RawExpression("using std::max")) cg.add( cg.App.pre_setup( config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'), config[CONF_NAME_ADD_MAC_SUFFIX], )) CORE.add_job(_add_automations, config) cg.add_build_flag("-fno-exceptions") # Libraries for lib in config[CONF_LIBRARIES]: if "@" in lib: name, vers = lib.split("@", 1) cg.add_library(name, vers) elif "://" in lib: # Repository... if "=" in lib: name, repo = lib.split("=", 1) cg.add_library(name, None, repo) else: cg.add_library(None, None, lib) else: cg.add_library(lib, None) cg.add_build_flag("-Wno-unused-variable") cg.add_build_flag("-Wno-unused-but-set-variable") cg.add_build_flag("-Wno-sign-compare") if CORE.using_arduino: CORE.add_job(add_arduino_global_workaround) if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES]) if CONF_PROJECT in config: cg.add_define("ESPHOME_PROJECT_NAME", config[CONF_PROJECT][CONF_NAME]) cg.add_define("ESPHOME_PROJECT_VERSION", config[CONF_PROJECT][CONF_VERSION]) if config[CONF_PLATFORMIO_OPTIONS]: CORE.add_job(_add_platformio_options, config[CONF_PLATFORMIO_OPTIONS])
async def to_code(config): cg.add_global(cg.global_ns.namespace("esphome").using) cg.add( cg.App.pre_setup( config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'), config[CONF_NAME_ADD_MAC_SUFFIX], )) CORE.add_job(_add_automations, config) # Set LWIP build constants for ESP8266 if CORE.is_esp8266: CORE.add_job(_esp8266_add_lwip_type) cg.add_build_flag("-fno-exceptions") # Libraries for lib in config[CONF_LIBRARIES]: if "@" in lib: name, vers = lib.split("@", 1) cg.add_library(name, vers) else: cg.add_library(lib, None) cg.add_build_flag("-Wno-unused-variable") cg.add_build_flag("-Wno-unused-but-set-variable") cg.add_build_flag("-Wno-sign-compare") if config.get(CONF_ESP8266_RESTORE_FROM_FLASH, False): cg.add_define("USE_ESP8266_PREFERENCES_FLASH") if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES])
def write_cpp(config): _LOGGER.info("Generating C++ source...") CORE.add_job(core_config.to_code, config[CONF_ESPHOME], domain='esphome') for domain in PRE_INITIALIZE: if domain == CONF_ESPHOME or domain not in config: continue CORE.add_job(get_component(domain).to_code, config[domain], domain=domain) for domain, component, conf in iter_components(config): if domain in PRE_INITIALIZE or not hasattr(component, 'to_code'): continue CORE.add_job(component.to_code, conf, domain=domain) CORE.flush_tasks() add(RawStatement('')) add(RawStatement('')) all_code = [] for exp in CORE.expressions: if not config[CONF_ESPHOME][CONF_USE_CUSTOM_CODE]: if isinstance(exp, Expression) and not exp.required: continue all_code.append(text_type(statement(exp))) writer.write_platformio_project() code_s = indent('\n'.join(line.rstrip() for line in all_code)) writer.write_cpp(code_s) return 0
async def to_code(config): cg.add_global(cg.global_ns.namespace("esphome").using) cg.add( cg.App.pre_setup( config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'), config[CONF_NAME_ADD_MAC_SUFFIX], )) CORE.add_job(_add_automations, config) # Set LWIP build constants for ESP8266 if CORE.is_esp8266: CORE.add_job(_esp8266_add_lwip_type) cg.add_build_flag("-fno-exceptions") # Libraries for lib in config[CONF_LIBRARIES]: if "@" in lib: name, vers = lib.split("@", 1) cg.add_library(name, vers) elif "://" in lib: # Repository... if "=" in lib: name, repo = lib.split("=", 1) cg.add_library(name, None, repo) else: cg.add_library(None, None, lib) else: cg.add_library(lib, None) if CORE.is_esp8266: # Arduino 2 has a non-standards conformant new that returns a nullptr instead of failing when # out of memory and exceptions are disabled. Since Arduino 2.6.0, this flag can be used to make # new abort instead. Use it so that OOM fails early (on allocation) instead of on dereference of # a NULL pointer (so the stacktrace makes more sense), and for consistency with Arduino 3, # which always aborts if exceptions are disabled. # For cases where nullptrs can be handled, use nothrow: `new (std::nothrow) T;` cg.add_build_flag("-DNEW_OOM_ABORT") cg.add_build_flag("-Wno-unused-variable") cg.add_build_flag("-Wno-unused-but-set-variable") cg.add_build_flag("-Wno-sign-compare") if config.get(CONF_ESP8266_RESTORE_FROM_FLASH, False): cg.add_define("USE_ESP8266_PREFERENCES_FLASH") if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES]) cg.add_define("ESPHOME_BOARD", CORE.board) if CONF_PROJECT in config: cg.add_define("ESPHOME_PROJECT_NAME", config[CONF_PROJECT][CONF_NAME]) cg.add_define("ESPHOME_PROJECT_VERSION", config[CONF_PROJECT][CONF_VERSION])
def to_code(config): cg.add_global(cg.global_ns.namespace('esphome').using) cg.add( cg.App.pre_setup(config[CONF_NAME], cg.RawExpression('__DATE__ ", " __TIME__'))) CORE.add_job(_add_automations, config) # Set LWIP build constants for ESP8266 if CORE.is_esp8266: CORE.add_job(_esp8266_add_lwip_type) cg.add_build_flag('-fno-exceptions') # Libraries if CORE.is_esp32: cg.add_library('ESPmDNS', None) elif CORE.is_esp8266: cg.add_library('ESP8266WiFi', None) cg.add_library('ESP8266mDNS', None) for lib in config[CONF_LIBRARIES]: if '@' in lib: name, vers = lib.split('@', 1) cg.add_library(name, vers) else: cg.add_library(lib, None) cg.add_build_flag('-Wno-unused-variable') cg.add_build_flag('-Wno-unused-but-set-variable') cg.add_build_flag('-Wno-sign-compare') if config.get(CONF_ESP8266_RESTORE_FROM_FLASH, False): cg.add_define('USE_ESP8266_PREFERENCES_FLASH') if config[CONF_INCLUDES]: CORE.add_job(add_includes, config[CONF_INCLUDES])
def register_text_sensor(var, config): if not CORE.has_id(config[CONF_ID]): var = Pvariable(config[CONF_ID], var, has_side_effects=True) add(App.register_text_sensor(var)) CORE.add_job(setup_text_sensor_core_, var, config)
def setup_text_sensor(text_sensor_obj, config): if not CORE.has_id(config[CONF_ID]): text_sensor_obj = Pvariable(config[CONF_ID], text_sensor_obj, has_side_effects=True) CORE.add_job(setup_text_sensor_core_, text_sensor_obj, config)
def setup_stepper(stepper_var, config): CORE.add_job(setup_stepper_core_, stepper_var, config)
def setup_time(time_var, config): CORE.add_job(setup_time_core_, time_var, config)
async def to_code(config): cg.add(esp8266_ns.setup_preferences()) cg.add_platformio_option("lib_ldf_mode", "off") cg.add_platformio_option("board", config[CONF_BOARD]) cg.add_build_flag("-DUSE_ESP8266") cg.add_define("ESPHOME_BOARD", config[CONF_BOARD]) cg.add_define("ESPHOME_VARIANT", "ESP8266") cg.add_platformio_option("extra_scripts", ["post:post_build.py"]) conf = config[CONF_FRAMEWORK] cg.add_platformio_option("framework", "arduino") cg.add_build_flag("-DUSE_ARDUINO") cg.add_build_flag("-DUSE_ESP8266_FRAMEWORK_ARDUINO") cg.add_build_flag("-Wno-nonnull-compare") cg.add_platformio_option("platform", conf[CONF_PLATFORM_VERSION]) cg.add_platformio_option( "platform_packages", [f"platformio/framework-arduinoespressif8266 @ {conf[CONF_SOURCE]}"], ) # Default for platformio is LWIP2_LOW_MEMORY with: # - MSS=536 # - LWIP_FEATURES enabled # - this only adds some optional features like IP incoming packet reassembly and NAPT # see also: # https://github.com/esp8266/Arduino/blob/master/tools/sdk/lwip2/include/lwipopts.h # Instead we use LWIP2_HIGHER_BANDWIDTH_LOW_FLASH with: # - MSS=1460 # - LWIP_FEATURES disabled (because we don't need them) # Other projects like Tasmota & ESPEasy also use this cg.add_build_flag( "-DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH") if config[CONF_RESTORE_FROM_FLASH]: cg.add_define("USE_ESP8266_PREFERENCES_FLASH") # Arduino 2 has a non-standards conformant new that returns a nullptr instead of failing when # out of memory and exceptions are disabled. Since Arduino 2.6.0, this flag can be used to make # new abort instead. Use it so that OOM fails early (on allocation) instead of on dereference of # a NULL pointer (so the stacktrace makes more sense), and for consistency with Arduino 3, # which always aborts if exceptions are disabled. # For cases where nullptrs can be handled, use nothrow: `new (std::nothrow) T;` cg.add_build_flag("-DNEW_OOM_ABORT") cg.add_platformio_option("board_build.flash_mode", config[CONF_BOARD_FLASH_MODE]) ver: cv.Version = CORE.data[KEY_CORE][KEY_FRAMEWORK_VERSION] cg.add_define( "USE_ARDUINO_VERSION_CODE", cg.RawExpression( f"VERSION_CODE({ver.major}, {ver.minor}, {ver.patch})"), ) if config[CONF_BOARD] in ESP8266_FLASH_SIZES: flash_size = ESP8266_FLASH_SIZES[config[CONF_BOARD]] ld_scripts = ESP8266_LD_SCRIPTS[flash_size] if ver <= cv.Version(2, 3, 0): # No ld script support ld_script = None if ver <= cv.Version(2, 4, 2): # Old ld script path ld_script = ld_scripts[0] else: ld_script = ld_scripts[1] if ld_script is not None: cg.add_platformio_option("board_build.ldscript", ld_script) CORE.add_job(add_pin_initial_states_array)
def setup_fan(fan_obj, config): fan_var = Pvariable(config[CONF_ID], fan_obj, has_side_effects=False) CORE.add_job(setup_fan_core_, fan_var, config)
def setup_output_platform(obj, config, skip_power_supply=False): CORE.add_job(setup_output_platform_, obj, config, skip_power_supply)
def setup_switch(switch_obj, config): if not CORE.has_id(config[CONF_ID]): switch_obj = Pvariable(config[CONF_ID], switch_obj, has_side_effects=True) CORE.add_job(setup_switch_core_, switch_obj, config)
def setup_binary_sensor(binary_sensor_obj, config): if not CORE.has_id(config[CONF_ID]): binary_sensor_obj = Pvariable(config[CONF_ID], binary_sensor_obj, has_side_effects=True) CORE.add_job(setup_binary_sensor_core_, binary_sensor_obj, config)
def setup_cover(cover_obj, config): CORE.add_job(setup_cover_core_, cover_obj, config)
def setup_display(display_var, config): CORE.add_job(setup_display_core_, display_var, config)
def build_automations(trigger, args, config): CORE.add_job(build_automation_, trigger, args, config)
def register_output(var, config): output_var = Pvariable(config[CONF_ID], var, has_side_effects=True) CORE.add_job(setup_output_platform_, output_var, config)
def register_sensor(var, config): sensor_var = Pvariable(config[CONF_ID], var, has_side_effects=True) add(App.register_sensor(sensor_var)) CORE.add_job(setup_sensor_core_, sensor_var, config)
def build_automation(trigger, arg_type, config): CORE.add_job(build_automation_, trigger, arg_type, config)
def register_switch(var, config): switch_var = Pvariable(config[CONF_ID], var, has_side_effects=True) add(App.register_switch(switch_var)) CORE.add_job(setup_switch_core_, switch_var, config)