using GpsCardGatewayPosition.Model.Config; using GpsCardGatewayPosition.Model.IoT; using GpsCardGatewayPosition.Service.Resolver.Interface; using GpsCardGatewayPosition.Service.Resolver.Property.Dto; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using GpsCardGatewayPosition.Service.Biz.Location; using GpsCardGatewayPosition.Service.Cache; using GpsCardGatewayPosition.Service.Biz.Location.Dto.Gaode; using GpsCardGatewayPosition.Service.Biz.Location.Dto.Wayz; using TelpoDataService.Util.Entities.GpsCard; using AutoMapper.Internal; using GpsCardGatewayPosition.Common.Helper; using GpsCardGatewayPosition.Common; using GpsCardGatewayPosition.Model.Enum; using GpsCardGatewayPosition.Service.Biz.Location.Dto; using GpsCardGatewayPosition.Service.MqProducer.Model; using GpsCardGatewayPosition.Model.Context; using GpsCardGatewayPosition.Service.MqProducer; using System.Data; using GpsCardGatewayPosition.Service.Biz.Health; using TelpoDataService.Util.Entities.GpsLocationHistory; using GpsCardGatewayPosition.Service.Biz.Pay; using GpsCardGatewayPosition.Service.Biz.Sos; using GpsCardGatewayPosition.Model.Templates; using GpsCardGatewayPosition.Service.Biz; namespace GpsCardGatewayPosition.Service.Resolver.Property { public class WifiPositionResolver : IPropertyResolver { private readonly ILogger _logger; private readonly WifiParamConfig _configWifiParam; private readonly DeviceCacheManager _deviceCacheMgr; private readonly GaodeService _serviceGaode; private readonly WayzService _serviceWayz; private readonly LocationLogic _serviceLocation; private readonly MqProcessLogic _serviceMqProcess; private readonly HealthLogic _serviceHealth; private readonly GlobalService _serviceGlobal; private readonly PayLogic _servicePay; private readonly SosLogic _serviceSos; private AsyncLocal _messageId = new AsyncLocal(); private AsyncLocal _package = new AsyncLocal(); private AsyncLocal> _propertyValue = new AsyncLocal>(); public WifiPositionResolver(ILogger logger, IOptions optWifiParamConfig, GlobalService serviceGlobal, PayLogic servicePay, HealthLogic serviceHealth, MqProcessLogic serviceMqProcess, WayzService serviceWayz, GaodeService serviceGaode, DeviceCacheManager deviceCacheMgr, SosLogic serviceSos, LocationLogic serviceLocation) { _serviceGaode = serviceGaode; _serviceWayz = serviceWayz; _deviceCacheMgr = deviceCacheMgr; _serviceLocation = serviceLocation; _serviceMqProcess = serviceMqProcess; _serviceHealth = serviceHealth; _servicePay= servicePay; _serviceSos = serviceSos; _serviceGlobal = serviceGlobal; _logger = logger; _configWifiParam = optWifiParamConfig.Value; } public void SetResolveInfo(PackageMsgModel msg) { _messageId.Value = msg.MessageId; _package.Value = ((JToken)msg.TopicInfo).ToObject()!; _propertyValue.Value = ((JToken)msg.DetailData).ToObject>()!; /// throw new NotImplementedException(); } public override string ToString() { return $"{nameof(WifiPositionResolver)}[{_messageId.Value}]"; } public async Task ExecuteMessageAsync() { var package = _package.Value; string serialno = package?.DeviceName!; //设备序列号 var messageId = _messageId.Value!; var propertyValue = _propertyValue.Value!; int IDType = propertyValue!.Value.IDType; string IDNumber = propertyValue.Value.IDNumber; string mmac = propertyValue.Value.Mmac; string macs = propertyValue.Value.macs; var eachParam = mmac.Split(','); var signal = Convert.ToInt32(eachParam[1]); string cityCode = ""; string addr = ""; decimal olat = 0; decimal olng = 0; decimal baiduLat = 0; decimal baiduLng = 0; decimal gaodeLat = 0; decimal gaodeLng = 0; int radius = 0; string hashParam = Guid.NewGuid().ToString(); string province = null; string city = null; string district = null; var fullAddress = string.Empty; //throw new NotImplementedException(); //以下时间段,wifi上报信息不过滤 var startOne = TimeSpan.Parse(_configWifiParam.StartOne); var endOne = TimeSpan.Parse(_configWifiParam.EndOne); var startTwo = TimeSpan.Parse(_configWifiParam.StartTwo); var endTwo = TimeSpan.Parse(_configWifiParam.EndTwo); //var device = await _deviceCacheMgr.GetDeviceBySerialNoAsync(messageId!, serialno!).ConfigureAwait(false); //if (device == null) //{ // _logger.LogError($"非法设备:{serialno}"); // return; //} var device = new GpsDevice() { DeviceId = serialno, }; #region 定位解析 var request = new GaodeWifiRequest { //Imei = serialno, Macs = macs, Mmac = mmac }; #region wifi var wifiItems = new List(); // 已经接入的wifi mmac:80:8f:1d:bf:45:b1,-70, if (mmac.Split(',').Length > 2) { wifiItems.Add(new WayzRequest.WifiItem { Connected = true, SignalStrength = Math.Abs(int.Parse(mmac.Split(',')[1])), MacAddress = mmac.Split(',')[0] }); } // 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, if (macs.Split('|').Length > 1) { macs.Split('|').ForAll(mac => { wifiItems.Add(new WayzRequest.WifiItem { Connected = false, SignalStrength = Math.Abs(int.Parse(mac.Split(',')[1])), MacAddress = mac.Split(',')[0] }); }); } #endregion var wayzWifiRequest = new WayzWifiRequest { Location = new WayzRequest.LocationDetail { Wifis = wifiItems }, Asset = new WayzRequest.AssetDevice { Id = serialno, ImeiMd5 = serialno, UniqueId = device.DeviceId } }; var positionStatus = await _deviceCacheMgr.GetPositionStatusCacheAsync(serialno).ConfigureAwait(false); //GetGaodePositionServiceResult gaodeResult = null; GetWayzPositionServiceResult wayzServiceResult = null; var timeOfNow = DateTime.Now.TimeOfDay; if ((timeOfNow >= startOne && timeOfNow <= endOne) || (timeOfNow >= startTwo && timeOfNow <= endTwo)) //处于以下时间段,wifi信息不过滤 { //gaodeResult = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, request).ConfigureAwait(false); wayzServiceResult = await _serviceWayz.GetWayzWifiAddressAsync(serialno, wayzWifiRequest).ConfigureAwait(false); // if (!wayzServiceResult.Flag) //{ // if (wayzServiceResult.CanRetry) _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All); // return; //} if (wayzServiceResult.Flag) { province = wayzServiceResult.Province; city = wayzServiceResult.City; district = wayzServiceResult.District; addr = wayzServiceResult.Address; cityCode = wayzServiceResult.CityCode; hashParam = wayzServiceResult.HashParam; fullAddress = wayzServiceResult.FullAddress; olat = wayzServiceResult.Lat; olng = wayzServiceResult.Lon; radius = wayzServiceResult.Accuracy; } else { _logger.LogInformation($"维智服务不能解析WIFI地址数据,将采用高德服务解析"); var wifiGaodeRequest = new GaodeWifiRequest() { Macs = macs, Mmac = mmac }; var gaodeServiceResult = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, wifiGaodeRequest); if (gaodeServiceResult.Flag) { province = gaodeServiceResult.Province; city = gaodeServiceResult.City; district = gaodeServiceResult.District; addr = 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($"维智服务和高德服务解析都不能解析WIFI地址定位数据"); return; } } decimal[] latLng = GeoConvert.ConvertGoogleBaiduLatLng(olat, olng); baiduLng = latLng[3]; baiduLat = latLng[2]; gaodeLng = latLng[1]; gaodeLat = latLng[0]; } else //以上时间段之外,应用过滤逻辑 { var cachePosition = positionStatus?.LastPosition; if (signal > -70 || cachePosition == null) { //gaodeResult = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, request).ConfigureAwait(false); wayzServiceResult = await _serviceWayz.GetWayzWifiAddressAsync(serialno, wayzWifiRequest).ConfigureAwait(false); // if (!wayzServiceResult.Flag) //{ // if (wayzServiceResult.CanRetry) _serviceWayz.SendRealtimeLocationAsync(serialno, Utils.ConvertToLocalDateTime(propertyValue.Time), RealtimeLocationTypeFlag.All); // return; //} if (wayzServiceResult.Flag) { province = wayzServiceResult.Province; city = wayzServiceResult.City; district = wayzServiceResult.District; addr = wayzServiceResult.Address; cityCode = wayzServiceResult.CityCode; hashParam = wayzServiceResult.HashParam; fullAddress = wayzServiceResult.FullAddress; olat = wayzServiceResult.Lat; olng = wayzServiceResult.Lon; radius = wayzServiceResult.Accuracy; } else { _logger.LogInformation($"维智服务不能解析WIFI地址数据,将采用高德服务解析"); var wifiGaodeRequest = new GaodeWifiRequest() { Macs = macs, Mmac = mmac }; var gaodeServiceResult = await _serviceGaode.GetGaodeWifiAddressAsync(serialno, wifiGaodeRequest); if (gaodeServiceResult.Flag) { province = gaodeServiceResult.Province; city = gaodeServiceResult.City; district = gaodeServiceResult.District; addr = 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($"维智服务和高德服务解析都不能解析WIFI定位数据"); return; } } decimal[] latLng = GeoConvert.ConvertGoogleBaiduLatLng(olat, olng); baiduLng = latLng[3]; baiduLat = latLng[2]; gaodeLng = latLng[1]; gaodeLat = latLng[0]; } ////******2022/04/24 领导决定不采用最后一次有效定位填充当前无效定位值 //else //{ // addr = cachePosition.Address; // olat = cachePosition.OriginalLat; // olng = cachePosition.OriginalLon; // baiduLng = cachePosition.BaiduLon; // baiduLat = cachePosition.BaiduLat; // gaodeLat = cachePosition.GaodeLat; // gaodeLng = cachePosition.GaodeLon; // cityCode = cachePosition.CityCode; // radius = cachePosition.Radius; //} } #endregion #region 保存历史轨迹 var loc = new LocationInfo { LocationId = Guid.NewGuid().ToString("D"), Address = addr, BaiduLat = baiduLat, BaiduLng = baiduLng, OLat = olat, OLng = olng, GLat = gaodeLat, GLng = gaodeLng, Course = 0, DeviceId = device.DeviceId, DeviceStatus = radius.ToString(), IsStop = false, LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time), UtcDate = Utils.ConvertToUtcDateTime(propertyValue.Time), LocationType = Convert.ToInt32(LocationType.WIFI), Remarks = cityCode, SerialNo = serialno, Speed = 0, Postcode = cityCode, IsRedressed = false, HashParam = hashParam, Province = province, City = city, District = district }; loc.Remarks = string.Format("Wayz_Wifi|{0}", fullAddress); if (string.IsNullOrWhiteSpace(loc.Address) || loc.GLng < 1 || loc.GLat < 1) { //没有符合定位解析的消息,直接退出 return; } var requestPositionData = new RequestLocationInfo { MapSource = 2, RequestLocationType = loc.LocationType, RequestData = wayzWifiRequest }; //return; 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 处理围栏 //过滤历史定位消息 if (!hisResult.IsHistoryLocation) { //_serviceLocation.ProcessGeofence(loc, messageId); await _serviceLocation.ProcessGeofenceAsync(loc, messageId); } else { _logger.LogInformation($"设备{serialno},收到历史定位"); } #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 = addr, IsStop = (bool)loc.IsStop, BaiduLat = baiduLat, BaiduLng = baiduLng, Olat = olat, Olng = olng, Glat = gaodeLat, Glng = gaodeLng, 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($"[{_messageId}] {result.Message}"); return; } //THOMAS Kafka 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"),string.Join("|", wifiItems.AsEnumerable().Select(i => i.MacAddress))); await _serviceMqProcess.ProcessPositionAsync(messageId, positionData, loc.LastUpdate.Value.ToString("yyyy-MM-dd HH:mm:ss"), $"{mmac}|{macs}"); #endregion #region 更新Alarm if (IDType == (int)IdType.Sos && !string.IsNullOrWhiteSpace(IDNumber)) { // THOMAS Kafka //var SOSAlarm = new SoSTemplates() //{ // imei = serialno, // sosId = 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 = 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 = 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 (IDType == (int)IdType.PayLog && !string.IsNullOrWhiteSpace(IDNumber)) { var payId = propertyValue.Value.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 (IDType == (int)IdType.Temperature && !string.IsNullOrWhiteSpace(IDNumber)) //温度上报(带地址) { var tempId = propertyValue.Value.IDNumber; //var hisTemp = await _serviceHealth.GetTemperatureAsync(messageId, $"{serialno}-{tempId}").ConfigureAwait(false); //if (hisTemp == null) //{ // hisTemp = new HisGpsTemperature // { // Serialno = serialno, // TemperatureId = $"{serialno}-{tempId}", // TempId = tempId, // Address = addr, // }; // await _serviceHealth.AddTemperatureAsync(messageId, hisTemp).ConfigureAwait(false); //} //else //{ // hisTemp.Address = addr; // await _serviceHealth.UpdateTemperatureAsync(messageId, hisTemp).ConfigureAwait(false); //} await _serviceHealth.HandleTemperatureAddressAsync(messageId, $"{serialno}-{tempId}", () => new HisGpsTemperature { TemperatureId = $"{serialno}-{tempId}", Serialno = serialno, Address = addr, Province = province, City = city, District = district, LastUpdate = Utils.ConvertToLocalDateTime(propertyValue.Time), TempId = tempId }, a => { a.Address = addr; a.Province = province; a.City = city; a.District = district; return a; }); } #endregion //推送数据到设备 await _serviceGlobal.PushLocationDataAsync(serialno, olat, olng); } } }