191 lines
6.2 KiB
C#
191 lines
6.2 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Serilog;
|
||
|
||
namespace Protocol376Simulator.Services
|
||
{
|
||
/// <summary>
|
||
/// 设备数据服务类,负责管理设备的业务数据
|
||
/// </summary>
|
||
public class DeviceDataService
|
||
{
|
||
private readonly string _deviceIdentifier;
|
||
private readonly Dictionary<byte, byte[]> _meterData = new Dictionary<byte, byte[]>();
|
||
private bool _valveStatus = false; // 阀门状态:false表示关闭,true表示打开
|
||
|
||
/// <summary>
|
||
/// 当数据更新时触发
|
||
/// </summary>
|
||
public event EventHandler<DataUpdateEventArgs> DataUpdated;
|
||
|
||
/// <summary>
|
||
/// 当阀门状态改变时触发
|
||
/// </summary>
|
||
public event EventHandler<bool> ValveStatusChanged;
|
||
|
||
/// <summary>
|
||
/// 阀门状态
|
||
/// </summary>
|
||
public bool ValveStatus
|
||
{
|
||
get => _valveStatus;
|
||
private set
|
||
{
|
||
if (_valveStatus != value)
|
||
{
|
||
_valveStatus = value;
|
||
ValveStatusChanged?.Invoke(this, _valveStatus);
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 数据更新事件参数
|
||
/// </summary>
|
||
public class DataUpdateEventArgs : EventArgs
|
||
{
|
||
public byte DataType { get; }
|
||
public byte[] Data { get; }
|
||
|
||
public DataUpdateEventArgs(byte dataType, byte[] data)
|
||
{
|
||
DataType = dataType;
|
||
Data = data;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 构造函数
|
||
/// </summary>
|
||
/// <param name="deviceIdentifier">设备标识(用于日志)</param>
|
||
public DeviceDataService(string deviceIdentifier)
|
||
{
|
||
_deviceIdentifier = deviceIdentifier;
|
||
|
||
// 初始化模拟数据
|
||
InitializeSimulatedData();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化模拟数据
|
||
/// </summary>
|
||
private void InitializeSimulatedData()
|
||
{
|
||
// 类型1:水表数据(模拟立方米读数)
|
||
_meterData[0x01] = new byte[] { 0x00, 0x00, 0x12, 0x34 }; // 1234 立方米
|
||
|
||
// 类型2:电表数据(模拟千瓦时读数)
|
||
_meterData[0x02] = new byte[] { 0x00, 0x01, 0x23, 0x45 }; // 12345 千瓦时
|
||
|
||
// 类型3:气表数据(模拟立方米读数)
|
||
_meterData[0x03] = new byte[] { 0x00, 0x00, 0x56, 0x78 }; // 5678 立方米
|
||
|
||
// 类型4:状态数据
|
||
_meterData[0x04] = new byte[] { 0x00, 0x01 }; // 状态码
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置表计数据
|
||
/// </summary>
|
||
/// <param name="dataType">数据类型</param>
|
||
/// <param name="data">数据内容</param>
|
||
public void SetMeterData(byte dataType, byte[] data)
|
||
{
|
||
if (data == null)
|
||
{
|
||
throw new ArgumentNullException(nameof(data));
|
||
}
|
||
|
||
_meterData[dataType] = data;
|
||
Log.Debug("{DeviceId} 已设置类型 {DataType} 的表计数据: {Data}",
|
||
_deviceIdentifier, dataType, BitConverter.ToString(data));
|
||
|
||
// 触发数据更新事件
|
||
DataUpdated?.Invoke(this, new DataUpdateEventArgs(dataType, data));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取表计数据
|
||
/// </summary>
|
||
/// <param name="dataType">数据类型</param>
|
||
/// <returns>数据内容</returns>
|
||
public byte[] GetMeterData(byte dataType)
|
||
{
|
||
if (_meterData.TryGetValue(dataType, out byte[] data))
|
||
{
|
||
return data;
|
||
}
|
||
|
||
// 如果没有指定类型的数据,返回空数组
|
||
Log.Warning("{DeviceId} 请求的数据类型 {DataType} 不存在", _deviceIdentifier, dataType);
|
||
return new byte[0];
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新阀门状态
|
||
/// </summary>
|
||
/// <param name="isOpen">阀门是否打开</param>
|
||
public void UpdateValveStatus(bool isOpen)
|
||
{
|
||
ValveStatus = isOpen;
|
||
Log.Information("{DeviceId} 阀门状态已更新为: {Status}",
|
||
_deviceIdentifier, isOpen ? "打开" : "关闭");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取所有表计数据类型
|
||
/// </summary>
|
||
/// <returns>数据类型列表</returns>
|
||
public IEnumerable<byte> GetAllDataTypes()
|
||
{
|
||
return _meterData.Keys;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否存在指定类型的数据
|
||
/// </summary>
|
||
/// <param name="dataType">数据类型</param>
|
||
/// <returns>是否存在</returns>
|
||
public bool HasData(byte dataType)
|
||
{
|
||
return _meterData.ContainsKey(dataType);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取设备数据状态的字符串表示
|
||
/// </summary>
|
||
/// <returns>格式化的数据状态</returns>
|
||
public string GetDataStatusReport()
|
||
{
|
||
var report = $"{_deviceIdentifier} 数据状态:\n";
|
||
report += $"阀门状态: {(ValveStatus ? "打开" : "关闭")}\n";
|
||
|
||
report += "表计数据:\n";
|
||
foreach (var entry in _meterData)
|
||
{
|
||
string typeName = GetDataTypeName(entry.Key);
|
||
string hexData = BitConverter.ToString(entry.Value);
|
||
report += $" 类型 {entry.Key} ({typeName}): {hexData}\n";
|
||
}
|
||
|
||
return report;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取数据类型的名称
|
||
/// </summary>
|
||
/// <param name="dataType">数据类型</param>
|
||
/// <returns>类型名称</returns>
|
||
private string GetDataTypeName(byte dataType)
|
||
{
|
||
return dataType switch
|
||
{
|
||
0x01 => "水表数据",
|
||
0x02 => "电表数据",
|
||
0x03 => "气表数据",
|
||
0x04 => "状态数据",
|
||
_ => "未知类型"
|
||
};
|
||
}
|
||
}
|
||
} |