fromTcp.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /*
  2. * 从tcp发来的数据
  3. * 第一步:解析。
  4. * 解析tcp数据
  5. */
  6. function fromTcp(rawData){
  7. var obj = {};
  8. fourfaithHandle(rawData, obj)
  9. obj.productId = '1dbfd476b7nm2';
  10. var json = JSON.stringify(obj);
  11. return json;
  12. }
  13. // 四信网关
  14. function fourfaithHandle(rawData, obj) {
  15. var rawDataArray = ConvertToUint8Array(rawData);
  16. // obj.rawDataArray = ArrayToHexString(rawDataArray);
  17. // obj.rawDataArrayLength = rawDataArray.length
  18. if (rawDataArray.length == 1 && rawDataArray[0] == 0xFE){
  19. obj.msg = '网关心跳';
  20. return ;
  21. }
  22. if (rawDataArray[0] == 0x78 && rawDataArray[1] == 0x56){
  23. obj.msg = '网关连接';
  24. return ;
  25. }
  26. // 校验
  27. if (!xor_verify(rawDataArray)){
  28. throw 'API数据异或和校验失败';
  29. }
  30. // 获取api协议中的数据
  31. var dataArray = ConvertToUint8Array(rawData, 6, rawData.length - 1);
  32. // obj.dataArray = ArrayToHexString(dataArray);
  33. // obj.dataArrayLength = dataArray.length;
  34. // 判断新老协议
  35. if (dataArray[0] == 0xEF){
  36. analysis_new(dataArray, obj);
  37. }else {
  38. analysis_old(dataArray, obj);
  39. }
  40. // 获取api协议中的目的地址
  41. var addressArray = ConvertToUint8Array(rawData, 4, 6);
  42. if (obj.patientCodeArray){
  43. obj.responseHex = ArrayToHexString(responseData(addressArray, obj.patientCodeArray));
  44. delete obj.patientCodeArray
  45. }
  46. }
  47. // 解析报警数据
  48. function analysis_old_alarm(dataArray, obj) {
  49. obj.dataType = 5;
  50. // 报警数据
  51. var dataView = new DataView(dataArray.buffer, 0);
  52. // 类型【1】
  53. var type = dataView.getUint8(1);
  54. if (type == 0x15){
  55. obj.pumpType = 1;
  56. }else if (type == 0x25){
  57. obj.pumpType = 2;
  58. }else if (type == 0x35){
  59. obj.pumpType = 3;
  60. }else {
  61. obj.pumpType = 0;
  62. obj.msg = '泵类型不存在';
  63. return;
  64. }
  65. // 泵号【2-9】
  66. obj.pumpCode = ArrayToHexString(dataArray, 2, 10);
  67. // 住院号【10-13】
  68. if (obj.pumpType == 1 && dataArray.length == 36){
  69. obj.patientCodeArray = concat(ConvertToUint8Array(dataArray, 10, 14), ConvertToUint8Array(dataArray, 32, 34));
  70. } else if (obj.pumpType == 2 && dataArray.length == 39){
  71. obj.patientCodeArray = concat(ConvertToUint8Array(dataArray, 10, 14), ConvertToUint8Array(dataArray, 35, 37));
  72. } else {
  73. obj.patientCodeArray = ConvertToUint8Array(dataArray, 10, 14);
  74. }
  75. var patientCodeDataView = new DataView(obj.patientCodeArray.buffer);
  76. var patientCode = patientCodeDataView.getUint32(0, true);
  77. if (patientCodeDataView.byteLength == 6){
  78. patientCode += patientCodeDataView.getUint16(4, true) * 1000000000;
  79. }
  80. obj.patientCode = patientCode + '';
  81. // 病区【14-15】
  82. obj.ward = dataView.getUint16(14, true);
  83. // 床号【16-17】
  84. obj.bedNo = dataView.getUint16(16, true);
  85. // 持续量【18-19】
  86. obj.continueDose = dataView.getUint16(18, true) * 0.1;
  87. // 锁定时间【20-21】
  88. obj.lockTime = dataView.getUint16(20, true);
  89. // 极限量【22-23】
  90. obj.ultimateDose = dataView.getUint16(22, true);
  91. // 首次量【24】
  92. obj.firstDose = dataView.getUint8(24);
  93. // 追加量【25-26】
  94. obj.appendDose = dataView.getUint16(25, true) * 0.1;
  95. // 报警【29】
  96. obj.alarm = [];
  97. obj.forcast = [];
  98. var alarmByte = dataView.getUint8(29);
  99. // 未装药盒 9
  100. if ((alarmByte & 0x03) == 0x03){
  101. obj.alarm.push(9);
  102. } else if ((alarmByte & 0x01) == 0x01){
  103. // 气泡或无液 1
  104. obj.alarm.push(1);
  105. } else if ((alarmByte & 0x02) == 0x02){
  106. // 堵塞 2
  107. obj.alarm.push(2);
  108. }
  109. // 总量 3
  110. if ((alarmByte & 0x04) == 0x04){
  111. obj.alarm.push(3);
  112. }
  113. // 极限量 4
  114. if ((alarmByte & 0x08) == 0x08){
  115. obj.alarm.push(4);
  116. }
  117. // 输液将结束 1
  118. if ((alarmByte & 0x10) == 0x10){
  119. obj.forcast.push(1);
  120. }
  121. // 输液结束 6
  122. if ((alarmByte & 0x20) == 0x20){
  123. obj.alarm.push(6);
  124. }
  125. // 电量偏低预警 5
  126. if ((alarmByte & 0x40) == 0x40){
  127. obj.alarm.push(5);
  128. }
  129. // 电量偏低预报 3
  130. if ((alarmByte & 0x80) == 0x80){
  131. obj.forcast.push(3);
  132. }
  133. var alarmByte30 = dataView.getUint8(30);
  134. // 点击失控 7
  135. if ((alarmByte30 & 0x0f) == 0x01){
  136. obj.alarm.push(7);
  137. } else if ((alarmByte30 & 0x0f) == 0x02){
  138. // 机器故障 8
  139. obj.alarm.push(8);
  140. }
  141. // 无报警
  142. if (obj.alarm.length == 0){
  143. obj.alarm.push(0);
  144. }
  145. // 无预报
  146. if (obj.forcast.length == 0){
  147. obj.forcast.push(0);
  148. }
  149. // 运行状态【30】
  150. obj.runStatus = (dataArray[30] & 0xf0) >> 4;
  151. // 电池电量【31】
  152. obj.electricity = dataView.getUint8(31);
  153. // 脉冲泵的属性
  154. if (obj.pumpType == 2){
  155. // 首次量锁时【32】
  156. obj.firstLockTime = dataView.getUint8(32);
  157. // 脉冲量【33】
  158. obj.pulseDose = dataView.getUint8(33);
  159. // 脉冲量锁时【34】
  160. obj.pulseLockTime = dataView.getUint8(34);
  161. } else if (obj.pumpType == 3){
  162. // 智能泵的属性
  163. // 加档时间【32】
  164. obj.filingCycle = dataView.getUint8(32) * 0.1;
  165. // 减档时间【33】
  166. obj.reductionPeriod = dataView.getUint8(33) * 0.1;
  167. // 加档PCA有效计数【34】
  168. obj.addTrueFrequency = dataView.getUint8(34);
  169. // 自调比例【35】
  170. obj.customScate = dataView.getUint8(35);
  171. // 加档上限【36】
  172. var data36 = dataView.getUint8(36);
  173. if (data36 > 100){
  174. obj.upperLimit = (data36 - 128) * 1.0;
  175. }else {
  176. obj.upperLimit = data36 * 0.1;
  177. }
  178. // 减档下限【37】
  179. obj.lowerLimit = dataView.getUint8(37) * 0.1;
  180. }
  181. }
  182. // 解析运行数据
  183. function analysis_old_run(dataArray, obj) {
  184. obj.dataType = 3;
  185. // 报警数据
  186. var dataView = new DataView(dataArray.buffer, 0);
  187. // 类型【1】
  188. var type = dataView.getUint8(1);
  189. if (type == 0x13){
  190. obj.pumpType = 1;
  191. }else if (type == 0x23){
  192. obj.pumpType = 2;
  193. }else if (type == 0x33){
  194. obj.pumpType = 3;
  195. }else {
  196. obj.pumpType = 0;
  197. obj.msg = '泵类型不存在';
  198. return;
  199. }
  200. // 住院号【2-5】
  201. if (obj.pumpType == 1 && dataArray.length == 18){
  202. obj.patientCodeArray = concat(ConvertToUint8Array(dataArray, 2, 6), ConvertToUint8Array(dataArray, 14, 16));
  203. } else if (obj.pumpType == 2 && dataArray.length == 18){
  204. obj.patientCodeArray = concat(ConvertToUint8Array(dataArray, 2, 6), ConvertToUint8Array(dataArray, 14, 16));
  205. } else {
  206. obj.patientCodeArray = ConvertToUint8Array(dataArray, 2, 6);
  207. }
  208. var patientCodeDataView = new DataView(obj.patientCodeArray.buffer);
  209. var patientCode = patientCodeDataView.getUint32(0, true);
  210. if (patientCodeDataView.byteLength == 6){
  211. patientCode += patientCodeDataView.getUint16(4, true) * 1000000000;
  212. }
  213. obj.patientCode = patientCode + '';
  214. // 总量。【6-7】
  215. obj.totalDose = dataView.getUint16(6, true);
  216. // 已输入量【8-9】
  217. obj.finishDose = dataView.getUint16(8, true) * 0.1;
  218. // 电池状态【10】
  219. obj.electricity = dataView.getUint8(10);
  220. // 有效次数【11】
  221. obj.validTimes = dataView.getUint8(11);
  222. // 无效次数【12】
  223. obj.invalidTimes = dataView.getUint8(12);
  224. // 预报【13】和报警
  225. obj.forcast = [];
  226. obj.alarm = [];
  227. var warnByte = dataView.getUint8(13);
  228. // 电量偏低预报 3
  229. if ((warnByte & 0x04) == 0x04){
  230. obj.forcast.push(3);
  231. }
  232. // 无预报
  233. if (obj.forcast.length == 0){
  234. obj.forcast.push(0);
  235. }
  236. // 无报警
  237. if (obj.alarm.length == 0){
  238. obj.alarm.push(0);
  239. }
  240. // 运行状态
  241. obj.runStatus = 2;
  242. }
  243. // 解析老协议
  244. function analysis_old(dataArray, obj) {
  245. // crc校验
  246. if (!crc_verify(dataArray)){
  247. obj.msg = '老协议数据CRC校验失败';
  248. return ;
  249. }
  250. // 泵数据
  251. var type = dataArray[1] & 0x0f;
  252. if (type == 5){
  253. analysis_old_alarm(dataArray, obj);
  254. }else if (type == 3){
  255. analysis_old_run(dataArray, obj);
  256. }else {
  257. obj.msg = '数据格式错误';
  258. }
  259. }
  260. // 解析新协议
  261. function analysis_new(dataArray, obj) {
  262. // crc校验
  263. if (!crc_verify(dataArray)){
  264. obj.msg = '新协议数据CRC校验失败';
  265. return ;
  266. }
  267. // 泵数据
  268. var dataView = new DataView(dataArray.buffer, 0);
  269. // 泵类型【2】 高4位
  270. obj.pumpType = (dataArray[2] & 0xf0) >> 4;
  271. // 版本【2】 低4位
  272. obj.version = dataArray[2] & 0x0f;
  273. // 泵号【3-10】
  274. obj.pumpCode = ArrayToHexString(dataArray, 3, 11);
  275. // 输注标识【11】
  276. obj.infusionId = dataView.getUint8(11);
  277. // 发送条数【12】
  278. obj.dataNumber = dataView.getUint8(12);
  279. // 医院编号【13-14】
  280. obj.userId = dataView.getUint16(13, true);
  281. // 住院号【15-20】
  282. var patientCodeArray = ConvertToUint8Array(dataArray, 15, 21);
  283. var patientCodeDataView = new DataView(patientCodeArray.buffer);
  284. var patientCode = patientCodeDataView.getUint32(0, true)
  285. + patientCodeDataView.getUint16(4, true) * 4294967295;
  286. obj.patientCode = patientCode + '';
  287. obj.patientCodeArray = patientCodeArray;
  288. // 持续量【21-22】
  289. obj.continueDose = dataView.getUint16(21, true) * 0.1;
  290. // 锁定时间【23】
  291. obj.lockTime = dataView.getUint8(23);
  292. // 极限量【24】
  293. obj.ultimateDose = dataView.getUint8(24);
  294. // 首次量【25】
  295. obj.firstDose = dataView.getUint8(25);
  296. // 追加量【26】
  297. obj.appendDose = dataView.getUint8(26) * 0.1;
  298. // 总量【27-28】
  299. obj.totalDose = dataView.getUint16(27, true);
  300. // 已输入量【29-30】
  301. obj.finishDose = dataView.getUint16(29, true) * 0.1;
  302. // 有效次数【31】
  303. obj.validTimes = dataView.getUint8(31);
  304. // 无效次数【32】
  305. obj.invalidTimes = dataView.getUint8(32);
  306. // 报警【33】
  307. obj.alarm = [];
  308. obj.forcast = [];
  309. var alarmByte = dataView.getUint8(33);
  310. // 气泡或无液 1
  311. if ((alarmByte & 0x01) == 0x01){
  312. obj.alarm.push(1);
  313. }
  314. // 堵塞 2
  315. if ((alarmByte & 0x02) == 0x02){
  316. obj.alarm.push(2);
  317. }
  318. // 未装药盒 9
  319. if ((alarmByte & 0x04) == 0x04){
  320. obj.alarm.push(9);
  321. }
  322. // 极限量 4
  323. if ((alarmByte & 0x08) == 0x08){
  324. obj.alarm.push(4);
  325. }
  326. // 总量 3
  327. if ((alarmByte & 0x10) == 0x10){
  328. obj.alarm.push(3);
  329. }
  330. // 输液将结束 1
  331. if ((alarmByte & 0x20) == 0x20){
  332. obj.forcast.push(1);
  333. }
  334. // 输液结束 6
  335. if ((alarmByte & 0x40) == 0x40){
  336. obj.alarm.push(6);
  337. }
  338. // 机器故障 8
  339. if ((alarmByte & 0x80) == 0x80){
  340. obj.alarm.push(8);
  341. }
  342. // 预报 [34]
  343. var warnByte = dataView.getUint8(34);
  344. // 电量偏低预警 5
  345. if ((warnByte & 0x01) == 0x01){
  346. obj.alarm.push(5);
  347. }
  348. // 电量偏低预报 3
  349. if ((warnByte & 0x02) == 0x02){
  350. obj.forcast.push(3);
  351. }
  352. // 遗忘报警 4
  353. if ((warnByte & 0x04) == 0x04){
  354. obj.forcast.push(4);
  355. }
  356. // 无报警
  357. if (obj.alarm.length == 0){
  358. obj.alarm.push(0);
  359. }
  360. // 无预报
  361. if (obj.forcast.length == 0){
  362. obj.forcast.push(0);
  363. }
  364. // 运行状态【35】
  365. obj.runStatus = (dataArray[35] & 0xf0) >> 4;
  366. // 电池电量【36】
  367. obj.electricity = dataView.getUint8(36);
  368. // CRC【37-38】不处理
  369. }
  370. // 获取返回的字节
  371. function responseData(dest, patientCodeArray){
  372. var length = dest.length + patientCodeArray.length + 7;
  373. var responseBytes = new Uint8Array(length);
  374. // 帧头
  375. responseBytes[0] = 0xFE;
  376. // 长度域
  377. responseBytes[1] = (dest.length + patientCodeArray.length + 2) & 0xff;
  378. // 命令域
  379. responseBytes[2] = 0x24;
  380. responseBytes[3] = 0x5f;
  381. // 目的地址
  382. responseBytes[4] = dest[0];
  383. responseBytes[5] = dest[1];
  384. // 固定位。0xAD 0xFC
  385. responseBytes[6] = 0xad;
  386. responseBytes[7] = 0xfc;
  387. // 数据。住院号
  388. for (var i = 0; i < patientCodeArray.length; i++){
  389. responseBytes[8 + i] = patientCodeArray[i];
  390. }
  391. // 异或和
  392. var xor_value = xor(responseBytes, 1, length - 1);
  393. responseBytes[length - 1] = xor_value & 0xff;
  394. return responseBytes;
  395. }