data_task.c 18 KB

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