thing.cc 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "thing.h"
  2. #include "application.h"
  3. #include <esp_log.h>
  4. #define TAG "Thing"
  5. namespace iot {
  6. static std::map<std::string, std::function<Thing*()>>* thing_creators = nullptr;
  7. void RegisterThing(const std::string& type, std::function<Thing*()> creator) {
  8. if (thing_creators == nullptr) {
  9. thing_creators = new std::map<std::string, std::function<Thing*()>>();
  10. }
  11. (*thing_creators)[type] = creator;
  12. }
  13. Thing* CreateThing(const std::string& type) {
  14. auto creator = thing_creators->find(type);
  15. if (creator == thing_creators->end()) {
  16. ESP_LOGE(TAG, "Thing type not found: %s", type.c_str());
  17. return nullptr;
  18. }
  19. return creator->second();
  20. }
  21. std::string Thing::GetDescriptorJson() {
  22. std::string json_str = "{";
  23. json_str += "\"name\":\"" + name_ + "\",";
  24. json_str += "\"description\":\"" + description_ + "\",";
  25. json_str += "\"properties\":" + properties_.GetDescriptorJson() + ",";
  26. json_str += "\"methods\":" + methods_.GetDescriptorJson();
  27. json_str += "}";
  28. return json_str;
  29. }
  30. std::string Thing::GetStateJson() {
  31. std::string json_str = "{";
  32. json_str += "\"name\":\"" + name_ + "\",";
  33. json_str += "\"state\":" + properties_.GetStateJson();
  34. json_str += "}";
  35. return json_str;
  36. }
  37. void Thing::Invoke(const cJSON* command) {
  38. auto method_name = cJSON_GetObjectItem(command, "method");
  39. auto input_params = cJSON_GetObjectItem(command, "parameters");
  40. try {
  41. auto& method = methods_[method_name->valuestring];
  42. for (auto& param : method.parameters()) {
  43. auto input_param = cJSON_GetObjectItem(input_params, param.name().c_str());
  44. if (param.required() && input_param == nullptr) {
  45. throw std::runtime_error("Parameter " + param.name() + " is required");
  46. }
  47. if (param.type() == kValueTypeNumber) {
  48. param.set_number(input_param->valueint);
  49. } else if (param.type() == kValueTypeString) {
  50. param.set_string(input_param->valuestring);
  51. } else if (param.type() == kValueTypeBoolean) {
  52. param.set_boolean(input_param->valueint == 1);
  53. }
  54. }
  55. Application::GetInstance().Schedule([&method]() {
  56. method.Invoke();
  57. });
  58. } catch (const std::runtime_error& e) {
  59. ESP_LOGE(TAG, "Method not found: %s", method_name->valuestring);
  60. return;
  61. }
  62. }
  63. } // namespace iot