dev #2

Merged
admin merged 176 commits from dev into master 2025-04-18 01:31:49 +00:00
22 changed files with 653 additions and 6 deletions
Showing only changes of commit ead1696059 - Show all commits

View File

@ -0,0 +1,54 @@
using FreeRedis;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace JiShe.CollectBus.FreeRedisProvider;
public class FreeRedisProviderService : IFreeRedisProviderService, ISingletonDependency
{
private FreeRedisOptions freeRedisOptions;
/// <summary>
/// FreeRedis
/// </summary>
public FreeRedisProviderService(IOptions<FreeRedisOptions> options)
{
freeRedisOptions = options.Value;
}
public IRedisClient FreeRedis { get => GetClient(); }
/// <summary>
/// 获取 FreeRedis 客户端
/// </summary>
/// <returns></returns>
public IRedisClient GetClient()
{
var redisClinet = new RedisClient(freeRedisOptions.ConnectionString);
redisClinet.Serialize = obj => JsonSerializer.Serialize(obj);
redisClinet.Deserialize = (json, type) => JsonSerializer.Deserialize(json, type);
redisClinet.Notice += (s, e) => Trace.WriteLine(e.Log);
return redisClinet;
}
/// <summary>
/// 切换Redis数据库
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
public IRedisClient GetDatabase(int index = 0)
{
var redisClinet = GetClient();
redisClinet.GetDatabase(index);
return redisClinet;
}
}

View File

@ -0,0 +1,29 @@
using FreeRedis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.FreeRedisProvider;
public interface IFreeRedisProviderService
{
/// <summary>
/// 默认客户端
/// </summary>
IRedisClient FreeRedis { get; }
/// <summary>
/// 获取客户端
/// </summary>
/// <returns></returns>
IRedisClient GetClient();
/// <summary>
/// 切换Redis数据库
/// </summary>
/// <param name="index"></param>
/// <returns></returns>
IRedisClient GetDatabase(int index = 0);
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.FreeRedisProvider;
public class FreeRedisOptions
{
/// <summary>
/// 连接字符串
/// </summary>
public string? ConnectionString { get; set; }
/// <summary>
/// 默认数据库
/// </summary>
public string? DefaultDB { get; set; }
/// <summary>
/// HangfireDB
/// </summary>
public string? HangfireDB { get; set; }
}

View File

@ -0,0 +1,26 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Modularity;
namespace JiShe.CollectBus.FreeRedisProvider;
public class FreeRedisProviderModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
var configuration = context.Services.GetConfiguration();
Configure<FreeRedisOptions>(options =>
{
configuration.GetSection("Redis").Bind(options);
});
}
}

View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="FreeRedis" Version="1.3.6" />
<PackageReference Include="Volo.Abp" Version="8.3.3" />
</ItemGroup>
</Project>

View File

