mg.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. // Copyright (c) 2020 Cesanta Software Limited
  2. // All rights reserved
  3. //
  4. // Example Websocket server. See https://mongoose.ws/tutorials/websocket-server/
  5. #include "mongoose.h"
  6. #include "datadef.h"
  7. #define PWR_TYPE PDU_AC_I3O3
  8. static const char *s_listen_on = "ws://localhost";
  9. static const char *s_web_root = ".";
  10. static void send_powerc(struct mg_connection* c);
  11. static int ws_send(struct mg_connection* c, int type, void *data, int len)
  12. {
  13. pkt_hdr_t* h = (pkt_hdr_t*)malloc(sizeof(pkt_hdr_t)+len);
  14. if (!h) {
  15. return -1;
  16. }
  17. h->magic = PKT_MAGIC;
  18. h->type = type;
  19. h->nack = 3;
  20. h->dlen = len;
  21. memcpy(h->data, data, len);
  22. mg_ws_send(c, (const void*)h, sizeof(pkt_hdr_t) + len, WEBSOCKET_OP_BINARY);
  23. return 0;
  24. }
  25. // This RESTful server implements the following endpoints:
  26. // /websocket - upgrade to Websocket, and implement websocket echo server
  27. // /rest - respond with JSON string {"result": 123}
  28. // any other URI serves static files from s_web_root
  29. static void fn(struct mg_connection *c, int ev, void *ev_data) {
  30. if (ev == MG_EV_WS_OPEN) {
  31. } else if (ev == MG_EV_HTTP_MSG) {
  32. struct mg_http_message *hm = (struct mg_http_message *) ev_data;
  33. if (mg_match(hm->uri, mg_str("/ws"), NULL)) {
  34. // Upgrade to websocket. From now on, a connection is a full-duplex
  35. // Websocket connection, which will receive MG_EV_WS_MSG events.
  36. mg_ws_upgrade(c, hm, NULL);
  37. } else if (mg_match(hm->uri, mg_str("/rest"), NULL)) {
  38. // Serve REST response
  39. mg_http_reply(c, 200, "", "{\"result\": %d}\n", 123);
  40. } else {
  41. // Serve static files
  42. struct mg_http_serve_opts opts = {.root_dir = s_web_root};
  43. mg_http_serve_dir(c, (struct mg_http_message*)ev_data, &opts);
  44. }
  45. } else if (ev == MG_EV_WS_MSG) {
  46. // Got websocket frame. Received data is wm->data. Echo it back!
  47. struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
  48. pkt_hdr_t *h= (pkt_hdr_t*)wm->data.buf;
  49. power_total_t* pt = (power_total_t*)h->data;
  50. //mg_ws_send(c, wm->data.buf, wm->data.len, WEBSOCKET_OP_TEXT);
  51. }
  52. }
  53. static float rand_float(float min, float max) {
  54. return ((float)rand()/(float)RAND_MAX) * (max - min) + min;
  55. }
  56. static void powert_rand(power_total_t *pt)
  57. {
  58. int i,cnt = 1;
  59. #if 0
  60. pt->voltage = 1.1f;
  61. pt->current = 2.2f;
  62. pt->freq = 3.3f;
  63. pt->power = 4.4f;
  64. pt->consump = 5.5f;
  65. pt->active = 6.6f;
  66. pt->reactive = 7.7f;
  67. pt->apparent = 8.8f;
  68. #else
  69. if (pt->type >= PDU_AC_I3O3) {
  70. cnt = 3;
  71. }
  72. for (i = 0; i < cnt; i++) {
  73. pt->total[i].voltage = rand_float(1.0f, 100.0f);
  74. pt->total[i].current = rand_float(1.0f, 100.0f);
  75. pt->total[i].freq = rand_float(1.0f, 100.0f);
  76. pt->total[i].power = rand_float(1.0f, 100.0f);
  77. pt->total[i].consump = rand_float(1.0f, 100.0f);
  78. pt->total[i].active = rand_float(1.0f, 100.0f);
  79. pt->total[i].reactive = rand_float(1.0f, 100.0f);
  80. pt->total[i].apparent = rand_float(1.0f, 100.0f);
  81. }
  82. #endif
  83. }
  84. static void thrval_set(thr_val_t* tv)
  85. {
  86. tv->en = 0;
  87. tv->val = 100.0f;
  88. tv->act = 0;
  89. memset(tv->para, 0, 14);
  90. }
  91. static void thr_set(thr_t *thr)
  92. {
  93. thrval_set(&thr->v_upper);
  94. thrval_set(&thr->v_lower);
  95. thrval_set(&thr->c_upper);
  96. thrval_set(&thr->p_upper);
  97. thrval_set(&thr->w_upper);
  98. }
  99. static void alarm_set(alarm_t* a)
  100. {
  101. a->v_upper = 0;
  102. a->v_lower = 0;
  103. a->c_upper = 0;
  104. a->p_upper = 0;
  105. a->w_upper = 0;
  106. }
  107. static void powerc_rand(power_ch_t* pc, uint8_t addr, uint8_t ch, uint8_t sch)
  108. {
  109. int i,cnt = 1;
  110. pc->info.type = PWR_TYPE;
  111. pc->info.addr = addr;
  112. pc->info.ch = ch;
  113. pc->info.sch = sch;
  114. pc->info.ph_id = 0;
  115. pc->info.start_delay = 0;
  116. pc->info.stop_delay = 0;
  117. thr_set(&pc->thr);
  118. alarm_set(&pc->alarm);
  119. if (pc->info.type >= PDU_AC_I3O3) {
  120. cnt = 3;
  121. }
  122. for (i = 0; i < cnt; i++) {
  123. pc->power[i].voltage = rand_float(100.0f, 400.0f);
  124. pc->power[i].current = rand_float(1.0f, 100.0f);
  125. pc->power[i].freq = 50.0f;
  126. pc->power[i].power = rand_float(1.0f, 100.0f);
  127. pc->power[i].consump = rand_float(1.0f, 100.0f);
  128. pc->power[i].factor = rand_float(0.0f, 1.0f);
  129. pc->power[i].status = 1;
  130. pc->power[i].nwire = 0;
  131. }
  132. pc->time = 0;
  133. }
  134. static void send_powerc(struct mg_connection *c)
  135. {
  136. int i,j,ch=0;
  137. power_ch_t pc;
  138. #if 1
  139. #define BOARD_CNT 2
  140. #define BOARC_CH_CNT 2
  141. //uint8_t addr[BOARD_CNT] = {2,4,6,7,8};
  142. uint8_t addr[BOARD_CNT] = { 2,4};
  143. #else
  144. #define BOARD_CNT 1
  145. #define BOARC_CH_CNT 1
  146. uint8_t addr[BOARD_CNT] = { 2 };
  147. #endif
  148. for (i = 0; i < BOARD_CNT; i++) {
  149. for (j = 0; j < BOARC_CH_CNT; j++) {
  150. powerc_rand(&pc, addr[i], ch, j);
  151. ws_send(c, PKT_TYPE_POWER_CH , &pc, sizeof(pc));
  152. ch++;
  153. }
  154. }
  155. }
  156. static void send_powert(struct mg_connection* c)
  157. {
  158. power_total_t pt;
  159. powert_rand(&pt);
  160. ws_send(c, PKT_TYPE_POWER_TOTAL , &pt, sizeof(pt));
  161. }
  162. static void send_alarm(struct mg_connection* c)
  163. {
  164. alarm_data_t a;
  165. a.ch = 0;
  166. a.alarm.v_upper = 1;
  167. a.alarm.v_lower = 0;
  168. a.alarm.c_upper = 0;
  169. a.alarm.p_upper = 0;
  170. a.alarm.w_upper = 0;
  171. a.time = 0;
  172. ws_send(c, PKT_TYPE_ALARM, &a, sizeof(a));
  173. }
  174. static void timer_fn(void* arg)
  175. {
  176. static uint32_t cnt = 0;
  177. struct mg_mgr* mgr = (struct mg_mgr*)arg;
  178. cnt++;
  179. for (struct mg_connection* c = mgr->conns; c != NULL; c = c->next) {
  180. send_powerc(c);
  181. send_powert(c);
  182. if (cnt%10==0) {
  183. send_alarm(c);
  184. }
  185. }
  186. }
  187. int main(void) {
  188. struct mg_mgr mgr; // Event manager
  189. srand((uint32_t)time(NULL));
  190. mg_mgr_init(&mgr); // Initialise event manager
  191. printf("ws server on %s/ws\n", s_listen_on);
  192. mg_timer_add(&mgr, 1000, MG_TIMER_REPEAT, timer_fn, &mgr);
  193. mg_http_listen(&mgr, s_listen_on, fn, NULL); // Create HTTP listener
  194. for (;;) mg_mgr_poll(&mgr, 200); // Infinite event loop
  195. mg_mgr_free(&mgr);
  196. return 0;
  197. }