diff --git a/esphome/components/binary_sensor/binary_sensor.h b/esphome/components/binary_sensor/binary_sensor.h index ecf68de74c..591f444387 100644 --- a/esphome/components/binary_sensor/binary_sensor.h +++ b/esphome/components/binary_sensor/binary_sensor.h @@ -74,8 +74,10 @@ class BinarySensor : public EntityBase { // ========== OVERRIDE METHODS ========== // (You'll only need this when creating your own custom binary sensor) - /// Get the default device class for this sensor, or empty string for no default. - ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01") + /** Override this to set the default device class. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual std::string device_class(); protected: diff --git a/esphome/components/cover/cover.h b/esphome/components/cover/cover.h index 779e4a2a46..1b5d3a8fa1 100644 --- a/esphome/components/cover/cover.h +++ b/esphome/components/cover/cover.h @@ -169,7 +169,11 @@ class Cover : public EntityBase { friend CoverCall; virtual void control(const CoverCall &call) = 0; - ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01") + + /** Override this to set the default device class. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual std::string device_class(); optional restore_state_(); diff --git a/esphome/components/esp32/__init__.py b/esphome/components/esp32/__init__.py index 161803eaf4..8214886f8c 100644 --- a/esphome/components/esp32/__init__.py +++ b/esphome/components/esp32/__init__.py @@ -417,7 +417,7 @@ def copy_files(): ) dir = os.path.dirname(__file__) - post_build_file = os.path.join(dir, "post_build.py") + post_build_file = os.path.join(dir, "post_build.py.script") copy_file_if_changed( post_build_file, CORE.relative_build_path("post_build.py"), diff --git a/esphome/components/esp32/post_build.py b/esphome/components/esp32/post_build.py.script similarity index 100% rename from esphome/components/esp32/post_build.py rename to esphome/components/esp32/post_build.py.script diff --git a/esphome/components/esp8266/__init__.py b/esphome/components/esp8266/__init__.py index 34a4a2fadb..7182042770 100644 --- a/esphome/components/esp8266/__init__.py +++ b/esphome/components/esp8266/__init__.py @@ -220,7 +220,7 @@ async def to_code(config): def copy_files(): dir = os.path.dirname(__file__) - post_build_file = os.path.join(dir, "post_build.py") + post_build_file = os.path.join(dir, "post_build.py.script") copy_file_if_changed( post_build_file, CORE.relative_build_path("post_build.py"), diff --git a/esphome/components/esp8266/post_build.py b/esphome/components/esp8266/post_build.py.script similarity index 100% rename from esphome/components/esp8266/post_build.py rename to esphome/components/esp8266/post_build.py.script diff --git a/esphome/components/sensor/sensor.h b/esphome/components/sensor/sensor.h index 794aecca95..d31fe9d834 100644 --- a/esphome/components/sensor/sensor.h +++ b/esphome/components/sensor/sensor.h @@ -150,20 +150,28 @@ class Sensor : public EntityBase { void internal_send_state_to_frontend(float state); protected: - /// Override this to set the default unit of measurement. - ESPDEPRECATED("unit_of_measurement() is deprecated, set property during config validation instead.", "2022.01") + /** Override this to set the default unit of measurement. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual std::string unit_of_measurement(); // NOLINT - /// Override this to set the default accuracy in decimals. - ESPDEPRECATED("accuracy_decimals() is deprecated, set property during config validation instead.", "2022.01") + /** Override this to set the default accuracy in decimals. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual int8_t accuracy_decimals(); // NOLINT - /// Override this to set the default device class. - ESPDEPRECATED("device_class() is deprecated, set property during config validation instead.", "2022.01") + /** Override this to set the default device class. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual std::string device_class(); // NOLINT - /// Override this to set the default state class. - ESPDEPRECATED("state_class() is deprecated, set property during config validation instead.", "2022.01") + /** Override this to set the default state class. + * + * @deprecated This method is deprecated, set the property during config validation instead. (2022.1) + */ virtual StateClass state_class(); // NOLINT uint32_t hash_base() override; diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 4cc77da256..7413af67c4 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -236,7 +236,18 @@ void WebServer::handle_index_request(AsyncWebServerRequest *request) { #ifdef USE_NUMBER for (auto *obj : App.get_numbers()) if (this->include_internal_ || !obj->is_internal()) - write_row(stream, obj, "number", ""); + write_row(stream, obj, "number", "", [](AsyncResponseStream &stream, EntityBase *obj) { + number::Number *number = (number::Number *) obj; + stream.print(R"(traits.get_min_value()); + stream.print(R"(" max=")"); + stream.print(number->traits.get_max_value()); + stream.print(R"(" step=")"); + stream.print(number->traits.get_step()); + stream.print(R"(" value=")"); + stream.print(number->state); + stream.print(R"("/>)"); + }); #endif #ifdef USE_SELECT @@ -652,8 +663,29 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM for (auto *obj : App.get_numbers()) { if (obj->get_object_id() != match.id) continue; - std::string data = this->number_json(obj, obj->state); - request->send(200, "text/json", data.c_str()); + + if (request->method() == HTTP_GET) { + std::string data = this->number_json(obj, obj->state); + request->send(200, "text/json", data.c_str()); + return; + } + + if (match.method != "set") { + request->send(404); + return; + } + + auto call = obj->make_call(); + + if (request->hasParam("value")) { + String value = request->getParam("value")->value(); + optional value_f = parse_number(value.c_str()); + if (value_f.has_value()) + call.set_value(*value_f); + } + + this->defer([call]() mutable { call.perform(); }); + request->send(200); return; } request->send(404); @@ -661,9 +693,8 @@ void WebServer::handle_number_request(AsyncWebServerRequest *request, const UrlM std::string WebServer::number_json(number::Number *obj, float value) { return json::build_json([obj, value](JsonObject root) { root["id"] = "number-" + obj->get_object_id(); - char buffer[64]; - snprintf(buffer, sizeof(buffer), "%f", value); - root["state"] = buffer; + std::string state = str_sprintf("%f", value); + root["state"] = state; root["value"] = value; }); } @@ -769,7 +800,7 @@ bool WebServer::canHandle(AsyncWebServerRequest *request) { #endif #ifdef USE_NUMBER - if (request->method() == HTTP_GET && match.domain == "number") + if ((request->method() == HTTP_POST || request->method() == HTTP_GET) && match.domain == "number") return true; #endif diff --git a/esphome/const.py b/esphome/const.py index daa61ebd9b..9005cc927a 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -1,6 +1,6 @@ """Constants used by esphome.""" -__version__ = "2022.1.0b2" +__version__ = "2022.1.0b3" ALLOWED_NAME_CHARS = "abcdefghijklmnopqrstuvwxyz0123456789-_" diff --git a/esphome/dashboard/dashboard.py b/esphome/dashboard/dashboard.py index f9ae3a4fc8..c68d037fe6 100644 --- a/esphome/dashboard/dashboard.py +++ b/esphome/dashboard/dashboard.py @@ -445,6 +445,7 @@ class DownloadBinaryRequestHandler(BaseHandler): self.set_header("Content-Type", "application/octet-stream") self.set_header("Content-Disposition", f'attachment; filename="{filename}"') + self.set_header("Cache-Control", "no-cache") if not Path(path).is_file(): self.send_error(404) return