@ -29,6 +29,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.DbMigrator
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JiShe.CollectBus.FreeSql", "src\JiShe.CollectBus.FreeSql\JiShe.CollectBus.FreeSql.csproj", "{FE0457D9-4038-4A17-8808-DCAD06CFC0A0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JiShe.CollectBus.FreeRedisProvider", "JiShe.CollectBus.FreeRedisProvider\JiShe.CollectBus.FreeRedisProvider.csproj", "{920445D9-18D2-4886-9053-6A4CC3B4F3E2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -83,6 +85,10 @@ Global
{FE0457D9-4038-4A17-8808-DCAD06CFC0A0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE0457D9-4038-4A17-8808-DCAD06CFC0A0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE0457D9-4038-4A17-8808-DCAD06CFC0A0}.Release|Any CPU.Build.0 = Release|Any CPU
{920445D9-18D2-4886-9053-6A4CC3B4F3E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{920445D9-18D2-4886-9053-6A4CC3B4F3E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{920445D9-18D2-4886-9053-6A4CC3B4F3E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{920445D9-18D2-4886-9053-6A4CC3B4F3E2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -100,6 +106,7 @@ Global
{38C1808B-009A-418B-B17B-AB3626341B5D} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{8BA01C3D-297D-42DF-BD63-EF07202A0A67} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{FE0457D9-4038-4A17-8808-DCAD06CFC0A0} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
{920445D9-18D2-4886-9053-6A4CC3B4F3E2} = {649A3FFA-182F-4E56-9717-E6A9A2BEC545}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {4324B3B4-B60B-4E3C-91D8-59576B4E26DD}

View File

@ -22,4 +22,8 @@
<ProjectReference Include="..\JiShe.CollectBus.Domain\JiShe.CollectBus.Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Workers\DTO\Prepay\" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,146 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.Workers.DTO.Energy
{
/// <summary>
/// 能耗电表信息数据模型
/// </summary>
public class EnergyAmmeterInfoDto
{
/// <summary>
/// 电表ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 电表名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 集中器ID
/// </summary>
public int FocusID { get; set; }
/// <summary>
/// 集中器地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 集中器区域代码
/// </summary>
public string AreaCode { get; set; }
/// <summary>
/// 电表类别 1单相、2三相三线、3三相四线,
/// 07协议 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表
/// 97协议//true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355"
/// </summary>
public int TypeName { get; set; }
/// <summary>
/// 跳合闸状态字段: 0 合闸1 跳闸
/// 电表TripState 0 合闸-通电, 1 断开、跳闸);
/// </summary>
public int TripState { get; set; }
/// <summary>
/// 规约 -电表default(30) 197协议3007协议
/// </summary>
public int? Protocol { get; set; }
/// <summary>
/// 一个集中器下的[MeteringCode]必须唯一。 PN
/// </summary>
public int MeteringCode { get; set; }
/// <summary>
/// 电表通信地址
/// </summary>
public string AmmerterAddress { get; set; }
/// <summary>
/// 波特率 default(2400)
/// </summary>
public int Baudrate { get; set; }
/// <summary>
/// MeteringPort 端口就几个可以枚举。
/// </summary>
public int MeteringPort { get; set; }
/// <summary>
/// 电表密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 采集时间间隔(分钟如15)
/// </summary>
public int TimeDensity { get; set; }
/// <summary>
/// 该电表方案下采集项0D_80
/// </summary>
public string ItemCodes { get; set; }
/// <summary>
/// State表状态:
/// 0新装未下发1运行(档案下发成功时设置状态值1) 2暂停, 100销表销表后是否重新启用
/// 特定State -1 已删除
/// </summary>
public int State { get; set; }
/// <summary>
/// 是否自动采集(0:主动采集1自动采集)
/// </summary>
public int AutomaticReport { get; set; }
/// <summary>
/// 该电表方案下采集项编号
/// </summary>
public string DataTypes { get; set; }
/// <summary>
/// 品牌型号
/// </summary>
public string BrandType { get; set; }
/// <summary>
/// 采集器编号
/// </summary>
public string GatherCode { get; set; }
/// <summary>
/// 是否特殊表
/// </summary>
public int Special { get; set; }
/// <summary>
/// 费率类型,单、多 (SingleRate :单费率单相表1多费率其他0 与TypeName字段无关)
/// SingleRate ? "单" : "复"
/// [SingleRate] --0 复费率 false 1 单费率 true 与PayPlanID保持一致
///对应 TB_PayPlan.Type: 1复费率2单费率
/// </summary>
public bool SingleRate { get; set; }
/// <summary>
/// 项目ID
/// </summary>
public int ProjectID { get; set; }
/// <summary>
/// 是否异常集中器 0:正常1异常
/// </summary>
public int AbnormalState { get; set; }
public DateTime LastTime { get; set; }
/// <summary>
/// 集中器地址
/// </summary>
public string FocusAddress { get; set; }
}
}

View File

@ -0,0 +1,45 @@
using JiShe.CollectBus.Ammeters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.Workers
{
/// <summary>
/// 定时任务基础约束
/// </summary>
interface IWorkerScheduledService
{
/// <summary>
/// 获取电表信息
/// </summary>
/// <returns></returns>
Task<List<AmmeterInfo>> GetAmmeterInfoList();
/// <summary>
/// 初始化电表缓存数据
/// </summary>
/// <returns></returns>
Task InitAmmeterCacheData();
/// <summary>
/// 1分钟采集电表数据
/// </summary>
/// <returns></returns>
Task ScheduledMeterOneMinuteReading();
/// <summary>
/// 5分钟采集电表数据
/// </summary>
/// <returns></returns>
Task ScheduledMeterFiveMinuteReading();
/// <summary>
/// 15分钟采集电表数据
/// </summary>
/// <returns></returns>
Task ScheduledMeterFifteenMinuteReading();
}
}

View File

@ -0,0 +1,31 @@
using System.Threading.Tasks;
using JiShe.CollectBus.Common.Models;
using JiShe.CollectBus.MessageReceiveds;
using Volo.Abp.Application.Services;
namespace JiShe.CollectBus.Subscribers
{
/// <summary>
/// 定时抄读任务消息订阅
/// </summary>
public interface IWorkerSubscriberAppService : IApplicationService
{
/// <summary>
/// 1分钟采集电表数据下行消息消费订阅
/// </summary>
/// <returns></returns>
Task ScheduledMeterOneMinuteReadingIssuedEvent(IssuedEventMessage issuedEventMessage);
/// <summary>
/// 5分钟采集电表数据下行消息消费订阅
/// </summary>
/// <returns></returns>
Task ScheduledMeterFiveMinuteReadingIssuedEvent(IssuedEventMessage issuedEventMessage);
/// <summary>
/// 15分钟采集电表数据下行消息消费订阅
/// </summary>
/// <returns></returns>
Task ScheduledMeterFifteenMinuteReadingIssuedEvent(IssuedEventMessage issuedEventMessage);
}
}

View File

@ -1,6 +1,12 @@
using JiShe.CollectBus.FreeSql;
using FreeRedis;
using FreeSql;
using JiShe.CollectBus.FreeRedisProvider;
using JiShe.CollectBus.FreeSql;
using JiShe.CollectBus.Localization;
using JiShe.CollectBus.Workers.DTO.Energy;
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace JiShe.CollectBus;
@ -9,10 +15,30 @@ namespace JiShe.CollectBus;
public abstract class CollectBusAppService : ApplicationService
{
public IFreeSqlProvider SqlProvider => LazyServiceProvider.LazyGetRequiredService<IFreeSqlProvider>();
protected IRedisClient? FreeRedis => LazyServiceProvider.LazyGetService<IFreeRedisProviderService>()?.FreeRedis;
protected CollectBusAppService()
{
LocalizationResource = typeof(CollectBusResource);
ObjectMapperContext = typeof(CollectBusApplicationModule);
}
#region
/// <summary>
/// 查找当前采集器下所有电表
/// </summary>
/// <param name="gatherCode">采集端Code</param>
/// <returns></returns>
protected async Task<List<EnergyAmmeterInfoDto>> GetAmmetersByGatherCode(string gatherCode = "V4-Gather-8890")
{
string sql = $@"SELECT C.ID,C.Name,C.FocusID,C.SingleRate,C.MeteringCode,C.Code AS BrandType,C.Baudrate,C.Password,C.MeteringPort,C.[Address] AS AmmerterAddress,C.TypeName,C.Protocol,C.TripState,C.[State],B.[Address],B.AreaCode,B.AutomaticReport,D.DataTypes,B.TimeDensity,A.GatherCode,C.Special,C.[ProjectID],B.AbnormalState,B.LastTime
FROM TB_GatherInfo(NOLOCK) AS A
INNER JOIN TB_FocusInfo(NOLOCK) AS B ON A.ID = B.GatherInfoID AND B.RemoveState >= 0 AND B.State>=0
INNER JOIN TB_AmmeterInfo(NOLOCK) AS C ON B.ID = C.FocusID AND C.State>= 0 AND C.State<100
INNER JOIN TB_AmmeterGatherItem(NOLOCK) AS D ON C.ID = D.AmmeterID AND D.State>=0
WHERE A.GatherCode = {gatherCode}";
return await SqlProvider.Instance.Change(DbEnum.EnergyDB).Select<EnergyAmmeterInfoDto>(sql).ToListAsync();
}
#endregion
}

View File

@ -10,6 +10,7 @@ using System.Reflection;
using JiShe.CollectBus.FreeSql;
using System;
using Volo.Abp.AspNetCore.Mvc.AntiForgery;
using JiShe.CollectBus.FreeRedisProvider;
namespace JiShe.CollectBus;
@ -19,6 +20,7 @@ namespace JiShe.CollectBus;
typeof(AbpDddApplicationModule),
typeof(AbpAutoMapperModule),
typeof(AbpBackgroundWorkersModule),
typeof(FreeRedisProviderModule),
typeof(CollectBusFreeSqlModule)
)]
public class CollectBusApplicationModule : AbpModule

View File

@ -23,6 +23,7 @@
<PackageReference Include="TouchSocket" Version="2.1.9" />
<PackageReference Include="TouchSocket.Hosting" Version="2.1.9" />
<PackageReference Include="DotNetCore.CAP" Version="8.3.1" />
<ProjectReference Include="..\..\JiShe.CollectBus.FreeRedisProvider\JiShe.CollectBus.FreeRedisProvider.csproj" />
<ProjectReference Include="..\JiShe.CollectBus.Application.Contracts\JiShe.CollectBus.Application.Contracts.csproj" />
<ProjectReference Include="..\JiShe.CollectBus.Common\JiShe.CollectBus.Common.csproj" />

View File

@ -53,14 +53,17 @@ namespace JiShe.CollectBus.Plugins
var aFn = (int?)hexStringList.GetAnalyzeValue(CommandChunkEnum.AFN);
var fn = (int?)hexStringList.GetAnalyzeValue(CommandChunkEnum.FN);
var aTuple = (Tuple<string, int>)hexStringList.GetAnalyzeValue(CommandChunkEnum.A);
if (aFn.HasValue && fn.HasValue)
if (aFn.HasValue && fn.HasValue && aTuple != null && !string.IsNullOrWhiteSpace(aTuple.Item1))
{
string oldClinetId = client.Id;
await client.ResetIdAsync(aTuple.Item1);
if ((AFN)aFn == AFN.)
{
switch (fn)
{
case 1:
await OnTcpLoginReceived(client, messageHexString, aTuple.Item1);
await OnTcpLoginReceived(client, messageHexString, aTuple.Item1, oldClinetId);
break;
case 3:
await OnTcpHeartbeatReceived(client, messageHexString, aTuple.Item1);
@ -113,7 +116,16 @@ namespace JiShe.CollectBus.Plugins
await e.InvokeNext();
}
private async Task OnTcpLoginReceived(ITcpSessionClient client, string messageHexString, string deviceNo)
/// <summary>
/// 登录帧处理
/// </summary>
/// <param name="client"></param>
/// <param name="messageHexString"></param>
/// <param name="deviceNo">集中器编号</param>
/// <param name="oldClinetId">TCP首次连接时的Id</param>
/// <returns></returns>
private async Task OnTcpLoginReceived(ITcpSessionClient client, string messageHexString, string deviceNo,string oldClinetId)
{
var messageReceivedLoginEvent = new MessageReceivedLogin
{

View File

@ -22,7 +22,7 @@ namespace JiShe.CollectBus.Workers
public override Task DoWorkAsync(CancellationToken cancellationToken = new CancellationToken())
{
_logger.LogInformation("Executed MyLogWorker..!");
_logger.LogError("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}

View File

@ -0,0 +1,27 @@
using FreeRedis;
using JiShe.CollectBus.FreeRedisProvider;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
namespace JiShe.CollectBus.Workers
{
/// <summary>
/// 定时采集服务
/// </summary>
public class ScheduledMeterReadingService : CollectBusAppService, IScheduledMeterReadingService
{
/// <summary>
/// 初始化能耗电表数据
/// </summary>
/// <returns></returns>
public async Task InitEnergyAmmeterData()
{
var ammerterList = await GetAmmetersByGatherCode();
}
}
}

View File

@ -0,0 +1,103 @@
using System;
using System.Threading.Tasks;
using DeviceDetectorNET.Parser.Device;
using DotNetCore.CAP;
using JiShe.CollectBus.Common.Enums;
using JiShe.CollectBus.Common.Models;
using JiShe.CollectBus.Devices;
using JiShe.CollectBus.MessageReceiveds;
using JiShe.CollectBus.Protocol.Contracts;
using JiShe.CollectBus.Protocol.Contracts.Interfaces;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using TouchSocket.Sockets;
using Volo.Abp.Caching;
using Volo.Abp.Domain.Repositories;
namespace JiShe.CollectBus.Subscribers
{
/// <summary>
/// 定时抄读任务消息消费订阅
/// </summary>
public class WorkerSubscriberAppService : CollectBusAppService, IWorkerSubscriberAppService,ICapSubscribe
{
private readonly ILogger<WorkerSubscriberAppService> _logger;
private readonly ITcpService _tcpService;
private readonly IServiceProvider _serviceProvider;
/// <summary>
/// Initializes a new instance of the <see cref="WorkerSubscriberAppService"/> class.
/// </summary>
/// <param name="logger">The logger.</param>
/// <param name="tcpService">The TCP service.</param>
/// <param name="serviceProvider">The service provider.</param>
public WorkerSubscriberAppService(ILogger<WorkerSubscriberAppService> logger,
ITcpService tcpService, IServiceProvider serviceProvider)
{
_logger = logger;
_tcpService = tcpService;
_serviceProvider = serviceProvider;
}
/// <summary>
/// 一分钟定时抄读任务消息消费订阅
/// </summary>
/// <param name="receivedMessage"></param>
/// <returns></returns>
[CapSubscribe(ProtocolConst.SubscriberWorkerOneMinuteIssuedEventName)]
public async Task ScheduledMeterOneMinuteReadingIssuedEvent(IssuedEventMessage receivedMessage)
{
_logger.LogInformation("1分钟采集电表数据下行消息消费队列开始处理");
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
if (protocolPlugin == null)
{
_logger.LogError("【1分钟采集电表数据下行消息消费队列开始处理】协议不存在");
}
else
{
await _tcpService.SendAsync(receivedMessage.ClientId, receivedMessage.Message);
}
}
/// <summary>
/// 5分钟采集电表数据下行消息消费订阅
/// </summary>
/// <param name="receivedMessage"></param>
/// <returns></returns>
[CapSubscribe(ProtocolConst.SubscriberWorkerOneMinuteIssuedEventName)]
public async Task ScheduledMeterFiveMinuteReadingIssuedEvent(IssuedEventMessage receivedMessage)
{
_logger.LogInformation("5分钟采集电表数据下行消息消费队列开始处理");
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
if (protocolPlugin == null)
{
_logger.LogError("【5分钟采集电表数据下行消息消费队列开始处理】协议不存在");
}
else
{
await _tcpService.SendAsync(receivedMessage.ClientId, receivedMessage.Message);
}
}
/// <summary>
/// 15分钟采集电表数据下行消息消费订阅
/// </summary>
/// <param name="receivedMessage"></param>
/// <returns></returns>
[CapSubscribe(ProtocolConst.SubscriberWorkerOneMinuteIssuedEventName)]
public async Task ScheduledMeterFifteenMinuteReadingIssuedEvent(IssuedEventMessage receivedMessage)
{
_logger.LogInformation("15分钟采集电表数据下行消息消费队列开始处理");
var protocolPlugin = _serviceProvider.GetKeyedService<IProtocolPlugin>("StandardProtocolPlugin");
if (protocolPlugin == null)
{
_logger.LogError("【15分钟采集电表数据下行消息消费队列开始处理】协议不存在");
}
else
{
await _tcpService.SendAsync(receivedMessage.ClientId, receivedMessage.Message);
}
}
}
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace JiShe.CollectBus.Common.Consts
{
public class FreeRedisConst
{
/// <summary>
/// 缓存基础目录
/// </summary>
public const string CacheBasicDirectoryKey = "CollectBus:";
/// <summary>
/// 缓存电表信息
/// </summary>
public const string CacheAmmeterInfoKey = $"{CacheBasicDirectoryKey}AmmeterInfo:";
}
}

View File

@ -8,80 +8,115 @@ namespace JiShe.CollectBus.Ammeters
{
public class AmmeterInfo
{
/// <summary>
/// 电表ID
/// </summary>
public int ID { get; set; }
/// <summary>
/// 电表名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 集中器ID
/// </summary>
public int FocusID { get; set; }
/// <summary>
/// 集中器地址
/// </summary>
public string Address { get; set; }
/// <summary>
/// 集中器区域代码
/// </summary>
public string AreaCode { get; set; }
/// <summary>
/// 电表类别 1单相、2三相三线、3三相四线,
/// 07协议 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表
/// 97协议//true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355"
/// </summary>
public int TypeName { get; set; }
/// <summary>
/// 跳合闸状态字段: 0 合闸1 跳闸
/// 电表TripState 0 合闸-通电, 1 断开、跳闸);
/// </summary>
public int TripState { get; set; }
/// <summary>
/// 规约 -电表default(30) 197协议3007协议
/// </summary>
public int? Protocol { get; set; }
/// <summary>
/// 一个集中器下的[MeteringCode]必须唯一。 PN
/// </summary>
public int MeteringCode { get; set; }
/// <summary>
/// 电表通信地址
/// </summary>
public string AmmerterAddress { get; set; }
/// <summary>
/// 波特率 default(2400)
/// </summary>
public int Baudrate { get; set; }
/// <summary>
/// MeteringPort 端口就几个可以枚举。
/// </summary>
public int MeteringPort { get; set; }
/// <summary>
/// 电表密码
/// </summary>
public string Password { get; set; }
/// <summary>
/// 采集时间间隔(分钟如15)
/// </summary>
public int TimeDensity { get; set; }
/// <summary>
/// 该电表方案下采集项0D_80
/// </summary>
public string ItemCodes { get; set; }
/// <summary>
/// State表状态:
/// 0新装未下发1运行(档案下发成功时设置状态值1) 2暂停, 100销表销表后是否重新启用
/// 特定State -1 已删除
/// </summary>
public int State { get; set; }
/// <summary>
/// 是否自动采集(0:主动采集1自动采集)
/// </summary>
public int AutomaticReport { get; set; }
/// <summary>
/// 该电表方案下采集项编号
/// </summary>
public string DataTypes { get; set; }
/// <summary>
/// 品牌型号
/// </summary>
public string BrandType { get; set; }
/// <summary>
/// 采集器编号
/// </summary>
public string GatherCode { get; set; }
/// <summary>
/// 是否特殊表
/// </summary>
public int Special { get; set; }
/// <summary>
/// 费率类型,单、多 (SingleRate :单费率单相表1多费率其他0 与TypeName字段无关)
/// SingleRate ? "单" : "复"
@ -89,11 +124,21 @@ namespace JiShe.CollectBus.Ammeters
///对应 TB_PayPlan.Type: 1复费率2单费率
/// </summary>
public bool SingleRate { get; set; }
/// <summary>
/// 项目ID
/// </summary>
public int ProjectID { get; set; }
/// <summary>
/// 是否异常集中器 0:正常1异常
/// </summary>
public int AbnormalState { get; set; }
public DateTime LastTime { get; set; }
/// <summary>
/// 集中器地址
/// </summary>
public string FocusAddress { get; set; }
}
}

View File

@ -27,16 +27,34 @@ namespace JiShe.CollectBus.Devices
Status = status;
}
/// <summary>
/// 集中器编号在集中器登录时解析获取并会更新为当前TCP连接的最新ClientId
/// </summary>
public string Number { get; set; }
/// <summary>
/// 首次上线时间
/// </summary>
public DateTime FirstOnlineTime { get; set; }
/// <summary>
/// 最后上线时间
/// </summary>
public DateTime LastOnlineTime { get; set; }
/// <summary>
/// TCP客户端首次连接ID在登录解析成功以后会被Number集中器编号覆盖
/// </summary>
public string ClientId { get; set; }
/// <summary>
/// TCP客户端断线时间用于计算是否断线
/// </summary>
public DateTime? LastOfflineTime { get; set; }
/// <summary>
/// 设备状态
/// </summary>
public DeviceStatus Status { get; set; }
public void UpdateByLoginAndHeartbeat(string clientId)

View File

@ -222,8 +222,9 @@ namespace JiShe.CollectBus.Host
{
context.Services.AddTcpService(config =>
{
config.SetListenIPHosts(int.Parse(configuration["TCP:ClientPort"] ?? "10500"))
config.SetListenIPHosts(int.Parse(configuration["TCP:ClientPort"] ?? "32580"))
//.SetTcpDataHandlingAdapter(()=>new StandardFixedHeaderDataHandlingAdapter())
.SetGetDefaultNewId(() => Guid.NewGuid().ToString())//定义ClinetId的生成策略
.ConfigurePlugins(a =>
{
a.Add<TcpCloseMonitor>();

View File

@ -14,5 +14,18 @@ namespace JiShe.CollectBus.Protocol.Contracts
public const string SubscriberReceivedHeartbeatEventName = "received.heartbeat.event";
public const string SubscriberReceivedLoginEventName = "received.login.event";
/// <summary>
/// 1分钟采集电表数据下行消息主题
/// </summary>
public const string SubscriberWorkerOneMinuteIssuedEventName = "issued.oneminute.event";
/// <summary>
/// 5分钟采集电表数据下行消息主题
/// </summary>
public const string SubscriberWorkerFiveMinuteIssuedEventName = "issued.fiveminute.event";
/// <summary>
/// 15分钟采集电表数据下行消息主题
/// </summary>
public const string SubscriberWorkerFifteenMinuteIssuedEventName = "issued.fifteenminute.event";
}
}