├── components
├── rgb
│ ├── __init__.py
│ ├── rgb_light_output.h
│ └── light.py
├── kauf_hlw8012
│ └── __init__.py
├── monochromatic
│ ├── __init__.py
│ ├── monochromatic_light_output.h
│ └── light.py
├── total_daily_energy
│ ├── __init__.py
│ ├── total_daily_energy.h
│ └── total_daily_energy.cpp
├── template
│ ├── __init__.py
│ ├── event
│ │ ├── template_event.h
│ │ └── __init__.py
│ ├── button
│ │ ├── __init__.py
│ │ └── template_button.h
│ ├── lock
│ │ ├── automation.h
│ │ ├── template_lock.h
│ │ ├── template_lock.cpp
│ │ └── __init__.py
│ ├── sensor
│ │ ├── template_sensor.h
│ │ ├── template_sensor.cpp
│ │ └── __init__.py
│ ├── text_sensor
│ │ ├── template_text_sensor.cpp
│ │ ├── template_text_sensor.h
│ │ └── __init__.py
│ ├── binary_sensor
│ │ ├── template_binary_sensor.cpp
│ │ ├── template_binary_sensor.h
│ │ └── __init__.py
│ ├── valve
│ │ ├── automation.h
│ │ └── template_valve.h
│ ├── output
│ │ ├── template_output.h
│ │ └── __init__.py
│ ├── fan
│ │ ├── template_fan.h
│ │ ├── template_fan.cpp
│ │ └── __init__.py
│ ├── switch
│ │ ├── template_switch.h
│ │ └── template_switch.cpp
│ ├── text
│ │ ├── template_text.cpp
│ │ ├── template_text.h
│ │ └── __init__.py
│ ├── datetime
│ │ ├── template_date.h
│ │ ├── template_time.h
│ │ ├── template_datetime.h
│ │ ├── template_date.cpp
│ │ └── template_time.cpp
│ ├── number
│ │ ├── template_number.cpp
│ │ └── template_number.h
│ ├── select
│ │ ├── template_select.h
│ │ └── template_select.cpp
│ └── cover
│ │ └── template_cover.h
├── gpio
│ ├── __init__.py
│ ├── output
│ │ ├── gpio_binary_output.cpp
│ │ ├── gpio_binary_output.h
│ │ └── __init__.py
│ ├── one_wire
│ │ ├── __init__.py
│ │ └── gpio_one_wire.h
│ ├── switch
│ │ ├── gpio_switch.h
│ │ ├── gpio_switch.cpp
│ │ └── __init__.py
│ └── binary_sensor
│ │ ├── gpio_binary_sensor.h
│ │ └── gpio_binary_sensor.cpp
├── switch
│ ├── automation.cpp
│ ├── binary_sensor
│ │ ├── switch_binary_sensor.cpp
│ │ ├── switch_binary_sensor.h
│ │ └── __init__.py
│ └── automation.h
├── light
│ ├── light_output.cpp
│ ├── automation.cpp
│ ├── light_json_schema.h
│ ├── esp_color_correction.cpp
│ ├── light_effect.cpp
│ ├── esp_hsv_color.h
│ ├── light_output.h
│ ├── light_traits.h
│ ├── light_effect.h
│ ├── esp_hsv_color.cpp
│ ├── light_transformer.h
│ ├── esp_range_view.h
│ ├── esp_range_view.cpp
│ ├── types.py
│ └── esp_color_correction.h
├── esp8266
│ ├── core.h
│ ├── preferences.h
│ ├── const.py
│ ├── post_build.py.script
│ ├── helpers.cpp
│ ├── gpio.h
│ └── core.cpp
├── safe_mode
│ ├── automation.h
│ ├── button
│ │ ├── safe_mode_button.h
│ │ ├── safe_mode_button.cpp
│ │ └── __init__.py
│ ├── switch
│ │ ├── safe_mode_switch.h
│ │ ├── safe_mode_switch.cpp
│ │ └── __init__.py
│ ├── safe_mode.h
│ └── __init__.py
├── captive_portal
│ ├── dns_server_esp32_idf.h
│ ├── captive_portal.h
│ └── __init__.py
├── web_server
│ ├── ota
│ │ ├── ota_web_server.h
│ │ └── __init__.py
│ └── list_entities.h
└── ddp
│ ├── ddp_light_effect.h
│ ├── ddp_addressable_light_effect.h
│ ├── ddp_light_effect_base.cpp
│ ├── ddp.h
│ ├── ddp_light_effect_base.h
│ └── __init__.py
├── esphome-webserver
├── packages
│ ├── v2
│ │ ├── src
│ │ │ ├── main.ts
│ │ │ ├── esp-logo.ts
│ │ │ └── css
│ │ │ │ ├── reset.ts
│ │ │ │ └── button.ts
│ │ ├── public
│ │ │ ├── home.svg
│ │ │ └── logo.svg
│ │ ├── index.html
│ │ ├── package.json
│ │ └── vite.config.ts
│ ├── v3
│ │ ├── src
│ │ │ ├── main.ts
│ │ │ ├── css
│ │ │ │ ├── input.ts
│ │ │ │ ├── reset.ts
│ │ │ │ ├── tab.ts
│ │ │ │ ├── button.ts
│ │ │ │ ├── app.ts
│ │ │ │ └── esp-entity-table.ts
│ │ │ ├── esp-logo.ts
│ │ │ ├── esp-entity-chart.ts
│ │ │ └── main.css
│ │ ├── index.html
│ │ ├── public
│ │ │ └── logo.svg
│ │ ├── package.json
│ │ └── vite.config.ts
│ ├── v1
│ │ ├── package.json
│ │ └── src
│ │ │ ├── webserver-v1.min.js
│ │ │ └── webserver-v1.js
│ └── captive-portal
│ │ ├── src
│ │ ├── icon
│ │ │ ├── wifi.svg
│ │ │ └── lock.svg
│ │ ├── main.ts
│ │ └── stylesheet.css
│ │ ├── public
│ │ └── config.json
│ │ ├── package.json
│ │ ├── vite.config.ts
│ │ ├── README.md
│ │ └── index.html
├── .prettierrc.json
├── package.json
├── scripts
│ └── make_header.sh
├── LICENSE
├── .gitignore
└── README.md
└── .gitignore
/components/rgb/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/kauf_hlw8012/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/monochromatic/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/total_daily_energy/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/src/main.ts:
--------------------------------------------------------------------------------
1 | import "./esp-app"
2 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/main.ts:
--------------------------------------------------------------------------------
1 | import "./esp-app"
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | _static
3 | node_modules
4 | esphome-webserver/captive-portal/package-lock.json
5 | notes.txt
6 |
--------------------------------------------------------------------------------
/components/template/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 |
3 | template_ns = cg.esphome_ns.namespace("template_")
4 |
--------------------------------------------------------------------------------
/components/gpio/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 |
3 | CODEOWNERS = ["@esphome/core"]
4 | gpio_ns = cg.esphome_ns.namespace("gpio")
5 |
--------------------------------------------------------------------------------
/esphome-webserver/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "html.format.wrapAttributes": "auto",
3 | "html.format.wrapLineLength": 0,
4 | "printWidth": 80
5 | }
6 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/public/home.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/css/input.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | input[type="text"] {
5 | width: 100% !important;
6 | height: 1rem !important;
7 | }
8 | `;
9 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v1/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@esphome-webserver/v1",
3 | "version": "1.0.0",
4 | "scripts": {
5 | "build": "mkdir -p ../../_static/v1 && cp ./src/* ../../_static/v1/"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/components/switch/automation.cpp:
--------------------------------------------------------------------------------
1 | #include "automation.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome {
5 | namespace switch_ {
6 |
7 | static const char *const TAG = "switch.automation";
8 |
9 | } // namespace switch_
10 | } // namespace esphome
11 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/src/icon/wifi.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/light/light_output.cpp:
--------------------------------------------------------------------------------
1 | #include "light_output.h"
2 | #include "transformers.h"
3 |
4 | namespace esphome::light {
5 |
6 | std::unique_ptr LightOutput::create_default_transition() {
7 | return make_unique();
8 | }
9 |
10 | } // namespace esphome::light
11 |
--------------------------------------------------------------------------------
/components/template/event/template_event.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/components/event/event.h"
5 |
6 | namespace esphome::template_ {
7 |
8 | class TemplateEvent final : public Component, public event::Event {};
9 |
10 | } // namespace esphome::template_
11 |
--------------------------------------------------------------------------------
/components/esp8266/core.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef USE_ESP8266
4 |
5 | #include
6 |
7 | extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_MODE[16];
8 | extern const uint8_t ESPHOME_ESP8266_GPIO_INITIAL_LEVEL[16];
9 |
10 | namespace esphome::esp8266 {} // namespace esphome::esp8266
11 |
12 | #endif // USE_ESP8266
13 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/public/config.json:
--------------------------------------------------------------------------------
1 | {"name":"My ESPhome",
2 | "aps":[
3 | {}
4 | ,{"ssid":"Hermione","rssi":-50,"lock":0}
5 | ,{"ssid":"Neville","rssi":-65,"lock":1}
6 | ,{"ssid":"Gandalf the Grey","rssi":-85,"lock":1}
7 | ,{"ssid":"Hagrid","rssi":-95,"lock":0}
8 | ]
9 | }
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/src/esp-logo.ts:
--------------------------------------------------------------------------------
1 | import { LitElement, svg } from "lit";
2 | import { customElement } from "lit/decorators.js";
3 |
4 | import logo from "/logo.svg?raw";
5 |
6 | @customElement("esp-logo")
7 | export default class EspLogo extends LitElement {
8 | render() {
9 | return svg([logo]);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/esp-logo.ts:
--------------------------------------------------------------------------------
1 | import { LitElement, svg } from "lit";
2 | import { customElement } from "lit/decorators.js";
3 |
4 | import logo from "/logo.svg?raw";
5 |
6 | @customElement("esp-logo")
7 | export default class EspLogo extends LitElement {
8 | render() {
9 | return svg([logo]);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/components/template/button/__init__.py:
--------------------------------------------------------------------------------
1 | from esphome.components import button
2 |
3 | from .. import template_ns
4 |
5 | TemplateButton = template_ns.class_("TemplateButton", button.Button)
6 |
7 | CONFIG_SCHEMA = button.button_schema(TemplateButton)
8 |
9 |
10 | async def to_code(config):
11 | await button.new_button(config)
12 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/css/reset.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | :host, button, select, input {
5 | font-family: ui-monospace, system-ui, "Helvetica", "Roboto",
6 | "Oxygen", "Ubuntu", sans-serif;
7 | --primary-color: #03a9f4;
8 | transition: all 350ms !important;
9 | }
10 | `;
11 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/src/icon/lock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/src/css/reset.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | :host {
5 | font-family: ui-monospace, system-ui, "Helvetica", "Arial Narrow", "Roboto",
6 | "Oxygen", "Ubuntu", sans-serif;
7 | color-scheme: light dark;
8 | --primary-color: #03a9f4;
9 | transition: all 350ms !important;
10 | }
11 | `;
12 |
--------------------------------------------------------------------------------
/esphome-webserver/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "esphome-webserver",
3 | "version": "3.0.0",
4 | "license": "MIT",
5 | "workspaces": [
6 | "packages/*"
7 | ],
8 | "scripts": {
9 | "build": "npm run build:packages && npm run deploy",
10 | "build:packages": "npm run build --workspaces --if-present",
11 | "deploy": "npm run deploy --workspaces --if-present"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/components/template/button/template_button.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/components/button/button.h"
4 |
5 | namespace esphome::template_ {
6 |
7 | class TemplateButton final : public button::Button {
8 | public:
9 | // Implements the abstract `press_action` but the `on_press` trigger already handles the press.
10 | void press_action() override{};
11 | };
12 |
13 | } // namespace esphome::template_
14 |
--------------------------------------------------------------------------------
/components/esp8266/preferences.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef USE_ESP8266
4 |
5 | #include "esphome/components/globals/globals_component.h"
6 |
7 | namespace esphome::esp8266 {
8 |
9 | void setup_preferences(uint32_t start_free);
10 | void preferences_prevent_write(bool prevent);
11 |
12 | void set_global_addr(globals::GlobalsComponent *ga_in);
13 |
14 | } // namespace esphome::esp8266
15 |
16 | #endif // USE_ESP8266
17 |
--------------------------------------------------------------------------------
/components/esp8266/const.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 |
3 | KEY_ESP8266 = "esp8266"
4 | KEY_BOARD = "board"
5 | KEY_PIN_INITIAL_STATES = "pin_initial_states"
6 | CONF_RESTORE_FROM_FLASH = "restore_from_flash"
7 | CONF_EARLY_PIN_INIT = "early_pin_init"
8 | KEY_FLASH_SIZE = "flash_size"
9 |
10 | # esp8266 namespace is already defined by arduino, manually prefix esphome
11 | esp8266_ns = cg.global_ns.namespace("esphome").namespace("esp8266")
12 |
--------------------------------------------------------------------------------
/components/gpio/output/gpio_binary_output.cpp:
--------------------------------------------------------------------------------
1 | #include "gpio_binary_output.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome {
5 | namespace gpio {
6 |
7 | static const char *const TAG = "gpio.output";
8 |
9 | void GPIOBinaryOutput::dump_config() {
10 | ESP_LOGCONFIG(TAG, "Binary Output:");
11 | LOG_PIN(" Pin: ", this->pin_);
12 | LOG_BINARY_OUTPUT(this);
13 | }
14 |
15 | } // namespace gpio
16 | } // namespace esphome
17 |
--------------------------------------------------------------------------------
/components/light/automation.cpp:
--------------------------------------------------------------------------------
1 | #include "automation.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome::light {
5 |
6 | static const char *const TAG = "light.automation";
7 |
8 | void addressableset_warn_about_scale(const char *field) {
9 | ESP_LOGW(TAG, "Lambda for parameter %s of light.addressable_set should return values in range 0-1 instead of 0-255.",
10 | field);
11 | }
12 |
13 | } // namespace esphome::light
14 |
--------------------------------------------------------------------------------
/components/safe_mode/automation.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include "safe_mode.h"
3 |
4 | #include "esphome/core/automation.h"
5 |
6 | namespace esphome {
7 | namespace safe_mode {
8 |
9 | class SafeModeTrigger : public Trigger<> {
10 | public:
11 | explicit SafeModeTrigger(SafeModeComponent *parent) {
12 | parent->add_on_safe_mode_callback([this]() { trigger(); });
13 | }
14 | };
15 |
16 | } // namespace safe_mode
17 | } // namespace esphome
18 |
--------------------------------------------------------------------------------
/components/template/lock/automation.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "template_lock.h"
4 |
5 | #include "esphome/core/automation.h"
6 |
7 | namespace esphome::template_ {
8 |
9 | template class TemplateLockPublishAction : public Action, public Parented {
10 | public:
11 | TEMPLATABLE_VALUE(lock::LockState, state)
12 |
13 | void play(const Ts &...x) override { this->parent_->publish_state(this->state_.value(x...)); }
14 | };
15 |
16 | } // namespace esphome::template_
17 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/css/tab.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | .tab-header {
5 | display: inline-flex;
6 | min-height: 40px;
7 | font-weight: 400;
8 | padding-inline: 1.5em;
9 | align-items: center;
10 | border-radius: 12px 12px 0px 0px;
11 | background-color: rgba(127, 127, 127, 0.3);
12 | margin-top: 1em;
13 | user-select: none;
14 | }
15 | .tab-container {
16 | border: 2px solid rgba(127, 127, 127, 0.3);
17 | border-radius: 0px 12px 12px 12px;
18 | }
19 | `;
20 |
--------------------------------------------------------------------------------
/components/switch/binary_sensor/switch_binary_sensor.cpp:
--------------------------------------------------------------------------------
1 | #include "switch_binary_sensor.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome {
5 | namespace switch_ {
6 |
7 | static const char *const TAG = "switch.binary_sensor";
8 |
9 | void SwitchBinarySensor::setup() {
10 | source_->add_on_state_callback([this](bool value) { this->publish_state(value); });
11 | this->publish_state(source_->state);
12 | }
13 |
14 | void SwitchBinarySensor::dump_config() { LOG_BINARY_SENSOR("", "Switch Binary Sensor", this); }
15 |
16 | } // namespace switch_
17 | } // namespace esphome
18 |
--------------------------------------------------------------------------------
/components/switch/binary_sensor/switch_binary_sensor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "../switch.h"
4 | #include "esphome/core/component.h"
5 | #include "esphome/components/binary_sensor/binary_sensor.h"
6 |
7 | namespace esphome {
8 | namespace switch_ {
9 |
10 | class SwitchBinarySensor : public binary_sensor::BinarySensor, public Component {
11 | public:
12 | void set_source(Switch *source) { source_ = source; }
13 | void setup() override;
14 | void dump_config() override;
15 |
16 | protected:
17 | Switch *source_;
18 | };
19 |
20 | } // namespace switch_
21 | } // namespace esphome
22 |
--------------------------------------------------------------------------------
/components/safe_mode/button/safe_mode_button.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/components/button/button.h"
4 | #include "esphome/components/safe_mode/safe_mode.h"
5 | #include "esphome/core/component.h"
6 |
7 | namespace esphome {
8 | namespace safe_mode {
9 |
10 | class SafeModeButton : public button::Button, public Component {
11 | public:
12 | void dump_config() override;
13 | void set_safe_mode(SafeModeComponent *safe_mode_component);
14 |
15 | protected:
16 | SafeModeComponent *safe_mode_component_;
17 | void press_action() override;
18 | };
19 |
20 | } // namespace safe_mode
21 | } // namespace esphome
22 |
--------------------------------------------------------------------------------
/components/safe_mode/switch/safe_mode_switch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/components/safe_mode/safe_mode.h"
4 | #include "esphome/components/switch/switch.h"
5 | #include "esphome/core/component.h"
6 |
7 | namespace esphome {
8 | namespace safe_mode {
9 |
10 | class SafeModeSwitch : public switch_::Switch, public Component {
11 | public:
12 | void dump_config() override;
13 | void set_safe_mode(SafeModeComponent *safe_mode_component);
14 |
15 | protected:
16 | SafeModeComponent *safe_mode_component_;
17 | void write_state(bool state) override;
18 | };
19 |
20 | } // namespace safe_mode
21 | } // namespace esphome
22 |
--------------------------------------------------------------------------------
/components/template/sensor/template_sensor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/template_lambda.h"
5 | #include "esphome/components/sensor/sensor.h"
6 |
7 | namespace esphome::template_ {
8 |
9 | class TemplateSensor final : public sensor::Sensor, public PollingComponent {
10 | public:
11 | template void set_template(F &&f) { this->f_.set(std::forward(f)); }
12 |
13 | void update() override;
14 |
15 | void dump_config() override;
16 |
17 | float get_setup_priority() const override;
18 |
19 | protected:
20 | TemplateLambda f_;
21 | };
22 |
23 | } // namespace esphome::template_
24 |
--------------------------------------------------------------------------------
/components/template/text_sensor/template_text_sensor.cpp:
--------------------------------------------------------------------------------
1 | #include "template_text_sensor.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome::template_ {
5 |
6 | static const char *const TAG = "template.text_sensor";
7 |
8 | void TemplateTextSensor::update() {
9 | if (!this->f_.has_value())
10 | return;
11 |
12 | auto val = this->f_();
13 | if (val.has_value()) {
14 | this->publish_state(*val);
15 | }
16 | }
17 |
18 | float TemplateTextSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
19 |
20 | void TemplateTextSensor::dump_config() { LOG_TEXT_SENSOR("", "Template Sensor", this); }
21 |
22 | } // namespace esphome::template_
23 |
--------------------------------------------------------------------------------
/components/template/event/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 | from esphome.components import event
3 | import esphome.config_validation as cv
4 | from esphome.const import CONF_EVENT_TYPES
5 |
6 | from .. import template_ns
7 |
8 | CODEOWNERS = ["@nohat"]
9 |
10 | TemplateEvent = template_ns.class_("TemplateEvent", event.Event, cg.Component)
11 |
12 | CONFIG_SCHEMA = event.event_schema(TemplateEvent).extend(
13 | {
14 | cv.Required(CONF_EVENT_TYPES): cv.ensure_list(cv.string_strict),
15 | }
16 | )
17 |
18 |
19 | async def to_code(config):
20 | var = await event.new_event(config, event_types=config[CONF_EVENT_TYPES])
21 | await cg.register_component(var, config)
22 |
--------------------------------------------------------------------------------
/components/template/binary_sensor/template_binary_sensor.cpp:
--------------------------------------------------------------------------------
1 | #include "template_binary_sensor.h"
2 | #include "esphome/core/log.h"
3 |
4 | namespace esphome::template_ {
5 |
6 | static const char *const TAG = "template.binary_sensor";
7 |
8 | void TemplateBinarySensor::setup() {
9 | if (!this->f_.has_value()) {
10 | this->disable_loop();
11 | } else {
12 | this->loop();
13 | }
14 | }
15 |
16 | void TemplateBinarySensor::loop() {
17 | auto s = this->f_();
18 | if (s.has_value()) {
19 | this->publish_state(*s);
20 | }
21 | }
22 |
23 | void TemplateBinarySensor::dump_config() { LOG_BINARY_SENSOR("", "Template Binary Sensor", this); }
24 |
25 | } // namespace esphome::template_
26 |
--------------------------------------------------------------------------------
/components/template/sensor/template_sensor.cpp:
--------------------------------------------------------------------------------
1 | #include "template_sensor.h"
2 | #include "esphome/core/log.h"
3 | #include
4 |
5 | namespace esphome::template_ {
6 |
7 | static const char *const TAG = "template.sensor";
8 |
9 | void TemplateSensor::update() {
10 | if (!this->f_.has_value())
11 | return;
12 |
13 | auto val = this->f_();
14 | if (val.has_value()) {
15 | this->publish_state(*val);
16 | }
17 | }
18 |
19 | float TemplateSensor::get_setup_priority() const { return setup_priority::HARDWARE; }
20 |
21 | void TemplateSensor::dump_config() {
22 | LOG_SENSOR("", "Template Sensor", this);
23 | LOG_UPDATE_INTERVAL(this);
24 | }
25 |
26 | } // namespace esphome::template_
27 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/public/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/components/light/light_json_schema.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/defines.h"
4 |
5 | #ifdef USE_JSON
6 |
7 | #include "esphome/components/json/json_util.h"
8 | #include "light_call.h"
9 | #include "light_state.h"
10 |
11 | namespace esphome::light {
12 |
13 | class LightJSONSchema {
14 | public:
15 | /// Dump the state of a light as JSON.
16 | static void dump_json(LightState &state, JsonObject root);
17 | /// Parse the JSON state of a light to a LightCall.
18 | static void parse_json(LightState &state, LightCall &call, JsonObject root);
19 |
20 | protected:
21 | static void parse_color_json(LightState &state, LightCall &call, JsonObject root);
22 | };
23 |
24 | } // namespace esphome::light
25 |
26 | #endif
27 |
--------------------------------------------------------------------------------
/components/captive_portal/dns_server_esp32_idf.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifdef USE_ESP_IDF
3 |
4 | #include
5 | #include "esphome/core/helpers.h"
6 | #include "esphome/components/network/ip_address.h"
7 | #include "esphome/components/socket/socket.h"
8 |
9 | namespace esphome::captive_portal {
10 |
11 | class DNSServer {
12 | public:
13 | void start(const network::IPAddress &ip);
14 | void stop();
15 | void process_next_request();
16 |
17 | protected:
18 | static constexpr size_t DNS_BUFFER_SIZE = 192;
19 |
20 | std::unique_ptr socket_{nullptr};
21 | network::IPAddress server_ip_;
22 | uint8_t buffer_[DNS_BUFFER_SIZE];
23 | };
24 |
25 | } // namespace esphome::captive_portal
26 |
27 | #endif // USE_ESP_IDF
28 |
--------------------------------------------------------------------------------
/components/template/text_sensor/template_text_sensor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/automation.h"
5 | #include "esphome/core/template_lambda.h"
6 | #include "esphome/components/text_sensor/text_sensor.h"
7 |
8 | namespace esphome::template_ {
9 |
10 | class TemplateTextSensor final : public text_sensor::TextSensor, public PollingComponent {
11 | public:
12 | template void set_template(F &&f) { this->f_.set(std::forward(f)); }
13 |
14 | void update() override;
15 |
16 | float get_setup_priority() const override;
17 |
18 | void dump_config() override;
19 |
20 | protected:
21 | TemplateLambda f_{};
22 | };
23 |
24 | } // namespace esphome::template_
25 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/src/css/button.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | button,
5 | .btn {
6 | cursor: pointer;
7 | border-radius: 4px;
8 | color: rgb(3, 169, 244);
9 | border: none;
10 | background-color: unset;
11 | padding: 8px;
12 | font-weight: 500;
13 | font-size: 12.25px;
14 | letter-spacing: 1.09375px;
15 | text-transform: uppercase;
16 | margin-right: -8px;
17 | }
18 |
19 | button:active,
20 | .btn:active {
21 | background-image: rgba(127, 127, 127, 0.2);
22 | transition-duration: 1s;
23 | }
24 |
25 | button:hover,
26 | .btn:hover {
27 | background-color: rgba(127, 127, 127, 0.2);
28 | transition-duration: 1s;
29 | }
30 | `;
31 |
--------------------------------------------------------------------------------
/components/web_server/ota/ota_web_server.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/defines.h"
4 | #ifdef USE_WEBSERVER_OTA
5 |
6 | #include "esphome/components/ota/ota_backend.h"
7 | #include "esphome/components/web_server_base/web_server_base.h"
8 | #include "esphome/core/component.h"
9 |
10 | namespace esphome {
11 | namespace web_server {
12 |
13 | class WebServerOTAComponent : public ota::OTAComponent {
14 | public:
15 | void setup() override;
16 | void dump_config() override;
17 | float get_setup_priority() const override { return setup_priority::AFTER_WIFI; }
18 |
19 | protected:
20 | friend class OTARequestHandler;
21 | };
22 |
23 | } // namespace web_server
24 | } // namespace esphome
25 |
26 | #endif // USE_WEBSERVER_OTA
27 |
--------------------------------------------------------------------------------
/components/template/binary_sensor/template_binary_sensor.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/template_lambda.h"
5 | #include "esphome/components/binary_sensor/binary_sensor.h"
6 |
7 | namespace esphome::template_ {
8 |
9 | class TemplateBinarySensor final : public Component, public binary_sensor::BinarySensor {
10 | public:
11 | template void set_template(F &&f) { this->f_.set(std::forward(f)); }
12 |
13 | void setup() override;
14 | void loop() override;
15 | void dump_config() override;
16 |
17 | float get_setup_priority() const override { return setup_priority::HARDWARE; }
18 |
19 | protected:
20 | TemplateLambda f_;
21 | };
22 |
23 | } // namespace esphome::template_
24 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/public/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/components/template/valve/automation.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "template_valve.h"
4 |
5 | #include "esphome/core/automation.h"
6 |
7 | namespace esphome::template_ {
8 |
9 | template class TemplateValvePublishAction : public Action, public Parented {
10 | TEMPLATABLE_VALUE(float, position)
11 | TEMPLATABLE_VALUE(valve::ValveOperation, current_operation)
12 |
13 | void play(const Ts &...x) override {
14 | if (this->position_.has_value())
15 | this->parent_->position = this->position_.value(x...);
16 | if (this->current_operation_.has_value())
17 | this->parent_->current_operation = this->current_operation_.value(x...);
18 | this->parent_->publish_state();
19 | }
20 | };
21 |
22 | } // namespace esphome::template_
23 |
--------------------------------------------------------------------------------
/components/ddp/ddp_light_effect.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef USE_ARDUINO
4 |
5 | #include "esphome/core/component.h"
6 | #include "esphome/components/light/light_effect.h"
7 | #include "esphome/components/light/light_output.h"
8 | #include "ddp_light_effect_base.h"
9 |
10 | namespace esphome {
11 | namespace ddp {
12 |
13 | class DDPLightEffect : public DDPLightEffectBase, public light::LightEffect {
14 | public:
15 | DDPLightEffect(const char *name);
16 |
17 | const char *get_name() override;
18 |
19 | void start() override;
20 | void stop() override;
21 | void apply() override;
22 |
23 | protected:
24 | uint16_t process_(const uint8_t *payload, uint16_t size, uint16_t used) override;
25 | };
26 |
27 | } // namespace ddp
28 | } // namespace esphome
29 |
30 | #endif // ESPHOME_DDP_LIGHT_EFFECT_H
31 |
--------------------------------------------------------------------------------
/components/esp8266/post_build.py.script:
--------------------------------------------------------------------------------
1 | import shutil
2 |
3 | # pylint: disable=E0602
4 | Import("env") # noqa
5 |
6 |
7 | def esp8266_copy_factory_bin(source, target, env):
8 | firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
9 | new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.factory.bin")
10 |
11 | shutil.copyfile(firmware_name, new_file_name)
12 |
13 |
14 | def esp8266_copy_ota_bin(source, target, env):
15 | firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin")
16 | new_file_name = env.subst("$BUILD_DIR/${PROGNAME}.ota.bin")
17 |
18 | shutil.copyfile(firmware_name, new_file_name)
19 |
20 |
21 | # pylint: disable=E0602
22 | env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp8266_copy_factory_bin) # noqa
23 | env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", esp8266_copy_ota_bin) # noqa
24 |
--------------------------------------------------------------------------------
/components/gpio/output/gpio_binary_output.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/hal.h"
5 | #include "esphome/components/output/binary_output.h"
6 |
7 | namespace esphome {
8 | namespace gpio {
9 |
10 | class GPIOBinaryOutput : public output::BinaryOutput, public Component {
11 | public:
12 | void set_pin(GPIOPin *pin) { pin_ = pin; }
13 |
14 | void setup() override {
15 | this->turn_off();
16 | this->pin_->setup();
17 | this->turn_off();
18 | }
19 | void dump_config() override;
20 | float get_setup_priority() const override { return setup_priority::HARDWARE; }
21 |
22 | protected:
23 | void write_state(bool state) override { this->pin_->digital_write(state); }
24 |
25 | GPIOPin *pin_;
26 | };
27 |
28 | } // namespace gpio
29 | } // namespace esphome
30 |
--------------------------------------------------------------------------------
/components/gpio/one_wire/__init__.py:
--------------------------------------------------------------------------------
1 | from esphome import pins
2 | import esphome.codegen as cg
3 | from esphome.components.one_wire import OneWireBus
4 | import esphome.config_validation as cv
5 | from esphome.const import CONF_ID, CONF_PIN
6 |
7 | from .. import gpio_ns
8 |
9 | CODEOWNERS = ["@ssieb"]
10 |
11 | GPIOOneWireBus = gpio_ns.class_("GPIOOneWireBus", OneWireBus, cg.Component)
12 |
13 | CONFIG_SCHEMA = cv.Schema(
14 | {
15 | cv.GenerateID(): cv.declare_id(GPIOOneWireBus),
16 | cv.Required(CONF_PIN): pins.internal_gpio_output_pin_schema,
17 | }
18 | ).extend(cv.COMPONENT_SCHEMA)
19 |
20 |
21 | async def to_code(config):
22 | var = cg.new_Pvariable(config[CONF_ID])
23 | await cg.register_component(var, config)
24 |
25 | pin = await cg.gpio_pin_expression(config[CONF_PIN])
26 | cg.add(var.set_pin(pin))
27 |
--------------------------------------------------------------------------------
/components/light/esp_color_correction.cpp:
--------------------------------------------------------------------------------
1 | #include "esp_color_correction.h"
2 | #include "light_color_values.h"
3 | #include "esphome/core/log.h"
4 |
5 | namespace esphome::light {
6 |
7 | void ESPColorCorrection::calculate_gamma_table(float gamma) {
8 | for (uint16_t i = 0; i < 256; i++) {
9 | // corrected = val ^ gamma
10 | auto corrected = to_uint8_scale(gamma_correct(i / 255.0f, gamma));
11 | this->gamma_table_[i] = corrected;
12 | }
13 | if (gamma == 0.0f) {
14 | for (uint16_t i = 0; i < 256; i++)
15 | this->gamma_reverse_table_[i] = i;
16 | return;
17 | }
18 | for (uint16_t i = 0; i < 256; i++) {
19 | // val = corrected ^ (1/gamma)
20 | auto uncorrected = to_uint8_scale(powf(i / 255.0f, 1.0f / gamma));
21 | this->gamma_reverse_table_[i] = uncorrected;
22 | }
23 | }
24 |
25 | } // namespace esphome::light
26 |
--------------------------------------------------------------------------------
/components/safe_mode/button/safe_mode_button.cpp:
--------------------------------------------------------------------------------
1 | #include "safe_mode_button.h"
2 | #include "esphome/core/hal.h"
3 | #include "esphome/core/log.h"
4 | #include "esphome/core/application.h"
5 |
6 | namespace esphome {
7 | namespace safe_mode {
8 |
9 | static const char *const TAG = "safe_mode.button";
10 |
11 | void SafeModeButton::set_safe_mode(SafeModeComponent *safe_mode_component) {
12 | this->safe_mode_component_ = safe_mode_component;
13 | }
14 |
15 | void SafeModeButton::press_action() {
16 | ESP_LOGI(TAG, "Restarting in safe mode");
17 | this->safe_mode_component_->set_safe_mode_pending(true);
18 |
19 | // Let MQTT settle a bit
20 | delay(100); // NOLINT
21 | App.safe_reboot();
22 | }
23 |
24 | void SafeModeButton::dump_config() { LOG_BUTTON("", "Safe Mode Button", this); }
25 |
26 | } // namespace safe_mode
27 | } // namespace esphome
28 |
--------------------------------------------------------------------------------
/components/gpio/output/__init__.py:
--------------------------------------------------------------------------------
1 | from esphome import pins
2 | import esphome.codegen as cg
3 | from esphome.components import output
4 | import esphome.config_validation as cv
5 | from esphome.const import CONF_ID, CONF_PIN
6 |
7 | from .. import gpio_ns
8 |
9 | GPIOBinaryOutput = gpio_ns.class_("GPIOBinaryOutput", output.BinaryOutput, cg.Component)
10 |
11 | CONFIG_SCHEMA = output.BINARY_OUTPUT_SCHEMA.extend(
12 | {
13 | cv.Required(CONF_ID): cv.declare_id(GPIOBinaryOutput),
14 | cv.Required(CONF_PIN): pins.gpio_output_pin_schema,
15 | }
16 | ).extend(cv.COMPONENT_SCHEMA)
17 |
18 |
19 | async def to_code(config):
20 | var = cg.new_Pvariable(config[CONF_ID])
21 | await output.register_output(var, config)
22 | await cg.register_component(var, config)
23 |
24 | pin = await cg.gpio_pin_expression(config[CONF_PIN])
25 | cg.add(var.set_pin(pin))
26 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@esphome-webserver/captive-portal",
3 | "version": "2.0.0",
4 | "main": "main.ts",
5 | "license": "MIT",
6 | "scripts": {
7 | "start": "npm run dev",
8 | "dev": "vite",
9 | "build": "vite build && npm run deploy",
10 | "serve": "vite preview",
11 | "deploy": "bash -c '../../scripts/make_header.sh ../../_static/captive_portal captive_index.h captive_portal'"
12 | },
13 | "dependencies": {
14 | "rollup-plugin-generate-html-template": "^1.7.0",
15 | "rollup-plugin-gzip": "^2.5.0",
16 | "rollup-plugin-minify-html-template-literals": "^1.2.0",
17 | "vite-plugin-html": "^2.1.1"
18 | },
19 | "devDependencies": {
20 | "@rollup/plugin-node-resolve": "^13.0.6",
21 | "@types/node": "^15.12.1",
22 | "typescript": "^4.1.3",
23 | "vite": "^2.6.14",
24 | "vite-plugin-singlefile": "^0.5.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/components/switch/binary_sensor/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 | from esphome.components import binary_sensor
3 | import esphome.config_validation as cv
4 | from esphome.const import CONF_SOURCE_ID
5 |
6 | from .. import Switch, switch_ns
7 |
8 | CODEOWNERS = ["@ssieb"]
9 |
10 | SwitchBinarySensor = switch_ns.class_(
11 | "SwitchBinarySensor", binary_sensor.BinarySensor, cg.Component
12 | )
13 |
14 |
15 | CONFIG_SCHEMA = (
16 | binary_sensor.binary_sensor_schema(SwitchBinarySensor)
17 | .extend(
18 | {
19 | cv.Required(CONF_SOURCE_ID): cv.use_id(Switch),
20 | }
21 | )
22 | .extend(cv.COMPONENT_SCHEMA)
23 | )
24 |
25 |
26 | async def to_code(config):
27 | var = await binary_sensor.new_binary_sensor(config)
28 | await cg.register_component(var, config)
29 |
30 | source = await cg.get_variable(config[CONF_SOURCE_ID])
31 | cg.add(var.set_source(source))
32 |
--------------------------------------------------------------------------------
/components/template/output/template_output.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/automation.h"
4 | #include "esphome/components/output/binary_output.h"
5 | #include "esphome/components/output/float_output.h"
6 |
7 | namespace esphome::template_ {
8 |
9 | class TemplateBinaryOutput final : public output::BinaryOutput {
10 | public:
11 | Trigger *get_trigger() const { return trigger_; }
12 |
13 | protected:
14 | void write_state(bool state) override { this->trigger_->trigger(state); }
15 |
16 | Trigger *trigger_ = new Trigger();
17 | };
18 |
19 | class TemplateFloatOutput final : public output::FloatOutput {
20 | public:
21 | Trigger *get_trigger() const { return trigger_; }
22 |
23 | protected:
24 | void write_state(float state) override { this->trigger_->trigger(state); }
25 |
26 | Trigger *trigger_ = new Trigger();
27 | };
28 |
29 | } // namespace esphome::template_
30 |
--------------------------------------------------------------------------------
/components/light/light_effect.cpp:
--------------------------------------------------------------------------------
1 | #include "light_effect.h"
2 | #include "light_state.h"
3 |
4 | namespace esphome::light {
5 |
6 | uint32_t LightEffect::get_index() const {
7 | if (this->state_ == nullptr) {
8 | return 0;
9 | }
10 | return this->get_index_in_parent_();
11 | }
12 |
13 | bool LightEffect::is_active() const {
14 | if (this->state_ == nullptr) {
15 | return false;
16 | }
17 | return this->get_index() != 0 && this->state_->get_current_effect_index() == this->get_index();
18 | }
19 |
20 | uint32_t LightEffect::get_index_in_parent_() const {
21 | if (this->state_ == nullptr) {
22 | return 0;
23 | }
24 |
25 | const auto &effects = this->state_->get_effects();
26 | for (size_t i = 0; i < effects.size(); i++) {
27 | if (effects[i] == this) {
28 | return i + 1; // Effects are 1-indexed in the API
29 | }
30 | }
31 | return 0; // Not found
32 | }
33 |
34 | } // namespace esphome::light
35 |
--------------------------------------------------------------------------------
/components/monochromatic/monochromatic_light_output.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/components/output/float_output.h"
5 | #include "esphome/components/light/light_output.h"
6 |
7 | namespace esphome {
8 | namespace monochromatic {
9 |
10 | class MonochromaticLightOutput : public light::LightOutput {
11 | public:
12 | void set_output(output::FloatOutput *output) { output_ = output; }
13 | light::LightTraits get_traits() override {
14 | auto traits = light::LightTraits();
15 | traits.set_supported_color_modes({light::ColorMode::BRIGHTNESS});
16 | return traits;
17 | }
18 | void write_state(light::LightState *state) override {
19 | float bright;
20 | state->current_values_as_brightness(&bright);
21 | this->output_->set_level(bright);
22 | }
23 |
24 | protected:
25 | output::FloatOutput *output_;
26 | };
27 |
28 | } // namespace monochromatic
29 | } // namespace esphome
30 |
--------------------------------------------------------------------------------
/components/safe_mode/switch/safe_mode_switch.cpp:
--------------------------------------------------------------------------------
1 | #include "safe_mode_switch.h"
2 | #include "esphome/core/application.h"
3 | #include "esphome/core/hal.h"
4 | #include "esphome/core/log.h"
5 |
6 | namespace esphome {
7 | namespace safe_mode {
8 |
9 | static const char *const TAG = "safe_mode.switch";
10 |
11 | void SafeModeSwitch::set_safe_mode(SafeModeComponent *safe_mode_component) {
12 | this->safe_mode_component_ = safe_mode_component;
13 | }
14 |
15 | void SafeModeSwitch::write_state(bool state) {
16 | // Acknowledge
17 | this->publish_state(false);
18 |
19 | if (state) {
20 | ESP_LOGI(TAG, "Restarting in safe mode");
21 | this->safe_mode_component_->set_safe_mode_pending(true);
22 |
23 | // Let MQTT settle a bit
24 | delay(100); // NOLINT
25 | App.safe_reboot();
26 | }
27 | }
28 |
29 | void SafeModeSwitch::dump_config() { LOG_SWITCH("", "Safe Mode Switch", this); }
30 |
31 | } // namespace safe_mode
32 | } // namespace esphome
33 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { defineConfig } from "vite";
2 | import gzipPlugin from "rollup-plugin-gzip";
3 | import { viteSingleFile } from "vite-plugin-singlefile";
4 |
5 | import minifyHTML from "rollup-plugin-minify-html-template-literals";
6 | import { minifyHtml as ViteMinifyHtml } from "vite-plugin-html";
7 |
8 | export default defineConfig({
9 | clearScreen: false,
10 | plugins: [
11 | viteSingleFile(),
12 | { ...minifyHTML(), enforce: "pre", apply: "build" },
13 | ViteMinifyHtml(),
14 | {
15 | ...gzipPlugin({ filter: /\.(html)$/ }),
16 | enforce: "post",
17 | apply: "build",
18 | },
19 | ],
20 | css: {
21 | postcss: {},
22 | },
23 | build: {
24 | brotliSize: false,
25 | cssCodeSplit: false,
26 | outDir: "../../_static/captive_portal",
27 | assetsInlineLimit: 100000000,
28 | polyfillModulePreload: false,
29 | },
30 | server: {
31 | open: "/", // auto open browser
32 | },
33 | });
34 |
--------------------------------------------------------------------------------
/components/light/esp_hsv_color.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/color.h"
4 | #include "esphome/core/helpers.h"
5 |
6 | namespace esphome::light {
7 |
8 | struct ESPHSVColor {
9 | union {
10 | struct {
11 | union {
12 | uint8_t hue;
13 | uint8_t h;
14 | };
15 | union {
16 | uint8_t saturation;
17 | uint8_t s;
18 | };
19 | union {
20 | uint8_t value;
21 | uint8_t v;
22 | };
23 | };
24 | uint8_t raw[3];
25 | };
26 | inline ESPHSVColor() ESPHOME_ALWAYS_INLINE : h(0), s(0), v(0) { // NOLINT
27 | }
28 | inline ESPHSVColor(uint8_t hue, uint8_t saturation, uint8_t value) ESPHOME_ALWAYS_INLINE : hue(hue),
29 | saturation(saturation),
30 | value(value) {}
31 | Color to_rgb() const;
32 | };
33 |
34 | } // namespace esphome::light
35 |
--------------------------------------------------------------------------------
/components/safe_mode/switch/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 | from esphome.components import switch
3 | import esphome.config_validation as cv
4 | from esphome.const import CONF_SAFE_MODE, ENTITY_CATEGORY_CONFIG, ICON_RESTART_ALERT
5 |
6 | from .. import SafeModeComponent, safe_mode_ns
7 |
8 | DEPENDENCIES = ["safe_mode"]
9 |
10 | SafeModeSwitch = safe_mode_ns.class_("SafeModeSwitch", switch.Switch, cg.Component)
11 |
12 | CONFIG_SCHEMA = (
13 | switch.switch_schema(
14 | SafeModeSwitch,
15 | block_inverted=True,
16 | entity_category=ENTITY_CATEGORY_CONFIG,
17 | icon=ICON_RESTART_ALERT,
18 | )
19 | .extend({cv.GenerateID(CONF_SAFE_MODE): cv.use_id(SafeModeComponent)})
20 | .extend(cv.COMPONENT_SCHEMA)
21 | )
22 |
23 |
24 | async def to_code(config):
25 | var = await switch.new_switch(config)
26 | await cg.register_component(var, config)
27 |
28 | safe_mode_component = await cg.get_variable(config[CONF_SAFE_MODE])
29 | cg.add(var.set_safe_mode(safe_mode_component))
30 |
--------------------------------------------------------------------------------
/components/ddp/ddp_addressable_light_effect.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef USE_ARDUINO
4 |
5 | #include "esphome/core/component.h"
6 | #include "esphome/components/light/addressable_light_effect.h"
7 | #include "ddp_light_effect_base.h"
8 |
9 | namespace esphome {
10 | namespace ddp {
11 |
12 | class DDPAddressableLightEffect : public DDPLightEffectBase, public light::AddressableLightEffect {
13 | public:
14 | DDPAddressableLightEffect(const char *name);
15 |
16 | const char *get_name() override;
17 |
18 | void start() override;
19 | void stop() override;
20 |
21 | void apply(light::AddressableLight &it, const Color ¤t_color) override;
22 |
23 | protected:
24 | uint16_t process_(const uint8_t *payload, uint16_t size, uint16_t used) override;
25 |
26 | float scan_packet_and_return_multiplier_(const uint8_t *payload, uint16_t start, uint16_t end);
27 | float multiplier_from_max_val_(uint8_t max_val);
28 | void set_max_brightness_();
29 |
30 | };
31 |
32 | } // namespace ddp
33 | } // namespace esphome
34 |
35 | #endif // USE_ARDUINO
36 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@esphome-webserver/v2",
3 | "version": "2.0.0",
4 | "scripts": {
5 | "start": "npm run dev",
6 | "dev": "vite",
7 | "xbuild": "vite build --emptyOutDir",
8 | "build": "vite build --emptyOutDir && npm run deploy",
9 | "serve": "vite preview",
10 | "deploy": "bash -c '../../scripts/make_header.sh ../../_static/v2 server_index_v2.h web_server 2'"
11 | },
12 | "dependencies": {
13 | "http-proxy-middleware": "^2.0.1",
14 | "lit": "^2.0.2"
15 | },
16 | "devDependencies": {
17 | "rollup-plugin-copy": "^3.4.0",
18 | "rollup-plugin-gzip": "^2.5.0",
19 | "rollup-plugin-minify-html-template-literals": "^1.2.0",
20 | "@rollup/plugin-node-resolve": "^13.0.6",
21 | "@rollup/plugin-replace": "^3.0.0",
22 | "@types/node": "^15.12.1",
23 | "rollup-plugin-strip-banner": "^2.0.0",
24 | "typescript": "^4.1.3",
25 | "vite": "^2.3.6",
26 | "vite-plugin-html": "^2.1.1",
27 | "vite-plugin-package-version": "^1.0.2",
28 | "vite-plugin-singlefile": "^0.5.1"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/components/template/fan/template_fan.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/components/fan/fan.h"
5 |
6 | namespace esphome::template_ {
7 |
8 | class TemplateFan final : public Component, public fan::Fan {
9 | public:
10 | TemplateFan() {}
11 | void setup() override;
12 | void dump_config() override;
13 | void set_has_direction(bool has_direction) { this->has_direction_ = has_direction; }
14 | void set_has_oscillating(bool has_oscillating) { this->has_oscillating_ = has_oscillating; }
15 | void set_speed_count(int count) { this->speed_count_ = count; }
16 | void set_preset_modes(std::initializer_list presets) { this->preset_modes_ = presets; }
17 | fan::FanTraits get_traits() override { return this->traits_; }
18 |
19 | protected:
20 | void control(const fan::FanCall &call) override;
21 |
22 | bool has_oscillating_{false};
23 | bool has_direction_{false};
24 | int speed_count_{0};
25 | fan::FanTraits traits_;
26 | std::vector preset_modes_{};
27 | };
28 |
29 | } // namespace esphome::template_
30 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/captive-portal/README.md:
--------------------------------------------------------------------------------
1 | # captive-portal
2 | Source code to build esphome captive portal. Output is `captive_index.h` file to be included by the Captive Portal Component https://esphome.io/components/captive_portal.html
3 |
4 | ### Features
5 |
6 | - All assets (css, svg and js) are inlined and served from index.html
7 | - index.html is gzipped, and stored in flash compressed saving ~1K of flash memory from previous version
8 | - ssid scan result is returned via `/config.json` api request
9 |
10 |
11 | development
12 | ===========
13 |
14 | ```
15 | git clone https://github.com/esphome/esphome-webserver.git
16 | cd captive-portal
17 | pnpm install
18 | ```
19 |
20 | `npm run start`
21 | Starts a dev server on http://localhost:3000
22 |
23 | build
24 | =====
25 | `npm run build`
26 | The build files are copied to `dist` folder. `captive_index.h` is built to be deployed to https://github.com/esphome/esphome/tree/dev/esphome/components/captive_portal
27 |
28 |
29 | serve
30 | =====
31 | `npm run server`
32 | Starts a production test server on http://localhost:5001
33 |
--------------------------------------------------------------------------------
/components/gpio/switch/gpio_switch.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/hal.h"
5 | #include "esphome/core/helpers.h"
6 | #include "esphome/components/switch/switch.h"
7 |
8 | namespace esphome {
9 | namespace gpio {
10 |
11 | class GPIOSwitch : public switch_::Switch, public Component {
12 | public:
13 | void set_pin(GPIOPin *pin) { pin_ = pin; }
14 |
15 | // ========== INTERNAL METHODS ==========
16 | // (In most use cases you won't need these)
17 | float get_setup_priority() const override;
18 |
19 | void setup() override;
20 | void dump_config() override;
21 | void set_interlock(const std::initializer_list &interlock);
22 | void set_interlock_wait_time(uint32_t interlock_wait_time) { interlock_wait_time_ = interlock_wait_time; }
23 |
24 | bool is_setup();
25 |
26 | protected:
27 | void write_state(bool state) override;
28 |
29 | GPIOPin *pin_;
30 | FixedVector interlock_;
31 | uint32_t interlock_wait_time_{0};
32 |
33 | bool is_setup_{false};
34 | };
35 |
36 | } // namespace gpio
37 | } // namespace esphome
38 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v2/src/css/button.ts:
--------------------------------------------------------------------------------
1 | import { css } from "lit";
2 |
3 | export default css`
4 | button,
5 | .btn {
6 | cursor: pointer;
7 | border-radius: 4px;
8 | background-color: inherit;
9 | background-image: linear-gradient(
10 | 0deg,
11 | rgba(127, 127, 127, 0.5) 0%,
12 | rgba(127, 127, 127, 0.5) 100%
13 | );
14 | color: inherit;
15 | border: 1px solid rgba(127, 127, 127, 0.5);
16 | padding: 2px;
17 | }
18 |
19 | button:active,
20 | .btn:active {
21 | background-image: linear-gradient(
22 | 0deg,
23 | rgba(127, 127, 127, 0.8) 0%,
24 | rgba(127, 127, 127, 0.2) 100%
25 | );
26 | transition-duration: 1s;
27 | }
28 |
29 | button:hover,
30 | .btn:hover {
31 | background-image: linear-gradient(
32 | 0deg,
33 | rgba(127, 127, 127, 0.2) 0%,
34 | rgba(127, 127, 127, 0.8) 100%
35 | );
36 | transition-duration: 1s;
37 | }
38 |
39 | .rnd {
40 | border-radius: 1rem;
41 | height: 2rem;
42 | width: 2rem;
43 | font-weight: 500;
44 | font-size: 1.2rem;
45 | }
46 | `;
47 |
--------------------------------------------------------------------------------
/components/safe_mode/button/__init__.py:
--------------------------------------------------------------------------------
1 | import esphome.codegen as cg
2 | from esphome.components import button
3 | import esphome.config_validation as cv
4 | from esphome.const import (
5 | CONF_SAFE_MODE,
6 | DEVICE_CLASS_RESTART,
7 | ENTITY_CATEGORY_CONFIG,
8 | ICON_RESTART_ALERT,
9 | )
10 |
11 | from .. import SafeModeComponent, safe_mode_ns
12 |
13 | DEPENDENCIES = ["safe_mode"]
14 |
15 | SafeModeButton = safe_mode_ns.class_("SafeModeButton", button.Button, cg.Component)
16 |
17 | CONFIG_SCHEMA = (
18 | button.button_schema(
19 | SafeModeButton,
20 | device_class=DEVICE_CLASS_RESTART,
21 | entity_category=ENTITY_CATEGORY_CONFIG,
22 | icon=ICON_RESTART_ALERT,
23 | )
24 | .extend({cv.GenerateID(CONF_SAFE_MODE): cv.use_id(SafeModeComponent)})
25 | .extend(cv.COMPONENT_SCHEMA)
26 | )
27 |
28 |
29 | async def to_code(config):
30 | var = await button.new_button(config)
31 | await cg.register_component(var, config)
32 |
33 | safe_mode_component = await cg.get_variable(config[CONF_SAFE_MODE])
34 | cg.add(var.set_safe_mode(safe_mode_component))
35 |
--------------------------------------------------------------------------------
/esphome-webserver/scripts/make_header.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | cat <./$1/$2
3 | #pragma once
4 | // Generated from https://github.com/esphome/esphome-webserver
5 |
6 | EOT
7 |
8 | if [ -n "$4" ]; then
9 | echo "#ifdef USE_WEBSERVER_LOCAL" >>./$1/$2
10 | echo "#if USE_WEBSERVER_VERSION == $4" >>./$1/$2
11 | echo "" >>./$1/$2
12 | fi
13 |
14 | cat <>./$1/$2
15 | #include "esphome/core/hal.h"
16 |
17 | namespace esphome {
18 | namespace $3 {
19 |
20 | EOT
21 | echo "const uint8_t INDEX_GZ[] PROGMEM = {" >>./$1/$2
22 | xxd -cols 19 -i $1/index.html.gz | sed -e '2,$!d' -e 's/^/ /' -e '$d' | sed -e '$d' | sed -e '$s/$/};/' >>./$1/$2
23 | cat <>./$1/$2
24 |
25 | } // namespace $3
26 | } // namespace esphome
27 | EOT
28 |
29 | if [ -n "$4" ]; then
30 | echo "" >>./$1/$2
31 | echo "#endif" >>./$1/$2
32 | echo "#endif" >>./$1/$2
33 |
34 | if [ "$4" = "3" ]; then
35 | cp ../../_static/v2/server_index_v2.h ../../../components/web_server/
36 | fi
37 | fi
38 |
39 |
40 | if [ "$3" = "captive_portal" ]; then
41 | cp ../../_static/captive_portal/captive_index.h ../../../components/captive_portal/
42 | fi
--------------------------------------------------------------------------------
/components/esp8266/helpers.cpp:
--------------------------------------------------------------------------------
1 | #include "esphome/core/helpers.h"
2 |
3 | #ifdef USE_ESP8266
4 |
5 | #include
6 | #include
7 | // for xt_rsil()/xt_wsr_ps()
8 | #include
9 |
10 | namespace esphome {
11 |
12 | uint32_t random_uint32() { return os_random(); }
13 | bool random_bytes(uint8_t *data, size_t len) { return os_get_random(data, len) == 0; }
14 |
15 | // ESP8266 doesn't have mutexes, but that shouldn't be an issue as it's single-core and non-preemptive OS.
16 | Mutex::Mutex() {}
17 | Mutex::~Mutex() {}
18 | void Mutex::lock() {}
19 | bool Mutex::try_lock() { return true; }
20 | void Mutex::unlock() {}
21 |
22 | IRAM_ATTR InterruptLock::InterruptLock() { state_ = xt_rsil(15); }
23 | IRAM_ATTR InterruptLock::~InterruptLock() { xt_wsr_ps(state_); }
24 |
25 | // ESP8266 doesn't support lwIP core locking, so this is a no-op
26 | LwIPLock::LwIPLock() {}
27 | LwIPLock::~LwIPLock() {}
28 |
29 | void get_mac_address_raw(uint8_t *mac) { // NOLINT(readability-non-const-parameter)
30 | wifi_get_macaddr(STATION_IF, mac);
31 | }
32 |
33 | } // namespace esphome
34 |
35 | #endif // USE_ESP8266
36 |
--------------------------------------------------------------------------------
/components/light/light_output.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "light_traits.h"
5 | #include "light_state.h"
6 | #include "light_transformer.h"
7 |
8 | namespace esphome::light {
9 |
10 | /// Interface to write LightStates to hardware.
11 | class LightOutput {
12 | public:
13 | /// Return the LightTraits of this LightOutput.
14 | virtual LightTraits get_traits() = 0;
15 |
16 | /// Return the default transformer used for transitions.
17 | virtual std::unique_ptr create_default_transition();
18 |
19 | virtual void setup_state(LightState *state) {}
20 |
21 | /// Called on every update of the current values of the associated LightState,
22 | /// can optionally be used to do processing of this change.
23 | virtual void update_state(LightState *state) {}
24 |
25 | /// Called from loop() every time the light state has changed, and should
26 | /// should write the new state to hardware. Every call to write_state() is
27 | /// preceded by (at least) one call to update_state().
28 | virtual void write_state(LightState *state) = 0;
29 | };
30 |
31 | } // namespace esphome::light
32 |
--------------------------------------------------------------------------------
/esphome-webserver/packages/v3/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@esphome-webserver/v3",
3 | "version": "3.0.0",
4 | "scripts": {
5 | "start": "npm run dev",
6 | "dev": "vite",
7 | "xbuild": "vite build --emptyOutDir",
8 | "build": "vite build --emptyOutDir && npm run deploy",
9 | "serve": "vite preview",
10 | "deploy": "bash -c '../../scripts/make_header.sh ../../_static/v3 server_index_v3.h web_server 3'"
11 | },
12 | "dependencies": {
13 | "chart.js": "^4.4.1",
14 | "http-proxy-middleware": "^2.0.1",
15 | "iconify-icon": "^1.0.8",
16 | "lit": "^2.0.2"
17 | },
18 | "devDependencies": {
19 | "rollup-plugin-copy": "^3.4.0",
20 | "rollup-plugin-gzip": "^2.5.0",
21 | "rollup-plugin-minify-html-template-literals": "^1.2.0",
22 | "@rollup/plugin-node-resolve": "^13.0.6",
23 | "@rollup/plugin-replace": "^3.0.0",
24 | "@types/node": "^15.12.1",
25 | "rollup-plugin-strip-banner": "^2.0.0",
26 | "typescript": "^4.1.3",
27 | "vite": "^2.3.6",
28 | "vite-plugin-html": "^2.1.1",
29 | "vite-plugin-package-version": "^1.0.2",
30 | "vite-plugin-singlefile": "^0.5.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/components/ddp/ddp_light_effect_base.cpp:
--------------------------------------------------------------------------------
1 | #ifdef USE_ARDUINO
2 |
3 | #include "ddp.h"
4 | #include "ddp_light_effect_base.h"
5 |
6 | namespace esphome {
7 | namespace ddp {
8 |
9 | DDPLightEffectBase::DDPLightEffectBase() {}
10 |
11 | void DDPLightEffectBase::start() {
12 | if (this->ddp_) {
13 | this->ddp_->add_effect(this);
14 | }
15 | }
16 |
17 | void DDPLightEffectBase::stop() {
18 | if (this->ddp_) {
19 | this->ddp_->remove_effect(this);
20 | }
21 | }
22 |
23 | // returns true if this effect is timed out
24 | // next_packet_will_be_first_ variable keeps it from timing out multiple times
25 | bool DDPLightEffectBase::timeout_check() {
26 |
27 | // don't timeout if timeout is disabled
28 | if ( this->timeout_ == 0) { return false; }
29 |
30 | // don't timeout if no ddp stream was ever started
31 | if ( this->next_packet_will_be_first_ ) { return false; }
32 |
33 | // don't timeout if timeout hasn't been reached
34 | if ( (millis() - this->last_ddp_time_ms_) <= this->timeout_ ) { return false; }
35 |
36 | return true;
37 |
38 | }
39 |
40 | } // namespace ddp
41 | } // namespace esphome
42 |
43 | #endif // USE_ARDUINO
44 |
--------------------------------------------------------------------------------
/esphome-webserver/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 wilberforce
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/components/rgb/rgb_light_output.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/components/output/float_output.h"
5 | #include "esphome/components/light/light_output.h"
6 |
7 | namespace esphome {
8 | namespace rgb {
9 |
10 | class RGBLightOutput : public light::LightOutput {
11 | public:
12 | void set_red(output::FloatOutput *red) { red_ = red; }
13 | void set_green(output::FloatOutput *green) { green_ = green; }
14 | void set_blue(output::FloatOutput *blue) { blue_ = blue; }
15 |
16 | light::LightTraits get_traits() override {
17 | auto traits = light::LightTraits();
18 | traits.set_supported_color_modes({light::ColorMode::RGB});
19 | return traits;
20 | }
21 | void write_state(light::LightState *state) override {
22 | float red, green, blue;
23 | state->current_values_as_rgb(&red, &green, &blue, false);
24 | this->red_->set_level(red);
25 | this->green_->set_level(green);
26 | this->blue_->set_level(blue);
27 | }
28 |
29 | protected:
30 | output::FloatOutput *red_;
31 | output::FloatOutput *green_;
32 | output::FloatOutput *blue_;
33 | };
34 |
35 | } // namespace rgb
36 | } // namespace esphome
37 |
--------------------------------------------------------------------------------
/components/template/lock/template_lock.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include "esphome/core/component.h"
4 | #include "esphome/core/automation.h"
5 | #include "esphome/core/template_lambda.h"
6 | #include "esphome/components/lock/lock.h"
7 |
8 | namespace esphome::template_ {
9 |
10 | class TemplateLock final : public lock::Lock, public Component {
11 | public:
12 | TemplateLock();
13 |
14 | void setup() override;
15 | void dump_config() override;
16 |
17 | template void set_state_lambda(F &&f) { this->f_.set(std::forward(f)); }
18 | Trigger<> *get_lock_trigger() const;
19 | Trigger<> *get_unlock_trigger() const;
20 | Trigger<> *get_open_trigger() const;
21 | void set_optimistic(bool optimistic);
22 | void loop() override;
23 |
24 | float get_setup_priority() const override;
25 |
26 | protected:
27 | void control(const lock::LockCall &call) override;
28 | void open_latch() override;
29 |
30 | TemplateLambda f_;
31 | bool optimistic_{false};
32 | Trigger<> *lock_trigger_;
33 | Trigger<> *unlock_trigger_;
34 | Trigger<> *open_trigger_;
35 | Trigger<> *prev_trigger_{nullptr};
36 | };
37 |
38 | } // namespace esphome::template_
39 |
--------------------------------------------------------------------------------
/components/ddp/ddp.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef USE_ARDUINO
4 |
5 | #include "esphome/core/component.h"
6 |
7 | #ifdef USE_ESP32
8 | #include
9 | #endif
10 |
11 | #ifdef USE_ESP8266
12 | #include
13 | #include
14 | #endif
15 |
16 | #ifdef USE_LIBRETINY
17 | #include
18 | #include
19 | #endif
20 |
21 | #include