Protocol376Simulator/Services/DeviceDataService.cs
2025-05-08 17:26:10 +08:00

191 lines
6.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 => "状态数据",
_ => "未知类型"
};
}
}
}