Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

437 lines
17KB

  1. using GpsCardGatewayPosition.Common.Helper;
  2. using GpsCardGatewayPosition.Common;
  3. using GpsCardGatewayPosition.Model.Enum;
  4. using GpsCardGatewayPosition.Model.IoT;
  5. using GpsCardGatewayPosition.Service.Biz.Location;
  6. using GpsCardGatewayPosition.Service.Biz.Location.Dto.Gaode;
  7. using GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz;
  8. using GpsCardGatewayPosition.Service.Cache;
  9. using GpsCardGatewayPosition.Service.MqProducer;
  10. using GpsCardGatewayPosition.Service.Resolver.Interface;
  11. using GpsCardGatewayPosition.Service.Resolver.Property.Dto;
  12. using Microsoft.Extensions.Logging;
  13. using Newtonsoft.Json.Linq;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.Linq;
  17. using System.Text;
  18. using System.Threading.Tasks;
  19. using TelpoDataService.Util.Entities.GpsCard;
  20. using GpsCardGatewayPosition.Service.Biz.Location.Dto;
  21. using GpsCardGatewayPosition.Model.Context;
  22. using GpsCardGatewayPosition.Service.MqProducer.Model;
  23. using GpsCardGatewayPosition.Service.Biz.Sos;
  24. using GpsCardGatewayPosition.Service.Biz.Pay;
  25. using GpsCardGatewayPosition.Service.Biz.Health;
  26. using GpsCardGatewayPosition.Service.Biz;
  27. using TelpoDataService.Util.Entities.GpsLocationHistory;
  28. using GpsCardGatewayPosition.Model.Templates;
  29. namespace GpsCardGatewayPosition.Service.Resolver.Property
  30. {
  31. /// <summary>
  32. /// Lbs Gsm方式定位消息
  33. /// </summary>
  34. public class LbsGsmPositionResolver : IPropertyResolver
  35. {
  36. private readonly ILogger<LbsGsmPositionResolver> _logger;
  37. private readonly WayzService _serviceWayz;
  38. private readonly GaodeService _serviceGaode;
  39. private readonly LocationLogic _serviceLocation;
  40. private readonly MqProcessLogic _serviceMqProcess;
  41. private readonly SosLogic _serviceSos;
  42. private readonly PayLogic _servicePay;
  43. private readonly HealthLogic _serviceHealth;
  44. private readonly GlobalService _serviceGlobal;
  45. private readonly DeviceCacheManager _deviceCacheMgr;
  46. private AsyncLocal<string> _messageId = new AsyncLocal<string>();
  47. private AsyncLocal<PropertyModel> _package = new AsyncLocal<PropertyModel>();
  48. private AsyncLocal<PropertyItemModel<LbsInfoModel>> _propertyValue = new AsyncLocal<PropertyItemModel<LbsInfoModel>>();
  49. public LbsGsmPositionResolver(ILogger<LbsGsmPositionResolver> logger,
  50. GaodeService serviceGaode,
  51. WayzService serviceWayz, LocationLogic serviceLocation, MqProcessLogic serviceMqProcess,
  52. SosLogic serviceSos, PayLogic servicePay, HealthLogic serviceHealth, GlobalService serviceGlobal,
  53. DeviceCacheManager deviceCacheMgr)
  54. {
  55. _logger = logger;
  56. _serviceGaode = serviceGaode;
  57. _serviceWayz = serviceWayz;
  58. _serviceLocation = serviceLocation;
  59. _serviceMqProcess = serviceMqProcess;
  60. _serviceSos = serviceSos;
  61. _servicePay = servicePay;
  62. _serviceHealth = serviceHealth;
  63. _serviceGlobal = serviceGlobal;
  64. _deviceCacheMgr = deviceCacheMgr;
  65. }
  66. public void SetResolveInfo(PackageMsgModel msg)
  67. {
  68. _messageId.Value = msg.MessageId;
  69. _package.Value = ((JToken)msg.TopicInfo).ToObject<PropertyModel>()!;
  70. _propertyValue.Value = ((JToken)msg.DetailData).ToObject<PropertyItemModel<LbsInfoModel>>()!;
  71. }
  72. public override string ToString()
  73. {
  74. return $"{nameof(LbsGsmPositionResolver)}[{_messageId.Value}]";
  75. }
  76. public async Task ExecuteMessageAsync()
  77. {
  78. var package = _package.Value;
  79. var serialno = package.DeviceName; //设备序列号
  80. var messageId = _messageId.Value;
  81. var propertyValue = _propertyValue.Value;
  82. var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(messageId!, serialno!).ConfigureAwait(false);
  83. if (device == null)
  84. {
  85. _logger.LogError($"非法设备:{serialno}");
  86. return;
  87. }
  88. //var device = new GpsDevice()
  89. //{
  90. // DeviceId = serialno,
  91. //};
  92. #region 定位解析
  93. var bts = propertyValue.Value.Bts.Split(',');
  94. WayzLbsRequest wayzLbsRequest = new WayzLbsRequest
  95. {
  96. Location = new WayzRequest.LocationDetail
  97. {
  98. Cellulars = new List<WayzRequest.CellularItem>
  99. {
  100. new WayzRequest.CellularItem {
  101. CellId = int.Parse(bts[3]),
  102. //RadioType = "lte",
  103. MobileCountryCode = int.Parse(bts[0]),
  104. MobileNetworkCode = int.Parse(bts[1]),
  105. LocationAreaCode = int.Parse(bts[2]),
  106. }
  107. }
  108. },
  109. Asset = new WayzRequest.AssetDevice
  110. {
  111. Id = serialno,
  112. ImeiMd5 = serialno,
  113. UniqueId = device.DeviceId
  114. }
  115. };
  116. var wayzServiceResult = await _serviceWayz.GetWayzLbsAddressAsync(serialno, wayzLbsRequest).ConfigureAwait(false);
  117. // if (!wayzServiceResult.Flag)
  118. //{
  119. // if (wayzServiceResult.CanRetry) _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All);
  120. // return;
  121. //}
  122. var province = string.Empty;
  123. var city = string.Empty;
  124. var district = string.Empty;
  125. var address = string.Empty;
  126. var cityCode = string.Empty;
  127. var hashParam = string.Empty;
  128. var fullAddress = string.Empty;
  129. decimal olat = 0M;
  130. decimal olng = 0M;
  131. int radius = 0;
  132. if (wayzServiceResult.Flag)
  133. {
  134. province = wayzServiceResult.Province;
  135. city = wayzServiceResult.City;
  136. district = wayzServiceResult.District;
  137. address = wayzServiceResult.Address;
  138. cityCode = wayzServiceResult.CityCode;
  139. hashParam = wayzServiceResult.HashParam;
  140. fullAddress = wayzServiceResult.FullAddress;
  141. olat = wayzServiceResult.Lat;
  142. olng = wayzServiceResult.Lon;
  143. radius = wayzServiceResult.Accuracy;
  144. }
  145. else
  146. {
  147. _logger.LogInformation($"维智服务不能解析LBS地址数据,将采用高德服务解析");
  148. var lbsGaodeRequest = new GaodeLbsRequest()
  149. {
  150. Bts = propertyValue.Value.Bts,
  151. Cdma = 0,
  152. //Imei = serialno,
  153. Imsi = propertyValue.Value.IMSI,
  154. NearBts = propertyValue.Value.Nearbts,
  155. Smac = propertyValue.Value.SMAC
  156. };
  157. var gaodeServiceResult = await _serviceGaode.GetGaodeLbsAddressAsync(serialno, lbsGaodeRequest);
  158. if (gaodeServiceResult.Flag)
  159. {
  160. province = gaodeServiceResult.Province;
  161. city = gaodeServiceResult.City;
  162. district = gaodeServiceResult.District;
  163. address = gaodeServiceResult.Address;
  164. cityCode = gaodeServiceResult.AdCode;
  165. hashParam = gaodeServiceResult.HashParam;
  166. olat = gaodeServiceResult.Lat;
  167. olng = gaodeServiceResult.Lon;
  168. radius = gaodeServiceResult.Accuracy;
  169. fullAddress = string.Format("{0}|{1}", "_Gaode", gaodeServiceResult.Address);
  170. }
  171. else
  172. {
  173. await _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All);
  174. _logger.LogInformation($"维智服务和高德服务解析都不能解析LBS地址定位数据");
  175. return;
  176. }
  177. }
  178. decimal[] latLng = GeoConvert.ConvertGoogleBaiduLatLng(olat, olng);
  179. #endregion
  180. #region 保存历史轨迹
  181. var loc = new LocationInfo
  182. {
  183. LocationId = Guid.NewGuid().ToString("D"),
  184. Address = address,
  185. BaiduLat = latLng[2],
  186. BaiduLng = latLng[3],
  187. OLat = olat,
  188. OLng = olng,
  189. GLat = latLng[0],
  190. GLng = latLng[1],
  191. Course = 0,
  192. DeviceId = device.DeviceId,
  193. DeviceStatus = radius.ToString(),
  194. IsStop = false,
  195. LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time),
  196. UtcDate = Utils.ConvertToUtcDateTime(propertyValue.Time),
  197. LocationType = Convert.ToInt32(LocationType.LBS),
  198. Remarks = cityCode,
  199. SerialNo = serialno,
  200. Speed = 0,
  201. IDNumber = propertyValue.Value.IDNumber,
  202. IDType = propertyValue.Value.IDType,
  203. Postcode = cityCode,
  204. IsRedressed = false,
  205. HashParam = hashParam,
  206. Province = province,
  207. City = city,
  208. District = district
  209. };
  210. loc.Remarks = string.Format("Wayz_LbsGms|{0}", fullAddress);
  211. var positionStatus = await _deviceCacheMgr.GetPositionStatusCacheAsync(serialno).ConfigureAwait(false);
  212. var requestPositionData = new RequestLocationInfo<WayzLbsRequest>
  213. {
  214. MapSource = 2,
  215. RequestLocationType = loc.LocationType,
  216. RequestData = wayzLbsRequest
  217. };
  218. var hisResult = await _serviceLocation.AddLocationAsync(messageId, loc, positionStatus, propertyValue.Time, cityCode, null, requestPositionData).ConfigureAwait(false);
  219. if (!hisResult.IsSuccess)
  220. {
  221. _logger.LogError($"{hisResult.Message}");
  222. return;
  223. }
  224. #endregion
  225. #region 保存最后位置信息
  226. var context = "online=1";
  227. var deviceStatus = await _deviceCacheMgr.GetDeviceStatusBySerialNoAsync(messageId, serialno).ConfigureAwait(false);
  228. var statusContext = new DeviceStatus();
  229. if (deviceStatus != null)
  230. {
  231. statusContext.Deserlize(deviceStatus.DeviceStatus);
  232. }
  233. statusContext.Deserlize(context);
  234. deviceStatus = new GpsDeviceStatus
  235. {
  236. Address = loc.Address,
  237. IsStop = (bool)loc.IsStop,
  238. BaiduLat = loc.BaiduLat,
  239. BaiduLng = loc.BaiduLng,
  240. Olat = loc.OLat,
  241. Olng = loc.OLng,
  242. Glat = loc.GLat,
  243. Glng = loc.GLng,
  244. Course = loc.Course,
  245. DeviceId = loc.DeviceId,
  246. DeviceStatus = statusContext.ToString(),
  247. DeviceUtcTime = loc.UtcDate,
  248. LastUpdate = loc.LastUpdate,
  249. LocationType = loc.LocationType,
  250. Remarks = loc.LocationId,
  251. Serialno = loc.SerialNo,
  252. //Speed = loc.Speed,
  253. Speed = SafeType.SafeInt(loc.DeviceStatus)
  254. };
  255. var result = await _serviceLocation.UpdateDeviceStatusAsync(messageId, deviceStatus).ConfigureAwait(false);
  256. if (!result.IsSuccess)
  257. {
  258. _logger.LogError($"{result.Message}");
  259. return;
  260. }
  261. //THOMAS
  262. var positionData = new LocationDatas()
  263. {
  264. imei = loc.SerialNo,
  265. altitude = 0,
  266. address = loc.Address,
  267. baiduLatitude = loc.BaiduLat,
  268. baiduLongitude = loc.BaiduLng,
  269. gaodeLatitude = loc.GLat,
  270. gaodeLongitude = loc.GLng,
  271. originalLatitude = loc.OLat,
  272. originalLongitude = loc.OLng,
  273. locationType = loc.LocationType,
  274. postcode = loc.Postcode,
  275. hashParam = loc.HashParam,
  276. radius = radius,
  277. province = province,
  278. city = city,
  279. district = district
  280. };
  281. await _serviceMqProcess.ProcessPositionAsync(messageId, positionData, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"));
  282. #endregion
  283. #region 更新Alarm
  284. if (loc.IDType == (int)IdType.Sos && loc.IDNumber != "")
  285. {
  286. // THOMAS Kafka
  287. //var SOSAlarm = new SoSTemplates()
  288. //{
  289. // imei = serialno,
  290. // sosId = loc.IDNumber,
  291. // address = loc.Address,
  292. // info = "您的宝贝在求救",
  293. // baiduLatitude = loc.BaiduLat,
  294. // baiduLongitude = loc.BaiduLng,
  295. // gaodeLatitude = loc.GLat,
  296. // gaodeLongitude = loc.GLng,
  297. // originalLatitude = loc.OLat,
  298. // originalLongitude = loc.OLng,
  299. //};
  300. //_serviceMqProcess.ProcessAlarmSos(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"));
  301. var sosId = loc.IDNumber;
  302. await _serviceSos.HandleSosAddressAsync(messageId, sosId, propertyValue.Time, () => new HisGpsAlarm
  303. {
  304. DeviceId = device.DeviceId,
  305. MessageId = sosId,
  306. Serialno = serialno,
  307. CreateTime = DateTime.Now,
  308. DeviceUtcTime = Utils.ConvertToUtcDateTime(propertyValue.Time),
  309. Olat = loc.OLat,
  310. Olng = loc.OLng,
  311. BaiduLat = loc.BaiduLat,
  312. BaiduLng = loc.BaiduLng,
  313. Glat = loc.GLat,
  314. Glng = loc.GLng
  315. },
  316. a =>
  317. {
  318. a.Olat = loc.OLat;
  319. a.Olng = loc.OLng;
  320. a.BaiduLat = loc.BaiduLat;
  321. a.BaiduLng = loc.BaiduLng;
  322. a.Glat = loc.GLat;
  323. a.Glng = loc.GLng;
  324. return a;
  325. },
  326. async () => {
  327. var SOSAlarm = new SoSTemplates()
  328. {
  329. imei = serialno,
  330. sosId = loc.IDNumber,
  331. address = loc.Address,
  332. info = "您的宝贝在求救",
  333. baiduLatitude = loc.BaiduLat,
  334. baiduLongitude = loc.BaiduLng,
  335. gaodeLatitude = loc.GLat,
  336. gaodeLongitude = loc.GLng,
  337. originalLatitude = loc.OLat,
  338. originalLongitude = loc.OLng,
  339. };
  340. await _serviceMqProcess.ProcessAlarmSosAsync(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"));
  341. });
  342. }
  343. else if (loc.IDType == (int)IdType.PayLog && loc.IDNumber != "")
  344. {
  345. var payId = loc.IDNumber;
  346. var pay = await _servicePay.GetPayLogAsync(messageId, $"{serialno}-{payId}").ConfigureAwait(false);
  347. if (pay == null)
  348. {
  349. pay = new GpsPayLog
  350. {
  351. Serialno = serialno,
  352. Payid = $"{serialno}-{payId}",
  353. DeviceId = device.DeviceId,
  354. Olat = loc.OLat,
  355. Olng = loc.OLng,
  356. BaiduLat = loc.BaiduLat,
  357. BaiduLng = loc.BaiduLng,
  358. Glat = loc.GLat,
  359. Glng = loc.GLng
  360. };
  361. await _servicePay.AddPayLogAsync(messageId, pay).ConfigureAwait(false);
  362. }
  363. else
  364. {
  365. pay.Olat = loc.OLat;
  366. pay.Olng = loc.OLng;
  367. pay.BaiduLat = loc.BaiduLat;
  368. pay.BaiduLng = loc.BaiduLng;
  369. pay.Glat = loc.GLat;
  370. pay.Glng = loc.GLng;
  371. await _servicePay.UpdatePayLogAsync(messageId, pay).ConfigureAwait(false);
  372. }
  373. }
  374. else if (loc.IDType == (int)IdType.Temperature && loc.IDNumber != "") //温度上报(带地址)
  375. {
  376. var tempId = loc.IDNumber;
  377. await _serviceHealth.HandleTemperatureAddressAsync(messageId, $"{serialno}-{tempId}", () => new HisGpsTemperature
  378. {
  379. TemperatureId = $"{serialno}-{tempId}",
  380. Serialno = serialno,
  381. Address = address,
  382. Province = province,
  383. City = city,
  384. District = district,
  385. LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time),
  386. TempId = tempId
  387. },
  388. a =>
  389. {
  390. a.Address = address;
  391. a.Province = province;
  392. a.City = city;
  393. a.District = district;
  394. return a;
  395. });
  396. }
  397. #endregion
  398. }
  399. }
  400. }