data_task.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478
  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(GATEWAY_PARAMS* current_device, char* string);
  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,transparent_lenth;
  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(get, string);
  50. }
  51. current_device=get->device_params;
  52. HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
  53. vTaskDelay(500);
  54. }
  55. myfree(SRAMEX, 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[currentModbusParams->registerByteNum /2];
  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); // 等待modbus读取完成,防止粘包
  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[currentModbusReadParams->registerByteNum /2]; // modbus寄存器长度
  295. while(mmodbus.done != 1) delay_ms(100); // 等待modbus读取完成,防止粘包
  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. }
  316. currentModbusReadParams = currentModbusReadParams->nextParams;
  317. }
  318. }
  319. break;
  320. case 3:/* reboot */
  321. __set_PRIMASK(1);
  322. NVIC_SystemReset();
  323. break;
  324. }
  325. current_device = current_device->nextDevice;
  326. myfree(SRAMEX, pubJsonString);
  327. }
  328. }
  329. // 重定义pow函数
  330. uint32_t my_pow(int base, int exponent) {
  331. uint32_t result = 1;
  332. for(int i = 0; i < exponent; i++) {
  333. result *= base;
  334. }
  335. return result;
  336. }
  337. void protocolsModeFunc(GATEWAY_PARAMS* get, char* string)
  338. {
  339. if(mqtt_connectFlag)
  340. {
  341. HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
  342. time1 = GetCurrentTime();
  343. sprintf(string,"{\"deviceId\":\"%s\",\"data\":[",get->deviceId); // 组成要发送的json语句
  344. if(startFlag && time2 <= time1 - ( 10 * 1000))// 10s进行一次全数据发送
  345. {
  346. mode = 0;//all
  347. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:All data");
  348. read_device_data(get->device_params,string);
  349. sprintf(string + strlen(string),"]}");
  350. mqtt_publish_data(string, QOS0, strlen(string), (char*)&get->messageTopic);
  351. time2 = GetCurrentTime();
  352. }
  353. else
  354. {
  355. mode = 1;// def
  356. read_device_data(get->device_params, string);
  357. if(def)// 检测string是否含有数据
  358. {
  359. def = 0;
  360. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"protocolsMode:Different data");
  361. sprintf(string + strlen(string),"]}");
  362. mqtt_publish_data(string, QOS0, strlen(string), (char*)&get->messageTopic);
  363. time2 = GetCurrentTime();
  364. }
  365. }
  366. startFlag = 1;
  367. memset(string,0,strlen(string));
  368. }
  369. }
  370. int transparent_data(DEVICE_PARAMS *device, char* string)
  371. {
  372. DEVICE_PARAMS *current_device=device;
  373. GATEWAY_READ_MODBUS_COMMAND *currentModbusParams = current_device->params->gateway_read_modbus_command;
  374. GATEWAY_READ_DLT645_COMMAND *currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  375. while(current_device->params != NULL)
  376. {
  377. HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_SET);
  378. if (current_device->protocol == MODBUS_READ)
  379. {
  380. uint16_t data[currentModbusParams->registerByteNum /2]; // modbus寄存器长度
  381. mmodbus_set16bitOrder(current_device->MDBbigLittleFormat);
  382. // 读单个寄存器
  383. if (currentModbusParams->functionCode == 0x03)
  384. {
  385. // bool success = mmodbus_readHoldingRegisters16i(0x17,0x00,0x02,data);
  386. bool success = mmodbus_readHoldingRegisters16i(currentModbusParams->slaveAddress,
  387. currentModbusParams->registerAddress,
  388. currentModbusParams->registerByteNum /2,
  389. data);
  390. if (success)
  391. {
  392. memcpy(string + transparent_lenth, mmodbus.rxBuf, mmodbus.rxIndex);
  393. transparent_lenth += mmodbus.rxIndex;
  394. }
  395. currentModbusParams = currentModbusParams->nextParams;
  396. if (currentModbusParams == NULL)
  397. {
  398. current_device = current_device->nextDevice;
  399. currentModbusParams = current_device->params->gateway_read_modbus_command;
  400. if(current_device == NULL)
  401. {
  402. return 1;
  403. }
  404. }
  405. }
  406. }
  407. else if (current_device->protocol == DLT645_2007 || current_device->protocol == DLT645_97)
  408. {
  409. uint8_t read_buf[10];
  410. memset(read_buf, 0, 10);
  411. memset(currentDLT645Params->data, 0, 10);
  412. dlt645_set_addr(&dlt645, currentDLT645Params->deviceID645);
  413. int8_t rs;
  414. if (current_device->protocol == DLT645_2007)
  415. {
  416. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_2007);
  417. }
  418. else if (current_device->protocol == DLT645_1997)
  419. {
  420. rs = dlt645_read_data(&dlt645, currentDLT645Params->Identification, read_buf, DLT645_1997);
  421. }
  422. if (rs != -1)
  423. {
  424. sprintf(string, "%s", read_buf);
  425. }
  426. currentDLT645Params = currentDLT645Params->nextParams;
  427. if (currentDLT645Params == NULL)
  428. {
  429. current_device = current_device->nextDevice;
  430. currentDLT645Params = current_device->params->gateway_read_dlt645_command;
  431. if(current_device == NULL)
  432. {
  433. return 1;
  434. }
  435. }
  436. }
  437. HAL_GPIO_WritePin(GPIOF,GPIO_PIN_6,GPIO_PIN_RESET);
  438. }
  439. return 1;
  440. }
  441. void transparentModeFunc(GATEWAY_PARAMS* get, char* string)
  442. {
  443. LogPrint(LOG_INFO,__FILE__,__FUNCTION__,__LINE__,"transparentMode:All data");
  444. printf("transparentMode:All data\n");
  445. memset(string,0,transparent_lenth);
  446. transparent_lenth = 0; // 记录string接收大小
  447. transparent_data(get->device_params, string);
  448. mqtt_publish_data(string, QOS0, transparent_lenth, (char*)&get->messageTopic);
  449. }