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.

452 lines
18KB

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