status.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /*
  2. handle status web page
  3. */
  4. #include "options.h"
  5. #include <Arduino.h>
  6. #include "version.h"
  7. #include <opendroneid.h>
  8. #include "status.h"
  9. extern ODID_UAS_Data UAS_data;
  10. typedef struct {
  11. String name;
  12. String value;
  13. } json_table_t;
  14. static String escape_string(String s)
  15. {
  16. s.replace("\"", "");
  17. return s;
  18. }
  19. /*
  20. create a json string from a table
  21. */
  22. static String json_format(const json_table_t *table, uint8_t n)
  23. {
  24. String s = "{";
  25. for (uint8_t i=0; i<n; i++) {
  26. const auto &t = table[i];
  27. s += "\"" + t.name + "\" : ";
  28. s += "\"" + escape_string(t.value) + "\"";
  29. if (i != n-1) {
  30. s += ",";
  31. }
  32. }
  33. s += "}";
  34. return s;
  35. }
  36. typedef struct {
  37. int v;
  38. String s;
  39. } enum_map_t;
  40. static const enum_map_t enum_uatype[] = {
  41. { ODID_UATYPE_NONE , "NONE" },
  42. { ODID_UATYPE_AEROPLANE , "AEROPLANE" },
  43. { ODID_UATYPE_HELICOPTER_OR_MULTIROTOR , "HELICOPTER_OR_MULTIROTOR" },
  44. { ODID_UATYPE_GYROPLANE , "GYROPLANE" },
  45. { ODID_UATYPE_HYBRID_LIFT , "HYBRID_LIFT" },
  46. { ODID_UATYPE_ORNITHOPTER , "ORNITHOPTER" },
  47. { ODID_UATYPE_GLIDER , "GLIDER" },
  48. { ODID_UATYPE_KITE , "KITE" },
  49. { ODID_UATYPE_FREE_BALLOON , "FREE_BALLOON" },
  50. { ODID_UATYPE_CAPTIVE_BALLOON , "CAPTIVE_BALLOON" },
  51. { ODID_UATYPE_AIRSHIP , "AIRSHIP" },
  52. { ODID_UATYPE_FREE_FALL_PARACHUTE , "FREE_FALL_PARACHUTE" },
  53. { ODID_UATYPE_ROCKET , "ROCKET" },
  54. { ODID_UATYPE_TETHERED_POWERED_AIRCRAFT , "TETHERED_POWERED_AIRCRAFT" },
  55. { ODID_UATYPE_GROUND_OBSTACLE , "GROUND_OBSTACLE" },
  56. { ODID_UATYPE_OTHER , "OTHER" },
  57. };
  58. static const enum_map_t enum_idtype[] = {
  59. { ODID_IDTYPE_NONE , "NONE" },
  60. { ODID_IDTYPE_SERIAL_NUMBER , "SERIAL_NUMBER" },
  61. { ODID_IDTYPE_CAA_REGISTRATION_ID , "CAA_REGISTRATION_ID" },
  62. { ODID_IDTYPE_UTM_ASSIGNED_UUID , "UTM_ASSIGNED_UUID" },
  63. { ODID_IDTYPE_SPECIFIC_SESSION_ID , "SPECIFIC_SESSION_ID" },
  64. };
  65. static const enum_map_t enum_loctype[] = {
  66. { ODID_OPERATOR_LOCATION_TYPE_TAKEOFF , "TAKEOFF" },
  67. { ODID_OPERATOR_LOCATION_TYPE_LIVE_GNSS , "LIVE_GNSS" },
  68. { ODID_OPERATOR_LOCATION_TYPE_FIXED , "FIXED" },
  69. };
  70. static const enum_map_t enum_classif[] = {
  71. { ODID_CLASSIFICATION_TYPE_UNDECLARED , "UNDECLARED" },
  72. { ODID_CLASSIFICATION_TYPE_EU , "EU" },
  73. };
  74. static const enum_map_t enum_status[] = {
  75. { ODID_STATUS_UNDECLARED , "UNDECLARED" },
  76. { ODID_STATUS_GROUND , "GROUND" },
  77. { ODID_STATUS_AIRBORNE , "AIRBORNE" },
  78. { ODID_STATUS_EMERGENCY , "EMERGENCY" },
  79. { ODID_STATUS_REMOTE_ID_SYSTEM_FAILURE , "REMOTE_ID_SYSTEM_FAILURE" },
  80. };
  81. static const enum_map_t enum_height[] = {
  82. { ODID_HEIGHT_REF_OVER_TAKEOFF , "REF_OVER_TAKEOFF" },
  83. { ODID_HEIGHT_REF_OVER_GROUND , "REF_OVER_GROUND" },
  84. };
  85. static const enum_map_t enum_hacc[] = {
  86. { ODID_HOR_ACC_UNKNOWN , "UNKNOWN" },
  87. { ODID_HOR_ACC_10NM , "10NM" },
  88. { ODID_HOR_ACC_4NM , "4NM" },
  89. { ODID_HOR_ACC_2NM , "2NM" },
  90. { ODID_HOR_ACC_1NM , "1NM" },
  91. { ODID_HOR_ACC_0_5NM , "0_5NM" },
  92. { ODID_HOR_ACC_0_3NM , "0_3NM" },
  93. { ODID_HOR_ACC_0_1NM , "0_1NM" },
  94. { ODID_HOR_ACC_0_05NM , "0_05NM" },
  95. { ODID_HOR_ACC_30_METER , "30_METER" },
  96. { ODID_HOR_ACC_10_METER , "10_METER" },
  97. { ODID_HOR_ACC_3_METER , "3_METER" },
  98. { ODID_HOR_ACC_1_METER , "1_METER" },
  99. };
  100. static const enum_map_t enum_vacc[] = {
  101. { ODID_VER_ACC_UNKNOWN , "UNKNOWN" },
  102. { ODID_VER_ACC_150_METER , "150_METER" },
  103. { ODID_VER_ACC_45_METER , "45_METER" },
  104. { ODID_VER_ACC_25_METER , "25_METER" },
  105. { ODID_VER_ACC_10_METER , "10_METER" },
  106. { ODID_VER_ACC_3_METER , "3_METER" },
  107. { ODID_VER_ACC_1_METER , "1_METER" },
  108. };
  109. static const enum_map_t enum_sacc[] = {
  110. { ODID_SPEED_ACC_UNKNOWN , "ACC_UNKNOWN" },
  111. { ODID_SPEED_ACC_10_METERS_PER_SECOND , "ACC_10_METERS_PER_SECOND" },
  112. { ODID_SPEED_ACC_3_METERS_PER_SECOND , "ACC_3_METERS_PER_SECOND" },
  113. { ODID_SPEED_ACC_1_METERS_PER_SECOND , "ACC_1_METERS_PER_SECOND" },
  114. { ODID_SPEED_ACC_0_3_METERS_PER_SECOND , "ACC_0_3_METERS_PER_SECOND" },
  115. };
  116. static const enum_map_t enum_desctype[] = {
  117. { ODID_DESC_TYPE_TEXT , "TYPE_TEXT" },
  118. { ODID_DESC_TYPE_EMERGENCY , "TYPE_EMERGENCY" },
  119. { ODID_DESC_TYPE_EXTENDED_STATUS , "TYPE_EXTENDED_STATUS" },
  120. };
  121. #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
  122. static String enum_string(const enum_map_t *m, uint8_t n, int v)
  123. {
  124. for (uint8_t i=0; i<n; i++) {
  125. if (m[i].v == v) {
  126. return m[i].s;
  127. }
  128. }
  129. return String(v);
  130. }
  131. #define ENUM_MAP(ename, v) enum_string(enum_ ## ename, ARRAY_SIZE(enum_ ## ename), int(v))
  132. String status_json(void)
  133. {
  134. const uint32_t now_s = millis() / 1000;
  135. const uint32_t sec = now_s % 60;
  136. const uint32_t min = (now_s / 60) % 60;
  137. const uint32_t hr = (now_s / 3600) % 24;
  138. const json_table_t table[] = {
  139. { "STATUS:VERSION", String(FW_VERSION_MAJOR) + "." + String(FW_VERSION_MINOR) },
  140. { "STATUS:UPTIME", String(hr) + ":" + String(min) + ":" + String(sec) },
  141. { "STATUS:FREEMEM", String(ESP.getFreeHeap()) },
  142. { "BASICID:UAType", ENUM_MAP(uatype, UAS_data.BasicID[0].UAType) },
  143. { "BASICID:IDType", ENUM_MAP(idtype, UAS_data.BasicID[0].IDType) },
  144. { "BASICID:UASID", String(UAS_data.BasicID[0].UASID) },
  145. { "OPERATORID:IDType", String(UAS_data.OperatorID.OperatorIdType) },
  146. { "OPERATORID:ID", String(UAS_data.OperatorID.OperatorId) },
  147. { "SELFID:DescType", ENUM_MAP(desctype, UAS_data.SelfID.DescType) },
  148. { "SELFID:Desc", String(UAS_data.SelfID.Desc) },
  149. { "SYSTEM:OperatorLocationType", ENUM_MAP(loctype, UAS_data.System.OperatorLocationType) },
  150. { "SYSTEM:ClassificationType", ENUM_MAP(classif, UAS_data.System.ClassificationType) },
  151. { "SYSTEM:OperatorLatitude", String(UAS_data.System.OperatorLatitude) },
  152. { "SYSTEM:OperatorLongitude", String(UAS_data.System.OperatorLongitude) },
  153. { "SYSTEM:AreaCount", String(UAS_data.System.AreaCount) },
  154. { "SYSTEM:AreaRadius", String(UAS_data.System.AreaRadius) },
  155. { "SYSTEM:AreaCeiling", String(UAS_data.System.AreaCeiling) },
  156. { "SYSTEM:AreaFloor", String(UAS_data.System.AreaFloor) },
  157. { "SYSTEM:CategoryEU", String(UAS_data.System.CategoryEU) },
  158. { "SYSTEM:ClassEU", String(UAS_data.System.ClassEU) },
  159. { "SYSTEM:OperatorAltitudeGeo", String(UAS_data.System.OperatorAltitudeGeo) },
  160. { "SYSTEM:Timestamp", String(UAS_data.System.Timestamp) },
  161. { "LOCATION:Status", ENUM_MAP(status, UAS_data.Location.Status) },
  162. { "LOCATION:Direction", String(UAS_data.Location.Direction) },
  163. { "LOCATION:SpeedHorizontal", String(UAS_data.Location.SpeedHorizontal) },
  164. { "LOCATION:SpeedVertical", String(UAS_data.Location.SpeedVertical) },
  165. { "LOCATION:Latitude", String(UAS_data.Location.Latitude) },
  166. { "LOCATION:Longitude", String(UAS_data.Location.Longitude) },
  167. { "LOCATION:AltitudeBaro", String(UAS_data.Location.AltitudeBaro) },
  168. { "LOCATION:AltitudeGeo", String(UAS_data.Location.AltitudeGeo) },
  169. { "LOCATION:HeightType", ENUM_MAP(height, UAS_data.Location.HeightType) },
  170. { "LOCATION:Height", String(UAS_data.Location.Height) },
  171. { "LOCATION:HorizAccuracy", ENUM_MAP(hacc, UAS_data.Location.HorizAccuracy) },
  172. { "LOCATION:VertAccuracy", ENUM_MAP(vacc, UAS_data.Location.VertAccuracy) },
  173. { "LOCATION:BaroAccuracy", ENUM_MAP(vacc, UAS_data.Location.BaroAccuracy) },
  174. { "LOCATION:SpeedAccuracy", ENUM_MAP(sacc, UAS_data.Location.SpeedAccuracy) },
  175. { "LOCATION:TSAccuracy", String(UAS_data.Location.TSAccuracy) },
  176. { "LOCATION:TimeStamp", String(UAS_data.Location.TimeStamp) },
  177. };
  178. return json_format(table, ARRAY_SIZE(table));
  179. }