Protocol376Simulator/Services/DeviceDataService.cs

191 lines
6.2 KiB
C#
Raw Permalink Normal View History

2025-05-08 17:26:10 +08:00
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 => "状态数据",
_ => "未知类型"
};
}
}
}