using GpsCardGatewayPosition.Common.Helper; using GpsCardGatewayPosition.Common; using GpsCardGatewayPosition.Model.Enum; using GpsCardGatewayPosition.Model.IoT; using GpsCardGatewayPosition.Service.Biz.Location; using GpsCardGatewayPosition.Service.Biz.Location.Dto.Gaode; using GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz; using GpsCardGatewayPosition.Service.Cache; using GpsCardGatewayPosition.Service.MqProducer; using GpsCardGatewayPosition.Service.Resolver.Interface; using GpsCardGatewayPosition.Service.Resolver.Property.Dto; using Microsoft.Extensions.Logging; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using TelpoDataService.Util.Entities.GpsCard; using GpsCardGatewayPosition.Service.Biz.Location.Dto; using GpsCardGatewayPosition.Model.Context; using GpsCardGatewayPosition.Service.MqProducer.Model; using GpsCardGatewayPosition.Service.Biz.Sos; using GpsCardGatewayPosition.Service.Biz.Pay; using GpsCardGatewayPosition.Service.Biz.Health; using GpsCardGatewayPosition.Service.Biz; using TelpoDataService.Util.Entities.GpsLocationHistory; using GpsCardGatewayPosition.Model.Templates; namespace GpsCardGatewayPosition.Service.Resolver.Property { /// /// Lbs Gsm方式定位消息 /// public class LbsGsmPositionResolver : IPropertyResolver { private readonly ILogger _logger; private readonly WayzService _serviceWayz; private readonly GaodeService _serviceGaode; private readonly LocationLogic _serviceLocation; private readonly MqProcessLogic _serviceMqProcess; private readonly SosLogic _serviceSos; private readonly PayLogic _servicePay; private readonly HealthLogic _serviceHealth; private readonly GlobalService _serviceGlobal; private readonly DeviceCacheManager _deviceCacheMgr; private AsyncLocal _messageId = new AsyncLocal(); private AsyncLocal _package = new AsyncLocal(); private AsyncLocal> _propertyValue = new AsyncLocal>(); public LbsGsmPositionResolver(ILogger logger, GaodeService serviceGaode, WayzService serviceWayz, LocationLogic serviceLocation, MqProcessLogic serviceMqProcess, SosLogic serviceSos, PayLogic servicePay, HealthLogic serviceHealth, GlobalService serviceGlobal, DeviceCacheManager deviceCacheMgr) { _logger = logger; _serviceGaode = serviceGaode; _serviceWayz = serviceWayz; _serviceLocation = serviceLocation; _serviceMqProcess = serviceMqProcess; _serviceSos = serviceSos; _servicePay = servicePay; _serviceHealth = serviceHealth; _serviceGlobal = serviceGlobal; _deviceCacheMgr = deviceCacheMgr; } public void SetResolveInfo(PackageMsgModel msg) { _messageId.Value = msg.MessageId; _package.Value = ((JToken)msg.TopicInfo).ToObject()!; _propertyValue.Value = ((JToken)msg.DetailData).ToObject>()!; } public override string ToString() { return $"{nameof(LbsGsmPositionResolver)}[{_messageId.Value}]"; } public async Task ExecuteMessageAsync() { var package = _package.Value; var serialno = package.DeviceName; //设备序列号 var messageId = _messageId.Value; var propertyValue = _propertyValue.Value; //var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(messageId!, serialno!).ConfigureAwait(false); //if (device == null) //{ // _logger.LogError($"非法设备:{serialno}"); // return; //} var device = new GpsDevice() { DeviceId = serialno, }; #region 定位解析 var bts = propertyValue.Value.Bts.Split(','); WayzLbsRequest wayzLbsRequest = new WayzLbsRequest { Location = new WayzRequest.LocationDetail { Cellulars = new List { new WayzRequest.CellularItem { CellId = int.Parse(bts[3]), //RadioType = "lte", MobileCountryCode = int.Parse(bts[0]), MobileNetworkCode = int.Parse(bts[1]), LocationAreaCode = int.Parse(bts[2]), } } }, Asset = new WayzRequest.AssetDevice { Id = serialno, ImeiMd5 = serialno, UniqueId = device.DeviceId } }; var wayzServiceResult = await _serviceWayz.GetWayzLbsAddressAsync(serialno, wayzLbsRequest).ConfigureAwait(false); // if (!wayzServiceResult.Flag) //{ // if (wayzServiceResult.CanRetry) _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All); // return; //} var province = string.Empty; var city = string.Empty; var district = string.Empty; var address = string.Empty; var cityCode = string.Empty; var hashParam = string.Empty; var fullAddress = string.Empty; decimal olat = 0M; decimal olng = 0M; int radius = 0; if (wayzServiceResult.Flag) { province = wayzServiceResult.Province; city = wayzServiceResult.City; district = wayzServiceResult.District; address = wayzServiceResult.Address; cityCode = wayzServiceResult.CityCode; hashParam = wayzServiceResult.HashParam; fullAddress = wayzServiceResult.FullAddress; olat = wayzServiceResult.Lat; olng = wayzServiceResult.Lon; radius = wayzServiceResult.Accuracy; } else { _logger.LogInformation($"维智服务不能解析LBS地址数据,将采用高德服务解析"); var lbsGaodeRequest = new GaodeLbsRequest() { Bts = propertyValue.Value.Bts, Cdma = 0, //Imei = serialno, Imsi = propertyValue.Value.IMSI, NearBts = propertyValue.Value.Nearbts, Smac = propertyValue.Value.SMAC }; var gaodeServiceResult = await _serviceGaode.GetGaodeLbsAddressAsync(serialno, lbsGaodeRequest); if (gaodeServiceResult.Flag) { province = gaodeServiceResult.Province; city = gaodeServiceResult.City; district = gaodeServiceResult.District; address = gaodeServiceResult.Address; cityCode = gaodeServiceResult.AdCode; hashParam = gaodeServiceResult.HashParam; olat = gaodeServiceResult.Lat; olng = gaodeServiceResult.Lon; radius = gaodeServiceResult.Accuracy; fullAddress = string.Format("{0}|{1}", "_Gaode", gaodeServiceResult.Address); } else { await _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All); _logger.LogInformation($"维智服务和高德服务解析都不能解析LBS地址定位数据"); return; } } decimal[] latLng = GeoConvert.ConvertGoogleBaiduLatLng(olat, olng); #endregion #region 保存历史轨迹 var loc = new LocationInfo { LocationId = Guid.NewGuid().ToString("D"), Address = address, BaiduLat = latLng[2], BaiduLng = latLng[3], OLat = olat, OLng = olng, GLat = latLng[0], GLng = latLng[1], Course = 0, DeviceId = device.DeviceId, DeviceStatus = radius.ToString(), IsStop = false, LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time), UtcDate = Utils.ConvertToUtcDateTime(propertyValue.Time), LocationType = Convert.ToInt32(LocationType.LBS), Remarks = cityCode, SerialNo = serialno, Speed = 0, IDNumber = propertyValue.Value.IDNumber, IDType = propertyValue.Value.IDType, Postcode = cityCode, IsRedressed = false, HashParam = hashParam, Province = province, City = city, District = district }; loc.Remarks = string.Format("Wayz_LbsGms|{0}", fullAddress); var positionStatus = await _deviceCacheMgr.GetPositionStatusCacheAsync(serialno).ConfigureAwait(false); var requestPositionData = new RequestLocationInfo { MapSource = 2, RequestLocationType = loc.LocationType, RequestData = wayzLbsRequest }; var hisResult = await _serviceLocation.AddLocationAsync(messageId, loc, positionStatus, propertyValue.Time, cityCode, null, requestPositionData).ConfigureAwait(false); if (!hisResult.IsSuccess) { _logger.LogError($"{hisResult.Message}"); return; } #endregion #region 保存最后位置信息 var context = "online=1"; var deviceStatus = await _deviceCacheMgr.GetDeviceStatusBySerialNoAsync(messageId, serialno).ConfigureAwait(false); var statusContext = new DeviceStatus(); if (deviceStatus != null) { statusContext.Deserlize(deviceStatus.DeviceStatus); } statusContext.Deserlize(context); deviceStatus = new GpsDeviceStatus { Address = loc.Address, IsStop = (bool)loc.IsStop, BaiduLat = loc.BaiduLat, BaiduLng = loc.BaiduLng, Olat = loc.OLat, Olng = loc.OLng, Glat = loc.GLat, Glng = loc.GLng, Course = loc.Course, DeviceId = loc.DeviceId, DeviceStatus = statusContext.ToString(), DeviceUtcTime = loc.UtcDate, LastUpdate = loc.LastUpdate, LocationType = loc.LocationType, Remarks = loc.LocationId, Serialno = loc.SerialNo, //Speed = loc.Speed, Speed = SafeType.SafeInt(loc.DeviceStatus) }; var result = await _serviceLocation.UpdateDeviceStatusAsync(messageId, deviceStatus).ConfigureAwait(false); if (!result.IsSuccess) { _logger.LogError($"{result.Message}"); return; } //THOMAS var positionData = new LocationDatas() { imei = loc.SerialNo, altitude = 0, address = loc.Address, baiduLatitude = loc.BaiduLat, baiduLongitude = loc.BaiduLng, gaodeLatitude = loc.GLat, gaodeLongitude = loc.GLng, originalLatitude = loc.OLat, originalLongitude = loc.OLng, locationType = loc.LocationType, postcode = loc.Postcode, hashParam = loc.HashParam, radius = radius, province = province, city = city, district = district }; await _serviceMqProcess.ProcessPositionAsync(messageId, positionData, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss")); #endregion #region 更新Alarm if (loc.IDType == (int)IdType.Sos && loc.IDNumber != "") { // THOMAS Kafka //var SOSAlarm = new SoSTemplates() //{ // imei = serialno, // sosId = loc.IDNumber, // address = loc.Address, // info = "您的宝贝在求救", // baiduLatitude = loc.BaiduLat, // baiduLongitude = loc.BaiduLng, // gaodeLatitude = loc.GLat, // gaodeLongitude = loc.GLng, // originalLatitude = loc.OLat, // originalLongitude = loc.OLng, //}; //_serviceMqProcess.ProcessAlarmSos(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss")); var sosId = loc.IDNumber; await _serviceSos.HandleSosAddressAsync(messageId, sosId, propertyValue.Time, () => new HisGpsAlarm { DeviceId = device.DeviceId, MessageId = sosId, Serialno = serialno, CreateTime = DateTime.Now, DeviceUtcTime = Utils.ConvertToUtcDateTime(propertyValue.Time), Olat = loc.OLat, Olng = loc.OLng, BaiduLat = loc.BaiduLat, BaiduLng = loc.BaiduLng, Glat = loc.GLat, Glng = loc.GLng }, a => { a.Olat = loc.OLat; a.Olng = loc.OLng; a.BaiduLat = loc.BaiduLat; a.BaiduLng = loc.BaiduLng; a.Glat = loc.GLat; a.Glng = loc.GLng; return a; }, async () => { var SOSAlarm = new SoSTemplates() { imei = serialno, sosId = loc.IDNumber, address = loc.Address, info = "您的宝贝在求救", baiduLatitude = loc.BaiduLat, baiduLongitude = loc.BaiduLng, gaodeLatitude = loc.GLat, gaodeLongitude = loc.GLng, originalLatitude = loc.OLat, originalLongitude = loc.OLng, }; await _serviceMqProcess.ProcessAlarmSosAsync(messageId, SOSAlarm, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss")); }); } else if (loc.IDType == (int)IdType.PayLog && loc.IDNumber != "") { var payId = loc.IDNumber; var pay = await _servicePay.GetPayLogAsync(messageId, $"{serialno}-{payId}").ConfigureAwait(false); if (pay == null) { pay = new GpsPayLog { Serialno = serialno, Payid = $"{serialno}-{payId}", DeviceId = device.DeviceId, Olat = loc.OLat, Olng = loc.OLng, BaiduLat = loc.BaiduLat, BaiduLng = loc.BaiduLng, Glat = loc.GLat, Glng = loc.GLng }; await _servicePay.AddPayLogAsync(messageId, pay).ConfigureAwait(false); } else { pay.Olat = loc.OLat; pay.Olng = loc.OLng; pay.BaiduLat = loc.BaiduLat; pay.BaiduLng = loc.BaiduLng; pay.Glat = loc.GLat; pay.Glng = loc.GLng; await _servicePay.UpdatePayLogAsync(messageId, pay).ConfigureAwait(false); } } else if (loc.IDType == (int)IdType.Temperature && loc.IDNumber != "") //温度上报(带地址) { var tempId = loc.IDNumber; await _serviceHealth.HandleTemperatureAddressAsync(messageId, $"{serialno}-{tempId}", () => new HisGpsTemperature { TemperatureId = $"{serialno}-{tempId}", Serialno = serialno, Address = address, Province = province, City = city, District = district, LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time), TempId = tempId }, a => { a.Address = address; a.Province = province; a.City = city; a.District = district; return a; }); } #endregion } } }