data_task.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564
  1. #include "data_task.h"
  2. #include "usart.h"
  3. #include "sys_mqtt.h"
  4. #include "sys_http.h"
  5. #include "mmodbus.h"
  6. #include "dlt645_port.h"
  7. #include "gd32_flash.h"
  8. #include "protocol.h"
  9. #include "timer.h"
  10. #include "led.h"
  11. #include "tcp_server.h"
  12. #include "log.h"
  13. void protocolsModeFunc(GATEWAY_PARAMS* current_device, char* buf, char* string);
  14. void transparentModeFunc(DEVICE_PARAMS* current_device);
  15. int ID = 1;
  16. uint8_t count = 0;
  17. uint8_t startFlag = 0;// 读取数据初始标志位
  18. int time1,time2;
  19. void data_task(void *pdata)
  20. {
  21. dlt645_init(1); // 若读不到数据,则延时 参数 秒
  22. mmodbus_init(10);// 若读不到数据,则延时 参数 秒
  23. GATEWAY_PARAMS *get;
  24. // 如果flash有config数据,则解析,进行下一步;若flash无config数据,则等待上位机发送数据
  25. do{
  26. char *device_config_json=pvPortMalloc( 10 *1024 );
  27. memset(device_config_json,0,strlen(device_config_json));
  28. portENTER_CRITICAL();
  29. read_data_from_flash(device_config_json);
  30. addGatewayParams(device_config_json);
  31. vPortFree(device_config_json);
  32. portEXIT_CRITICAL();
  33. get= get_gateway_config_params();
  34. delay_ms(100);
  35. }while(get->device_params == NULL);
  36. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"device params not empty");
  37. DEVICE_PARAMS *current_device=get->device_params;
  38. char *buf = pvPortMalloc(1024); // 接收读取的全部数据
  39. char *string = pvPortMalloc(1024); // 接收读取的不同数据
  40. if(buf == NULL || string == NULL)
  41. {
  42. LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"buf or string malloc fail");
  43. }
  44. memset(buf,0,strlen(buf));
  45. memset(string,0,strlen(string));
  46. while (current_device!=NULL)
  47. {
  48. if(ProtocolsModeFlag)
  49. {
  50. protocolsModeFunc(get, buf, string);
  51. }
  52. else if(TransparentModeFlag)
  53. {
  54. transparentModeFunc(current_device);
  55. }
  56. current_device=get->device_params;
  57. vTaskDelay(1000);
  58. }
  59. vPortFree(buf);
  60. vPortFree(string);
  61. LogPrint(LOG_ERROR,__FILE__,__FUNCTION__,__LINE__,"data_task return");
  62. }
  63. /*
  64. *********************************************************************************************************
  65. * 函 数 名: int compareArrays(uint8_t arr1[], uint8_t arr2[], int size)
  66. * 功能说明: 比较两个数组是否相同
  67. * 形 参: arr1[] 数组1,arr2[] 数组2,size 比较数组的大小
  68. * 返 回 值: 1: 相同 0:不相同
  69. *********************************************************************************************************
  70. */
  71. int compareArrays(uint8_t arr1[], uint8_t arr2[], int size) {
  72. for (int i = 0; i < size; ++i) {
  73. if (arr1[i] != arr2[i]) {
  74. return 1; // 两个数组不相同,返回0
  75. }
  76. }
  77. return 0; // 两个数组相同,返回1
  78. }
  79. /*
  80. *********************************************************************************************************
  81. * 函 数 名: int READ_MODBUS_DATA(DEVICE_PARAMS *device)
  82. * 功能说明: 读取当前节点上的modbus数据
  83. * 形 参: DEVICE_PARAMS *device 当前设备
  84. * 返 回 值: 1: 成功 0:失败
  85. *********************************************************************************************************
  86. */
  87. int read_device_data(DEVICE_PARAMS *device, char* buf, char* string)
  88. {
  89. DEVICE_PARAMS *current_device=device;
  90. GATEWAY_READ_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_read_modbus_command;
  91. GATEWAY_READ_DLT645_COMMAND *currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  92. while(current_device->params != NULL)
  93. {
  94. gd_eval_led_toggle(LED_485TX);
  95. if (current_device->protocol == MODBUS_READ)
  96. {
  97. uint8_t cmd; //开关水阀命令
  98. uint8_t state; // 水阀状态
  99. uint16_t data[currentModbusParams->registerByteNum /2]; // modbus寄存器长度
  100. mmodbus_set16bitOrder(current_device->MDBbigLittleFormat);
  101. // 读水阀状态
  102. if(currentModbusParams->functionCode == 0x01)
  103. {
  104. bool success = mmodbus_readCoil(currentModbusParams->slaveAddress,
  105. currentModbusParams->registerByteNum /2,
  106. &state);
  107. if(success)
  108. {
  109. if(state == 0)
  110. {
  111. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\":close},",
  112. current_device->deviceID, currentModbusParams->keyword);
  113. }else{
  114. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\":open},",
  115. current_device->deviceID, currentModbusParams->keyword);
  116. }
  117. }
  118. currentModbusParams = currentModbusParams->nextParams;
  119. if (currentModbusParams == NULL)
  120. {
  121. current_device = current_device->nextDevice;
  122. currentModbusParams = current_device->params->gateway_read_modbus_command;
  123. if(current_device == NULL)
  124. {
  125. sprintf(buf + strlen(buf) - 1, "");
  126. return 1;
  127. }
  128. }
  129. }
  130. // 读单个寄存器
  131. if (currentModbusParams->functionCode == 0x03)
  132. {
  133. // bool success = mmodbus_readHoldingRegisters16i(0x17,0x00,0x02,data);
  134. bool success = mmodbus_readHoldingRegisters16i(currentModbusParams->slaveAddress,
  135. currentModbusParams->registerAddress,
  136. currentModbusParams->registerByteNum /2,
  137. data);
  138. if (success)
  139. {
  140. uint32_t value;
  141. if (currentModbusParams->registerByteNum == 4)
  142. {
  143. value = (uint32_t)data[0] | data[1];
  144. }
  145. else if (currentModbusParams->registerByteNum == 2)
  146. {
  147. value = data[0];
  148. }
  149. if((value - currentModbusParams->value) != 0)
  150. {
  151. count++;
  152. sprintf(string + strlen(string), "{\"deviceId\":\"%s\",\"%s\":%d},",
  153. current_device->deviceID, currentModbusParams->keyword, value);
  154. }
  155. else
  156. {
  157. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\":%d},",
  158. current_device->deviceID, currentModbusParams->keyword, value);
  159. }
  160. if (currentModbusParams->decimalPoint == 0)
  161. {
  162. currentModbusParams->value = value;
  163. }
  164. else
  165. {
  166. currentModbusParams->value = value / my_pow(10,currentModbusParams->decimalPoint);
  167. }
  168. }
  169. currentModbusParams = currentModbusParams->nextParams;
  170. if (currentModbusParams == NULL)
  171. {
  172. current_device = current_device->nextDevice;
  173. currentModbusParams = current_device->params->gateway_read_modbus_command;
  174. if(current_device == NULL)
  175. {
  176. sprintf(buf + strlen(buf) - 1, "");
  177. sprintf(string + strlen(string) - 1, "");
  178. return 1;
  179. }
  180. }
  181. }
  182. // 开关水阀
  183. if(currentModbusParams->functionCode == 0x05)
  184. {
  185. bool success = mmodbus_writeCoil(currentModbusParams->slaveAddress,
  186. currentModbusParams->registerByteNum /2,
  187. cmd);
  188. if(success)
  189. {
  190. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\": success},",
  191. current_device->deviceID, currentModbusParams->keyword);
  192. }
  193. else{
  194. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\": fail},",
  195. current_device->deviceID, currentModbusParams->keyword);
  196. }
  197. currentModbusParams = currentModbusParams->nextParams;
  198. if (currentModbusParams == NULL)
  199. {
  200. current_device = current_device->nextDevice;
  201. currentModbusParams = current_device->params->gateway_read_modbus_command;
  202. if(current_device == NULL)
  203. {
  204. sprintf(buf + strlen(buf) - 1, "");
  205. return 1;
  206. }
  207. }
  208. }
  209. // 写单个寄存器
  210. if(currentModbusParams->functionCode == 0x06)
  211. {
  212. bool success = mmodbus_writeHoldingRegisters16i(currentModbusParams->slaveAddress,
  213. currentModbusParams->registerAddress,
  214. currentModbusParams->registerByteNum /2,
  215. data);
  216. if(success)
  217. {
  218. sprintf(buf + strlen(buf), "{\"deviceId\":\"%s\",\"%s\":write success},",
  219. current_device->deviceID, currentModbusParams->keyword);
  220. }
  221. currentModbusParams = currentModbusParams->nextParams;
  222. if (currentModbusParams == NULL)
  223. {
  224. current_device = current_device->nextDevice;
  225. currentModbusParams = current_device->params->gateway_read_modbus_command;
  226. if(current_device == NULL)
  227. {
  228. sprintf(buf + strlen(buf) - 1, "");
  229. return 1;
  230. }
  231. }
  232. }
  233. }
  234. else if (current_device->protocol == DLT645_2007 || current_device->protocol == DLT645_97)
  235. {
  236. uint8_t read_buf[10];
  237. uint32_t dltValue;
  238. currentDLT645Params->rxLen = 0;
  239. memset(read_buf, 0, 10);
  240. memset(currentDLT645Params->data, 0, 10);
  241. dlt645_set_addr(&dlt645, currentDLT645Params->deviceID645);
  242. int8_t rs;
  243. if (current_device->protocol == DLT645_2007)
  244. {
  245. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_2007);
  246. }
  247. else if (current_device->protocol == DLT645_1997)
  248. {
  249. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_1997);
  250. }
  251. if (rs != -1)
  252. {
  253. if(compareArrays(read_buf,currentDLT645Params->data,10))// 不相同1,相同0
  254. {
  255. if (rs <= 4)
  256. {
  257. memcpy(currentDLT645Params->data, read_buf, 4);
  258. currentDLT645Params->rxLen = 4;
  259. }
  260. else if (rs == 5)
  261. {
  262. memcpy(currentDLT645Params->data, read_buf, 5);
  263. currentDLT645Params->rxLen = 5;
  264. }
  265. else if (rs > 5)
  266. {
  267. memcpy(currentDLT645Params->data, read_buf, 9);
  268. currentDLT645Params->rxLen = 9;
  269. }
  270. dltValue = currentDLT645Params->data[0] << 24 | currentDLT645Params->data[1] << 16|
  271. currentDLT645Params->data[2] << 8 | currentDLT645Params->data[3];
  272. sprintf(string + strlen(string), "{\"identifier\":\"%s\",\"deviceID645\":\"%02x%02x%02x%02x%02x%02x\",\"identifier645\":%d,\"value\":%X}",
  273. currentDLT645Params->keyword, currentDLT645Params->deviceID645[0],
  274. currentDLT645Params->deviceID645[1],currentDLT645Params->deviceID645[2],
  275. currentDLT645Params->deviceID645[3],currentDLT645Params->deviceID645[4],
  276. currentDLT645Params->deviceID645[5],currentDLT645Params->Identification,dltValue);
  277. count++;
  278. }
  279. else
  280. {
  281. if (rs <= 4)
  282. {
  283. memcpy(currentDLT645Params->data, read_buf, 4);
  284. currentDLT645Params->rxLen = 4;
  285. }
  286. else if (rs == 5)
  287. {
  288. memcpy(currentDLT645Params->data, read_buf, 5);
  289. currentDLT645Params->rxLen = 5;
  290. }
  291. else if (rs > 5)
  292. {
  293. memcpy(currentDLT645Params->data, read_buf, 9);
  294. currentDLT645Params->rxLen = 9;
  295. }
  296. dltValue = currentDLT645Params->data[0] << 24 | currentDLT645Params->data[1] << 16|
  297. currentDLT645Params->data[2] << 8 | currentDLT645Params->data[3];
  298. sprintf(buf + strlen(buf), "{\"identifier\":\"%s\",\"deviceID645\":\"%02x%02x%02x%02x%02x%02x\",\"identifier645\":%d,\"value\":%X}",
  299. currentDLT645Params->keyword, currentDLT645Params->deviceID645[0],
  300. currentDLT645Params->deviceID645[1],currentDLT645Params->deviceID645[2],
  301. currentDLT645Params->deviceID645[3],currentDLT645Params->deviceID645[4],
  302. currentDLT645Params->deviceID645[5],currentDLT645Params->Identification,dltValue);
  303. }
  304. }
  305. currentDLT645Params = currentDLT645Params->nextParams;
  306. if (currentDLT645Params == NULL)
  307. {
  308. current_device = current_device->nextDevice;
  309. currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  310. if(current_device == NULL)
  311. {
  312. sprintf(buf + strlen(buf) - 1, "");
  313. return 1;
  314. }
  315. }
  316. }
  317. }
  318. return 1;
  319. }
  320. /*
  321. *********************************************************************************************************
  322. * 函 数 名: void send_mqtt(char*buf, int jsonCunt)
  323. * 功能说明: 将数据发送到mqtt
  324. * 形 参: 参数1:读取数据 参数2:第一次发送标志
  325. * 返 回 值: 无
  326. *********************************************************************************************************
  327. */
  328. void send_mqtt(char*buf){
  329. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"send to mqtt");
  330. GATEWAY_PARAMS *get;
  331. get= get_gateway_config_params();
  332. char *pubJsonString = pvPortMalloc(700);
  333. sprintf(pubJsonString,"ID: %d {\"DEVICEID\":\"%s\",\"data\":[%s]}",ID, get->deviceId, buf); // 组成要发送的json语句
  334. mqtt_publish_data(pubJsonString, QOS0, strlen(pubJsonString), (char*)&get->messageTopic);
  335. vPortFree(pubJsonString);
  336. }
  337. /*
  338. *********************************************************************************************************
  339. * 函 数 名:void WRITE_MODBUS_DATA(char* cJSONstring)
  340. * 功能说明: 接收mqtt数据并写入modbus寄存器
  341. * 形 参:char* cJSONstring mqtt接收到的数据
  342. * 返 回 值: 无
  343. *********************************************************************************************************
  344. */
  345. void write_modbus_data(char* JSON_STRING)
  346. {
  347. JSON_CMD jsonMsg;
  348. GATEWAY_PARAMS* get;
  349. get = get_gateway_config_params();
  350. DEVICE_PARAMS* current_device = get->device_params;
  351. parseStringField(JSON_STRING, "\"deviceId\":\"", jsonMsg.deviceId);
  352. jsonMsg.function = parseIntField(JSON_STRING, "\"function\":");
  353. jsonMsg.cmd = parseIntField(JSON_STRING, "\"cmd\":");
  354. jsonMsg.power = parseIntField(JSON_STRING, "\"power\":");
  355. jsonMsg.temp = parseIntField(JSON_STRING, "\"temp\":");
  356. jsonMsg.mode = parseIntField(JSON_STRING, "\"mode\":");
  357. jsonMsg.fan = parseIntField(JSON_STRING, "\"fan\":");
  358. while(current_device)
  359. {
  360. char* device_ID = (char*)current_device->deviceID;
  361. GATEWAY_WRITE_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_write_modbus_command;
  362. if(!strcmp(device_ID,jsonMsg.deviceId)) //匹配ID
  363. {
  364. portENTER_CRITICAL();
  365. delay_ms(50);
  366. if(jsonMsg.function == 5)
  367. // 开关阀门
  368. {
  369. mmodbus_writeCoil(jsonMsg.slaveAddress,jsonMsg.registerAddress,jsonMsg.cmd);
  370. }
  371. if(jsonMsg.function == 6)
  372. {
  373. /* 写入寄存器操作 */
  374. if(jsonMsg.power)
  375. {
  376. mmodbus_writeHoldingRegister16i(currentModbusParams->slaveAddress,
  377. currentModbusParams->registerAddress, jsonMsg.power);
  378. }
  379. delay_ms(10);
  380. if(jsonMsg.temp)
  381. {
  382. currentModbusParams = currentModbusParams->nextParams;
  383. mmodbus_writeHoldingRegister16i(currentModbusParams->slaveAddress,
  384. currentModbusParams->registerAddress, jsonMsg.temp);
  385. }
  386. delay_ms(10);
  387. if(jsonMsg.mode)
  388. {
  389. currentModbusParams = currentModbusParams->nextParams;
  390. mmodbus_writeHoldingRegister16i(currentModbusParams->slaveAddress,
  391. currentModbusParams->registerAddress, jsonMsg.mode);
  392. }
  393. delay_ms(10);
  394. if(jsonMsg.fan)
  395. {
  396. currentModbusParams = currentModbusParams->nextParams;
  397. mmodbus_writeHoldingRegister16i(currentModbusParams->slaveAddress,
  398. currentModbusParams->registerAddress, jsonMsg.fan);
  399. }
  400. }
  401. delay_ms(10);
  402. portEXIT_CRITICAL();
  403. }
  404. current_device = current_device->nextDevice;
  405. }
  406. }
  407. // 重定义pow函数
  408. uint32_t my_pow(int base, int exponent) {
  409. uint32_t result = 1;
  410. for(int i = 0; i < exponent; i++) {
  411. result *= base;
  412. }
  413. return result;
  414. }
  415. void protocolsModeFunc(GATEWAY_PARAMS* get, char* buf, char* string)
  416. {
  417. if(mqtt_connectFlag)
  418. {
  419. time1 = GetCurrentTime();
  420. if(startFlag && time2 <= time1 - ( 10 * 1000))// 60s进行一次全数据发送
  421. {
  422. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:All data");
  423. read_device_data(get->device_params, buf, string);
  424. send_mqtt(buf);
  425. time2 = GetCurrentTime();
  426. }
  427. else
  428. {
  429. read_device_data(get->device_params, buf, string);
  430. if(count > 0)// count检测string是否含有数据
  431. {
  432. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:Different data");
  433. count = 0;
  434. send_mqtt(string);
  435. time2 = GetCurrentTime();
  436. }
  437. }
  438. startFlag = 1;
  439. memset(buf,0,strlen(buf));
  440. memset(string,0,strlen(string));
  441. }
  442. }
  443. int transparent_data(DEVICE_PARAMS *device)
  444. {
  445. DEVICE_PARAMS *current_device=device;
  446. GATEWAY_READ_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_read_modbus_command;
  447. GATEWAY_READ_DLT645_COMMAND *currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  448. while(current_device->params != NULL)
  449. {
  450. gd_eval_led_toggle(LED_485TX);
  451. if (current_device->protocol == MODBUS_READ)
  452. {
  453. uint16_t data[currentModbusParams->registerByteNum /2]; // modbus寄存器长度
  454. mmodbus_set16bitOrder(current_device->MDBbigLittleFormat);
  455. // 读单个寄存器
  456. if (currentModbusParams->functionCode == 0x03)
  457. {
  458. // bool success = mmodbus_readHoldingRegisters16i(0x17,0x00,0x02,data);
  459. bool success = mmodbus_readHoldingRegisters16i(currentModbusParams->slaveAddress,
  460. currentModbusParams->registerAddress,
  461. currentModbusParams->registerByteNum /2,
  462. data);
  463. if (success)
  464. {
  465. uint32_t value;
  466. if((value - currentModbusParams->value) != 0)
  467. {
  468. for (uint8_t i = 0; i < mmodbus.rxBuf[2]; i += 2)
  469. {
  470. uint8_t H = mmodbus.rxBuf[i + 3];
  471. mmodbus.rxBuf[i + 3] = mmodbus.rxBuf[i + 3 + 1];
  472. mmodbus.rxBuf[i + 3 + 1] = H;
  473. }
  474. gd_com_485_send(mmodbus.rxBuf,mmodbus.rxIndex);
  475. count++;
  476. vTaskDelay(100);
  477. }
  478. }
  479. currentModbusParams = currentModbusParams->nextParams;
  480. if (currentModbusParams == NULL)
  481. {
  482. current_device = current_device->nextDevice;
  483. currentModbusParams = current_device->params->gateway_read_modbus_command;
  484. if(current_device == NULL)
  485. {
  486. return 1;
  487. }
  488. }
  489. }
  490. }
  491. else if (current_device->protocol == DLT645_2007 || current_device->protocol == DLT645_97)
  492. {
  493. uint8_t read_buf[10];
  494. memset(read_buf, 0, 10);
  495. memset(currentDLT645Params->data, 0, 10);
  496. dlt645_set_addr(&dlt645, currentDLT645Params->deviceID645);
  497. int8_t rs;
  498. if (current_device->protocol == DLT645_2007)
  499. {
  500. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_2007);
  501. }
  502. else if (current_device->protocol == DLT645_1997)
  503. {
  504. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_1997);
  505. }
  506. if (rs != -1)
  507. {
  508. if(compareArrays(read_buf,currentDLT645Params->data,10))// 不相同1,相同0
  509. {
  510. portENTER_CRITICAL();
  511. gd_com_485_send(mmodbus.rxBuf,mmodbus.rxIndex);
  512. portEXIT_CRITICAL();
  513. vTaskDelay(100);
  514. }
  515. }
  516. currentDLT645Params = currentDLT645Params->nextParams;
  517. if (currentDLT645Params == NULL)
  518. {
  519. current_device = current_device->nextDevice;
  520. currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  521. if(current_device == NULL)
  522. {
  523. return 1;
  524. }
  525. }
  526. }
  527. gd_eval_led_off(LED_485TX);
  528. }
  529. return 1;
  530. }
  531. void transparentModeFunc(DEVICE_PARAMS* current_device)
  532. {
  533. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"transparentMode:All data");
  534. printf("transparentMode:All data\n");
  535. transparent_data(current_device);
  536. }