You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

923 lines
45KB

  1. using AutoMapper.Internal;
  2. using GpsCardGatewayPosition.Common;
  3. using GpsCardGatewayPosition.Common.Helper;
  4. using GpsCardGatewayPosition.Model.Config;
  5. using GpsCardGatewayPosition.Model.Context;
  6. using GpsCardGatewayPosition.Model.Enum;
  7. using GpsCardGatewayPosition.Model.IoT;
  8. using GpsCardGatewayPosition.Model.Templates;
  9. using GpsCardGatewayPosition.Service.Biz;
  10. using GpsCardGatewayPosition.Service.Biz.Health;
  11. using GpsCardGatewayPosition.Service.Biz.Location;
  12. using GpsCardGatewayPosition.Service.Biz.Location.Dto;
  13. using GpsCardGatewayPosition.Service.Biz.Location.Dto.Gaode;
  14. using GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz;
  15. using GpsCardGatewayPosition.Service.Biz.Pay;
  16. using GpsCardGatewayPosition.Service.Biz.Sos;
  17. using GpsCardGatewayPosition.Service.Cache;
  18. using GpsCardGatewayPosition.Service.MqProducer;
  19. using GpsCardGatewayPosition.Service.MqProducer.Model;
  20. using GpsCardGatewayPosition.Service.Resolver.Interface;
  21. using GpsCardGatewayPosition.Service.Resolver.Property.Dto;
  22. using Microsoft.Extensions.Logging;
  23. using Microsoft.Extensions.Options;
  24. using Newtonsoft.Json;
  25. using Newtonsoft.Json.Linq;
  26. using System;
  27. using System.Collections.Generic;
  28. using System.Linq;
  29. using System.Text;
  30. using System.Threading.Tasks;
  31. using TelpoDataService.Util.Entities.GpsCard;
  32. using TelpoDataService.Util.Entities.GpsLocationHistory;
  33. using static GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz.WayzRequest;
  34. namespace GpsCardGatewayPosition.Service.Resolver.Property
  35. {
  36. public class WifiPlus2PositionResolver : IPropertyResolver
  37. {
  38. private readonly ILogger<WifiPlus2PositionResolver> _logger;
  39. private readonly WifiParamConfig _configWifiParam;
  40. private readonly DeviceCacheManager _deviceCacheMgr;
  41. private readonly GaodeService _serviceGaode;
  42. private readonly WayzService _serviceWayz;
  43. private readonly MqProcessLogic _serviceMqProcess;
  44. private readonly GlobalService _serviceGlobal;
  45. private readonly PayLogic _servicePay;
  46. private readonly SosLogic _serviceSos;
  47. private readonly HealthLogic _serviceHealth;
  48. private readonly LocationLogic _serviceLocation;
  49. private AsyncLocal<string> _messageId = new AsyncLocal<string>();
  50. private AsyncLocal<PropertyModel> _package = new AsyncLocal<PropertyModel>();
  51. private AsyncLocal<PropertyItemModel<List<EachWifiPlus2Model>>> _propertyValue = new AsyncLocal<PropertyItemModel<List<EachWifiPlus2Model>>>();
  52. private AsyncLocal<PackageMsgModel> _packageMsgModel = new AsyncLocal<PackageMsgModel>();
  53. public WifiPlus2PositionResolver(ILogger<WifiPlus2PositionResolver> logger, IOptions<WifiParamConfig> optConfigWifiParam,
  54. MqProcessLogic serviceMqProcess, GlobalService serviceGlobal, PayLogic servicePay, HealthLogic serviceHealth, LocationLogic serviceLocation,
  55. WayzService serviceWayz, SosLogic serviceSos, GaodeService serviceGaode, DeviceCacheManager deviceCacheMgr
  56. )
  57. {
  58. _serviceGlobal = serviceGlobal;
  59. _servicePay = servicePay;
  60. _serviceHealth = serviceHealth;
  61. _serviceLocation = serviceLocation;
  62. _serviceSos = serviceSos;
  63. _serviceMqProcess = serviceMqProcess;
  64. _serviceGaode = serviceGaode;
  65. _serviceWayz = serviceWayz;
  66. _deviceCacheMgr = deviceCacheMgr;
  67. _logger = logger;
  68. _configWifiParam = optConfigWifiParam.Value;
  69. }
  70. public void SetResolveInfo(PackageMsgModel msg)
  71. {
  72. _messageId.Value = msg.MessageId;
  73. _package.Value = ((JToken)msg.TopicInfo).ToObject<PropertyModel>()!;
  74. _propertyValue.Value = ((JToken)msg.DetailData).ToObject<PropertyItemModel<List<EachWifiPlus2Model>>>()!;
  75. }
  76. public override string ToString()
  77. {
  78. return $"{nameof(WifiPlus2PositionResolver)}[{_messageId.Value}]";
  79. }
  80. public async Task ExecuteMessageAsync()
  81. {
  82. var package = _package.Value;
  83. var serialno = package?.DeviceName; //设备序列号
  84. var messageId = _messageId.Value;
  85. var propertyValue = _propertyValue.Value;
  86. var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(messageId!, serialno!).ConfigureAwait(false);
  87. if (device == null)
  88. {
  89. _logger.LogError($"非法设备:{serialno}");
  90. return;
  91. }
  92. //var device = new GpsDevice()
  93. //{
  94. // DeviceId = serialno,
  95. //};
  96. DateTime now = DateTime.Now;
  97. LocationType type = LocationType.LBS;
  98. foreach (var item in propertyValue!.Value)
  99. {
  100. try
  101. {
  102. var datetime = Utils.ConvertToLocalDateTime(item.Datetime);
  103. var mmac = item.Mmac;
  104. var macs = item.Macs;
  105. var imei = item.Imei;
  106. var smac = item.Smac;
  107. var imsi = item.Imsi;
  108. var nearbts = item.NearBts;
  109. var network = item.Network;
  110. var cdma = item.Cdma;
  111. var bts = item.Bts;
  112. var IDType = item.IdType;
  113. var IDNumber = item.IdNumber;
  114. var steps = SafeType.SafeInt(item.Steps); //2分钟内的步数值增量
  115. bool isRedressed = false;
  116. if (imei.Contains("unkonw") || bts.Length == 0) // || nearbts.Length == 0 //紧急修改,应急用
  117. {
  118. continue;
  119. }
  120. string cityCode = null;
  121. string addr = null;
  122. string province = null;
  123. string city = null;
  124. string district = null;
  125. decimal olat = 0;
  126. decimal olng = 0;
  127. decimal baiduLat = 0;
  128. decimal baiduLng = 0;
  129. decimal gaodeLat = 0;
  130. decimal gaodeLng = 0;
  131. int radius = 0;
  132. decimal[] latLngWifi = new decimal[4];
  133. decimal[] latLngLbs = new decimal[4];
  134. string hashParam = Guid.NewGuid().ToString();
  135. //bool isBtsOnly = false; //标识第二次主基站lbs查询
  136. //bool isBtsOnly = true; //取消标识第二次主基站lbs查询
  137. var WayzFullAddress = string.Empty;
  138. #region 定位解析
  139. //var wifiRequest = new GaodeWifiRequest
  140. //{
  141. // //Imei = serialno,
  142. // Macs = macs,
  143. // Mmac = mmac
  144. //};
  145. //var joWifi = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, wifiRequest).ConfigureAwait(false);
  146. //var lbsRequest = new GaodeLbsRequest
  147. //{
  148. // Bts = bts,
  149. // Cdma = 0,
  150. // //Imei = serialno,
  151. // Imsi = imsi,
  152. // // NearBts = nearbts,
  153. // // 2022/11/21
  154. // // 所有的基站定位都采用只使用主基站进行获取高德定位数据。不用nearbts的附近基站定位
  155. // NearBts = string.Empty,
  156. // Smac = ""
  157. //};
  158. //var joLbs = await _serviceGaode.GetGaodeLbsAddressAsync(serialno, lbsRequest).ConfigureAwait(false);
  159. #region 维智地图请求
  160. // wayz wifi
  161. var wifiWayzItems = new List<WayzRequest.WifiItem>();
  162. // 已经接入的wifi mmac:80:8f:1d:bf:45:b1,-70,
  163. if (mmac.Split(',').Length > 2)
  164. {
  165. wifiWayzItems.Add(new WifiItem
  166. {
  167. Connected = true,
  168. SignalStrength = Math.Abs(int.Parse(mmac.Split(',')[1])),
  169. MacAddress = mmac.Split(',')[0]
  170. });
  171. }
  172. // wifi 列表 macs:08:9b:4b:b7:b3:5d,-70,|20:6b:e7:7e:4d:30,-70,|8c:a6:df:74:33:15,-74,|74:7d:24:0f:ff:60,-74,|78:44:76:0a:3c:74,-75,|02:0e:5e:ad:5d:d1,-78,|10:a4:be:f6:12:bf,-78,
  173. if (macs.Split('|').Length > 1)
  174. {
  175. macs.Split('|').ForAll(mac =>
  176. {
  177. wifiWayzItems.Add(new WifiItem
  178. {
  179. Connected = false,
  180. SignalStrength = Math.Abs(int.Parse(mac.Split(',')[1])),
  181. MacAddress = mac.Split(',')[0]
  182. });
  183. });
  184. }
  185. var wifiWayzRequest = new WayzWifiRequest
  186. {
  187. Location = new LocationDetail
  188. {
  189. Wifis = wifiWayzItems
  190. },
  191. Asset = new AssetDevice
  192. {
  193. Id = serialno,
  194. ImeiMd5 = serialno,
  195. UniqueId = device.DeviceId
  196. }
  197. };
  198. //wifiWayzRequest.Timestamp = Utils.ConvertToSTimeStamp(Utils.ConvertToLocalDateTime(item.Datetime));
  199. //wifiWayzRequest.Asset.Id = serialno;
  200. ////wifiWayzRequest.Asset.ImeiMd5 = Convert.ToBase64String(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(serialno)));
  201. //wifiWayzRequest.Asset.ImeiMd5 = serialno;
  202. //wifiWayzRequest.Asset.UniqueId = device.DeviceId;
  203. var joWayzWifi = await _serviceWayz.GetWayzWifiAddressAsync(serialno, wifiWayzRequest).ConfigureAwait(false);
  204. // wayz lbs
  205. var cellularWayzItems = new List<CellularItem>();
  206. // 非cdma:格式为mcc,mnc,lac,cellid,signal。
  207. if (cdma == 0)
  208. {
  209. var mcc = bts.Split(',')[0];
  210. var mnc = bts.Split(',')[1];
  211. var lac = bts.Split(',')[2];
  212. var cellId = bts.Split(',')[3];
  213. cellularWayzItems.Add(new CellularItem
  214. {
  215. CellId = int.Parse(cellId),
  216. RadioType = network,
  217. MobileCountryCode = int.Parse(mcc),
  218. MobileNetworkCode = int.Parse(mnc),
  219. LocationAreaCode = int.Parse(lac),
  220. });
  221. }
  222. // cdma:格式为sid,nid,bid,lon,lat,signal
  223. else
  224. {
  225. // sid
  226. var mnc = bts.Split(',')[0];
  227. // bid
  228. var cellId = bts.Split(',')[2];
  229. // nid
  230. var lac = bts.Split(',')[1];
  231. cellularWayzItems.Add(new CellularItem
  232. {
  233. CellId = int.Parse(cellId),
  234. RadioType = network,
  235. //MobileCountryCode = int.Parse(mcc),
  236. MobileNetworkCode = int.Parse(mnc),
  237. LocationAreaCode = int.Parse(lac),
  238. });
  239. }
  240. var lbsWayzRequest = new WayzLbsRequest
  241. {
  242. Location = new LocationDetail
  243. {
  244. Cellulars = cellularWayzItems
  245. },
  246. Asset = new AssetDevice
  247. {
  248. Id = serialno,
  249. ImeiMd5 = serialno,
  250. UniqueId = device.DeviceId
  251. }
  252. };
  253. //lbsWayzRequest.Timestamp = Utils.ConvertToSTimeStamp(Utils.ConvertToLocalDateTime(item.Datetime));
  254. //lbsWayzRequest.Asset.Id = serialno;
  255. ////lbsWayzRequest.Asset.ImeiMd5 = Convert.ToBase64String(MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(serialno)));
  256. //lbsWayzRequest.Asset.ImeiMd5 = serialno;
  257. //lbsWayzRequest.Asset.UniqueId = device.DeviceId;
  258. var joWayzLbs = await _serviceWayz.GetWayzLbsAddressAsync(serialno, lbsWayzRequest).ConfigureAwait(false);
  259. #endregion
  260. // 只用通过主机站数据查询lbs
  261. //if (!joWayzLbs.Flag)
  262. //{
  263. // //通过主机站数据查询lbs
  264. // //lbsRequest = new GaodeLbsRequest
  265. // //{
  266. // // Bts = bts,
  267. // // Cdma = 0,
  268. // // Imsi = imsi,
  269. // // Smac = "",
  270. // //};
  271. // //joLbs = await _serviceGaode.GetGaodeLbsAddressAsync(serialno, lbsRequest).ConfigureAwait(false);
  272. // joWayzLbs = await _serviceWayz.GetWayzLbsAddressAsync(serialno, lbsWayzRequest).ConfigureAwait(false);
  273. // isBtsOnly = true;
  274. // WayzFullAddress = joWayzLbs.FullAddress;
  275. // }
  276. if (joWayzLbs.Flag)
  277. {
  278. cityCode = joWayzLbs.AdCode;
  279. addr = joWayzLbs.Address;
  280. province = joWayzLbs.Province;
  281. city = joWayzLbs.City;
  282. district = joWayzLbs.District;
  283. radius = joWayzLbs.Accuracy;
  284. //lbs对应经纬度
  285. latLngLbs = GeoConvert.ConvertGoogleBaiduLatLng(joWayzLbs.Lat, joWayzLbs.Lon);
  286. olat = joWayzLbs.Lat;
  287. olng = joWayzLbs.Lon;
  288. baiduLng = latLngLbs[3];
  289. baiduLat = latLngLbs[2];
  290. gaodeLng = latLngLbs[1];
  291. gaodeLat = latLngLbs[0];
  292. hashParam = joWayzLbs.HashParam;
  293. WayzFullAddress = joWayzLbs.FullAddress;
  294. }
  295. if (joWayzWifi.Flag) //wifi定位比lbs精准,所以优先采用wifi定位
  296. {
  297. //wifi对应经纬度
  298. latLngWifi = GeoConvert.ConvertGoogleBaiduLatLng(joWayzWifi.Lat, joWayzWifi.Lon);
  299. //计算wifi和lbs定位结果之间的直线距离
  300. //double distance_1st = 0, distance_2nd = 0;
  301. double distance_1st = 0;
  302. //var distance = distance_1st = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)latLngWifi[1], (double)latLngWifi[0], (double)latLngLbs[1], (double)latLngLbs[0]) : 0;
  303. var distance = distance_1st = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)joWayzWifi.Lon, (double)joWayzWifi.Lat, (double)joWayzLbs.Lon, (double)joWayzLbs.Lat) : 0;
  304. if (distance >= 1 * 10000)
  305. {
  306. _logger.LogWarning($"lbs漂移较大 [{joWayzLbs.AdCode}] [{joWayzLbs.Address}]");
  307. //if (!isBtsOnly)
  308. //{
  309. // ////通过主机站数据查询lbs
  310. // //lbsRequest = new GaodeLbsRequest
  311. // //{
  312. // // Bts = bts,
  313. // // Cdma = 0,
  314. // // Imsi = imsi,
  315. // // Smac = "",
  316. // //};
  317. // //joLbs = await _serviceGaode.GetGaodeLbsAddressAsync(serialno, lbsRequest).ConfigureAwait(false);
  318. // joWayzLbs = await _serviceWayz.GetWayzLbsAddressAsync(serialno, lbsWayzRequest).ConfigureAwait(false);
  319. // //lbs对应经纬度
  320. // latLngLbs = GeoConvert.ConvertGoogleBaiduLatLng(joWayzLbs.Lat, joWayzLbs.Lon);
  321. // //计算wifi和lbs定位结果之间的直线距离
  322. // //distance = distance_2nd = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)latLngWifi[1], (double)latLngWifi[0], (double)latLngLbs[1], (double)latLngLbs[0]) : 0;
  323. // distance = distance_2nd = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)joWayzWifi.Lon, (double)joWayzWifi.Lat, (double)joWayzLbs.Lon, (double)joWayzLbs.Lat) : 0;
  324. // isBtsOnly = true;
  325. // WayzFullAddress = joWayzLbs.FullAddress;
  326. // }
  327. }
  328. //2020/12/17山西设备(862622050677507) lbs直径距离大于1公里
  329. //讨论结果定为10公里
  330. if (distance < 1 * 10000) //两种定位方式的直线距离小于10km,否则抛弃定位
  331. {
  332. //cityCode = joWifi.AdCode;
  333. //addr = joWifi.Address;
  334. //province = joWifi.Province;
  335. //city = joWifi.City;
  336. //district = joWifi.District;
  337. //radius = joWifi.Accuracy;
  338. //olat = joWifi.Lat;
  339. //olng = joWifi.Lon;
  340. //baiduLng = latLngWifi[3];
  341. //baiduLat = latLngWifi[2];
  342. //gaodeLng = latLngWifi[1];
  343. //gaodeLat = latLngWifi[0];
  344. //type = LocationType.WIFI;
  345. //hashParam = joWifi.HashParam;
  346. #region 2022/11/11 增加判断wifi解析的地址是为空或null,就采用LBS的地址解析信息,否则用wifi解析的地址信息
  347. /**
  348. * 864002050460741 定位解析没有地址信息,入库也无法显示,需要切换LBS解析的处理。
  349. */
  350. // wifi解析的地址信息有效
  351. if (!string.IsNullOrEmpty(joWayzWifi.Address))
  352. {
  353. cityCode = joWayzWifi.AdCode;
  354. addr = joWayzWifi.Address;
  355. province = joWayzWifi.Province;
  356. city = joWayzWifi.City;
  357. district = joWayzWifi.District;
  358. radius = joWayzWifi.Accuracy;
  359. olat = joWayzWifi.Lat;
  360. olng = joWayzWifi.Lon;
  361. baiduLng = latLngWifi[3];
  362. baiduLat = latLngWifi[2];
  363. gaodeLng = latLngWifi[1];
  364. gaodeLat = latLngWifi[0];
  365. type = LocationType.WIFI;
  366. hashParam = joWayzWifi.HashParam;
  367. WayzFullAddress = joWayzWifi.FullAddress;
  368. }
  369. // wifi解析的地址信息无效,采用LBS的地址信息
  370. else if (!string.IsNullOrEmpty(joWayzLbs.Address))
  371. {
  372. cityCode = joWayzLbs.AdCode;
  373. addr = joWayzLbs.Address;
  374. province = joWayzLbs.Province;
  375. city = joWayzLbs.City;
  376. district = joWayzLbs.District;
  377. radius = joWayzLbs.Accuracy;
  378. olat = joWayzLbs.Lat;
  379. olng = joWayzLbs.Lon;
  380. baiduLng = latLngLbs[3];
  381. baiduLat = latLngLbs[2];
  382. gaodeLng = latLngLbs[1];
  383. gaodeLat = latLngLbs[0];
  384. type = LocationType.LBS;
  385. hashParam = joWayzLbs.HashParam;
  386. WayzFullAddress = joWayzLbs.FullAddress;
  387. }
  388. // LBS和Wifi都不能解析地址,不入库
  389. else
  390. {
  391. return;
  392. }
  393. #endregion
  394. }
  395. //else
  396. //{
  397. // //记录日志
  398. // await _telpoFailureApiClient.AddAsync(new TelpoFailureOperator
  399. // {
  400. // Schema="GaodeLbsError",
  401. // Table=messageId,
  402. // EntityFullname=$"距离 1st={distance_1st}, 2nd={distance_2nd}",
  403. // OperateType= DelayOperateTypeEnum.Insert,
  404. // OperateTime= datetime,
  405. // CreateTime =DateTime.Now,
  406. // JsonData=JsonConvert.SerializeObject(item),
  407. // State=1,
  408. // ErrorMessage=joLbs.Address
  409. // }, new RequestHeader { RequestId = messageId }).ConfigureAwait(false);
  410. // continue;
  411. //}
  412. }
  413. // 维智不能解析定位调用高德和纠偏
  414. else
  415. {
  416. _logger.LogInformation($"维智服务不能解析wifi数据,将采用高德服务解析");
  417. var wifiGaodeRequest = new GaodeWifiRequest
  418. {
  419. //Imei = serialno,
  420. Macs = macs,
  421. Mmac = mmac
  422. };
  423. var joGaodeWifi = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, wifiGaodeRequest);
  424. if (joGaodeWifi.Flag)
  425. {
  426. _logger.LogInformation($"高德服务解析解析wifi定位数据");
  427. cityCode = joGaodeWifi.AdCode;
  428. addr = joGaodeWifi.Address;
  429. province = joGaodeWifi.Province;
  430. city = joGaodeWifi.City;
  431. district = joGaodeWifi.District;
  432. radius = joGaodeWifi.Accuracy;
  433. olat = joGaodeWifi.Lat;
  434. olng = joGaodeWifi.Lon;
  435. latLngWifi = GeoConvert.ConvertGoogleBaiduLatLng(joGaodeWifi.Lat, joGaodeWifi.Lon);
  436. baiduLng = latLngWifi[3];
  437. baiduLat = latLngWifi[2];
  438. gaodeLng = latLngWifi[1];
  439. gaodeLat = latLngWifi[0];
  440. type = LocationType.WIFI;
  441. hashParam = joGaodeWifi.HashParam;
  442. WayzFullAddress = string.Format("{0}|{1}", "_Gaode", joGaodeWifi.Address);
  443. //调用维智纠偏
  444. //await _serviceWayz.WayzWifiCalbration(wifiWayzRequest);
  445. /** 高德wifi与维智LBS对比
  446. latLngWifi = GeoConvert.ConvertGoogleBaiduLatLng(joWayzWifi.Lat, joWayzWifi.Lon);
  447. double distance_1st = 0;
  448. //var distance = distance_1st = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)latLngWifi[1], (double)latLngWifi[0], (double)latLngLbs[1], (double)latLngLbs[0]) : 0;
  449. var distance = distance_1st = joWayzLbs.Flag ? GeoUtils.GetDistance2((double)joGaodeWifi.Lon, (double)joGaodeWifi.Lat, (double)joWayzLbs.Lon, (double)joWayzLbs.Lat) : 0;
  450. if (distance >= 1 * 10000)
  451. {
  452. _logger.LogWarning($"lbs漂移较大 [{joWayzLbs.AdCode}] [{joWayzLbs.Address}]");
  453. }
  454. if (distance < 1 * 10000)
  455. {
  456. cityCode = joGaodeWifi.AdCode;
  457. addr = joGaodeWifi.Address;
  458. province = joGaodeWifi.Province;
  459. city = joGaodeWifi.City;
  460. district = joGaodeWifi.District;
  461. radius = joGaodeWifi.Accuracy;
  462. olat = joGaodeWifi.Lat;
  463. olng = joGaodeWifi.Lon;
  464. baiduLng = latLngWifi[3];
  465. baiduLat = latLngWifi[2];
  466. gaodeLng = latLngWifi[1];
  467. gaodeLat = latLngWifi[0];
  468. type = LocationType.WIFI;
  469. hashParam = joGaodeWifi.HashParam;
  470. WayzFullAddress = string.Format("{0}|{1}", "_Gaode", joGaodeWifi.Address);
  471. }
  472. */
  473. }
  474. else
  475. {
  476. _logger.LogInformation($"维智服务和高德服务解析都不能解析wifi定位数据");
  477. }
  478. }
  479. //处理业务
  480. var positionStatus = await _deviceCacheMgr.GetPositionStatusCacheAsync(imei).ConfigureAwait(false);
  481. var eachParam = mmac.Split(',');
  482. var signal = Convert.ToInt32(eachParam[1]); //主wifi信号强度值
  483. if (positionStatus?.LastPosition != null)
  484. {
  485. if (!joWayzLbs.Flag && !joWayzWifi.Flag)
  486. {
  487. if (joWayzLbs.CanRetry || joWayzWifi.CanRetry)
  488. {
  489. await _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All);
  490. }
  491. // 2022/11/29 高德解析不了地址,丢弃不入库,但写日志
  492. // isRedressed = true;
  493. _logger.LogInformation($"设备{serialno},{nameof(WifiPlus2PositionResolver)} 解析不了地址,丢弃不入库,但写日志");
  494. return;
  495. }
  496. //2022/11/07 取消LBS覆盖操作(HW) 统一都按LBS定位处理,作为无效定位,不更新定位数据,只更新时间
  497. //2022/07/19新需求:少于步数增量阈值的lbs定位需要用上一次成功定位点的值替换,并入库
  498. // if (type == LocationType.LBS && steps < _configWifiParam.ThresholdSteps)
  499. //{
  500. // isRedressed = true;
  501. //}
  502. // 2022/11/29 高德解析不了地址,丢弃不入库,但写日志
  503. // 2022/11/11 可能存在不是 LBS和wifi都解析地址就使用缓存的数据
  504. //if (isRedressed)
  505. //{
  506. // var pos = positionStatus.LastPosition;
  507. // type = (LocationType)pos.LocationType;
  508. // radius = pos.Radius;
  509. // addr = pos.Address;
  510. // baiduLat = pos.BaiduLat;
  511. // baiduLng = pos.BaiduLon;
  512. // olat = pos.OriginalLat;
  513. // olng = pos.OriginalLon;
  514. // gaodeLat = pos.GaodeLat;
  515. // gaodeLng = pos.GaodeLon;
  516. // province = pos.Province;
  517. // city = pos.City;
  518. // district = pos.District;
  519. //}
  520. }
  521. ////******2022/04/24 领导决定不采用最后一次有效定位填充当前无效定位值
  522. //if (signal > -70) //主wifi信号强度
  523. //{
  524. //}
  525. //else if (type == LocationType.WIFI && radius > Consts.RadiusThreshold)
  526. //{
  527. // var cachePosition = positionStatus?.LastPosition;
  528. // if (cachePosition != null)
  529. // {
  530. // // 如果主mac信号强度小于-70,则进行距离判断
  531. // // 计算当前wifi点和上一个可信点之间的直线距离
  532. // var positionDistance = GeoUtils.GetDistance2((double)cachePosition.GaodeLon, (double)cachePosition.GaodeLat, (double)latLngWifi[1], (double)latLngWifi[0]);
  533. // //换算步数之间的距离
  534. // var movingDistance = Utils.GetMovingDistance(steps, _configWifiParam);
  535. // //位置的确发生了变化的情况
  536. // // positionDistance大于100米同时步数距离大于100米,其他情况都认为没有动
  537. // if (positionDistance >= 100 && movingDistance >= 100) //使用新点,用新点更新缓存,认为设备移动了
  538. // {
  539. // }
  540. // else //取上一个可信点,认为设备没有移动
  541. // {
  542. // addr = cachePosition.Address;
  543. // olat = cachePosition.OriginalLat;
  544. // olng = cachePosition.OriginalLon;
  545. // baiduLng = cachePosition.BaiduLon;
  546. // baiduLat = cachePosition.BaiduLat;
  547. // gaodeLat = cachePosition.GaodeLat;
  548. // gaodeLng = cachePosition.GaodeLon;
  549. // cityCode = cachePosition.CityCode;
  550. // radius = cachePosition.Radius;
  551. // }
  552. // }
  553. //}
  554. #endregion
  555. #region 保存历史轨迹
  556. var loc = new LocationInfo
  557. {
  558. LocationId = Guid.NewGuid().ToString("D"),
  559. Address = addr,
  560. BaiduLat = baiduLat,
  561. BaiduLng = baiduLng,
  562. OLat = olat,
  563. OLng = olng,
  564. GLat = gaodeLat,
  565. GLng = gaodeLng,
  566. Course = 0,
  567. DeviceId = device.DeviceId,
  568. DeviceStatus = radius.ToString(),
  569. IsStop = false,
  570. LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time), //LastUpdate = datetime,
  571. UtcDate = Utils.ConvertToUtcDateTime(propertyValue.Time), //UtcDate = datetime.ToUniversalTime(),
  572. LocationType = (int)type,
  573. Remarks = cityCode,
  574. SerialNo = serialno,
  575. Speed = 0,
  576. Postcode = cityCode,
  577. IsRedressed = isRedressed,
  578. HashParam = hashParam,
  579. Province = province,
  580. City = city,
  581. District = district
  582. };
  583. loc.Remarks = string.Format("Wayz_WifiPlus2|{0}", WayzFullAddress);
  584. var requestPositionData = new object();
  585. if (loc.LocationType == 2)
  586. {
  587. var requestLbsPositionData = new RequestLocationInfo<WayzLbsRequest>
  588. {
  589. MapSource = 2,
  590. RequestLocationType = loc.LocationType,
  591. RequestData = lbsWayzRequest
  592. };
  593. requestPositionData = requestLbsPositionData;
  594. }
  595. if (loc.LocationType == 3)
  596. {
  597. var requestWifiPositionData = new RequestLocationInfo<WayzWifiRequest>
  598. {
  599. MapSource = 2,
  600. RequestLocationType = loc.LocationType,
  601. RequestData = wifiWayzRequest
  602. };
  603. requestPositionData = requestWifiPositionData;
  604. }
  605. // 2022/11/23 定位缓存需要增加步数字段实现前端“静止/行走”状态展示,增加了steps参数
  606. var result = await _serviceLocation.AddLocationAsync(messageId, loc, positionStatus, propertyValue.Time, cityCode, steps, requestPositionData).ConfigureAwait(false);
  607. if (!result.IsSuccess)
  608. {
  609. _logger.LogError($"{result.Message}");
  610. return;
  611. }
  612. #endregion
  613. if (radius <= Consts.RadiusThreshold) //新需求:有效定位才做围栏判断
  614. {
  615. #region 处理围栏
  616. //过滤历史定位
  617. //if (!result.IsHistoryLocation)
  618. //{
  619. // _serviceLocation.ProcessGeofence(loc, messageId);
  620. //}
  621. //else
  622. //{
  623. // _logger.LogInformation($"设备{serialno},收到历史定位");
  624. //}
  625. #endregion
  626. }
  627. #region 保存最后位置信息
  628. var context = "online=1";
  629. var deviceStatus = await _deviceCacheMgr.GetDeviceStatusBySerialNoAsync(messageId, serialno).ConfigureAwait(false);
  630. var statusContext = new DeviceStatus();
  631. if (deviceStatus != null)
  632. {
  633. statusContext.Deserlize(deviceStatus.DeviceStatus);
  634. }
  635. statusContext.Deserlize(context);
  636. //重新构建设备状态数据
  637. deviceStatus = new GpsDeviceStatus
  638. {
  639. Address = addr,
  640. IsStop = (bool)loc.IsStop,
  641. BaiduLat = baiduLat,
  642. BaiduLng = baiduLng,
  643. Olat = olat,
  644. Olng = olng,
  645. Glat = gaodeLat,
  646. Glng = gaodeLng,
  647. Course = loc.Course,
  648. DeviceId = loc.DeviceId,
  649. DeviceStatus = statusContext.ToString(),
  650. DeviceUtcTime = loc.UtcDate,
  651. LastUpdate = loc.LastUpdate,
  652. LocationType = loc.LocationType,
  653. Remarks = loc.LocationId,
  654. Serialno = loc.SerialNo,
  655. //Speed = loc.Speed,
  656. Speed = SafeType.SafeInt(loc.DeviceStatus)
  657. };
  658. var updateOper = await _serviceLocation.UpdateDeviceStatusAsync(messageId, deviceStatus).ConfigureAwait(false);
  659. if (!updateOper.IsSuccess)
  660. {
  661. _logger.LogError($"{updateOper.Message}");
  662. return;
  663. }
  664. //THOMAS Kafka
  665. var positionData = new LocationDatas()
  666. {
  667. imei = loc.SerialNo,
  668. altitude = 0,
  669. address = loc.Address,
  670. baiduLatitude = loc.BaiduLat,
  671. baiduLongitude = loc.BaiduLng,
  672. gaodeLatitude = loc.GLat,
  673. gaodeLongitude = loc.GLng,
  674. originalLatitude = loc.OLat,
  675. originalLongitude = loc.OLng,
  676. locationType = loc.LocationType,
  677. postcode = loc.Postcode,
  678. hashParam = loc.HashParam,
  679. radius = radius,
  680. province = province,
  681. city = city,
  682. district = district
  683. };
  684. //await _serviceMqProcess.ProcessPositionAsync(messageId, positionData, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"), string.Join("|", wifiWayzItems.AsEnumerable().Select(i=>i.MacAddress)));
  685. await _serviceMqProcess.ProcessPositionAsync(messageId, positionData, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"), $"{mmac}|{macs}");
  686. #endregion
  687. #region 更新Alarm
  688. if (IDType == (int)IdType.Sos && !string.IsNullOrWhiteSpace(IDNumber))
  689. {
  690. // THOMAS Kafka
  691. //var SOSAlarm = new SoSTemplates()
  692. //{
  693. // imei = serialno,
  694. // sosId = IDNumber,
  695. // address = loc.Address,
  696. // info = "您的宝贝在求救",
  697. // baiduLatitude = loc.BaiduLat,
  698. // baiduLongitude = loc.BaiduLng,
  699. // gaodeLatitude = loc.GLat,
  700. // gaodeLongitude = loc.GLng,
  701. // originalLatitude = loc.OLat,
  702. // originalLongitude = loc.OLng,
  703. //};
  704. //_serviceMqProcess.ProcessAlarmSos(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"));
  705. var sosId = IDNumber;
  706. await _serviceSos.HandleSosAddressAsync(messageId, sosId, propertyValue.Time, () => new HisGpsAlarm
  707. {
  708. DeviceId = device.DeviceId,
  709. MessageId = sosId,
  710. Serialno = serialno,
  711. TypeId = (int)AlarmType.SosAlarm,
  712. CreateTime = DateTime.Now,
  713. DeviceUtcTime = Utils.ConvertToUtcDateTime(propertyValue.Time),
  714. Olat = loc.OLat,
  715. Olng = loc.OLng,
  716. BaiduLat = loc.BaiduLat,
  717. BaiduLng = loc.BaiduLng,
  718. Glat = loc.GLat,
  719. Glng = loc.GLng
  720. },
  721. a =>
  722. {
  723. a.Olat = loc.OLat;
  724. a.Olng = loc.OLng;
  725. a.BaiduLat = loc.BaiduLat;
  726. a.BaiduLng = loc.BaiduLng;
  727. a.Glat = loc.GLat;
  728. a.Glng = loc.GLng;
  729. return a;
  730. },
  731. async () => {
  732. var SOSAlarm = new SoSTemplates()
  733. {
  734. imei = serialno,
  735. sosId = IDNumber,
  736. address = loc.Address,
  737. info = "您的宝贝在求救",
  738. baiduLatitude = loc.BaiduLat,
  739. baiduLongitude = loc.BaiduLng,
  740. gaodeLatitude = loc.GLat,
  741. gaodeLongitude = loc.GLng,
  742. originalLatitude = loc.OLat,
  743. originalLongitude = loc.OLng,
  744. };
  745. await _serviceMqProcess.ProcessAlarmSosAsync(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"));
  746. });
  747. }
  748. else if (IDType == (int)IdType.PayLog && !string.IsNullOrWhiteSpace(IDNumber))
  749. {
  750. var payId = IDNumber;
  751. var pay = await _servicePay.GetPayLogAsync(messageId, $"{serialno}-{payId}").ConfigureAwait(false);
  752. if (pay == null)
  753. {
  754. pay = new GpsPayLog
  755. {
  756. Serialno = serialno,
  757. Payid = $"{serialno}-{payId}",
  758. DeviceId = device.DeviceId,
  759. Olat = loc.OLat,
  760. Olng = loc.OLng,
  761. BaiduLat = loc.BaiduLat,
  762. BaiduLng = loc.BaiduLng,
  763. Glat = loc.GLat,
  764. Glng = loc.GLng
  765. };
  766. await _servicePay.AddPayLogAsync(messageId, pay).ConfigureAwait(false);
  767. }
  768. else
  769. {
  770. pay.Olat = loc.OLat;
  771. pay.Olng = loc.OLng;
  772. pay.BaiduLat = loc.BaiduLat;
  773. pay.BaiduLng = loc.BaiduLng;
  774. pay.Glat = loc.GLat;
  775. pay.Glng = loc.GLng;
  776. await _servicePay.UpdatePayLogAsync(messageId, pay).ConfigureAwait(false);
  777. }
  778. }
  779. else if (IDType == (int)IdType.Temperature && !string.IsNullOrWhiteSpace(IDNumber)) //温度上报(带地址)
  780. {
  781. var tempId = IDNumber;
  782. //var hisTemp = await _serviceHealth.GetTemperatureAsync(messageId, $"{serialno}-{tempId}").ConfigureAwait(false);
  783. //if (hisTemp == null)
  784. //{
  785. // hisTemp = new HisGpsTemperature
  786. // {
  787. // Serialno = serialno,
  788. // TemperatureId = $"{serialno}-{tempId}",
  789. // TempId = tempId,
  790. // Address = addr,
  791. // };
  792. // await _serviceHealth.AddTemperatureAsync(messageId, hisTemp).ConfigureAwait(false);
  793. //}
  794. //else
  795. //{
  796. // hisTemp.Address = addr;
  797. // await _serviceHealth.UpdateTemperatureAsync(messageId, hisTemp).ConfigureAwait(false);
  798. //}
  799. //_serviceMqProcess.ProcessCommonInfo(messageId, DeviceInfoFlagType.Temperature, propertyValue.Time, propertyValue.Value, serialno);
  800. await _serviceHealth.HandleTemperatureAddressAsync(messageId, $"{serialno}-{tempId}", () => new HisGpsTemperature
  801. {
  802. TemperatureId = $"{serialno}-{tempId}",
  803. Serialno = serialno,
  804. Address = addr,
  805. Province = province,
  806. City = city,
  807. District = district,
  808. LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time),
  809. TempId = tempId
  810. },
  811. a =>
  812. {
  813. a.Address = addr;
  814. a.Province = province;
  815. a.City = city;
  816. a.District = district;
  817. return a;
  818. },
  819. //2022/11/10 增加 type 参数判断定位类型
  820. null,
  821. type
  822. );
  823. }
  824. #endregion
  825. //推送数据到设备
  826. await _serviceGlobal.PushLocationDataAsync(serialno, olat, olng);
  827. }
  828. catch (Exception ex)
  829. {
  830. _logger.LogError($"ProcessWifiPlus2Info[异常], Item: {JsonConvert.SerializeObject(item)}\n {ex.Message}, {ex.StackTrace}");
  831. }
  832. }
  833. }
  834. }
  835. }