using System; using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using TouchSocket.Core; using WCS.BLL.Config; using WCS.DAL.Db; using WCS.DAL.DbModels; namespace WCS.BLL.HardWare { public class SmartShelfModule : IModuleBase { #region 协议 /// /// 进入入库模式 /// public byte[] GoInInstoreData = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 确认入库 /// public byte[] ComfirmInstoreData = { 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; public byte[] ComfirmErrInstoreData = { 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 退出入库模式 /// public byte[] GoOutInstoreData = { 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 自检模式 /// public byte[] CheckModeData = { 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 进入出库模式 /// public byte[] GoInOutstoreModeData = { 0x05, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 }; /// /// 确认出库信号 /// public byte[] ComfirmOutstoreData = { 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 退出出库模式 /// public byte[] GoOutOutstoreModeData = { 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 进入盘点模式 /// 04代表颜色为蓝色色 /// public byte[] GoInStockTakingModeData = { 0x09, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }; /// /// 确认盘点 /// 03代表颜色为黄色 /// public byte[] ConfirmStockTakingData = { 0x09, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00 }; /// /// 退出盘点模式 /// public byte[] GoOutStockTakingModeData = { 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 复位命令 /// public byte[] ResetData = { 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 查询当前电压值 /// public byte[] VoltageSingleData = { 0x17, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 查询电压偏移值 /// public byte[] OffsetSingleData = { 0x18, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 查询电压标准值 /// public byte[] StandardSingleData = { 0x19, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 标定 /// public byte[] CalibrationData = { 0x0D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /// /// 设置偏移量 01 F4 = 500 /// public byte[] SetOffsetData = { 0x0E, 0x0A, 0x01, 0xF4, 0x00, 0x00, 0x00, 0x00 }; #endregion public int ModuleId { get; set; } public string ModuleCode { get; set; } public int BoardId { get; set; } public bool IsEnable { get; set; } public Mode CurrentMode { get; set; } /// /// 是否已发送自检命令 /// public bool IsSelfCheck { get; set; } = false; public List CurrentOutSns { get; set; } public List CurrentStockTakingSns { get; set; } public void SetCurrentMode() { } public void GoInInstoreMode(TCPClient tcpClient) { if (CurrentMode != Mode.待机模式) { //TO DO 退出对应的模式 然后再发送进入入库模式 } var storeInfos = DbHelp.db.Queryable() .Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); char[] data = "0000000000000000".ToCharArray(); //禁用 char[] dataBan = "0000000000000000".ToCharArray(); var boardStoreNumber = storeInfos.Count(); foreach (var storeInfo in storeInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= boardStoreNumber) { data[storeInfo.LightNumber - 1] = '1'; //禁用 if (storeInfo.CurrentMatSn == "禁用") { dataBan[storeInfo.LightNumber - 1] = '1'; } } } var dataStr = string.Join("", data.Reverse()); var data1 = dataStr.Substring(8, 8); var data2 = dataStr.Substring(0, 8); GoInInstoreData[1] = Convert.ToByte(data1, 2); GoInInstoreData[2] = Convert.ToByte(data2, 2); //禁用 var dataBanStr = string.Join("", dataBan.Reverse()); var data1Ban = dataBanStr.Substring(8, 8); var data2Ban = dataBanStr.Substring(0, 8); GoInInstoreData[6] = Convert.ToByte(data1Ban, 2); GoInInstoreData[7] = Convert.ToByte(data2Ban, 2); tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoInInstoreData)); } public void ComfirmInstore(TCPClient tcpClient) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmInstoreData)); } public void ComfirmErrInstore(TCPClient tcpClient) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmErrInstoreData)); } public void GoOutInstoreMode(TCPClient tcpClient) { if (CurrentMode == Mode.入库模式) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoOutInstoreData)); } else { //这里应该是状态异常的 正常不会是这种状态 Reset(tcpClient); } } /// /// 复位 /// /// public void Reset(TCPClient tcpClient) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, ResetData)); } /// /// 自检 /// /// public void ShelfCheck(TCPClient tcpClient) { if (CurrentMode != Mode.待机模式) { return; } var storeInfos = DbHelp.db.Queryable() .Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); char[] data = "0000000000000000".ToCharArray(); //禁用功能 char[] dataBan = "0000000000000000".ToCharArray(); var boardStoreNumber = storeInfos.Count(); foreach (var storeInfo in storeInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= boardStoreNumber) { data[storeInfo.LightNumber - 1] = '1'; //禁用功能 if (storeInfo.CurrentMatSn == "禁用") { dataBan[storeInfo.LightNumber - 1] = '1'; } } } var dataStr = string.Join("", data.Reverse()); var data1 = dataStr.Substring(8, 8); var data2 = dataStr.Substring(0, 8); CheckModeData[1] = Convert.ToByte(data1, 2); CheckModeData[2] = Convert.ToByte(data2, 2); //禁用功能 var dataBanStr = string.Join("", dataBan.Reverse()); var data1Ban = dataBanStr.Substring(8, 8); var data2Ban = dataBanStr.Substring(0, 8); CheckModeData[6] = Convert.ToByte(data1Ban, 2); CheckModeData[7] = Convert.ToByte(data2Ban, 2); tcpClient.Send(tcpClient.GenerateMessage(BoardId, CheckModeData)); } /// /// 进入出库模式、亮灯 /// /// public void GoInOutStoreMode(TCPClient tcpClient, List outSns) { Logs.Write($"模组{ModuleCode},本次亮灯物料{string.Join(",", outSns)}", LogsType.Outstore); CurrentOutSns = outSns; var storeInfos = DbHelp.db.Queryable().Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); //计算物料在库的库位 char[] data = "0000000000000000".ToCharArray(); //计算禁用的库位 char[] dataBan = "0000000000000000".ToCharArray(); var storeNumber = storeInfos.Count(); foreach (var storeInfo in storeInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) { data[storeInfo.LightNumber - 1] = '1'; //禁用 if (storeInfo.CurrentMatSn == "禁用") { dataBan[storeInfo.LightNumber - 1] = '1'; } } } var dataStr = string.Join("", data.Reverse()); var data1 = dataStr.Substring(8, 8); var data2 = dataStr.Substring(0, 8); GoInOutstoreModeData[1] = Convert.ToByte(data1, 2); GoInOutstoreModeData[2] = Convert.ToByte(data2, 2); //禁用 var dataBanStr = string.Join("", dataBan.Reverse()); var data1Ban = dataBanStr.Substring(8, 8); var data2Ban = dataBanStr.Substring(0, 8); GoInOutstoreModeData[6] = Convert.ToByte(data1Ban, 2); GoInOutstoreModeData[7] = Convert.ToByte(data2Ban, 2); //出库位置亮灯 if (outSns != null && outSns.Count > 0) { var outStoreInfos = storeInfos.Where(t => outSns.Contains(t.CurrentMatSn)) .ToList(); char[] outData = "0000000000000000".ToCharArray(); foreach (var storeInfo in outStoreInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) { outData[storeInfo.LightNumber - 1] = '1'; } } var outDataStr = string.Join("", outData.Reverse()); var data3 = outDataStr.Substring(8, 8); var data4 = outDataStr.Substring(0, 8); GoInOutstoreModeData[3] = Convert.ToByte(data3, 2); GoInOutstoreModeData[4] = Convert.ToByte(data4, 2); if (LocalFile.Config.IsSameMatCodeOut) { GoInOutstoreModeData[5] = LocalStatic.CurrentOutStoreColor; } else { GoInOutstoreModeData[5] = 0x02; } } tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoInOutstoreModeData)); } public void ComfirmOutstore(TCPClient tcpClient, byte lightNumber) { ComfirmOutstoreData[1] = lightNumber; tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmOutstoreData)); } /// /// 退出出库模式 /// /// public void GoOutOutStoreMode(TCPClient tcpClient) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoOutOutstoreModeData)); } /// /// 未盘点的物料进入盘点模式、亮灯 /// /// public void GoInStockTakingMode(TCPClient tcpClient, List stockTakingSns) { CurrentStockTakingSns = stockTakingSns; var storeInfos = DbHelp.db.Queryable().Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); //计算物料在库的库位 char[] data = "0000000000000000".ToCharArray(); var storeNumber = storeInfos.Count(); char[] outData = "0000000000000000".ToCharArray(); //盘点位置亮灯 if (stockTakingSns != null && stockTakingSns.Count > 0) { var outStoreInfos = storeInfos.Where(t => stockTakingSns.Contains(t.CurrentMatSn)) .ToList(); foreach (var storeInfo in outStoreInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) { outData[storeInfo.LightNumber - 1] = '1'; } } } var outDataStr = string.Join("", outData.Reverse()); var data3 = outDataStr.Substring(8, 8); var data4 = outDataStr.Substring(0, 8); GoInStockTakingModeData[2] = Convert.ToByte(data3, 2); GoInStockTakingModeData[3] = Convert.ToByte(data4, 2); tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoInStockTakingModeData)); } /// /// 已确认过的物料 /// /// public void ConfirmStockTaking(TCPClient tcpClient, List stockTakingSns) { CurrentStockTakingSns = stockTakingSns; var storeInfos = DbHelp.db.Queryable().Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); //计算物料在库的库位 char[] data = "0000000000000000".ToCharArray(); var storeNumber = storeInfos.Count(); char[] outData = "0000000000000000".ToCharArray(); //盘点位置亮灯 if (stockTakingSns != null && stockTakingSns.Count > 0) { var outStoreInfos = storeInfos.Where(t => stockTakingSns.Contains(t.CurrentMatSn)) .ToList(); foreach (var storeInfo in outStoreInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) { outData[storeInfo.LightNumber - 1] = '1'; } } } var outDataStr = string.Join("", outData.Reverse()); var data3 = outDataStr.Substring(8, 8); var data4 = outDataStr.Substring(0, 8); ConfirmStockTakingData[2] = Convert.ToByte(data3, 2); ConfirmStockTakingData[3] = Convert.ToByte(data4, 2); tcpClient.Send(tcpClient.GenerateMessage(BoardId, ConfirmStockTakingData)); } /// /// 单个确认物料 /// /// public void ConfirmStockTakingSingle(TCPClient tcpClient, int lightNumber) { var storeInfos = DbHelp.db.Queryable().Where(t => t.ModuleId == ModuleId) .Where(t => t.BoardId == BoardId) .OrderBy(t => t.LightNumber) .ToList(); //计算物料在库的库位 char[] data = "0000000000000000".ToCharArray(); var storeNumber = storeInfos.Count(); //盘点位置亮灯 var outStoreInfos = storeInfos.Where(t => t.LightNumber == lightNumber) .ToList(); char[] outData = "0000000000000000".ToCharArray(); foreach (var storeInfo in outStoreInfos) { if (!string.IsNullOrEmpty(storeInfo.CurrentMatSn) && storeInfo.LightNumber > 0 && storeInfo.LightNumber <= storeNumber) { outData[storeInfo.LightNumber - 1] = '1'; } } var outDataStr = string.Join("", outData.Reverse()); var data3 = outDataStr.Substring(8, 8); var data4 = outDataStr.Substring(0, 8); ConfirmStockTakingData[2] = Convert.ToByte(data3, 2); ConfirmStockTakingData[3] = Convert.ToByte(data4, 2); tcpClient.Send(tcpClient.GenerateMessage(BoardId, ConfirmStockTakingData)); } /// /// 退出盘点模式 /// /// public void GoOutStockTakingMode(TCPClient tcpClient) { tcpClient.Send(tcpClient.GenerateMessage(BoardId, GoOutStockTakingModeData)); } public void ComfirmStockTaking(TCPClient tcpClient, byte lightNumber) { ComfirmOutstoreData[1] = lightNumber; tcpClient.Send(tcpClient.GenerateMessage(BoardId, ComfirmOutstoreData)); } /// /// 查询电压值 /// /// public void QueryVoltage(TCPClient tcpClient) { Thread.Sleep(10); Task.Run(() => { tcpClient.Send(tcpClient.GenerateMessage(BoardId, VoltageSingleData)); Thread.Sleep(50); tcpClient.Send(tcpClient.GenerateMessage(BoardId, StandardSingleData)); Thread.Sleep(50); tcpClient.Send(tcpClient.GenerateMessage(BoardId, OffsetSingleData)); }); } public void CalibrationSetOffset(int offSet, TCPClient tcpClient) { var offSetData = BitConverter.GetBytes(unchecked((short)offSet)); // 检查是否需要交换字节 if (BitConverter.IsLittleEndian) { // 如果是小端序系统,则交换字节 byte temp = offSetData[0]; offSetData[0] = offSetData[1]; offSetData[1] = temp; } SetOffsetData[2] = offSetData[0]; SetOffsetData[3] = offSetData[1]; tcpClient.Send(tcpClient.GenerateMessage(BoardId, CalibrationData)); Thread.Sleep(100); tcpClient.Send(tcpClient.GenerateMessage(BoardId, SetOffsetData)); } } }