hwh
2024-09-06 ce6a232b55646e8d39cb0b4861ee363608b6f9aa
服务状态读数据库;报警复位功能
7个文件已修改
166 ■■■■ 已修改文件
Admin.NET/WCS.Application/Hub/PlcHub.cs 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/PLC/PLCUtil.cs 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/Config/SysConfigService.cs 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsAlarmInfo/Dto/WcsAlarmInfoInput.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs 35 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Web/src/views/device/alarmManage/index.vue 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Admin.NET/WCS.Application/Hub/PlcHub.cs
@@ -10,10 +10,11 @@
public class PlcHub : Hub<IPlcHub>
{
    private readonly IHubContext<PlcHub, IPlcHub> _plcHubContext;
    public PlcHub(IHubContext<PlcHub, IPlcHub> plcHubContext)
    private readonly SysConfigService _sysConfigService;
    public PlcHub(IHubContext<PlcHub, IPlcHub> plcHubContext, SysConfigService sysConfigService)
    {
        _plcHubContext = plcHubContext;
        _sysConfigService = sysConfigService;
    }
    /// <summary>
    /// 下发PLC连接状态
@@ -48,13 +49,20 @@
                PLCTaskAction.Init();
            else
                PLCTaskAction.Stop();
            await _sysConfigService.UpdateConfigValue("sys_RunningState", context.BoRunningState.Value);
        }
        //脱机模式
        if (context.BoOffline.HasValue)
        {
            PLCTaskAction.boOffline = context.BoOffline.Value;
            await _sysConfigService.UpdateConfigValue("sys_Offline", context.BoOffline.Value);
        }
        //自刷新
        if (context.BoRefresh.HasValue)
        {
            PLCTaskAction.boRefresh = context.BoRefresh.Value;
            await _sysConfigService.UpdateConfigValue("sys_Refresh", context.BoRefresh.Value);
        }
        await _plcHubContext.Clients.All.UpdateService(new PLCServiceModel() { BoRunningState = PLCTaskAction.boRunningState, BoRefresh = PLCTaskAction.boRefresh, BoOffline = PLCTaskAction.boOffline });
    }
}
Admin.NET/WCS.Application/PLC/PLCTaskAction.cs
@@ -19,6 +19,7 @@
    private static readonly ISqlSugarClient _db = SqlSugarSetup.ITenant.GetConnectionScope(SqlSugarConst.MainConfigId);
    private static readonly SysCacheService sysCacheService = App.GetRequiredService<SysCacheService>();
    private static readonly IHubContext<PlcHub, IPlcHub> _plcHubContext = App.GetService<IHubContext<PlcHub, IPlcHub>>();
    private static readonly SysConfigService _sysConfigService = App.GetService<SysConfigService>();
    private static List<WcsPlc> listPlc = new List<WcsPlc>();
    private static List<WcsDevice> listPlcDevice = new List<WcsDevice>();
@@ -37,6 +38,9 @@
    {
        //订阅事件
        DeviceValueChangeEvent += PLCService.OnChangeEvent;
        boRunningState = _sysConfigService.GetConfigValue<bool>("sys_RunningState").Result;
        boOffline = _sysConfigService.GetConfigValue<bool>("sys_Offline").Result;
        boRefresh = _sysConfigService.GetConfigValue<bool>("sys_Refresh").Result;
    }
    /// <summary>
    /// 初始化PLC连接
@@ -60,19 +64,21 @@
            var plc = new PLCUtil(modPlc);
            listPlcUtil.Add(plc);
        }
        cts = new CancellationTokenSource();
        boRunningState = true;
        _plcHubContext.Clients.All.UpdateService(new PLCServiceModel()
        {
            BoRunningState = boRunningState,
            BoOffline = boOffline,
            BoRefresh = boRefresh
        });
        if (boRunningState)
        {
            cts = new CancellationTokenSource();
        StartRead();
        ConnectionStatus();
        StartWatchAlarm();
        StartWatchPosition();
    }
    }
    /// <summary>
    /// 开启读取plc线程
    /// </summary>
