This commit is contained in:
zenghongyao 2025-05-21 10:45:24 +08:00
commit 6adbfe7883
8 changed files with 246 additions and 188 deletions

View File

@ -31,7 +31,7 @@ namespace JiShe.CollectBus.Protocol.T1882018
T188ControlHandlers = Telemetry1882018PacketBuilder.T1882018ControlHandlers;
}
public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "376.1/188-2018", "TCP", "376.1/188-2018协议", "HJ-LXS-15 DN15");
public sealed override ProtocolInfo Info => new(nameof(T1882018ProtocolPlugin), "376.1/188-2018", "TCP", "376.1/188-2018协议", "云集");
public override async Task<T> AnalyzeAsync<T>(ITcpSessionClient client, string messageReceived, Action<T>? sendAction = null)
{

View File

@ -137,101 +137,46 @@ namespace JiShe.CollectBus.ScheduledMeterReading
//电表定时广播校时,一天一次。
string currentTimeStr = $"{currentTime:HH:mm:00}";
//if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时
//{
// //_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
// //return;
// _ = CreateMeterPublishTask<DeviceInfo>(
// timeDensity: timeDensity,
// nextTaskTime: currentTime,
// meterType: MeterTypeEnum.Ammeter,
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
// {
// var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps);
// if (tempTask == null || tempTask.Count <= 0)
// {
// _logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}");
// return;
// }
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
// });
//}
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取
//{
// _ = CreateMeterPublishTask<DeviceInfo>(
// timeDensity: timeDensity,
// nextTaskTime: currentTime,
// meterType: MeterTypeEnum.Ammeter,
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
// {
// var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps);
// if (tempTask == null || tempTask.Count <= 0)
// {
// _logger.LogWarning($"集中器终端版本信息 {data.Name} 任务数据构建失败:{data.Serialize()}");
// return;
// }
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
// });
//}
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取
//{
// _ = CreateMeterPublishTask<DeviceInfo>(
// timeDensity: timeDensity,
// nextTaskTime: currentTime,
// meterType: MeterTypeEnum.Ammeter,
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
// {
// var tempTask = await ConcentratorScheduledAutomaticGetTelematicsModule(timeDensity, data, groupIndex, timestamps);
// if (tempTask == null || tempTask.Count <= 0)
// {
// _logger.LogWarning($"集中器SIM卡读取 {data.Name} 任务数据构建失败:{data.Serialize()}");
// return;
// }
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
// });
//}
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//月冻结
//{
// _ = CreateMeterPublishTask<DeviceInfo>(
// timeDensity: timeDensity,
// nextTaskTime: currentTime,
// meterType: MeterTypeEnum.Ammeter,
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
// {
// var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps);
// if (tempTask == null || tempTask.Count <= 0)
// {
// _logger.LogWarning($"电表月冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
// return;
// }
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
// });
//}
//else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结
//{
// _ = CreateMeterPublishTask<DeviceInfo>(
// timeDensity: timeDensity,
// nextTaskTime: currentTime,
// meterType: MeterTypeEnum.Ammeter,
// taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
// {
// var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps);
// if (tempTask == null || tempTask.Count <= 0)
// {
// _logger.LogWarning($"电表日冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
// return;
// }
// _ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
// });
//}
//else
//{
// _logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他");
//}
if (string.Equals(currentTimeStr, _applicationOptions.AutomaticVerificationTime, StringComparison.CurrentCultureIgnoreCase))//自动校时
{
//_logger.LogInformation($"{nameof(AmmeterScheduledAutomaticVerificationTime)} 电表自动校时,非自动校时时间");
//return;
_ = CreateMeterPublishTask<DeviceInfo>(
timeDensity: timeDensity,
nextTaskTime: currentTime,
meterType: MeterTypeEnum.Ammeter,
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
{
var tempTask = await AmmeterScheduledAutomaticVerificationTime(timeDensity, data, groupIndex, timestamps);
if (tempTask == null || tempTask.Count <= 0)
{
_logger.LogWarning($"电表自动校时 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
});
}
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTerminalVersionTime, StringComparison.CurrentCultureIgnoreCase))//集中器版本号读取
{
_ = CreateMeterPublishTask<DeviceInfo>(
timeDensity: timeDensity,
nextTaskTime: currentTime,
meterType: MeterTypeEnum.Ammeter,
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
{
var tempTask = await ConcentratorScheduledAutomaticGetTerminalVersion(timeDensity, data, groupIndex, timestamps);
if (tempTask == null || tempTask.Count <= 0)
{
_logger.LogWarning($"集中器终端版本信息 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
});
}
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticTelematicsModuleTime, StringComparison.CurrentCultureIgnoreCase))//SIM卡读取
{
_ = CreateMeterPublishTask<DeviceInfo>(
timeDensity: timeDensity,
nextTaskTime: currentTime,
@ -246,8 +191,45 @@ namespace JiShe.CollectBus.ScheduledMeterReading
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
});
}
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticMonthFreezeTime, StringComparison.CurrentCultureIgnoreCase))//月冻结
{
_ = CreateMeterPublishTask<DeviceInfo>(
timeDensity: timeDensity,
nextTaskTime: currentTime,
meterType: MeterTypeEnum.Ammeter,
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
{
var tempTask = await AmmeterScheduledGetAutomaticMonthFreezeData(timeDensity, data, groupIndex, timestamps);
if (tempTask == null || tempTask.Count <= 0)
{
_logger.LogWarning($"电表月冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
});
}
else if (string.Equals(currentTimeStr, _applicationOptions.AutomaticDayFreezeTime, StringComparison.CurrentCultureIgnoreCase))//日冻结
{
_ = CreateMeterPublishTask<DeviceInfo>(
timeDensity: timeDensity,
nextTaskTime: currentTime,
meterType: MeterTypeEnum.Ammeter,
taskCreateAction: async (timeDensity, data, groupIndex, timestamps) =>
{
var tempTask = await AmmeterScheduledGetAutomaticDayFreezeData(timeDensity, data, groupIndex, timestamps);
if (tempTask == null || tempTask.Count <= 0)
{
_logger.LogWarning($"电表日冻结 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerOtherIssuedEventName, tempTask));
});
}
else
{
_logger.LogInformation($"{nameof(CreateToBeIssueTasks)} 不是自动校时、采集终端信息等时间,继续处理其他");
}
//检查任务时间节点由于定时任务10秒钟运行一次需要判定当前时间是否在任务时间节点内不在则跳过
var currentTaskTime = tasksToBeIssueModel.LastTaskTime.CalculateNextCollectionTime(timeDensity);//程序启动缓存电表的时候NextTaskTime需要格式化到下一个采集点时间。
@ -259,8 +241,6 @@ namespace JiShe.CollectBus.ScheduledMeterReading
var meterTypes = EnumExtensions.ToEnumDictionary<MeterTypeEnum>();
//tasksToBeIssueModel.NextTaskTime;
if (meteryType == MeterTypeEnum.Ammeter.ToString())
{
_ = CreateMeterPublishTask<DeviceInfo>(
@ -272,7 +252,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
var tempTask = await AmmerterCreatePublishTaskAction(timeDensity, data, groupIndex, timestamps);
if (tempTask == null || tempTask.Count <= 0)
{
//_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
_logger.LogWarning($"电表 {data.Name} 任务数据构建失败:{data.Serialize()}");
return;
}
_ = _dataChannelManage.ScheduledMeterTaskWriterAsync(DataChannelManage.TaskDataChannel.Writer, (ProtocolConst.AmmeterSubscriberWorkerFifteenMinuteIssuedEventName, tempTask));
@ -933,7 +913,13 @@ namespace JiShe.CollectBus.ScheduledMeterReading
{
FocusAddress = ammeterInfo.FocusAddress,
Pn = ammeterInfo.MeteringCode,
ItemCode = item
ItemCode = item,
DataTimeMark = new Protocol.DataTimeMark()
{
Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值
Point = 1,
DataTime = currentTime.AddDays(-1),//日冻结抄读时间为昨天
},
});
var meterReadingRecords = CreateAmmeterPacketInfo(
@ -981,9 +967,19 @@ namespace JiShe.CollectBus.ScheduledMeterReading
try
{
#if DEBUG
#else
//需要检查是不是每月1号抄读上个月的数据
if (currentTime.Date != currentTime.FirstDayOfMonth().Date)
{
_logger.LogInformation($"{nameof(AmmeterScheduledGetAutomaticMonthFreezeData)} 非月冻结数据抄读时间,暂不处理");
return null;
}
else
{
timestamps = currentTime.LastDayOfPrdviousMonth();
}
//判断是否是月冻结数据抄读
if (!string.Equals(currentTimeStr, _applicationOptions.AutomaticMonthFreezeTime, StringComparison.CurrentCultureIgnoreCase))
{
@ -1002,13 +998,23 @@ namespace JiShe.CollectBus.ScheduledMeterReading
return null;
}
foreach (var item in DayFreezeCodes)
foreach (var item in MonthFreezeCodes)
{
ProtocolBuildResponse builderResponse = await protocolPlugin.BuildAsync(new ProtocolBuildRequest()
{
FocusAddress = ammeterInfo.FocusAddress,
Pn = ammeterInfo.MeteringCode,
ItemCode = item
ItemCode = item,
DataTimeMark = new Protocol.DataTimeMark()
{
Density = ammeterInfo.TimeDensity.GetFocusDensity(),//转换成协议的值
Point = 1,
#if DEBUG
DataTime = currentTime.AddMonths(-1),//月冻结抄读时间为上个月
#else
DataTime = timestamps,//月冻结抄读时间为上个月
#endif
},
});
var meterReadingRecords = CreateAmmeterPacketInfo(
@ -1270,14 +1276,14 @@ namespace JiShe.CollectBus.ScheduledMeterReading
{
timeDensity = watermeter.TimeDensity;//水表默认为60分钟
typeName = watermeter.LinkType;
if (watermeter.MeterBrand.Contains("泉高阀门") || watermeter.MeterBrand.Equals("LXSY-山水翔"))
if (watermeter.BrandType.Contains("泉高阀门") || watermeter.BrandType.Equals("LXSY-山水翔"))
{
typeName = watermeter.MeterBrand;
typeName = watermeter.BrandType;
}
}
else if (watermeter.MeterType == MeterTypeEnum.WaterMeterFlowmeter)
{
typeName = watermeter.MeterBrand;
typeName = watermeter.BrandType;
}
else
{

View File

@ -560,6 +560,38 @@ namespace JiShe.CollectBus.ScheduledMeterReading
{
try
{
#if DEBUG
var redisCacheDeviceInfoHashKeyTemp = $"CollectBus:Energy:JiSheCollectBus109:DeviceInfo";
List<DeviceInfo> deviceInfos = FreeRedisProvider.Instance.Get<List<DeviceInfo>>(redisCacheDeviceInfoHashKeyTemp);
if (deviceInfos == null || deviceInfos.Count <= 0)
{
deviceInfos = new List<DeviceInfo>();
deviceInfos.Add(new DeviceInfo()
{
Baudrate = 2400,
FocusAddress = "322011149",
Name = "LXSY-25E 保利",
FocusId = 57675,
DatabaseBusiID = 1,
MeteringCode = 0,
MeterAddress = "341587000473",
MeterId = 1025,
TypeName = 1,
TimeDensity = 60,
BrandType = "云集",
MeterType = MeterTypeEnum.WaterMeter,
ProjectID = 1,
MeteringPort = MeteringPortConst.MeteringPortTwo,
Password = "000000",
LinkType = "RS-485",
TimesRate = 1.0000m,
});
}
return deviceInfos;
#else
string sql = $@"SELECT
A.ID as MeterId,
A.Name,
@ -575,7 +607,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
A.LinkType,
A.HaveValve,
A.MeterType AS MeterTypeName,
A.MeterBrand,
A.MeterBrand AS BrandType,
A.TimesRate,
A.TimeDensity,
A.TripState,
@ -602,6 +634,7 @@ namespace JiShe.CollectBus.ScheduledMeterReading
return await SqlProvider.Instance.Change(DbEnum.EnergyDB)
.Ado
.QueryAsync<DeviceInfo>(sql);
#endif
}
catch (Exception)
{

View File

@ -47,13 +47,6 @@ namespace JiShe.CollectBus.IotSystems.Devices
/// </summary>
public string MeterTypeName { get; set; }
/// <summary>
/// 设备品牌;
/// (当 MeterType = 水表, 如 威铭、捷先 等)
/// (当 MeterType = 流量计, 如 西恩超声波流量计、西恩电磁流量计、涡街流量计 等)
/// </summary>
public string MeterBrand { get; set; }
/// <summary>
/// 倍率
/// </summary>
@ -75,7 +68,7 @@ namespace JiShe.CollectBus.IotSystems.Devices
public string AreaCode { get; set; }
/// <summary>
/// 电表类别 1单相、2三相三线、3三相四线,
/// 仅当MeterType为电表时电表类别 1单相、2三相三线、3三相四线,
/// 07协议 开合闸指令(1A开闸断电,1C单相表合闸,1B多相表合闸) 645 2007 表
/// 97协议//true(合闸);false(跳闸) 545 1997 没有单相多相 之分 "true" ? "9966" : "3355"
/// </summary>

View File

@ -265,5 +265,79 @@ namespace JiShe.CollectBus.Common.Extensions
}
return DateTime.TryParseExact(dateLong.ToString(), "yyyyMMdd HHmmssZZ", null, System.Globalization.DateTimeStyles.None, out DateTime date) ? date : throw new ArgumentException("Date must be between 10000101 and 99991231.");
}
/// <summary>
/// 取得某月的第一天
/// </summary>
/// <param name="datetime">要取得月份第一天的时间</param>
/// <returns></returns>
public static DateTime FirstDayOfMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day);
}
///<summary>
/// 取得某月的最后一天
/// </summary>
/// <param name="datetime">要取得月份最后一天的时间</param>
/// <returns></returns>
public static DateTime LastDayOfMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
}
/// <summary>
/// 取得上个月第一天
/// </summary>
/// <param name="datetime">要取得上个月第一天的当前时间</param>
/// <returns></returns>
public static DateTime FirstDayOfPreviousMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day).AddMonths(-1);
}
/// <summary>
/// 取得上个月的最后一天
/// </summary>
/// <param name="datetime">要取得上个月最后一天的当前时间</param>
/// <returns></returns>
public static DateTime LastDayOfPrdviousMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day).AddDays(-1);
}
/// <summary>
/// 取得某月第一天0点以及最后一天的23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetMonthDateRange(this DateTime datetime)
{
var lastDayOfMonthDate = LastDayOfMonth(datetime);
return new Tuple<DateTime, DateTime>(datetime.FirstDayOfMonth(), new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
}
/// <summary>
/// 取得某一天0点到当月最后一天的23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetCurrentDateToLastDayRange(this DateTime datetime)
{
var lastDayOfMonthDate = LastDayOfMonth(datetime);
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
}
/// <summary>
/// 取得某一天0点到23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetCurrentDateRange(this DateTime datetime)
{
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(datetime.Year, datetime.Month, datetime.Day, 23, 59, 59));
}
}
}

View File

@ -136,57 +136,7 @@ namespace JiShe.CollectBus.Common.Helpers
return objModel;
}
/// <summary>
/// 取得某月的第一天
/// </summary>
/// <param name="datetime">要取得月份第一天的时间</param>
/// <returns></returns>
public static DateTime FirstDayOfMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day);
}
///<summary>
/// 取得某月的最后一天
/// </summary>
/// <param name="datetime">要取得月份最后一天的时间</param>
/// <returns></returns>
public static DateTime LastDayOfMonth(this DateTime datetime)
{
return datetime.AddDays(1 - datetime.Day).AddMonths(1).AddDays(-1);
}
/// <summary>
/// 取得某月第一天0点以及最后一天的23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetMonthDateRange(this DateTime datetime)
{
var lastDayOfMonthDate = LastDayOfMonth(datetime);
return new Tuple<DateTime, DateTime>(datetime.FirstDayOfMonth(), new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
}
/// <summary>
/// 取得某一天0点到当月最后一天的23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetCurrentDateToLastDayRange(this DateTime datetime)
{
var lastDayOfMonthDate = LastDayOfMonth(datetime);
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(lastDayOfMonthDate.Year, lastDayOfMonthDate.Month, lastDayOfMonthDate.Day, 23, 59, 59));
}
/// <summary>
/// 取得某一天0点到23:59:59时间范围
/// </summary>
/// <param name="datetime"></param>
/// <returns></returns>
public static Tuple<DateTime, DateTime> GetCurrentDateRange(this DateTime datetime)
{
return new Tuple<DateTime, DateTime>(datetime.Date, new DateTime(datetime.Year, datetime.Month, datetime.Day, 23, 59, 59));
}
/// <summary>
/// 获取指定枚举的所有 Attribute 说明以及value组成的键值对

View File

@ -23,8 +23,10 @@
},
"IoTDBOptions": {
"UserName": "root",
"Password": "Yp2eU6MVdIjXCL",
"ClusterList": [ "47.110.53.196:6667", "47.110.60.222:6667", "47.110.62.104:6667" ],
//"Password": "Yp2eU6MVdIjXCL",
//"ClusterList": [ "47.110.53.196:6667", "47.110.60.222:6667", "47.110.62.104:6667" ],
"Password": "root",
"ClusterList": [ "121.42.175.177:16667" ],
"PoolSize": 2,
"DataBaseName": "energy",
"OpenDebugMode": true,

View File

@ -26,7 +26,7 @@
"IoTDBOptions": {
"UserName": "root",
"Password": "root",
"ClusterList": [ "192.168.5.9:6667" ],
"ClusterList": [ "121.42.175.177:16667" ],
"PoolSize": 32,
"DataBaseName": "energy",
"OpenDebugMode": true,