Files

279 lines
8.5 KiB
C#
Raw Permalink Normal View History

2026-06-14 11:19:15 +08:00
using System;
using System.Collections.Generic;
using System.Linq;
using SimpleCore.Library;
namespace StandardScene.ExtendDevice.Door
{
/// <summary>
/// 门状态枚举
/// </summary>
public enum DoorState
{
/// <summary>
/// 关闭
/// </summary>
Closed = 0,
/// <summary>
/// 打开
/// </summary>
Open = 1,
/// <summary>
/// 未知状态
/// </summary>
Unknown = 2
}
/// <summary>
/// 门控制器状态枚举
/// </summary>
public enum DoorControllerState
{
/// <summary>
/// 离线
/// </summary>
Offline = 0,
/// <summary>
/// 在线
/// </summary>
Online = 1,
/// <summary>
/// 连接中
/// </summary>
Connecting = 2,
/// <summary>
/// 错误
/// </summary>
Error = 3
}
/// <summary>
/// 基础门控制器类
/// </summary>
public abstract class BasicDoorController
{
/// <summary>
/// 控制器索引
/// </summary>
public int Index { get; set; }
/// <summary>
/// IP地址
/// </summary>
public string Ip { get; set; } = string.Empty;
/// <summary>
/// 端口
/// </summary>
public int Port { get; set; } = 502;
/// <summary>
/// 控制器状态
/// </summary>
public DoorControllerState State { get; protected set; } = DoorControllerState.Offline;
/// <summary>
/// 是否在线
/// </summary>
public bool IsOnline => State == DoorControllerState.Online;
/// <summary>
/// 门状态字典,键为门索引
/// </summary>
public Dictionary<int, DoorState> DoorStates { get; protected set; } = new Dictionary<int, DoorState>();
/// <summary>
/// 门目标控制字典,键为门索引,值为期望的开关状态(true=打开,false=关闭)
/// 仅作为指令缓存,实际通信由具体门控制器内部线程完成
/// </summary>
public Dictionary<int, bool> DoorControlTargets { get; protected set; } = new Dictionary<int, bool>();
/// <summary>
/// 门配置信息字典,键为门索引
/// </summary>
public Dictionary<int, DoorModel> DoorConfigs { get; protected set; } = new Dictionary<int, DoorModel>();
/// <summary>
/// 最后更新时间
/// </summary>
public DateTime LastUpdateTime { get; protected set; } = DateTime.Now;
/// <summary>
/// 错误信息
/// </summary>
public string ErrorMessage { get; protected set; } = string.Empty;
/// <summary>
/// 更新控制器状态
/// </summary>
public virtual void UpdateState(DoorControllerState newState, string errorMessage = "")
{
State = newState;
ErrorMessage = errorMessage;
LastUpdateTime = DateTime.Now;
}
/// <summary>
/// 更新门状态
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <param name="state">门状态</param>
public virtual void UpdateDoorState(int doorIndex, DoorState state)
{
if (!DoorStates.ContainsKey(doorIndex))
{
Diagnosis.Post($"门控制器{Index}不存在门{doorIndex}");
}
DoorStates[doorIndex] = state;
LastUpdateTime = DateTime.Now;
}
/// <summary>
/// 获取门状态
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <returns>门状态,如果不存在则返回Unknown</returns>
public virtual DoorState GetDoorState(int doorIndex)
{
return DoorStates.TryGetValue(doorIndex, out var state) ? state : DoorState.Unknown;
}
/// <summary>
/// 初始化门状态
/// </summary>
/// <param name="doorIndices">门索引列表</param>
public virtual void InitializeDoors(List<int> doorIndices)
{
DoorStates.Clear();
DoorControlTargets.Clear();
foreach (var index in doorIndices)
{
DoorStates[index] = DoorState.Closed;
DoorControlTargets[index] = false;
}
}
/// <summary>
/// 初始化门配置信息
/// </summary>
/// <param name="doorConfigs">门配置列表</param>
public virtual void InitializeDoorConfigs(List<DoorModel> doorConfigs)
{
DoorConfigs.Clear();
if (doorConfigs != null)
{
foreach (var config in doorConfigs)
{
DoorConfigs[config.Index] = new DoorModel
{
Index = config.Index,
ControlAddress = config.ControlAddress,
OpenStatusAddress = config.OpenStatusAddress,
NoControl = config.NoControl
};
}
}
}
/// <summary>
/// 更新门配置信息
/// </summary>
/// <param name="doorConfigs">门配置列表</param>
public virtual void UpdateDoorConfigs(List<DoorModel> doorConfigs)
{
if (doorConfigs == null)
{
DoorConfigs.Clear();
return;
}
// 创建配置字典
var configDict = doorConfigs.ToDictionary(d => d.Index);
// 删除配置中不存在的门
var toRemove = DoorConfigs.Keys.Where(k => !configDict.ContainsKey(k)).ToList();
foreach (var key in toRemove)
{
DoorConfigs.Remove(key);
}
// 添加或更新门配置
foreach (var config in doorConfigs)
{
DoorConfigs[config.Index] = new DoorModel
{
Index = config.Index,
ControlAddress = config.ControlAddress,
OpenStatusAddress = config.OpenStatusAddress,
NoControl = config.NoControl
};
}
}
/// <summary>
/// 获取门配置信息
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <returns>门配置信息,如果不存在则返回null</returns>
public virtual DoorModel GetDoorConfig(int doorIndex)
{
return DoorConfigs.TryGetValue(doorIndex, out var config) ? config : null;
}
/// <summary>
/// 设置门的目标控制状态(仅修改内存字段,不直接进行通信)
/// 实际的通信写入由具体门控制器在内部线程中根据该目标状态执行
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <param name="open">true=打开,false=关闭</param>
public virtual void SetDoorControlTarget(int doorIndex, bool open)
{
// 统一支持 NoControl:当门被配置为不允许发送任何控制指令时,
// 强制将目标置为 false,并避免为其它控制器留下“需要开门”的目标。
if (DoorConfigs.TryGetValue(doorIndex, out var cfg) && cfg != null && cfg.NoControl)
{
DoorControlTargets[doorIndex] = false;
LastUpdateTime = DateTime.Now;
return;
}
DoorControlTargets[doorIndex] = open;
LastUpdateTime = DateTime.Now;
}
/// <summary>
/// 连接门控制器
/// </summary>
public virtual void Connect()
{
UpdateState(DoorControllerState.Connecting);
}
/// <summary>
/// 断开连接
/// </summary>
public virtual void Disconnect()
{
UpdateState(DoorControllerState.Offline);
}
/// <summary>
/// 读取门状态(开到位信号)
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <returns>门状态</returns>
public abstract bool ReadDoorState(int doorIndex);
/// <summary>
/// 写入门控制信号(开关控制)
/// </summary>
/// <param name="doorIndex">门索引</param>
/// <param name="open">true=打开,false=关闭</param>
public abstract void WriteDoorControl(int doorIndex, bool open);
}
}