Waste/Waste.Application/ThirdApiInfo/OpenService.cs

449 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Furion;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Nirvana.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Waste.Domain;
namespace Waste.Application.ThirdApiInfo
{
/// <summary>
/// 设备对接接口
/// </summary>
public class OpenService : IOpenService, ITransient
{
private static string ApiUrl = App.Configuration["SZDevPlatSetting:ApiUrl"];
private static string UserId = App.Configuration["SZDevPlatSetting:UserId"];
private static string ApiSecret = App.Configuration["SZDevPlatSetting:ApiSecret"];
private static string ApiSecretHash = App.Configuration["SZDevPlatSetting:ApiSecretHash"];
private static string WebSocketUrl = App.Configuration["SZDevPlatSetting:SocketUrl"];
private readonly ISqlSugarRepository<W_Device> repository;
private readonly SqlSugarClient dbClient;
private readonly ISuZhouService _suZhouService;
private readonly ILoggerService _loggerService;
public OpenService(ISqlSugarRepository<W_Device> sqlSugarRepository, ISuZhouService suZhouService, ILoggerService loggerService)
{
repository = sqlSugarRepository;
dbClient = repository.Context;
_suZhouService = suZhouService;
_loggerService = loggerService;
}
/// <summary>
/// 更新上报状态
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> UpdateStatusAsync(UpdateStatusDto data)
{
Guid resultid = Guid.Empty;
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
{
if (await dbClient.Queryable<W_ResultExt>().AnyAsync(x => x.ResultId == resultid))
{
await dbClient.Updateable<W_ResultExt>().SetColumns(x => new W_ResultExt
{
Status = data.status
}).Where(x => x.ResultId == resultid).ExecuteCommandAsync();
}
else
{
var insertdata = new W_ResultExt
{
Id = IDGen.NextID(),
Status = data.status,
CreateTime = DateTime.Now,
ResultId = resultid
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "success");
}
return new ResultInfo(ResultState.SUCCESS, "记录id未找到");
}
/// <summary>
/// 获取设备上报相关信息
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> GetDevInfoAsync(GetDevInfoRequestDto data)
{
//更新上报记录结果
Guid resultid = Guid.Empty;
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret)
|| string.IsNullOrEmpty(devicesecret.SecretHash)
|| string.IsNullOrEmpty(devicesecret.DevId))
{
return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息");
}
int timestamp = _suZhouService.GetUTCTimestamp();
int noncestr = _suZhouService.GetNonce();
var result = await dbClient.Queryable<W_Result>().FirstAsync(x => x.Id == resultid);
if (result == null)
{
return new ResultInfo(ResultState.SUCCESS, "记录id未找到");
}
var returndata = new GetDevInfoResponseDto
{
DeviceId = devicesecret.DevId,
noncestr = noncestr,
timestamp = timestamp,
Secret = devicesecret.Secret,
SecretHash = devicesecret.SecretHash,
UserId = UserId,
PostUrl = ApiUrl,
ScanningTime = timestamp,
ResultId = resultid,
trash = result.Registration,
Weight = result.GrossWeight.ToDouble(),
status = 0,
IsSuccessed = true,
type = TrashType(result.WasteType)
};
string[] paramlist = new string[] {
returndata.Weight.ToString(),returndata.trash,returndata.type.ToString(),returndata.ScanningTime.ToString(),returndata.status.ToString()};
returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist);
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
else
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
var returndata = new GetDevInfoResponseDto {
ResultId= IDGen.NextID(),
UserId = UserId,
PostUrl= ApiUrl
};
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
// 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E300D0A
if (!string.IsNullOrEmpty(data.data) && data.data.Length > 52)
{
data.data = data.data.Replace(" ", "");
//收到的为16进制,对数据进行解析,0-4预留,5-垃圾种类,6-垃圾桶大小,7-@,8-12垃圾桶编号,13@,14-21垃圾种类汉字,22@,23-结束重量, OD OA 回车换行
data.data = data.data.Substring(0, data.data.Length - 4);
var trashhex = data.data.Substring(16, 10); //垃圾桶编号
var typehex = data.data.Substring(28, 16); //垃圾种类
var sizehex = data.data.Substring(12, 2);//桶大小,30-小桶,31-大桶
var weighthex = data.data.Substring(46, data.data.Length - 46);
returndata.trash = HextToDec(trashhex).ToString(); //垃圾桶编号使用10进制
//检查是否为15分钟内第一次上报
var time15 = DateTime.Now.AddMinutes(-15);
if(await dbClient.Queryable<W_Result>().AnyAsync(x=>x.DeviceId == device.Id && x.Registration == returndata.trash && x.CreateTime > time15))
{
_loggerService.AddLogger($"重复垃圾桶编号的数据:{returndata.ToJson()}", 1);
return new ResultInfo(ResultState.FAIL, "15分钟内同一垃圾桶编号上报");
}
var type = GetChsFromHex(typehex);
var weight = GetChsFromHex(weighthex);
returndata.type = TrashType(type);
returndata.Weight = weight.ToDouble();
returndata.IsSuccessed = true;
//计算净重,毛重-皮重=净重如果净重小于等于0则不上报保存
returndata.Weight = returndata.Weight - device.Tare.ToDouble();
if(returndata.Weight <= 0)
{
_loggerService.AddLogger($"重量小于等于0:{returndata.ToJson()}", 1);
return new ResultInfo(ResultState.FAIL, "无效的重量");
}
//保存测量结果
var devicedata = await dbClient.Queryable<W_DeviceData>().FirstAsync(x => x.DeviceId == device.Id);
DateTime time = DateTime.Now;
//检查设备是否为今天第一次上报
bool isfrist = false;
if (device.LastHeartTime.HasValue && device.LastHeartTime.Value.Date != DateTime.Now.Date)
{
isfrist = true;
}
//记录数据
data.IMEI = data.IMEI.ToStr();
data.ICCID = data.ICCID.ToStr();
data.IMSI = data.IMSI.ToStr();
await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new
{
deviceid = device.Id,
businessid = device.Businessid,
resultid = returndata.ResultId,
imei = data.IMEI,
iccid = data.ICCID,
imsi = data.IMSI,
time = time,
latitude = data.Latitude,
longitude = data.Longitude,
sign = data.GSLQ,
city = "",
area = returndata.trash,
wastetype = type,
weigth = weight,
isheart = 0,
tare = device.Tare,
isfrist = isfrist
});
}
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
if (devicesecret == null || string.IsNullOrEmpty(devicesecret.Secret)
|| string.IsNullOrEmpty(devicesecret.SecretHash)
|| string.IsNullOrEmpty(devicesecret.DevId))
{
return new ResultInfo(ResultState.FAIL, "设备还未获取验证信息");
}
int timestamp = _suZhouService.GetUTCTimestamp();
int noncestr = _suZhouService.GetNonce();
returndata.DeviceId = devicesecret.DevId;
returndata.noncestr = noncestr;
returndata.timestamp = timestamp;
returndata.Secret = devicesecret.Secret;
returndata.SecretHash = devicesecret.SecretHash;
returndata.ScanningTime = timestamp;
string[] paramlist = new string[] {
returndata.Weight.ToString(),returndata.trash,returndata.type.ToString(),returndata.ScanningTime.ToString(),returndata.status.ToString()
};
returndata.sign = _suZhouService.GetUserApiSign(returndata.Secret, paramlist);
_loggerService.AddLogger($"发送的数据:{returndata.ToJson()}", 1);
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
}
/// <summary>
/// 16进制转汉字
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
private string GetChsFromHex(string hex)
{
if (hex == null)
return "";
if (hex.Length % 2 != 0)
{
hex += "20";//空格
}
// 需要将 hex 转换成 byte 数组。
byte[] bytes = new byte[hex.Length / 2];
for (int i = 0; i < bytes.Length; i++)
{
try
{
// 每两个字符是一个 byte。
bytes[i] = byte.Parse(hex.Substring(i * 2, 2),
System.Globalization.NumberStyles.HexNumber);
}
catch
{
}
}
// 获得 GB2312Chinese Simplified。
Encoding chs = Encoding.GetEncoding("gb2312");
return chs.GetString(bytes);
}
/// <summary>
/// 16进制转10进制
/// </summary>
/// <param name="hex"></param>
/// <returns></returns>
public long HextToDec(string hex)
{
char[] nums = hex.ToCharArray();
long total = 0;
try
{
for (int i = 0; i < nums.Length; i++)
{
String strNum = nums[i].ToString().ToUpper();
switch (strNum)
{
case "A":
strNum = "10";
break;
case "B":
strNum = "11";
break;
case "C":
strNum = "12";
break;
case "D":
strNum = "13";
break;
case "E":
strNum = "14";
break;
case "F":
strNum = "15";
break;
default:
break;
}
double power = Math.Pow(16, Convert.ToDouble(nums.Length - i - 1));
total += Convert.ToInt64(strNum) * Convert.ToInt64(power);
}
}
catch (System.Exception ex)
{
string strErorr = ex.ToString();
return 0;
}
return total;
}
/// <summary>
/// 心跳数据上报
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
public async Task<ResultInfo> PostHeartAsync(DevHeartRequestDto data)
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == device.Id))
{
//更新设备心跳信息
if (data.Latitude == 0 || data.Longitude == 0)
{
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastBeatTime = DateTime.Now
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
else
{
string longitude = data.Longitude.ToString();
string Latitude = data.Latitude.ToString();
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastBeatTime = DateTime.Now,
Longitude = longitude,
Latitude = Latitude
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
}
else
{
var insertdata = new W_DeviceData
{
DeviceId = device.Id,
Sign = data.GSLQ.ToString(),
IMSI = data.IMSI,
ICCID = data.ICCID,
IMEI = data.IMEI,
LastBeatTime = DateTime.Now,
Latitude = data.Latitude.ToString(),
Longitude = data.Longitude.ToString()
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
return new ResultInfo(ResultState.SUCCESS, "success");
}
/// <summary>
/// 获取设备注册信息,第一次开机使用
/// </summary>
/// <param name="ecode"></param>
/// <returns></returns>
public async Task<ResultInfo> RegInfoAsync(string ecode)
{
var device = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Ecode == ecode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到", new DevRegInfoResponseDto());
}
//更新开机时间
if (await dbClient.Queryable<W_DeviceData>().AnyAsync(x => x.DeviceId == device.Id))
{
await dbClient.Updateable<W_DeviceData>()
.SetColumns(x => new W_DeviceData
{
LastStartTime = DateTime.Now
})
.Where(x => x.DeviceId == device.Id).ExecuteCommandAsync();
}
else
{
var insertdata = new W_DeviceData
{
DeviceId = device.Id,
Sign = "",
IMSI = "",
ICCID = "",
IMEI = "",
Latitude = "0",
Longitude = "0",
LastStartTime = DateTime.Now
};
await dbClient.Insertable(insertdata).ExecuteCommandAsync();
}
var data = new DevRegInfoResponseDto
{
status = 0,
WebSocketUrl = WebSocketUrl
};
//获取授权信息
var devicesecret = await dbClient.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
if (devicesecret != null && !string.IsNullOrEmpty(devicesecret.Secret)
&& !string.IsNullOrEmpty(devicesecret.SecretHash)
&& !string.IsNullOrEmpty(devicesecret.DevId))
{
data.timestamp = _suZhouService.GetUTCTimestamp();
data.noncestr = _suZhouService.GetNonce();
data.UserId = UserId;
data.Secret = devicesecret.Secret;
data.SecretHash = devicesecret.SecretHash;
data.DeviceId = devicesecret.DevId.ToString();
}
return new ResultInfo(ResultState.SUCCESS, "success", data);
}
private int TrashType(string type)
{
if (type == "厨余垃圾") return 1;
else if (type == "可回收物") return 2;
else if (type == "有害垃圾") return 3;
else if (type == "其他垃圾") return 4;
else return 0;
}
private int GetTimestamp(DateTime time)
{
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
int timestamp = Convert.ToInt32((time - dateTimeStart).TotalSeconds);
return timestamp;
}
/// <summary>
/// 字节数组转16进制
/// </summary>
/// <param name="bt"></param>
/// <returns></returns>
private string BytesToHexStr(byte[] bt)
{
string returnStr = "";
if (bt != null)
{
for (int i = 0; i < bt.Length; i++)
{
returnStr += bt[i].ToString("X2");
}
}
return returnStr;
}
}
}