22static const char *
const TAG =
"api";
30 ESP_LOGCONFIG(TAG,
"Setting up Home Assistant API server...");
34 uint32_t hash = 88491486UL;
40 ESP_LOGD(TAG,
"Loaded saved Noise PSK");
48 ESP_LOGW(TAG,
"Could not create socket");
53 int err = this->
socket_->setsockopt(SOL_SOCKET, SO_REUSEADDR, &enable,
sizeof(
int));
55 ESP_LOGW(TAG,
"Socket unable to set reuseaddr: errno %d", err);
58 err = this->
socket_->setblocking(
false);
60 ESP_LOGW(TAG,
"Socket unable to set nonblocking mode: errno %d", err);
69 ESP_LOGW(TAG,
"Socket unable to set sockaddr: errno %d", errno);
76 ESP_LOGW(TAG,
"Socket unable to bind: errno %d", errno);
83 ESP_LOGW(TAG,
"Socket unable to listen: errno %d", errno);
93 c->try_send_log_message(level, tag, message);
101#ifdef USE_ESP32_CAMERA
104 [
this](
const std::shared_ptr<esp32_camera::CameraImage> &image) {
107 c->set_camera_state(image);
118 socklen_t addr_len =
sizeof(source_addr);
119 auto sock = this->
socket_->accept((
struct sockaddr *) &source_addr, &addr_len);
122 ESP_LOGD(TAG,
"Accepted %s", sock->getpeername().c_str());
131 size_t client_index = 0;
132 while (client_index < this->
clients_.size()) {
133 auto &client = this->
clients_[client_index];
135 if (client->remove_) {
138 ESP_LOGV(TAG,
"Removing connection to %s", client->client_info_.c_str());
141 if (client_index < this->
clients_.size() - 1) {
155 const uint32_t now =
millis();
158 ESP_LOGE(TAG,
"No client connected to API. Rebooting...");
170 ESP_LOGCONFIG(TAG,
"API Server:");
173 ESP_LOGCONFIG(TAG,
" Using noise encryption: %s", YESNO(this->
noise_ctx_->has_psk()));
175 ESP_LOGCONFIG(TAG,
" Supports noise encryption: YES");
178 ESP_LOGCONFIG(TAG,
" Using noise encryption: NO");
187 uint32_t len_a = this->
password_.length();
188 const char *b = password.c_str();
189 uint32_t len_b = password.length();
192 volatile uint32_t
length = len_b;
193 volatile const char *left =
nullptr;
194 volatile const char *right = b;
198 left = *((
volatile const char **) &a);
206 for (
size_t i = 0; i <
length; i++) {
207 result |= *left++ ^ *right++;
215#ifdef USE_BINARY_SENSOR
220 c->send_binary_sensor_state(obj,
state);
229 c->send_cover_state(obj);
238 c->send_fan_state(obj);
247 c->send_light_state(obj);
256 c->send_sensor_state(obj,
state);
265 c->send_switch_state(obj,
state);
269#ifdef USE_TEXT_SENSOR
274 c->send_text_sensor_state(obj,
state);
283 c->send_climate_state(obj);
292 c->send_number_state(obj,
state);
296#ifdef USE_DATETIME_DATE
301 c->send_date_state(obj);
305#ifdef USE_DATETIME_TIME
310 c->send_time_state(obj);
314#ifdef USE_DATETIME_DATETIME
319 c->send_datetime_state(obj);
328 c->send_text_state(obj,
state);
337 c->send_select_state(obj,
state);
346 c->send_lock_state(obj, obj->
state);
355 c->send_valve_state(obj);
359#ifdef USE_MEDIA_PLAYER
364 c->send_media_player_state(obj);
371 c->send_event(obj, event_type);
378 c->send_update_state(obj);
382#ifdef USE_ALARM_CONTROL_PANEL
387 c->send_alarm_control_panel_state(obj);
398 for (
auto &client : this->
clients_) {
399 client->send_homeassistant_service_call(
call);
404 std::function<
void(std::string)> f) {
406 .entity_id = std::move(entity_id),
407 .attribute = std::move(attribute),
408 .callback = std::move(f),
414 std::function<
void(std::string)> f) {
416 .entity_id = std::move(entity_id),
417 .attribute = std::move(attribute),
418 .callback = std::move(f),
434 if (std::equal(old_psk.begin(), old_psk.end(), psk.begin())) {
435 ESP_LOGW(TAG,
"New PSK matches old");
441 ESP_LOGW(TAG,
"Failed to save Noise PSK");
446 ESP_LOGW(TAG,
"Failed to sync preferences");
449 ESP_LOGD(TAG,
"Noise PSK saved");
452 ESP_LOGW(TAG,
"Disconnecting all clients to reset connections");
463#ifdef USE_HOMEASSISTANT_TIME
465 for (
auto &client : this->
clients_) {
466 if (!client->remove_ && client->is_authenticated())
467 client->send_time_request();
virtual void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message="unspecified")
void status_clear_warning()
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
void setup_controller(bool include_internal=false)
virtual bool sync()=0
Commit pending writes to flash.
virtual ESPPreferenceObject make_preference(size_t length, uint32_t type, bool in_flash)=0
void trigger(Ts... x)
Inform the parent automation that the event has triggered.
void on_valve_update(valve::Valve *obj) override
std::vector< std::unique_ptr< APIConnection > > clients_
void on_select_update(select::Select *obj, const std::string &state, size_t index) override
void send_homeassistant_service_call(const HomeassistantServiceResponse &call)
void set_password(const std::string &password)
void on_time_update(datetime::TimeEntity *obj) override
void on_cover_update(cover::Cover *obj) override
void on_binary_sensor_update(binary_sensor::BinarySensor *obj, bool state) override
void on_sensor_update(sensor::Sensor *obj, float state) override
void on_light_update(light::LightState *obj) override
void on_media_player_update(media_player::MediaPlayer *obj) override
void set_port(uint16_t port)
void dump_config() override
void handle_disconnect(APIConnection *conn)
void set_reboot_timeout(uint32_t reboot_timeout)
bool save_noise_psk(psk_t psk, bool make_active=true)
void on_lock_update(lock::Lock *obj) override
void on_date_update(datetime::DateEntity *obj) override
bool uses_password() const
bool is_connected() const
void on_update(update::UpdateEntity *obj) override
bool check_password(const std::string &password) const
void get_home_assistant_state(std::string entity_id, optional< std::string > attribute, std::function< void(std::string)> f)
const std::vector< HomeAssistantStateSubscription > & get_state_subs() const
std::shared_ptr< APINoiseContext > noise_ctx_
void on_number_update(number::Number *obj, float state) override
void on_text_update(text::Text *obj, const std::string &state) override
Trigger< std::string, std::string > * client_disconnected_trigger_
void subscribe_home_assistant_state(std::string entity_id, optional< std::string > attribute, std::function< void(std::string)> f)
void on_climate_update(climate::Climate *obj) override
ESPPreferenceObject noise_pref_
void on_text_sensor_update(text_sensor::TextSensor *obj, const std::string &state) override
void on_fan_update(fan::Fan *obj) override
std::vector< HomeAssistantStateSubscription > state_subs_
void on_switch_update(switch_::Switch *obj, bool state) override
uint16_t get_port() const
void set_noise_psk(psk_t psk)
void on_datetime_update(datetime::DateTimeEntity *obj) override
void on_event(event::Event *obj, const std::string &event_type) override
float get_setup_priority() const override
std::unique_ptr< socket::Socket > socket_
void on_shutdown() override
void on_alarm_control_panel_update(alarm_control_panel::AlarmControlPanel *obj) override
Base class for all binary_sensor-type classes.
ClimateDevice - This is the base class for all climate integrations.
Base class for all cover devices.
void add_image_callback(std::function< void(std::shared_ptr< CameraImage >)> &&callback)
This class represents the communication layer between the front-end MQTT layer and the hardware outpu...
Base class for all locks.
LockState state
The current reported state of the lock.
void add_on_log_callback(std::function< void(int, const char *, const char *)> &&callback)
Register a callback that will be called for every log message sent.
Base-class for all numbers.
Base-class for all selects.
Base-class for all sensors.
Base class for all switches.
Base-class for all text inputs.
Base class for all valve devices.
APIServer * global_api_server
std::array< uint8_t, 32 > psk_t
ESP32Camera * global_esp32_camera
std::string get_use_address()
Get the active network hostname.
const float AFTER_WIFI
For components that should be initialized after WiFi is connected.
std::unique_ptr< Socket > socket_ip(int type, int protocol)
Create a socket in the newest available IP domain (IPv6 or IPv4) of the given type and protocol.
socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port)
Set a sockaddr to the any address and specified port for the IP version used by socket_ip().
Providing packet encoding functions for exchanging data with a remote host.
ESPPreferences * global_preferences
void IRAM_ATTR HOT delay(uint32_t ms)
uint32_t IRAM_ATTR HOT millis()
Application App
Global storage of Application pointer - only one Application can exist.