2025-01-19 22:54:28 +08:00
|
|
|
|
using JiShe.CollectBus.Common.Enums;
|
|
|
|
|
|
using JiShe.CollectBus.Common.Extensions;
|
|
|
|
|
|
using JiShe.CollectBus.Common.Models;
|
|
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
2025-02-27 17:02:50 +08:00
|
|
|
|
using System.Data;
|
|
|
|
|
|
using System.Reflection.Metadata;
|
2025-01-19 22:54:28 +08:00
|
|
|
|
using static System.Runtime.InteropServices.JavaScript.JSType;
|
|
|
|
|
|
|
|
|
|
|
|
namespace JiShe.CollectBus.Common.BuildSendDatas
|
|
|
|
|
|
{
|
|
|
|
|
|
public static class Build645SendData
|
|
|
|
|
|
{
|
|
|
|
|
|
//起始字符
|
|
|
|
|
|
private const string startStr = "68";
|
|
|
|
|
|
//结束字符
|
|
|
|
|
|
private const string endStr = "16";
|
|
|
|
|
|
|
|
|
|
|
|
#region 645下行命令
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表阀控下发数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="specialControlCode">特殊控制码</param>
|
|
|
|
|
|
/// <param name="password">密码</param>
|
|
|
|
|
|
/// <param name="state">是否为开阀</param>
|
|
|
|
|
|
/// <param name="modelCode">型号码</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterValveControlSendDataUnit(string ammeterAddress, string specialControlCode, string password, bool state, string modelCode = "")
|
|
|
|
|
|
{
|
|
|
|
|
|
var code = string.Empty;
|
|
|
|
|
|
|
|
|
|
|
|
if (state)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (string.IsNullOrEmpty(specialControlCode))
|
|
|
|
|
|
code = "1B";
|
|
|
|
|
|
else
|
|
|
|
|
|
code = specialControlCode == "1B" || specialControlCode == "1C" ? specialControlCode : "1C";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
code = "1A";//跳闸
|
|
|
|
|
|
|
|
|
|
|
|
if (specialControlCode == "1W")
|
|
|
|
|
|
{
|
|
|
|
|
|
if (state)
|
|
|
|
|
|
code = "1A";
|
|
|
|
|
|
else
|
|
|
|
|
|
code = "1C";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var pwdLevel = "02";
|
|
|
|
|
|
if (modelCode == "HL_DTSU2625" || modelCode == "DDZY9866")
|
|
|
|
|
|
pwdLevel = "04";
|
|
|
|
|
|
else if (modelCode == "DDS2705")
|
|
|
|
|
|
pwdLevel = "03"; //不带安全认证密级
|
|
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrWhiteSpace(password) && password.Contains("|"))
|
|
|
|
|
|
{
|
|
|
|
|
|
var sp = password.Split('|');
|
|
|
|
|
|
pwdLevel = sp[1];
|
|
|
|
|
|
password = sp[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var strDate = DateTime.Now.AddYears(3).ToString("000012ddMMyy").StrAddSpan();//命令有效截止时间
|
|
|
|
|
|
if (specialControlCode == "1D" || modelCode == "SZBD_DDZY1225")
|
|
|
|
|
|
strDate = "FF FF FF FF FF FF";
|
|
|
|
|
|
var strP = password.StrAddSpan().StrReverseOrder();
|
|
|
|
|
|
var strSJY = " " + pwdLevel + " " + strP + " 01 00 00 00 " + code + " 00 " + strDate;
|
|
|
|
|
|
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "1C", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
|
|
|
|
|
|
//string strLen = (strSJY.Replace(" ", "").Length / 2).ToString("X2");
|
|
|
|
|
|
//string strReturn = "68 " + address.StrAddSpan().StrReverseOrder() + " 68 1C " + strLen + " " + strSJY.StrAddHex33() + " ";
|
|
|
|
|
|
//string strSum = strReturn.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries).Select(i => Convert.ToInt32(i, 16)).Sum().ToString("X");
|
|
|
|
|
|
//strReturn += strSum.Substring(strSum.Length - 2) + " 16";
|
|
|
|
|
|
//return strReturn.Split(' ').ToList();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表保电下发数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="state">true 保电 false 保电解除</param>
|
|
|
|
|
|
/// <param name="modelCode">型号码</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterLockSendDataUnit(string ammeterAddress, string password, bool state, string modelCode = "")
|
|
|
|
|
|
{
|
|
|
|
|
|
var code = state ? "3A" : "3B";
|
|
|
|
|
|
|
|
|
|
|
|
var strDate = (code + DateTime.Now.AddDays(1).ToString("00000012ddMMyy")).StrAddSpan();
|
|
|
|
|
|
|
|
|
|
|
|
if (modelCode == "SZBD_DDZY1225")
|
|
|
|
|
|
strDate = $"{code} 00 FF FF FF FF FF FF";
|
|
|
|
|
|
|
|
|
|
|
|
var strP = password.StrAddSpan().StrReverseOrder();
|
|
|
|
|
|
var strSJY = " 02 " + strP + " 01 00 00 00 " + strDate;
|
|
|
|
|
|
|
|
|
|
|
|
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "1C", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表认证下发数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="ramDon"></param>
|
|
|
|
|
|
/// <param name="maco"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterIdentitySendDataUnit(string ammeterAddress, string ramDon, string maco)
|
|
|
|
|
|
{
|
|
|
|
|
|
var codeList = "070004FF".StringToPairs();
|
|
|
|
|
|
codeList.Reverse();
|
|
|
|
|
|
|
|
|
|
|
|
var ramDonList = ramDon.StringToPairs();
|
|
|
|
|
|
ramDonList.Reverse();
|
|
|
|
|
|
|
|
|
|
|
|
var macoList = maco.StringToPairs();
|
|
|
|
|
|
macoList.Reverse();
|
|
|
|
|
|
|
|
|
|
|
|
var dataUnit = new List<string>();
|
|
|
|
|
|
dataUnit.AddRange(codeList);
|
|
|
|
|
|
dataUnit.AddRange(ramDonList);
|
|
|
|
|
|
dataUnit.AddRange(macoList);
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "03", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表清零下发数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterClearSendDataUnit(string ammeterAddress, string password)
|
|
|
|
|
|
{
|
|
|
|
|
|
var strP = password.StrAddSpan().StrReverseOrder();
|
|
|
|
|
|
var strSJY = " 02 " + strP + " 01 00 00 00 ";
|
|
|
|
|
|
var dataUnit = strSJY.Replace(" ", "").StringToPairs();
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "1A", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 透明转发 表计校时/广播校时 F10-104
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="s_operator"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="cmdType">类型 0:日期部分指令,1,时间部分指令</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
|
|
|
|
/// <exception cref="Exception"></exception>
|
|
|
|
|
|
public static List<string> BuildAmmeterCorrectionTimeSendDataUnit(string ammeterAddress,string password, string dataMark, int cmdType, string s_operator = "00000001")
|
|
|
|
|
|
{
|
|
|
|
|
|
List<string> dataUnit = new List<string>();
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(password))
|
|
|
|
|
|
password = "000000";
|
|
|
|
|
|
if (password?.Length != 6)
|
|
|
|
|
|
password = password.PadLeft(6, '0');
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(s_operator) || s_operator?.Length != 8)
|
|
|
|
|
|
throw new ArgumentNullException("电表操作人员格式不能为空或长度不等6位");
|
|
|
|
|
|
|
|
|
|
|
|
//数据标识 DIODI1DI2DI3+PAP0P1P2+C0C1C2C3+DATA
|
|
|
|
|
|
var dataMarks = dataMark.Split(' ').ToList();
|
|
|
|
|
|
dataMarks.Reverse();
|
|
|
|
|
|
dataUnit.AddRange(dataMarks);//数据标识
|
|
|
|
|
|
|
|
|
|
|
|
//密码权限 02明文 PAP0P1P2
|
|
|
|
|
|
var passsList = password.StringToPairs(true);
|
|
|
|
|
|
dataUnit.Add("02");//--密码权限 02明文
|
|
|
|
|
|
foreach (var item in passsList)
|
|
|
|
|
|
{
|
|
|
|
|
|
dataUnit.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
//操作人员 C0C1C2C3
|
|
|
|
|
|
var opers = s_operator.StringToPairs(true);
|
|
|
|
|
|
foreach (var item in opers)
|
|
|
|
|
|
{
|
|
|
|
|
|
dataUnit.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
//数据体 DATA
|
|
|
|
|
|
List<string> datas = null;
|
|
|
|
|
|
switch (cmdType)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 0:
|
|
|
|
|
|
datas = Date_MeterTiming();
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
datas = Time_MeterTiming();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (datas == null)
|
|
|
|
|
|
throw new Exception($"透明转发 表计校时/广播校时生成的数据内容为空");
|
|
|
|
|
|
datas.Reverse();
|
|
|
|
|
|
dataUnit.AddRange(datas);
|
|
|
|
|
|
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "14", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 设置尖峰平谷时段 F10-103
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
/// <param name="s_operator"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="ArgumentNullException"></exception>
|
|
|
|
|
|
public static List<string> BuildAmmeterTimeSetSendDataUnit(string ammeterAddress,string password, string dataMark,string data, string s_operator= "00000001")
|
|
|
|
|
|
{
|
2025-02-27 17:02:50 +08:00
|
|
|
|
var datas = data.Split(' ').ToList();
|
|
|
|
|
|
datas.Reverse();
|
|
|
|
|
|
List<string> dataUnit = BuildAmmeterTimeSetDataUnit(password, dataMark, datas);
|
2025-01-19 22:54:28 +08:00
|
|
|
|
|
2025-02-27 17:02:50 +08:00
|
|
|
|
List<string> dataList = new List<string>();
|
|
|
|
|
|
dataList.Add("68");
|
|
|
|
|
|
dataList.AddRange(ammeterAddress.PadLeft(12, '0').StringToPairs(true));
|
|
|
|
|
|
dataList.Add("68");
|
|
|
|
|
|
dataList.Add("14");//控制码
|
|
|
|
|
|
//transpond.Operator = "01000000";
|
|
|
|
|
|
dataList.Add(dataUnit.Count.DecToHex().PadLeft(2, '0'));//数据域长度
|
|
|
|
|
|
dataList.AddRange(dataUnit);
|
|
|
|
|
|
var csSum = HexStringExtensions.GetCRC(dataList);// GetCheckSumsHexString(string.Join("", content).StringToHexByte());
|
|
|
|
|
|
dataList.Add(csSum);
|
|
|
|
|
|
dataList.Add("16");
|
2025-01-19 22:54:28 +08:00
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
2025-02-27 17:02:50 +08:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 工具生成指令 F10 103
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="cmd"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> GenerateContent(string ammeterAddress, string cmd)
|
|
|
|
|
|
{
|
|
|
|
|
|
//替换表计地址
|
|
|
|
|
|
var meterAddress = ammeterAddress.PadLeft(12, '0').StringToPairs(true);
|
|
|
|
|
|
var cmdArr = cmd.Replace(" ", "").StringToPairs(true);
|
|
|
|
|
|
cmdArr.RemoveRange(1, 6);
|
|
|
|
|
|
cmdArr.InsertRange(1, meterAddress);
|
|
|
|
|
|
//替换校验码
|
|
|
|
|
|
var csSum = HexStringExtensions.GetCRC(cmdArr); //GetCheckSumsHexString(string.Join("", cmdArr.Take(cmdArr.Count - 2)).StringToHexByte());
|
|
|
|
|
|
cmdArr.RemoveRange(cmdArr.Count - 2, 2);
|
|
|
|
|
|
cmdArr.Add(csSum);
|
|
|
|
|
|
|
|
|
|
|
|
cmdArr.Add("16");
|
|
|
|
|
|
|
|
|
|
|
|
return cmdArr;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// AFN16_F106
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="comandCodeEnum"></param>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="cmd"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterGenerateBCCommand(ComandCodeEnum comandCodeEnum,string ammeterAddress,string cmd, string password, string dataMark, string data)
|
2025-01-19 22:54:28 +08:00
|
|
|
|
{
|
2025-02-27 17:02:50 +08:00
|
|
|
|
List<string> content = new List<string>();
|
|
|
|
|
|
var meterAddress = ammeterAddress.PadLeft(12, '0').StringToPairs(true);
|
|
|
|
|
|
if (comandCodeEnum == ComandCodeEnum.SpecialMeter_A)
|
|
|
|
|
|
{
|
|
|
|
|
|
//编程指令
|
|
|
|
|
|
//TODO:替换表计地址
|
|
|
|
|
|
var cmdArr = cmd.Replace(" ", "").StringToPairs();
|
|
|
|
|
|
cmdArr.RemoveRange(1, 6);
|
|
|
|
|
|
cmdArr.InsertRange(1, meterAddress);
|
|
|
|
|
|
//TODO:替换校验码
|
|
|
|
|
|
var csSum = HexStringExtensions.GetCRC(cmdArr); //GetCheckSumsHexString(string.Join("", cmdArr).StringToHexByte());
|
|
|
|
|
|
cmdArr.Add(csSum);
|
|
|
|
|
|
cmdArr.Add("16");
|
|
|
|
|
|
return cmdArr;
|
|
|
|
|
|
}
|
|
|
|
|
|
else if(comandCodeEnum == ComandCodeEnum.SpecialMeter_B)
|
|
|
|
|
|
{
|
|
|
|
|
|
content.Add("68");
|
|
|
|
|
|
content.AddRange(meterAddress);
|
|
|
|
|
|
content.Add("68");
|
|
|
|
|
|
content.Add("14");//控制码
|
|
|
|
|
|
//transpond.Operator = "01000000";
|
|
|
|
|
|
var datas = data.StringToPairs(true);
|
|
|
|
|
|
var dataUnit = BuildAmmeterTimeSetDataUnit(password, dataMark, datas);
|
|
|
|
|
|
content.Add(dataUnit.Count.DecToHex().PadLeft(2, '0'));//数据域长度
|
|
|
|
|
|
content.AddRange(dataUnit);
|
|
|
|
|
|
var csSum = HexStringExtensions.GetCRC(content); //GetCheckSumsHexString(string.Join("", content).StringToHexByte());
|
|
|
|
|
|
content.Add(csSum);
|
|
|
|
|
|
content.Add("16");
|
|
|
|
|
|
}
|
|
|
|
|
|
return content;
|
2025-01-19 22:54:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表读取下发数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="cmdType">功率读取 余额读取</param>
|
|
|
|
|
|
/// <param name="dataId">数据标识</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterReadDataUnit(string ammeterAddress, CmdType cmdType, string dataId = "")
|
|
|
|
|
|
{
|
|
|
|
|
|
var dn = "";
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(dataId))
|
|
|
|
|
|
{
|
|
|
|
|
|
if (cmdType == CmdType.PowerRead) dn = "04090B01";
|
|
|
|
|
|
else if (cmdType == CmdType.BalanceRead) dn = "00900200";
|
|
|
|
|
|
else if (cmdType == CmdType.CurrentRead) dn = "04090801";
|
|
|
|
|
|
else if (cmdType == CmdType.WsPowerDown) dn = "0E300103";
|
|
|
|
|
|
else if (cmdType == CmdType.ReadMeterStatus) dn = "04000503";
|
|
|
|
|
|
else if (cmdType == CmdType.TimeSet) dn = "04010001";//主用第一套时段数据
|
|
|
|
|
|
else if (cmdType == CmdType.ReadTimeSetMonth) dn = "04010000";//主用时区数据
|
|
|
|
|
|
else if (cmdType == CmdType.ReadTimeSetNum) dn = "04000202";//日时段数
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
dn = dataId;
|
|
|
|
|
|
|
|
|
|
|
|
var dataUnit = dn.StringToPairs(true);
|
|
|
|
|
|
|
|
|
|
|
|
var dataList = Build645SendCommand(ammeterAddress, "11", dataUnit);
|
|
|
|
|
|
return dataList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表修正时间下发命令-PMAC9523
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildPMAC9523AmmeterCorrectionTimeSendDataUnit(string ammeterAddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
|
var year = (now.Year - 2000).ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var month = now.Month.ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var day = now.Day.ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var hour = now.Hour.ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var minute = now.Minute.ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var second = now.Second.ToString("X2").PadLeft(4, '0');
|
|
|
|
|
|
var adress = int.Parse(ammeterAddress.Substring(ammeterAddress.Length - 3)).DecToHex().PadLeft(2, '0');
|
|
|
|
|
|
var fm = new List<string>() { adress, "10", "23", "35", "00", "06", "0C" };
|
|
|
|
|
|
fm.AddRange($"{second}{minute}{hour}{day}{month}{year}".StringToPairs());
|
|
|
|
|
|
|
|
|
|
|
|
var bts = fm.Select(s => s.HexToDec()).Select(s => byte.Parse(s.ToString())).ToArray();
|
|
|
|
|
|
var getCrc = HexStringExtensions.GetCRC16(bts, true).Select(s => int.Parse(s.ToString()).DecToHex().PadLeft(2, '0'));//long.Parse ?
|
|
|
|
|
|
fm.AddRange(getCrc);
|
|
|
|
|
|
|
|
|
|
|
|
return fm;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表修正时间下发命令-DTSU193
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildDTSU193AmmeterCorrectionTimeSendDataUnit(string ammeterAddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
|
var year = now.Year.ToString().Substring(2);
|
|
|
|
|
|
var month = now.Month.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var day = now.Day.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var week = ((int)now.DayOfWeek).ToString().PadLeft(2, '0');
|
|
|
|
|
|
var hour = now.Hour.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var minute = now.Minute.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var second = now.Second.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var fm = GenerateCTCommand(ammeterAddress, $"{year}{month}{day}{week}{hour}{minute}{second}");
|
|
|
|
|
|
return fm;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表修正时间下发命令
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<List<string>> BuildAmmeterCorrectionTimeSendDataUnit(string ammeterAddress,string password)
|
|
|
|
|
|
{
|
|
|
|
|
|
var listDataUnit = new List<List<string>>();
|
|
|
|
|
|
|
|
|
|
|
|
var now = DateTime.Now;
|
|
|
|
|
|
var year = now.Year.ToString().PadLeft(4, '0');
|
|
|
|
|
|
var month = now.Month.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var day = now.Day.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var week = ((int)now.DayOfWeek).ToString().PadLeft(2, '0');
|
|
|
|
|
|
var hour = now.Hour.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var minute = now.Minute.ToString().PadLeft(2, '0');
|
|
|
|
|
|
var second = now.Second.ToString().PadLeft(2, '0');
|
|
|
|
|
|
|
|
|
|
|
|
//组装数据域
|
|
|
|
|
|
List<string> dataList = new List<string>();
|
|
|
|
|
|
var dataMarkList = "04000101".StringToPairs(true);
|
|
|
|
|
|
dataList.AddRange(dataMarkList);
|
|
|
|
|
|
dataList.Add("02");
|
|
|
|
|
|
if (string.IsNullOrEmpty(password))
|
|
|
|
|
|
password = "000000";
|
|
|
|
|
|
var passwordList = password.StringToPairs(true);
|
|
|
|
|
|
dataList.AddRange(passwordList);
|
|
|
|
|
|
dataList.AddRange("00000000".StringToPairs(true));
|
|
|
|
|
|
dataList.AddRange($"{year}{month}{day}{week}".StringToPairs(true));
|
|
|
|
|
|
|
|
|
|
|
|
var fm = Build645SendCommand(ammeterAddress, "14", dataList);
|
|
|
|
|
|
listDataUnit.Add(fm);
|
|
|
|
|
|
|
|
|
|
|
|
dataList = new List<string>();
|
|
|
|
|
|
dataMarkList = "04000102".StringToPairs(true);
|
|
|
|
|
|
dataList.AddRange(dataMarkList);
|
|
|
|
|
|
dataList.Add("02");
|
|
|
|
|
|
dataList.AddRange(passwordList);
|
|
|
|
|
|
dataList.AddRange("00000000".StringToPairs(true));
|
|
|
|
|
|
dataList.AddRange($"{hour}{minute}{second}".StringToPairs(true));
|
|
|
|
|
|
var fm2 = Build645SendCommand(ammeterAddress, "14", dataList);
|
|
|
|
|
|
listDataUnit.Add(fm2);
|
|
|
|
|
|
|
|
|
|
|
|
return listDataUnit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
///
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildPMAC9523ReadMeterTimeSetSendDataUnit(string ammeterAddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
//LogHelper.LogStr("ReadMeterTimeSet", $"表编号[{meterInfo.meter_address}]进入PMAC9523时段设置");
|
|
|
|
|
|
var adress = int.Parse(ammeterAddress.Substring(ammeterAddress.Length - 3)).DecToHex().PadLeft(2, '0');
|
|
|
|
|
|
var fm = new List<string>() { adress, "03", "55", "F9", "00", "28" };
|
|
|
|
|
|
var bts = fm.Select(s => s.HexToDec()).Select(s => byte.Parse(s.ToString())).ToArray();
|
|
|
|
|
|
var getCrc = HexStringExtensions.GetCRC16(bts, true)
|
|
|
|
|
|
.Select(s => int.Parse(s.ToString()).DecToHex().PadLeft(2, '0'));
|
|
|
|
|
|
fm.AddRange(getCrc);
|
|
|
|
|
|
return fm;
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表表号读取下发命令
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildAmmeterReadNumSendCmd(string ammeterAddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dataUnit = "04000402".StringToPairs(true);
|
|
|
|
|
|
return Build645SendCommand(ammeterAddress, "11", dataUnit);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static List<List<string>> BuildPMAC9523AmmeterSetTimeSetSendDataUnit(string ammeterAddress, List<TimeSetDetail> data)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<List<string>> dataUnitList = new List<List<string>>();
|
|
|
|
|
|
var adress = int.Parse(ammeterAddress.Substring(ammeterAddress.Length - 3)).DecToHex().PadLeft(2, '0');
|
|
|
|
|
|
//第一步启用复费率编程:寄存器64503,写数据01启动编程
|
|
|
|
|
|
var fm = new List<string>() { adress, "10", "FB", "F6", "00", "01", "02", "00", "01" };
|
|
|
|
|
|
var bts = fm.Select(s => s.HexToDec()).Select(s => byte.Parse(s.ToString())).ToArray();
|
|
|
|
|
|
var getCrc = HexStringExtensions.GetCRC16(bts, true).Select(s => int.Parse(s.ToString()).DecToHex().PadLeft(2, '0'));
|
|
|
|
|
|
fm.AddRange(getCrc);
|
|
|
|
|
|
dataUnitList.Add(fm);
|
|
|
|
|
|
|
|
|
|
|
|
//第二步写复费率模式:寄存器22002,写数据01固定一套费率
|
|
|
|
|
|
var fm2 = new List<string>() { adress, "10", "55", "F1", "00", "01", "02", "00", "01" };
|
|
|
|
|
|
var bts2 = fm2.Select(s => s.HexToDec()).Select(s => byte.Parse(s.ToString())).ToArray();
|
|
|
|
|
|
var getCrc2 = HexStringExtensions.GetCRC16(bts2, true).Select(s => int.Parse(s.ToString()).DecToHex().PadLeft(2, '0'));
|
|
|
|
|
|
fm2.AddRange(getCrc2);
|
|
|
|
|
|
dataUnitList.Add(fm2);
|
|
|
|
|
|
|
|
|
|
|
|
//第三步写时段参数:寄存器22010开始,后续多少个寄存器根据时段内容来。
|
|
|
|
|
|
var timeSetDetailList = data.FirstOrDefault().Data;
|
|
|
|
|
|
var fm3 = new List<string>() { adress, "10", "55", "F9", "00" };
|
|
|
|
|
|
//寄存器个数
|
|
|
|
|
|
var timeNum = timeSetDetailList.Sum(o => o.Times.Count);
|
|
|
|
|
|
fm3.Add($"{timeNum * 2 + 1:X2}");
|
|
|
|
|
|
//数据长度
|
|
|
|
|
|
fm3.Add($"{(timeNum * 2 + 1) * 2:X2}");
|
|
|
|
|
|
|
|
|
|
|
|
//时段个数
|
|
|
|
|
|
fm3.Add("00");
|
|
|
|
|
|
fm3.Add($"{timeNum:X2}");
|
|
|
|
|
|
Dictionary<string, string> setDic = new Dictionary<string, string>();
|
|
|
|
|
|
int rate = 0;
|
|
|
|
|
|
foreach (var item in timeSetDetailList)
|
|
|
|
|
|
{
|
|
|
|
|
|
int.TryParse(item.Rate, out rate);
|
|
|
|
|
|
foreach (var itemItem in item.Times)
|
|
|
|
|
|
{
|
|
|
|
|
|
fm3.Add("00");
|
|
|
|
|
|
fm3.Add($"{rate - 1:X2}");
|
|
|
|
|
|
fm3.Add("00");
|
|
|
|
|
|
fm3.Add($"{itemItem.StartTime.TakeTimeToInt():X2}");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
var bts3 = fm3.Select(s => s.HexToDec()).Select(s => byte.Parse(s.ToString())).ToArray();
|
|
|
|
|
|
var getCrc3 = HexStringExtensions.GetCRC16(bts3, true).Select(s => int.Parse(s.ToString()).DecToHex().PadLeft(2, '0'));
|
|
|
|
|
|
fm3.AddRange(getCrc3);
|
|
|
|
|
|
dataUnitList.Add(fm3);
|
|
|
|
|
|
|
|
|
|
|
|
return dataUnitList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// F1:透明转发 读取通信地址 04 00 04 01 NNNNNNNNNNNN 6 通信地址
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> BuildReadMeterAddressSendDataUnit(string ammeterAddress)
|
|
|
|
|
|
{
|
|
|
|
|
|
var dataMark = new List<string> { "04", "00", "04", "01" };
|
|
|
|
|
|
//content.AddRange(string.Join("", transpond.MeterAddress.Split(2, true)).PadRight(12, '0').Split(2, false));
|
|
|
|
|
|
dataMark.Reverse();
|
|
|
|
|
|
return Build645SendCommand(ammeterAddress, "11", dataMark);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建645协议下发命令
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress">电表地址</param>
|
|
|
|
|
|
/// <param name="controlCode">控制码</param>
|
|
|
|
|
|
/// <param name="dataUnit">数据域 发送方按字节进行加33处理,接收方按字节减33</param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> Build645SendCommand(string ammeterAddress, string controlCode, List<string>? dataUnit)
|
|
|
|
|
|
{
|
|
|
|
|
|
var cmdStrList = new List<string>();
|
|
|
|
|
|
cmdStrList.Add(startStr);
|
|
|
|
|
|
|
|
|
|
|
|
ammeterAddress = ammeterAddress.PadLeft(12, '0');
|
|
|
|
|
|
var addressList = ammeterAddress.StringToPairs();
|
|
|
|
|
|
addressList.Reverse();
|
|
|
|
|
|
cmdStrList.AddRange(addressList);
|
|
|
|
|
|
|
|
|
|
|
|
cmdStrList.Add(startStr);
|
|
|
|
|
|
|
|
|
|
|
|
cmdStrList.Add(controlCode);
|
|
|
|
|
|
|
|
|
|
|
|
var len = dataUnit != null ? dataUnit.Count.DecToHex().PadLeft(2, '0') : "00";
|
|
|
|
|
|
cmdStrList.Add(len);
|
|
|
|
|
|
|
|
|
|
|
|
if (dataUnit != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
cmdStrList.AddRange(dataUnit.AddHex33());
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var strSum = cmdStrList.Select(i => Convert.ToInt32(i, 16)).Sum().ToString("X");
|
|
|
|
|
|
strSum = strSum.Substring(strSum.Length - 2);
|
|
|
|
|
|
cmdStrList.Add(strSum);
|
|
|
|
|
|
cmdStrList.Add(endStr);
|
|
|
|
|
|
|
|
|
|
|
|
return cmdStrList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 威胜表的超功率(第一路恶性负载超功率判断阀值)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="power"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string>? AssembleWsSupperPower(string ammeterAddress, string password, string dataMark, decimal power)
|
|
|
|
|
|
{
|
|
|
|
|
|
power = Math.Round(power, 4);
|
|
|
|
|
|
if (power > (decimal)99.9999) return null;
|
|
|
|
|
|
var strPower = power < 10 ? $"0{power}" : power.ToString();
|
|
|
|
|
|
var pStr = strPower.Replace(".", "").PadRight(6, '0');
|
|
|
|
|
|
var data = new string[] { pStr[4] + "" + pStr[5], pStr[2] + "" + pStr[3], pStr[0] + "" + pStr[1] };
|
|
|
|
|
|
return AssembleWrite(ammeterAddress, password, dataMark, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 威胜表的超功率(超功率开关)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="isOn"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> AssembleWsOnSupperPower(string ammeterAddress, string password, bool isOn = true)
|
|
|
|
|
|
{
|
|
|
|
|
|
var data = new string[] { (isOn ? "01" : "00") };
|
|
|
|
|
|
return AssembleWrite(ammeterAddress, password, "0E400001", data);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 威胜表的超功率(第一路恶性负载绝对功率判断阈值)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="power"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string>? AssembleWsAbsolutePowerSetting(string ammeterAddress, string password, string dataMark, decimal power)
|
|
|
|
|
|
{
|
|
|
|
|
|
power = Math.Round(power, 4);
|
|
|
|
|
|
if (power > (decimal)99.9999) return null;
|
|
|
|
|
|
var strPower = power < 10 ? $"0{power}" : power.ToString();
|
|
|
|
|
|
var pStr = strPower.Replace(".", "").PadRight(6, '0');
|
|
|
|
|
|
var data = new string[] { pStr[4] + "" + pStr[5], pStr[2] + "" + pStr[3], pStr[0] + "" + pStr[1] };
|
|
|
|
|
|
return AssembleWrite(ammeterAddress, password, dataMark, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 威胜表的超功率(第一路恶性负载功率因数判断阀值)
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="factor"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string>? AssembleWsPowerFactor(string ammeterAddress, string password, string dataMark, decimal factor)
|
|
|
|
|
|
{
|
|
|
|
|
|
factor = Math.Round(factor, 3);
|
|
|
|
|
|
if (factor >= (decimal)1.0 || factor <= 0) return null;
|
|
|
|
|
|
var strFactor = factor.ToString();
|
|
|
|
|
|
var pStr = strFactor.Replace(".", "").PadRight(4, '0');
|
|
|
|
|
|
var data = new string[] { pStr[2] + "" + pStr[3], pStr[0] + "" + pStr[1] };
|
|
|
|
|
|
return AssembleWrite(ammeterAddress, password, dataMark, data);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建写数据
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="di0_3"></param>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> AssembleWrite(string ammeterAddress, string password, string di0_3, string[] data)
|
|
|
|
|
|
{
|
|
|
|
|
|
var returnList = new List<string>();
|
|
|
|
|
|
returnList.Add(startStr);
|
|
|
|
|
|
|
|
|
|
|
|
var addressList = ammeterAddress.StringToPairs();
|
|
|
|
|
|
addressList.Reverse();
|
|
|
|
|
|
returnList.AddRange(addressList);
|
|
|
|
|
|
|
|
|
|
|
|
returnList.Add(startStr);
|
|
|
|
|
|
returnList.Add("14");
|
|
|
|
|
|
|
|
|
|
|
|
var len = (12 + data.Length).ToString("X2");
|
|
|
|
|
|
returnList.Add(len);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var di03List = di0_3.StringToPairs();
|
|
|
|
|
|
di03List.Reverse();
|
|
|
|
|
|
di03List.Add("02");
|
|
|
|
|
|
|
|
|
|
|
|
var pwdList = password.StringToPairs();
|
|
|
|
|
|
pwdList.Reverse();
|
|
|
|
|
|
di03List.AddRange(pwdList);
|
|
|
|
|
|
|
|
|
|
|
|
var mList = new List<string>() { "00", "11", "22", "33" };
|
|
|
|
|
|
di03List.AddRange(mList);
|
|
|
|
|
|
di03List.AddRange(data);
|
|
|
|
|
|
var listAdd33 = di03List.AddHex33();
|
|
|
|
|
|
|
|
|
|
|
|
returnList.AddRange(listAdd33);
|
|
|
|
|
|
|
|
|
|
|
|
var strSum = returnList.Select(i => Convert.ToInt32(i, 16)).Sum().ToString("X");
|
|
|
|
|
|
var cs = strSum.Substring(strSum.Length - 2);
|
|
|
|
|
|
returnList.Add(cs);
|
|
|
|
|
|
returnList.Add(endStr);
|
|
|
|
|
|
|
|
|
|
|
|
return returnList;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 生成软编程指令
|
|
|
|
|
|
/// <param name="modelCode">型号编码</param>
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
public static List<string> SoftProgram(string ammeterAddress, string modelCode, string password)
|
|
|
|
|
|
{
|
|
|
|
|
|
string bccmd = string.Empty;
|
|
|
|
|
|
if (modelCode == "DDS71")
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
bccmd = "68 AA AA AA AA AA AA 68 04 07 4E F4 35 BB BB BB 32";
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
bccmd = "68 AA AA AA AA AA AA 68 14 10 41 35 33 41 37 33 33 33 34 33 33 33 77 66 55 44";
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//替换密码
|
|
|
|
|
|
var passwordList = password.StringToPairs();
|
|
|
|
|
|
passwordList.Reverse();
|
|
|
|
|
|
passwordList = passwordList.AddHex33();
|
|
|
|
|
|
var passwordStr = string.Join(" ", passwordList);
|
|
|
|
|
|
bccmd = bccmd.Replace("BB BB BB", passwordStr);
|
|
|
|
|
|
//替换表地址
|
|
|
|
|
|
var addressList = ammeterAddress.StringToPairs();
|
|
|
|
|
|
addressList.Reverse();
|
|
|
|
|
|
var addressStr = string.Join(" ", addressList);
|
|
|
|
|
|
bccmd = bccmd.Replace("AA AA AA AA AA AA", addressStr);
|
|
|
|
|
|
var fm = bccmd.Split(' ').ToList();
|
|
|
|
|
|
//生成CRC
|
|
|
|
|
|
var cRC = HexStringExtensions.GetCRC(fm);
|
|
|
|
|
|
fm.Add(cRC);
|
|
|
|
|
|
fm.Add("16");
|
|
|
|
|
|
|
|
|
|
|
|
return fm;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static List<string> GenerateCTCommand(string ammeterAddress, string data)
|
|
|
|
|
|
{
|
|
|
|
|
|
List<string> fm = new List<string>();
|
|
|
|
|
|
fm.Add(startStr);
|
|
|
|
|
|
List<string> addressList = ammeterAddress.StringToPairs();
|
|
|
|
|
|
addressList.Reverse();
|
|
|
|
|
|
fm.AddRange(addressList);
|
|
|
|
|
|
fm.Add(startStr);
|
|
|
|
|
|
fm.Add("14");
|
|
|
|
|
|
fm.Add("13");
|
|
|
|
|
|
fm.Add("3F");
|
|
|
|
|
|
fm.Add("34");
|
|
|
|
|
|
fm.Add("33");
|
|
|
|
|
|
fm.Add("37");
|
|
|
|
|
|
fm.Add("35");
|
|
|
|
|
|
fm.Add("33");
|
|
|
|
|
|
fm.Add("33");
|
|
|
|
|
|
fm.Add("33");
|
|
|
|
|
|
fm.Add("44");
|
|
|
|
|
|
fm.Add("44");
|
|
|
|
|
|
fm.Add("44");
|
|
|
|
|
|
fm.Add("44");
|
|
|
|
|
|
//组装数据域
|
|
|
|
|
|
var dataList = data.StringToPairs();
|
|
|
|
|
|
dataList.Reverse();
|
|
|
|
|
|
|
|
|
|
|
|
fm.AddRange(dataList.AddHex33());
|
|
|
|
|
|
|
|
|
|
|
|
var cRC = HexStringExtensions.GetCRC(fm);
|
|
|
|
|
|
fm.Add(cRC);
|
|
|
|
|
|
fm.Add(endStr);
|
|
|
|
|
|
return fm;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static List<string> Time_MeterTiming()
|
|
|
|
|
|
{
|
|
|
|
|
|
return new List<string>
|
|
|
|
|
|
{
|
|
|
|
|
|
DateTime.Now.Hour.ToString().PadLeft(2, '0'),
|
|
|
|
|
|
DateTime.Now.Minute.ToString().PadLeft(2, '0'),
|
|
|
|
|
|
(DateTime.Now.Second + 2).ToString().PadLeft(2, '0')
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private static List<string> Date_MeterTiming()
|
|
|
|
|
|
{
|
|
|
|
|
|
var week = (int)DateTime.Now.DayOfWeek;
|
|
|
|
|
|
var year = DateTime.Now.Year;
|
|
|
|
|
|
var month = DateTime.Now.Month;
|
|
|
|
|
|
var day = DateTime.Now.Day;
|
|
|
|
|
|
|
|
|
|
|
|
return new List<string>
|
|
|
|
|
|
{
|
|
|
|
|
|
year.ToString().Substring(2,2).PadLeft(2,'0'),
|
|
|
|
|
|
month.ToString().PadLeft(2,'0'),
|
|
|
|
|
|
day.ToString().PadLeft(2,'0'),
|
|
|
|
|
|
week.ToString().PadLeft(2,'0'),
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 构建电表时段设置数据单元
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
/// <param name="ammeterAddress"></param>
|
|
|
|
|
|
/// <param name="password"></param>
|
|
|
|
|
|
/// <param name="dataMark"></param>
|
|
|
|
|
|
/// <param name="data"></param>
|
|
|
|
|
|
/// <param name="s_operator"></param>
|
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
|
/// <exception cref="ArgumentNullException"></exception>
|
2025-02-27 17:02:50 +08:00
|
|
|
|
private static List<string> BuildAmmeterTimeSetDataUnit(string password, string dataMark, List<string> datas, string s_operator = "00000001")
|
2025-01-19 22:54:28 +08:00
|
|
|
|
{
|
|
|
|
|
|
List<string> dataUnit = new List<string>();
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(password))
|
|
|
|
|
|
password = "000000";
|
|
|
|
|
|
if (password?.Length != 6)
|
|
|
|
|
|
password = password.PadLeft(6, '0');
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(s_operator) || s_operator?.Length != 8)
|
|
|
|
|
|
throw new ArgumentNullException("电表操作人员格式不能为空或长度不等6位");
|
|
|
|
|
|
|
|
|
|
|
|
//数据标识 DIODI1DI2DI3+PAP0P1P2+C0C1C2C3+DATA
|
|
|
|
|
|
var dataMarks = dataMark.Split(' ').ToList();
|
|
|
|
|
|
dataMarks.Reverse();
|
|
|
|
|
|
dataUnit.AddRange(dataMarks);//数据标识
|
|
|
|
|
|
|
|
|
|
|
|
//密码权限 02明文 PAP0P1P2
|
|
|
|
|
|
var passs = password.StringToPairs(true);
|
|
|
|
|
|
dataUnit.Add("02");//--密码权限 02明文
|
|
|
|
|
|
foreach (var item in passs)
|
|
|
|
|
|
{
|
|
|
|
|
|
dataUnit.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
//操作人员 C0C1C2C3
|
|
|
|
|
|
var opers = s_operator.StringToPairs(true);
|
|
|
|
|
|
foreach (var item in opers)
|
|
|
|
|
|
{
|
|
|
|
|
|
dataUnit.Add(item);
|
|
|
|
|
|
}
|
|
|
|
|
|
//TODO:数据体 DATA
|
|
|
|
|
|
dataUnit.AddRange(datas);
|
|
|
|
|
|
return dataUnit;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|