Admin.NET/WCS.Application/PLC/PLCUtil.cs
@@ -53,41 +53,55 @@
                address = DbNumber + "." + Pos;
            else
                address = DbNumber + Pos;
            return this.GetPlcDBValue(PosType, address, Length);
        }
    }
    /// <summary>
    /// 读取PLC值
    /// </summary>
    /// <param name="PosType">字符类型</param>
    /// <param name="Pos">偏移量/地址</param>
    /// <param name="Length">长度(字符串)</param>
    /// <returns></returns>
    public (IoTClient.Result, dynamic value) GetPlcDBValue(PLCDataTypeEnum PosType, string Pos, int? Length = 0)
    {
        lock (OLock)
        {
            dynamic result = null;
            switch (PosType)
            {
                case PLCDataTypeEnum.Bit:
                    result = _client.ReadBoolean(address);
                    result = _client.ReadBoolean(Pos);
                    break;
                case PLCDataTypeEnum.Byte:
                    result = _client.ReadByte(address);
                    result = _client.ReadByte(Pos);
                    break;
                case PLCDataTypeEnum.Short:
                    result = _client.ReadInt16(address);
                    result = _client.ReadInt16(Pos);
                    break;
                case PLCDataTypeEnum.UShort:
                    result = _client.ReadUInt16(address);
                    result = _client.ReadUInt16(Pos);
                    break;
                case PLCDataTypeEnum.Int:
                    result = _client.ReadInt32(address);
                    result = _client.ReadInt32(Pos);
                    break;
                case PLCDataTypeEnum.UInt:
                    result = _client.ReadUInt32(address);
                    result = _client.ReadUInt32(Pos);
                    break;
                case PLCDataTypeEnum.Long:
                    result = _client.ReadInt64(address);
                    result = _client.ReadInt64(Pos);
                    break;
                case PLCDataTypeEnum.ULong:
                    result = _client.ReadUInt64(address);
                    result = _client.ReadUInt64(Pos);
                    break;
                case PLCDataTypeEnum.Float:
                    result = _client.ReadFloat(address);
                    result = _client.ReadFloat(Pos);
                    break;
                case PLCDataTypeEnum.Double:
                    result = _client.ReadDouble(address);
                    result = _client.ReadDouble(Pos);
                    break;
                case PLCDataTypeEnum.String:
                    result = _client.ReadString(address, Convert.ToUInt16(Length));
                    result = _client.ReadString(Pos, Convert.ToUInt16(Length));
                    break;
                default:
                    result = new IoTClient.Result<object>();
@@ -159,6 +173,13 @@
            address = DbNumber + "." + Pos;
        else
            address = DbNumber + Pos;
        return this.SetPlcDBValue(PosType, address, Pos, Value);
    }
    /// <summary>
    /// 写入PLC值
    /// </summary>
    public IoTClient.Result SetPlcDBValue(PLCDataTypeEnum PosType, string Pos, string Value)
    {
        switch (PosType)
        {
            case PLCDataTypeEnum.Bit:
@@ -173,25 +194,25 @@
                        throw new Exception("写入值错误");
                    }
                }
                return _client.Write(address, bit);
                return _client.Write(Pos, bit);
            case PLCDataTypeEnum.Byte:
                return _client.Write(address, byte.Parse(Value));
                return _client.Write(Pos, byte.Parse(Value));
            case PLCDataTypeEnum.Short:
                return _client.Write(address, short.Parse(Value));
                return _client.Write(Pos, short.Parse(Value));
            case PLCDataTypeEnum.UShort:
                return _client.Write(address, ushort.Parse(Value));
                return _client.Write(Pos, ushort.Parse(Value));
            case PLCDataTypeEnum.Int:
                return _client.Write(address, int.Parse(Value));
                return _client.Write(Pos, int.Parse(Value));
            case PLCDataTypeEnum.UInt:
                return _client.Write(address, uint.Parse(Value));
                return _client.Write(Pos, uint.Parse(Value));
            case PLCDataTypeEnum.Long:
                return _client.Write(address, long.Parse(Value));
                return _client.Write(Pos, long.Parse(Value));
            case PLCDataTypeEnum.ULong:
                return _client.Write(address, ulong.Parse(Value));
                return _client.Write(Pos, ulong.Parse(Value));
            case PLCDataTypeEnum.Float:
                return _client.Write(address, float.Parse(Value));
                return _client.Write(Pos, float.Parse(Value));
            case PLCDataTypeEnum.Double:
                return _client.Write(address, float.Parse(Value));
                return _client.Write(Pos, float.Parse(Value));
            default:
                return new IoTClient.Result();
        }
Admin.NET/WCS.Application/Service/Config/SysConfigService.cs
@@ -107,4 +107,21 @@
        _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}");
    }
    /// <summary>
    /// 更新参数配置值
    /// </summary>
    /// <param name="code"></param>
    /// <param name="value"></param>
    /// <returns></returns>
    [NonAction]
    public async Task UpdateConfigValue(string code, bool value)
    {
        var config = await _sysConfigRep.GetFirstAsync(u => u.Code == code);
        if (config == null) return;
        config.Value = value?"True":"False";
        await _sysConfigRep.AsUpdateable(config).ExecuteCommandAsync();
        _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}");
    }
}
Admin.NET/WCS.Application/Service/WcsAlarmInfo/Dto/WcsAlarmInfoInput.cs
@@ -200,3 +200,9 @@
{
}
public class ResetInput
{
    [Required(ErrorMessage = "楼层不能为空")]
    public int layer { get; set; }
}
Admin.NET/WCS.Application/Service/WcsAlarmInfo/WcsAlarmInfoService.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.SignalR;
using Admin.NET.Core.Service;
using Microsoft.AspNetCore.SignalR;
namespace WCS.Application;
@@ -10,10 +11,12 @@
{
    private readonly SqlSugarRepository<WcsAlarmInfo> _wcsAlarmInfoRep;
    private readonly IHubContext<PlcHub, IPlcHub> _plcHubContext;
    public WcsAlarmInfoService(SqlSugarRepository<WcsAlarmInfo> wcsAlarmInfoRep, IHubContext<PlcHub, IPlcHub> plcHubContext)
    private readonly SysDictDataService _dictDataService;
    public WcsAlarmInfoService(SqlSugarRepository<WcsAlarmInfo> wcsAlarmInfoRep, IHubContext<PlcHub, IPlcHub> plcHubContext, SysDictDataService dictDataService)
    {
        _wcsAlarmInfoRep = wcsAlarmInfoRep;
        _plcHubContext = plcHubContext;
        _dictDataService = dictDataService;
    }
    /// <summary>
@@ -121,13 +124,35 @@
    [HttpPost]
    [ApiDescriptionSettings(Name = "Reset")]
    [DisplayName("复位报警")]
    public async Task Reset()
    public async Task Reset(ResetInput input)
    {
        //测试推数据用的
        await _plcHubContext.Clients.All.PublicAlarm(new List<WcsAlarmInfo>() { new WcsAlarmInfo() { Id = 100, StationNum = "260", AlarmCode = "MB102", AlarmName = "有物品遮挡", AlarmTime = DateTime.Now, Status = YesNoEnum.N } });
        //await _plcHubContext.Clients.All.PublicAlarm(new List<WcsAlarmInfo>() { new WcsAlarmInfo() { Id = 100, StationNum = "260", AlarmCode = "MB102", AlarmName = "有物品遮挡", AlarmTime = DateTime.Now, Status = YesNoEnum.Y } });
        //await _plcHubContext.Clients.All.PublicAlarm(new WcsAlarmInfo() { Id = 100, StationNum = "260", AlarmCode = "MB102", AlarmName = "有物品遮挡", AlarmTime = DateTime.Now, Status = YesNoEnum.Y });
        var modPlc = await _wcsAlarmInfoRep.Context.Queryable<WcsPlc>().Where(s => s.Type == PLCTypeEnum.ConveyorLine && s.Text == (input.layer.ToString() + "层托盘输送线")).FirstAsync();
        if (modPlc == null)
            throw Oops.Bah("未找到输送线PLC");
        var listDict = await _dictDataService.GetDataList("reset_alarm");
        var value = listDict.FirstOrDefault(s => s.Code == input.layer.ToString());
        if (value == null)
            throw Oops.Bah("未找到复位地址,请在字典管理中设置");
        PLCUtil modUtil = new PLCUtil(modPlc);
        switch (input.layer)
        {
            case 1:
                break;
            case 2:
                {
                    modUtil.SetPlcDBValue(PLCDataTypeEnum.Bit, value.Value, "1");
                }
                break;
            case 3:
                break;
            default:
                break;
        }
        modUtil.Close();
        //throw Oops.Bah("开发中");
    }
Web/src/views/device/alarmManage/index.vue
@@ -18,9 +18,9 @@
            </el-col>
            <el-col :span="19">
                <div class="card-page">
                    <el-button type="primary" :plain="isPlain1" @click="floorTogglePlain(1)">一层平面</el-button>
                    <el-button type="primary" :plain="isPlain2" @click="floorTogglePlain(2)">二层平面</el-button>
                    <el-button type="primary" :plain="isPlain3" @click="floorTogglePlain(3)">三层平面</el-button>
                    <el-button type="primary" :plain="layer != 1" @click="floorTogglePlain(1)">一层平面</el-button>
                    <el-button type="primary" :plain="layer != 2" @click="floorTogglePlain(2)">二层平面</el-button>
                    <el-button type="primary" :plain="layer != 3" @click="floorTogglePlain(3)">三层平面</el-button>
                </div>
                <div style="margin: 40px; height: 50%;">
                    <div class="grid-container-line">
@@ -1950,32 +1950,21 @@
//复位报警
const reset = async () => {
    await resetWcsAlarmInfo();
    await resetWcsAlarmInfo({ layer: layer.value });
    // await handleQuery();
}
const isPlain1 = ref(false);//一层
const isPlain2 = ref(true);//二层
const isPlain3 = ref(true);//三层
const layer = ref(1);
//切换层平面
function floorTogglePlain(buttonNumber) {
    layer.value = buttonNumber;
    if (buttonNumber === 1) {
        isPlain1.value = false;
        isPlain2.value = true;
        isPlain3.value = true;
        //切换输送线数据
        cellsData.value = cellsDataOne.value;
    } else if (buttonNumber === 2) {
        isPlain2.value = false;
        isPlain1.value = true;
        isPlain3.value = true;
        //切换输送线数据
        cellsData.value = cellsDataTwo.value;
    } else if (buttonNumber === 3) {
        isPlain3.value = false;
        isPlain1.value = true;
        isPlain2.value = true;
        //切换输送线数据
        cellsData.value = cellsDataThree.value;
    }