using DotNetCore.CAP;
using Furion;
using Furion.DependencyInjection;
using Furion.DistributedIDGenerator;
using Microsoft.Extensions.Caching.Distributed;
using Nirvana.Common;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Furion.LinqBuilder;
using Waste.Application.SubscribeInfo;
using Waste.Domain;
using Waste.Domain.DataModel;
using System.Net.Http;
using Newtonsoft.Json.Linq;
namespace Waste.Application.ThirdApiInfo
{
///
/// 设备对接接口
///
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 repository;
private readonly SqlSugarClient dbClient;
private readonly ISuZhouService _suZhouService;
private readonly ILoggerService _loggerService;
private readonly ICapPublisher _capBus;
private readonly IDistributedCache _cahce;
private readonly IResultService _resultService;
private readonly IDistributedIDGenerator _idgen;
public OpenService(ISqlSugarRepository sqlSugarRepository, ISuZhouService suZhouService, ILoggerService loggerService, ICapPublisher capPublisher, IDistributedCache distributedCache, IResultService resultService, IDistributedIDGenerator distributedIDGenerator)
{
repository = sqlSugarRepository;
dbClient = repository.Context;
_suZhouService = suZhouService;
_loggerService = loggerService;
_capBus = capPublisher;
_cahce = distributedCache;
_resultService = resultService;
_idgen = distributedIDGenerator;
}
///
/// 更新上报状态
///
///
///
public async Task UpdateStatusAsync(UpdateStatusDto data)
{
//await _capBus.PublishAsync("result.service.update", data);
//return new ResultInfo(ResultState.SUCCESS, "success");
Guid resultid = Guid.Empty;
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
{
if (await dbClient.Queryable().AnyAsync(x => x.ResultId == resultid))
{
await dbClient.Updateable().SetColumns(x => new W_ResultExt
{
Status = data.status
}).Where(x => x.ResultId == resultid).ExecuteCommandAsync();
}
else
{
var insertdata = new W_ResultExt
{
Id = _idgen.Create().ToGuid(),
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未找到");
}
///
/// 获取设备上报相关信息
///
///
///
public async Task GetDevInfoAsync(GetDevInfoRequestDto data)
{
//更新上报记录结果
Guid resultid = Guid.Empty;
//这里进行去重处理
if (!string.IsNullOrEmpty(data.ResultId) && Guid.TryParse(data.ResultId, out resultid))
{
var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
var devicesecret = await dbClient.Queryable().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().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().FirstAsync(x => x.Ecode == data.ECode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
if (device.Status == (int)DeviceStatus.Error)
{
return new ResultInfo(ResultState.FAIL, "设备已停止运行");
}
var returndata = new GetDevInfoResponseDto
{
ResultId = _idgen.Create().ToGuid(),
UserId = UserId,
PostUrl = ApiUrl
};
var devicesecret = await dbClient.Queryable().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, "设备还未获取验证信息");
}
// trash@1@62942200205496@4.964 trash@垃圾种类@垃圾桶编号@垃圾重量
//20250327 添加名称和操作员 trash@5@干垃圾@30654605660104@技术员@0.22 (@干垃圾) 是名称 (@技术员) 是操作员
if (!string.IsNullOrEmpty(data.data) && data.data.StartsWith("trash@"))
{
var arr = data.data.Split('@');
if (arr.Length == 4)
{
var type = arr.GetListValue(1);
returndata.trash = arr.GetListValue(2);
var weight = arr.GetListValue(3);
var result = await UpdateDevInfo(data, returndata, device, type, weight);
if (result != null) return result;
}
else if (arr.Length == 6)
{
var type = arr.GetListValue(1);
var typename = arr.GetListValue(2);
returndata.trash = arr.GetListValue(3);
var name = arr.GetListValue(4);
var weight = arr.GetListValue(5);
var result = await UpdateDevInfo(data, returndata, device, type, weight, typename, name);
if (result != null) return result;
}
else
{
return new ResultInfo(ResultState.FAIL, $"协议格式不正确:{data.ToJson()}");
}
}
//解析协议,IC卡数据@垃圾桶编号@厨余垃圾@7.91
// 00000000003031 40 0F00010009 40 C6E4CBFBC0ACBBF8 40 31352E39
// 00000000003031 40 000F000002 40 C6E4CBFBC0ACBBF8 40 35312E30 0D0A
else 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进制
var type = GetChsFromHex(typehex);
var weight = GetChsFromHex(weighthex);
var result = await UpdateDevInfo(data, returndata, device, type, weight);
if (result != null) return result;
}
else
{
_loggerService.AddLogger($"{data.ECode},{device.Name},协议格式不正确:{data.ToJson()}", 1);
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($"{data.ECode},{device.Name},发送的数据:{returndata.ToJson()}", 1);
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
}
}
///
/// 16进制转10进制
///
///
///
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;
}
///
/// 心跳数据上报
///
///
///
public async Task PostHeartAsync(DevHeartRequestDto data)
{
if (!await dbClient.Queryable().AnyAsync(x => x.Ecode == data.ECode))
{
return new ResultInfo(ResultState.FAIL, "设备未找到");
}
await _capBus.PublishAsync("device.service.postheart", data);
return new ResultInfo(ResultState.SUCCESS, "success");
}
///
/// 获取设备注册信息,第一次开机使用
///
///
///
public async Task RegInfoAsync(string ecode)
{
var device = await dbClient.Queryable().FirstAsync(x => x.Ecode == ecode);
if (device == null)
{
return new ResultInfo(ResultState.FAIL, "设备未找到", new DevRegInfoResponseDto());
}
//更新开机时间
await _capBus.PublishAsync("device.service.update", device.Id);
var data = new DevRegInfoResponseDto
{
status = 0,
WebSocketUrl = WebSocketUrl
};
//获取授权信息
var devicesecret = await dbClient.Queryable().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);
}
///
/// 更新设备版本信息
///
///
///
public async Task UpdateVersionAsync(DeviceVerS2SDto data)
{
await _capBus.PublishAsync("device.service.updatever", data);
}
///
/// 通过ailink wifi模式发送的数据
///
///
///
public async Task