Fork of the espurna firmware for `mhsw` switches
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

60 lines
1.8 KiB

Terminal: change command-line parser (#2247) Change the underlying command line handling: - switch to a custom parser, inspired by redis / sds - update terminalRegisterCommand signature, pass only bare minimum - clean-up `help` & `commands`. update settings `set`, `get` and `del` - allow our custom test suite to run command-line tests - clean-up Stream IO to allow us to print large things into debug stream (for example, `eeprom.dump`) - send parsing errors to the debug log As a proof of concept, introduce `TERMINAL_MQTT_SUPPORT` and `TERMINAL_WEB_API_SUPPORT` - MQTT subscribes to the `<root>/cmd/set` and sends response to the `<root>/cmd`. We can't output too much, as we don't have any large-send API. - Web API listens to the `/api/cmd?apikey=...&line=...` (or PUT, params inside the body). This one is intended as a possible replacement of the `API_SUPPORT`. Internals introduce a 'task' around the AsyncWebServerRequest object that will simulate what WiFiClient does and push data into it continuously, switching between CONT and SYS. Both are experimental. We only accept a single command and not every command is updated to use Print `ctx.output` object. We are also somewhat limited by the Print / Stream overall, perhaps I am overestimating the usefulness of Arduino compatibility to such an extent :) Web API handler can also sometimes show only part of the result, whenever the command tries to yield() by itself waiting for something. Perhaps we would need to create a custom request handler for that specific use-case.
4 years ago
  1. /*
  2. Part of the WEBSERVER MODULE
  3. Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
  4. */
  5. #pragma once
  6. #include "web.h"
  7. #include "libs/TypeChecks.h"
  8. #include <Schedule.h>
  9. #if WEB_SUPPORT
  10. namespace asyncwebprint_traits {
  11. template <typename T>
  12. using print_callable_t = decltype(std::declval<T>()(std::declval<Print&>()));
  13. template <typename T>
  14. using is_print_callable = is_detected<print_callable_t, T>;
  15. }
  16. template<typename CallbackType>
  17. void AsyncWebPrint::scheduleFromRequest(const AsyncWebPrintConfig& config, AsyncWebServerRequest* request, CallbackType callback) {
  18. static_assert(asyncwebprint_traits::is_print_callable<CallbackType>::value, "CallbackType needs to be a callable with void(Print&)");
  19. // because of async nature of the server, we need to make sure we outlive 'request' object
  20. auto print = std::shared_ptr<AsyncWebPrint>(new AsyncWebPrint(config, request));
  21. // attach one ptr to onDisconnect capture, so we can detect disconnection before scheduled function runs
  22. request->onDisconnect([print]() {
  23. print->setState(AsyncWebPrint::State::Done);
  24. });
  25. // attach another capture to the scheduled function, so we execute as soon as we exit next loop()
  26. schedule_function([callback, print]() {
  27. if (State::None != print->getState()) return;
  28. callback(*print.get());
  29. print->flush();
  30. });
  31. }
  32. constexpr AsyncWebPrintConfig AsyncWebPrintDefaults {
  33. /*mimeType =*/ "text/plain",
  34. /*backlogCountMax=*/ 2,
  35. /*backlogSizeMax= */ TCP_MSS,
  36. /*backlogTimeout= */ 5000
  37. };
  38. template<typename CallbackType>
  39. void AsyncWebPrint::scheduleFromRequest(AsyncWebServerRequest* request, CallbackType callback) {
  40. AsyncWebPrint::scheduleFromRequest(AsyncWebPrintDefaults, request, callback);
  41. }
  42. #endif