mirror of
https://github.com/esphome/esphome.git
synced 2025-10-24 12:43:51 +01:00
🏗 Merge C++ into python codebase (#504)
## Description: Move esphome-core codebase into esphome (and a bunch of other refactors). See https://github.com/esphome/feature-requests/issues/97 Yes this is a shit ton of work and no there's no way to automate it :( But it will be worth it 👍 Progress: - Core support (file copy etc): 80% - Base Abstractions (light, switch): ~50% - Integrations: ~10% - Working? Yes, (but only with ported components). Other refactors: - Moves all codegen related stuff into a single class: `esphome.codegen` (imported as `cg`) - Rework coroutine syntax - Move from `component/platform.py` to `domain/component.py` structure as with HA - Move all defaults out of C++ and into config validation. - Remove `make_...` helpers from Application class. Reason: Merge conflicts with every single new integration. - Pointer Variables are stored globally instead of locally in setup(). Reason: stack size limit. Future work: - Rework const.py - Move all `CONF_...` into a conf class (usage `conf.UPDATE_INTERVAL` vs `CONF_UPDATE_INTERVAL`). Reason: Less convoluted import block - Enable loading from `custom_components` folder. **Related issue (if applicable):** https://github.com/esphome/feature-requests/issues/97 **Pull request in [esphome-docs](https://github.com/esphome/esphome-docs) with documentation (if applicable):** esphome/esphome-docs#<esphome-docs PR number goes here> ## Checklist: - [ ] The code change is tested and works locally. - [ ] Tests have been added to verify that the new code works (under `tests/` folder). If user exposed functionality or configuration variables are added/changed: - [ ] Documentation added/updated in [esphomedocs](https://github.com/OttoWinter/esphomedocs).
This commit is contained in:
142
esphome/components/web_server/web_server.h
Normal file
142
esphome/components/web_server/web_server.h
Normal file
@@ -0,0 +1,142 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/component.h"
|
||||
#include "esphome/core/controller.h"
|
||||
|
||||
#include <vector>
|
||||
#include <ESPAsyncWebServer.h>
|
||||
|
||||
namespace esphome {
|
||||
namespace web_server {
|
||||
|
||||
/// Internal helper struct that is used to parse incoming URLs
|
||||
struct UrlMatch {
|
||||
std::string domain; ///< The domain of the component, for example "sensor"
|
||||
std::string id; ///< The id of the device that's being accessed, for example "living_room_fan"
|
||||
std::string method; ///< The method that's being called, for example "turn_on"
|
||||
bool valid; ///< Whether this match is valid
|
||||
};
|
||||
|
||||
/** This class allows users to create a web server with their ESP nodes.
|
||||
*
|
||||
* Behind the scenes it's using AsyncWebServer to set up the server. It exposes 3 things:
|
||||
* an index page under '/' that's used to show a simple web interface (the css/js is hosted
|
||||
* by esphome.io by default), an event source under '/events' that automatically sends
|
||||
* all state updates in real time + the debug log. Lastly, there's an REST API available
|
||||
* under the '/light/...', '/sensor/...', ... URLs. A full documentation for this API
|
||||
* can be found under https://esphome.io/web-api/index.html.
|
||||
*/
|
||||
class WebServer : public Controller, public Component, public AsyncWebHandler {
|
||||
public:
|
||||
/// Initialize the web server with the specified port
|
||||
explicit WebServer(uint16_t port);
|
||||
|
||||
/** Set the URL to the CSS <link> that's sent to each client. Defaults to
|
||||
* https://esphome.io/_static/webserver-v1.min.css
|
||||
*
|
||||
* @param css_url The url to the web server stylesheet.
|
||||
*/
|
||||
void set_css_url(const char *css_url);
|
||||
|
||||
/** Set the URL to the script that's embedded in the index page. Defaults to
|
||||
* https://esphome.io/_static/webserver-v1.min.js
|
||||
*
|
||||
* @param js_url The url to the web server script.
|
||||
*/
|
||||
void set_js_url(const char *js_url);
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
/// Setup the internal web server and register handlers.
|
||||
void setup() override;
|
||||
|
||||
void dump_config() override;
|
||||
|
||||
/// MQTT setup priority.
|
||||
float get_setup_priority() const override;
|
||||
|
||||
/// Handle an index request under '/'.
|
||||
void handle_index_request(AsyncWebServerRequest *request);
|
||||
|
||||
void handle_update_request(AsyncWebServerRequest *request);
|
||||
|
||||
#ifdef USE_SENSOR
|
||||
void on_sensor_update(sensor::Sensor *obj, float state) override;
|
||||
/// Handle a sensor request under '/sensor/<id>'.
|
||||
void handle_sensor_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the sensor state with its value as a JSON string.
|
||||
std::string sensor_json(sensor::Sensor *obj, float value);
|
||||
#endif
|
||||
|
||||
#ifdef USE_SWITCH
|
||||
void on_switch_update(switch_::Switch *obj, bool state) override;
|
||||
|
||||
/// Handle a switch request under '/switch/<id>/</turn_on/turn_off/toggle>'.
|
||||
void handle_switch_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the switch state with its value as a JSON string.
|
||||
std::string switch_json(switch_::Switch *obj, bool value);
|
||||
#endif
|
||||
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) override;
|
||||
|
||||
/// Handle a binary sensor request under '/binary_sensor/<id>'.
|
||||
void handle_binary_sensor_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the binary sensor state with its value as a JSON string.
|
||||
std::string binary_sensor_json(binary_sensor::BinarySensor *obj, bool value);
|
||||
#endif
|
||||
|
||||
#ifdef USE_FAN
|
||||
void on_fan_update(fan::FanState *obj) override;
|
||||
|
||||
/// Handle a fan request under '/fan/<id>/</turn_on/turn_off/toggle>'.
|
||||
void handle_fan_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the fan state as a JSON string.
|
||||
std::string fan_json(fan::FanState *obj);
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHT
|
||||
void on_light_update(light::LightState *obj) override;
|
||||
|
||||
/// Handle a light request under '/light/<id>/</turn_on/turn_off/toggle>'.
|
||||
void handle_light_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the light state as a JSON string.
|
||||
std::string light_json(light::LightState *obj);
|
||||
#endif
|
||||
|
||||
#ifdef USE_TEXT_SENSOR
|
||||
void on_text_sensor_update(text_sensor::TextSensor *obj, std::string state) override;
|
||||
|
||||
/// Handle a text sensor request under '/text_sensor/<id>'.
|
||||
void handle_text_sensor_request(AsyncWebServerRequest *request, UrlMatch match);
|
||||
|
||||
/// Dump the text sensor state with its value as a JSON string.
|
||||
std::string text_sensor_json(text_sensor::TextSensor *obj, const std::string &value);
|
||||
#endif
|
||||
|
||||
/// Override the web handler's canHandle method.
|
||||
bool canHandle(AsyncWebServerRequest *request) override;
|
||||
/// Override the web handler's handleRequest method.
|
||||
void handleRequest(AsyncWebServerRequest *request) override;
|
||||
void handleUpload(AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len,
|
||||
bool final) override;
|
||||
/// This web handle is not trivial.
|
||||
bool isRequestHandlerTrivial() override;
|
||||
|
||||
protected:
|
||||
uint16_t port_;
|
||||
AsyncWebServer *server_;
|
||||
AsyncEventSource events_{"/events"};
|
||||
const char *css_url_{nullptr};
|
||||
const char *js_url_{nullptr};
|
||||
uint32_t last_ota_progress_{0};
|
||||
uint32_t ota_read_length_{0};
|
||||
};
|
||||
|
||||
} // namespace web_server
|
||||
} // namespace esphome
|
||||
Reference in New Issue
Block a user