diff --git a/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj b/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj index dbc15171..e645d6a1 100644 --- a/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj +++ b/BPASmartClient.DRCoffee/BPASmartClient.DRCoffee.csproj @@ -4,4 +4,9 @@ net6.0 + + + + + diff --git a/BPASmartClient.DRCoffee/Class1.cs b/BPASmartClient.DRCoffee/Class1.cs deleted file mode 100644 index 66097ed2..00000000 --- a/BPASmartClient.DRCoffee/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.DRCoffee -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.DRCoffee/CoffeeMachine.cs b/BPASmartClient.DRCoffee/CoffeeMachine.cs new file mode 100644 index 00000000..e7e9850e --- /dev/null +++ b/BPASmartClient.DRCoffee/CoffeeMachine.cs @@ -0,0 +1,155 @@ +using BPASmartClient.DRCoffee; +using BPASmartClient.Helper; +using BPASmartClient.SerialPort; +using System; +using System.Collections.Generic; +using System.Threading; + +namespace HBLDevice.Coffee +{ + /// + /// 咖啡机 + /// + public class CoffeeMachine + { + + //通讯代理 + SerialPortClient commProxy = null; + //数据仓库 + private DataStorage dataStorage = new DataStorage(); + //指令组装 + private CommandHandler commandHandler = new CommandHandler(); + //主线程运行标识 + private bool running = false; + //是否下发指令,主线程等待 + private bool free = true; + + private DrCoffeeStatus drCoffeeStatus; + /// + /// 咖啡机状态 + /// + public DrCoffeeStatus CurrentCoffeeStatus + { + get { return drCoffeeStatus; } + set + { + if (drCoffeeStatus != value) + { + drCoffeeStatus = value; + CoffeeStatusChanged?.Invoke(value); + } + } + } + private DrCoffeeAppStatus coffeeAppStatus; + /// + /// 应用状态 + /// + public DrCoffeeAppStatus CurrentCoffeeAppStatus + { + get { return coffeeAppStatus; } + set + { + if (coffeeAppStatus != value) + { + coffeeAppStatus = value; + CoffeeAppStatusChanged?.Invoke(value); + } + } + } + + public Action SendCallback; + public Action ReciveCallback; + + /// + /// 咖啡机状态改变回调 + /// + public Action CoffeeStatusChanged; + /// + /// 应用状态改变回调 + /// + public Action CoffeeAppStatusChanged; + + public CoffeeMachine(string portName, BaudRates baud) + { + commProxy = new SerialPortClient(portName, baud); + commProxy.SetDataStorage(dataStorage); + commandHandler.Init(commProxy); + commandHandler.PauseAsk = delegate (bool pause) + { + free = !pause; + }; + } + + /// + /// 主线程开始运行 + /// + public void Start() + { + commProxy.Start(); + running = true; + MainLoop(); + } + + /// + /// 停止运行 + /// + public void Stop() + { + commProxy.Stop(); + running = false; + } + + /// + /// 主循环,循环询问状态 + /// + private void MainLoop() + { + ThreadManage.GetInstance.StartLong(new Action(() => + { + if (free) + { + commProxy.SendData(commandHandler.GetStatusAsk()); + SendCallback?.Invoke(BitConverter.ToString(commandHandler.GetStatusAsk())); + } + Thread.Sleep(200); + }),"咖啡机询问线程"); + + ThreadManage.GetInstance.StartLong(new Action(() => + { + List temp = new List(); + //一系列解包 + while (dataStorage.GetSize() > 0) + { + byte item = dataStorage.GetData(); + if (DrCoffee.HEADER == item) + { + if (temp.Count == DrCoffee.LENGTH - 1) + { + temp.Add(item); + var package = DrCoffee.UnPack(temp.ToArray()); + ReciveCallback?.Invoke(BitConverter.ToString(temp.ToArray())); + temp.Clear(); + MorkCStatus.GetInstance().ProcessPackage(package); + } + else + { + temp.Clear(); + temp.Add(item); + } + continue; + } + else + { + if (temp.Count == 1 && item != DrCoffee.LENGTH) + { + temp.Clear(); + continue; + } + temp.Add(item); + } + } + Thread.Sleep(5); + }), "咖啡机解析线程"); + } + } +} diff --git a/BPASmartClient.DRCoffee/CommandHandler.cs b/BPASmartClient.DRCoffee/CommandHandler.cs new file mode 100644 index 00000000..632adb45 --- /dev/null +++ b/BPASmartClient.DRCoffee/CommandHandler.cs @@ -0,0 +1,119 @@ + +using BPASmartClient.DRCoffee; +using BPASmartClient.Message; +using BPASmartClient.MessageCommunication; +using BPASmartClient.MessageCommunication.MsgControl; +using BPASmartClient.SerialPort; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace HBLDevice.Coffee +{ + /// + /// 指令封装 + /// + internal class CommandHandler + { + byte[] cmdAsk; + private SerialPortClient commProxy; + private DrCoffeePackage drinksOrder = new DrCoffeePackage(); + public Action PauseAsk { get; set; } + + /// + /// 初始化 + /// + internal void Init(SerialPortClient commProxy) + { + this.commProxy = commProxy; + DrCoffeePackage package = new DrCoffeePackage(); + package.CommCmd = DrCoffeeCommCmd.饮品制作指令; + cmdAsk = DrCoffee.Packe(package); + drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令; + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.DRCoffee_MakeCoffee,"MakeCoffeeHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.DRCoffee_CancelMakeCoffee,"CancelMakeCoffeeHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.DRCoffee_CoffeeCommCmd,"CoffeeCommCmdHandler"); + } + + /// + /// 制作咖啡 + /// + public void MakeCoffeeHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is string) + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + drinksOrder.CommCmd = DrCoffeeCommCmd.饮品制作指令; + drinksOrder.DrinksCode = (DrCoffeeDrinksCode)int.Parse(e.obj_MessageObj.ToString()); + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + PauseAsk?.Invoke(false); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.DRCoffee 中引发错误,CancelMakeCoffeeHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// 取消制作 + /// + public void CancelMakeCoffeeHandler(object sender,InnerMessageEventArgs e) + { + try + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + drinksOrder.CommCmd = DrCoffeeCommCmd.取消应用指令; + drinksOrder.DrinksCode = 0; + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + PauseAsk?.Invoke(false); + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.DRCoffee 中引发错误,CancelMakeCoffeeHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// 模式设置 + /// + /// + /// + public void CoffeeCommCmdHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is string) + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + drinksOrder.CommCmd = (DrCoffeeCommCmd)int.Parse(e.obj_MessageObj.ToString()); + commProxy.SendData(DrCoffee.Packe(drinksOrder)); + Thread.Sleep(200); + PauseAsk?.Invoke(false); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.DRCoffee 中引发错误,CoffeeCommCmdHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// 发送状态询问 + /// + internal byte[] GetStatusAsk() + { + return cmdAsk; + } + } +} diff --git a/BPASmartClient.DRCoffee/MorkCStatus.cs b/BPASmartClient.DRCoffee/MorkCStatus.cs new file mode 100644 index 00000000..72221603 --- /dev/null +++ b/BPASmartClient.DRCoffee/MorkCStatus.cs @@ -0,0 +1,76 @@ +using BPASmartClient.DRCoffee; +using BPASmartClient.MessageCommunication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace HBLDevice.Coffee +{ + public class MorkCStatus + { + private volatile static MorkCStatus _Instance; + public static MorkCStatus GetInstance() => _Instance ?? (_Instance = new MorkCStatus()); + private MorkCStatus() { } + + private DateTime lastRefreshTime = DateTime.MinValue; + /// + /// 是否在线 + /// + public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } + /// + /// 咖啡机状态 + /// + public DrCoffeeStatus CoffeeStatus { get; set; } + /// + /// 应用状态 + /// + public DrCoffeeAppStatus AppStatus { get; set; } + /// + /// 警告信息 + /// + public DrCoffeeWarning Warning { get; set; } + /// + /// 故障信息 + /// + public DrCoffeeFault Fault { get; set; } + + public bool CanDo + { + get + + { + if (!OnLine) + return false; + if (Warning != DrCoffeeWarning.无警告) + return false; + if (Fault != DrCoffeeFault.无故障) + return false; + return true; + } + } + + /// + /// 咖啡机状态解析 + /// + /// + public void ProcessPackage(DrCoffeePackage package) + { + if (CoffeeStatus == DrCoffeeStatus.Running && package.Status != DrCoffeeStatus.Running) + { + CoffeeStatus = package.Status; + Class_InnerMessageBus.GetInstance().PostMessage(this,Class_MessageName.DRCoffee_CoffeEndCook,""); + } + else { + CoffeeStatus = package.Status; + } + + AppStatus = package.ApplicationStatus; + Warning = package.Warning; + Fault = package.Fault; + + lastRefreshTime = DateTime.Now; + } + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeAppCode.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeAppCode.cs new file mode 100644 index 00000000..e39974e6 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeAppCode.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 应用编号 + /// + public enum DrCoffeAppCode:byte + { + 无应用= 0x00, + 饮品制作应用 = 0x01, + 冲煮系统快速冲洗应用 = 0x02, + 牛奶系统快速冲洗应用 = 0x03, + 粉料系统快速冲洗应用 = 0x04, + 蒸汽杆快速冲洗应用 = 0x05, + 冲煮系统清洁应用 = 0x06, + 冲煮系统清洗应用 = 0x07, + 牛奶系统清洗应用 = 0x08, + 除垢应用 = 0x09, + 清空系统应用 = 0x0A, + 系统补水应用 = 0x0B, + 冲泡器复位应用 = 0x0C, + 分相阀复位应用 = 0x0D, + 研磨效验应用 = 0x0E, + 粉料效验应用 = 0x0F, + 功能测试应用 = 0x10, + 开机应用 = 0x11, + 关机应用 = 0x12, + 一键清洗应用 = 0x13, + 待机应用 = 0x14, + 滤芯快速冲洗应用 = 0x15, + 牛奶系统强制冲洗应用 = 0x16, + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffee.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffee.cs new file mode 100644 index 00000000..a20b8e7e --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffee.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + public class DrCoffee + { + public const int LENGTH = 26; + public const byte HEADER = 0x7E; + public const byte END = 0x7E; + + public static DrCoffeePackage UnPack(byte[] datagram) + { + if (LENGTH != datagram.Length) + return default(DrCoffeePackage); + // 分配结构体大小的内存空间 + IntPtr structPtr = Marshal.AllocHGlobal(LENGTH); + // 将byte数组拷到分配好的内存空间 + Marshal.Copy(datagram, 0, structPtr, LENGTH); + // 将内存空间转换为目标结构体 + DrCoffeePackage obj = (DrCoffeePackage)Marshal.PtrToStructure(structPtr, typeof(DrCoffeePackage)); + // 释放内存空间 + Marshal.FreeHGlobal(structPtr); + // 返回结构体 + return obj; + + } + + public static byte[] Packe(DrCoffeePackage package) + { + package.Header = HEADER; + package.Length = LENGTH; + package.End = END; + package.CalcCode = PackageCalcValideCode(package); + // 创建byte数组 + byte[] bytes = new byte[LENGTH]; + // 分配结构体大小的内存空间 + IntPtr structPtr = Marshal.AllocHGlobal(LENGTH); + // 将结构体拷到分配好的内存空间 + Marshal.StructureToPtr(package, structPtr, false); + //从 内存空间拷到byte数组 + Marshal.Copy(structPtr, bytes, 0, LENGTH); + // 释放内存空间 + Marshal.FreeHGlobal(structPtr); + // 返回byte数组 + return bytes; + } + + public static byte PackageCalcValideCode(DrCoffeePackage package) + { + var sum = (long)package.Length + + (long)package.Warning + + (long)package.Fault + + (long)package.Status + + (long)package.CommCmd + + (long)package.ApplicationStatus + + (long)package.DrinksCode + + (long)package.ApplicationCode + + (long)package.Retain; + return (byte)(sum & 0xff); + } + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeAppStatus.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeAppStatus.cs new file mode 100644 index 00000000..bb5afba6 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeAppStatus.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + public enum DrCoffeeAppStatus : byte + { + 应用无状态 = 0x00, + 应用运行状态 = 0x01, + 应用阶段成功状态 = 0x02, + 应用完全成功状态 = 0x03, + 应用失败状态 = 0x04, + 应用等待状态_咖啡机不接受, 会回复失败状态=0x05 + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeCommCmd.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeCommCmd.cs new file mode 100644 index 00000000..d58adee2 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeCommCmd.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 通信指令 + /// + public enum DrCoffeeCommCmd : byte + { + 无指令 = 0x00, + 饮品制作指令 = 0x01, + 冲煮系统快速冲洗指令 = 0x02, + 牛奶系统快速冲洗指令 = 0x03, + 粉料系统快速冲洗指令 = 0x04, + 冲煮系统清洁指令 = 0x05, + 冲煮系统清洗指令 = 0x06, + 牛奶系统清洗指令 = 0x07, + 除垢指令 = 0x08, + 清空系统指令 = 0x09, + 系统补水指令 = 0x0A, + 冲泡器复位指令 = 0x0B, + 分相阀复位指令 = 0x0C, + 研磨效验指令 = 0x0D, + 粉料效验指令 = 0x0E, + 握手指令 = 0x0F, + 询问状态指令 = 0x10, + 取消应用指令 = 0x11, + 设置参数指令 = 0x12, + 更新程序指令 = 0x13, + 功能测试指令 = 0x14, + 开机指令 = 0x15, + 关机指令 = 0x16, + 一键清洗指令 = 0x17, + 蒸汽杆快速冲洗指令 = 0x18, + 蒸汽制作指令 = 0x19, + 滤芯快速冲洗指令 = 0x1A, + 牛奶系统强制冲洗指令 = 0x1B, + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeDrinksCode.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeDrinksCode.cs new file mode 100644 index 00000000..fb7d67e7 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeDrinksCode.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 饮品编号 + /// + public enum DrCoffeeDrinksCode : byte + { + 意式浓缩 = 1, + 美式咖啡 = 2, + 卡布奇诺 = 3, + 两杯意式浓缩 = 4, + 拿铁咖啡 = 5, + 热牛奶 = 6, + 热牛沫 = 7, + 热水 = 8, + 澳白咖啡 = 9, + 玛琪雅朵 = 10, + 拿铁玛琪雅朵 = 11, + 大壶咖啡 = 12, + 现磨咖啡 = 13, + 冰美式 = 14, + 芮斯崔朵 = 15, + 美式奶咖 = 16, + 意式奶咖 = 17, + 咖啡粉制作 = 18, + 两杯芮斯崔朵 = 19, + 两杯卡布奇诺 = 20, + 两杯拿铁咖啡 = 21, + 两杯澳白咖啡 = 22, + 拿铁咖啡_冰 = 23, + 美式咖啡_大 = 24, + 奶盖 = 25, + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeFault.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeFault.cs new file mode 100644 index 00000000..a55cf2ab --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeFault.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 故障 + /// + public enum DrCoffeeFault : long + { + 无故障 = 0x0, + HMI通信异常 = 0x1, + 咖啡锅炉加热超时 = 0x2, + 蒸汽锅炉加热超时 = 0x4, + 热水锅炉加热超时 = 0x8, + 咖啡锅炉NTC异常 = 0x10, + 蒸汽锅炉NTC异常 = 0x20, + 热水锅炉NTC故障 = 0x40, + 咖啡锅炉供水故障 = 0x80, + 蒸汽锅炉供水故障 = 0x100, + 热水锅炉供水故障 = 0x200, + 冲煮系统异常 = 0x400, + 分向阀系统异常 = 0x800, + 磨豆机1异常 = 0x1000, + 磨豆机2异常 = 0x2000, + 磨豆机3异常 = 0x4000, + 冰箱通信异常 = 0x8000, + 蒸汽锅炉补水超时异常 = 0x10000 + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeePackage.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeePackage.cs new file mode 100644 index 00000000..f1aafa02 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeePackage.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// Dr咖啡机基础协议 + /// + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public struct DrCoffeePackage + { + /// + /// 包头(固定0x7E) + /// + public byte Header; + /// + /// 包长度: 固定为26个字节 + /// + public byte Length; + /// + /// 警告(咖啡机负责写,工控机负责读) + /// + public DrCoffeeWarning Warning; + /// + /// 故障(咖啡机负责写,工控机负责读) + /// + public DrCoffeeFault Fault; + /// + /// 咖啡机状态(咖啡机负责写,工控机负责读) + /// + public DrCoffeeStatus Status; + /// + /// 通信指令(咖啡机负责读,工控机负责写) + /// + public DrCoffeeCommCmd CommCmd; + /// + /// 应用状态(咖啡机负责写,工控机负责读) + /// + public DrCoffeeAppStatus ApplicationStatus; + /// + /// 饮品编号(咖啡机负责读,工控机负责写) + /// + public DrCoffeeDrinksCode DrinksCode; + /// + /// 应用编号(咖啡机负责写,工控机负责读) + /// + public DrCoffeAppCode ApplicationCode; + /// + /// 预留 + /// + public byte Retain; + /// + /// 校验和(除去包头包尾和校验和以外的 所有字节累加和的低字节) + /// + public byte CalcCode; + /// + /// 包尾(固定为0x7E) + /// + public byte End; + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeStatus.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeStatus.cs new file mode 100644 index 00000000..25fd4a2c --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeStatus.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 状态 + /// + public enum DrCoffeeStatus:byte + { + /// + /// 待机状态 拒绝制作饮品命令 + /// + Wait = 0x01, + /// + /// 空闲状态 接受制作饮品命令 + /// + Free = 0x02, + /// + /// 运行状态 拒绝制作饮品命令 + /// + Running = 0x03, + /// + /// 警告状态 拒绝制作饮品命令 + /// + Warning = 0x04, + /// + /// 故障状态 拒绝制作饮品命令 + /// + Fault = 0x05 + } +} diff --git a/BPASmartClient.DRCoffee/Protocal/DrCoffeeWarning.cs b/BPASmartClient.DRCoffee/Protocal/DrCoffeeWarning.cs new file mode 100644 index 00000000..6762bc19 --- /dev/null +++ b/BPASmartClient.DRCoffee/Protocal/DrCoffeeWarning.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.DRCoffee +{ + /// + /// 警告 + /// + public enum DrCoffeeWarning : long + { + 无警告 = 0, + 蓄水盘未安装到位=0x01, + 容渣盒已满=0x02, + 水箱缺水=0x04, + 蓄水盘水满=0x08, + 桶装水缺水=0x10, + 废水桶水满=0x20, + 冲泡器未安装到位=0x40, + 门未关闭到位=0x80, + 豆盒1未安装到位=0x100, + 豆盒2未安装到位=0x200, + 豆盒3未安装到位=0x400, + 豆盒1缺豆=0x800, + 豆盒2缺豆=0x1000, + 豆盒3缺豆=0x2000, + 粉料盒1未安装到位=0x4000, + 粉料盒2未安装到位=0x8000, + 粉料盒3未安装到位=0x10000, + 粉料盒1缺粉=0x20000, + 粉料盒2缺粉=0x40000, + 粉料盒3缺粉=0x80000, + 研磨机校验=0x100000, + 咖啡机需要除垢=0x200000, + 冲煮系统需要清洗=0x400000, + 冲泡器需要清洁=0x800000, + 牛奶系统需要清洗=0x1000000, + 粉料系统需要清洗=0x2000000, + 牛奶温度过低=0x4000000, + 牛奶温度过高= 0x08000000, + 牛奶不足= 0x10000000, + 牛奶盒未安装= 0x20000000, + 系统缺水= 0x40000000, + 系统压力过大= 0x80000000, + 冲泡器自检= 0x100000000, + 分向阀自检= 0x200000000, + 环境温度过高= 0x400000000, + 环境温度过低= 0x800000000, + 咖啡锅炉温度过高= 0x1000000000, + 蒸汽锅炉温度过高= 0x2000000000, + 热水锅炉温度过高= 0x4000000000, + 咖啡锅炉温度过低= 0x8000000000, + 蒸汽锅炉温度过低= 0x10000000000, + 热水锅炉温度过低= 0x20000000000, + 系统补水超时= 0x40000000000, + 网络异常= 0x80000000000, + 蒸汽杆NTC异常= 0x100000000000, + 滤芯需要更换= 0x200000000000 + } +} diff --git a/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj b/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj index dbc15171..9fe941ae 100644 --- a/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj +++ b/BPASmartClient.GSIceCream/BPASmartClient.GSIceCream.csproj @@ -1,7 +1,12 @@ - + net6.0 + + + + + diff --git a/BPASmartClient.GSIceCream/Class1.cs b/BPASmartClient.GSIceCream/Class1.cs deleted file mode 100644 index 3bf73622..00000000 --- a/BPASmartClient.GSIceCream/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.GSIceCream -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.GSIceCream/CommandHandler.cs b/BPASmartClient.GSIceCream/CommandHandler.cs new file mode 100644 index 00000000..c4b8ad81 --- /dev/null +++ b/BPASmartClient.GSIceCream/CommandHandler.cs @@ -0,0 +1,134 @@ +using BPASmartClient.Message; +using BPASmartClient.MessageCommunication; +using BPASmartClient.MessageCommunication.MsgControl; +using BPASmartClient.SerialPort; +using System; +using System.Threading; + +namespace BPASmartClient.GSIceCream +{ + /// + /// 指令封装 + /// + internal class CommandHandler + { + byte[] cmdHeartDW; + + private SerialPortClient commProxy; + public Action PauseAsk { get; set; } + + /// + /// 初始化 + /// + internal void Init(SerialPortClient commProxy) + { + this.commProxy = commProxy; + ICMSG_Heart_DW heartDW = new ICMSG_Heart_DW(); + cmdHeartDW = IcPack.StructureToByte(heartDW); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.GSIceCream_ModeSet,"ModeSetHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.GSIceCream_Discharge,"DischargeHandler"); + } + + /// + /// 发送心跳 + /// + internal byte[] GetHeartDW() + { + return cmdHeartDW; + } + /// + /// 模式设置 + /// + public void ModeSetHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is MORKI_MODE) + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build((MORKI_MODE)(e.obj_MessageObj))); + commProxy.SendData(data); + Thread.Sleep(200); + PauseAsk?.Invoke(false); + MessageLog.GetInstance.Show(string.Format("设置模式[{0}]",Enum.GetName(typeof(MORKI_MODE),(MORKI_MODE)e.obj_MessageObj))); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.GSIceCream 中引发错误,ModeSetHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// 打料 + /// + public void DischargeHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is MORKI_MODE) + { + if (MorkIStatus.GetInstance().Fault != MORKI_FAULT.未发生故障) + { + MessageLog.GetInstance.Show(string.Format("当前存在故障[{0}%],不允许制作",MorkIStatus.GetInstance().Fault)); + //callBack?.Invoke(false); + return; + } + if (MorkIStatus.GetInstance().CXB <= 86) + { + MessageLog.GetInstance.Show(string.Format("当前成型比[{0}%],低于86%,不允许制作",MorkIStatus.GetInstance().CXB)); + //callBack?.Invoke(false); + return; + } + + bool modeRight = MorkIStatus.GetInstance().CurrentMode == MORKI_MODE.制冷模式; + + if (!modeRight) + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + + var temp = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.制冷模式)); + commProxy.SendData(temp); + + Thread.Sleep(200); + PauseAsk?.Invoke(false); + MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.制冷模式)); + + DateTime freeTime = DateTime.Now.AddSeconds(5); + while (DateTime.Now < freeTime) + { + Thread.Sleep(10); + modeRight = MorkIStatus.GetInstance().CurrentMode == MORKI_MODE.制冷模式; + if (modeRight) + break; + } + } + + if (modeRight) + { + PauseAsk?.Invoke(true); + Thread.Sleep(200); + var data = IcPack.StructureToByte(ICMSG_MODE_DW.Build(MORKI_MODE.打料)); + commProxy.SendData(data); + Thread.Sleep(200); + PauseAsk?.Invoke(false); + Class_InnerMessageBus.GetInstance().PostMessage(this,Class_MessageName.GSIceCream_EndCook,""); + MessageLog.GetInstance.Show(string.Format("出料操作->设置模式[{0}]",MORKI_MODE.打料)); + //callBack?.Invoke(true); + } + else + { + MessageLog.GetInstance.Show(string.Format("出料操作->模式切换失败,当前模式[{0}],不允许出料",MorkIStatus.GetInstance().CurrentMode)); + //callBack?.Invoke(false); + } + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.GSIceCream 中引发错误,ModeSetHandler 类,描述:[{ex.Message}]"); + } + } + } +} diff --git a/BPASmartClient.GSIceCream/IceCreamMachine.cs b/BPASmartClient.GSIceCream/IceCreamMachine.cs new file mode 100644 index 00000000..dab7e5dc --- /dev/null +++ b/BPASmartClient.GSIceCream/IceCreamMachine.cs @@ -0,0 +1,155 @@ +using BPASmartClient.Helper; +using BPASmartClient.SerialPort; +using System; +using System.Collections.Generic; +using System.Threading; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + public class IceCreamMachine + { + //指令组装 + private CommandHandler commandHandler = new CommandHandler(); + //通讯代理 + SerialPortClient commProxy = null; + //数据仓库 + private DataStorage dataStorage = new DataStorage(); + //主线程运行标识 + private bool running = false; + //是否下发指令,主线程等待 + private bool free = true; + public Action SendCallback; + public Action ReciveCallback; + + public IceCreamMachine(string portName, BaudRates baud) + { + commProxy = new SerialPortClient(portName, baud); + commProxy.SetDataStorage(dataStorage); + commandHandler.Init(commProxy); + commandHandler.PauseAsk = delegate (bool pause) + { + free = !pause; + }; + } + + public void Start() + { + commProxy.Start(); + running = true; + MainLoop(); + } + + public void Stop() + { + } + + private MSG_RESOLVE_STEP currentStep; + private void MainLoop() + { + ThreadManage.GetInstance.StartLong(new Action(() => + { + if (free) + { + commProxy.SendData(commandHandler.GetHeartDW()); + SendCallback?.Invoke(BitConverter.ToString(commandHandler.GetHeartDW())); + } + Thread.Sleep(500); + }), "冰淇淋询问线程"); + + ThreadManage.GetInstance.StartLong(new Action(() => + { + ResolveMsg(); + //Thread.Sleep(2000); + }), "冰淇淋解析线程"); + } + int contentLength = 0; + int currentContentOffset = 0; + private void ResolveMsg() + { + + //while (running) + //{ + List temp = new List(); + //一系列解包 + while (dataStorage.GetSize() > 0) + { + byte item = dataStorage.GetData(); + switch (currentStep) + { + case MSG_RESOLVE_STEP.NONE: + if (item == MessageDefine.HEADER1) + { + temp.Add(item); + currentStep = MSG_RESOLVE_STEP.HEADER1; + continue; + } + break; + case MSG_RESOLVE_STEP.HEADER1: + if (item == MessageDefine.HEADER2_UP) + { + temp.Add(item); + currentStep = MSG_RESOLVE_STEP.HEADER2; + continue; + } + else + { + temp.Clear(); + currentStep = MSG_RESOLVE_STEP.NONE; + continue; + } + case MSG_RESOLVE_STEP.HEADER2: + switch ((IC_CMD)item) + { + case IC_CMD.HEART: + temp.Add(item); + contentLength = MessageDefine.MSG_LENGTH[(IC_CMD)item]; + currentContentOffset = 0; + currentStep = MSG_RESOLVE_STEP.CMD; + break; + default: + temp.Clear(); + currentStep = MSG_RESOLVE_STEP.NONE; + break; + } + break; + } + int retry = 3; + while (dataStorage.GetSize() < contentLength + 2 && retry >= 0) + { + retry--; + Thread.Sleep(100); + } + if (retry < 0) + { + currentStep = MSG_RESOLVE_STEP.NONE; + currentContentOffset = 0; + contentLength = 0; + continue; + } + while (currentContentOffset < contentLength) + { + item = dataStorage.GetData(); + temp.Add(item); + currentContentOffset++; + } + + retry = 3; + while (dataStorage.GetSize() < 2 && retry >= 0) + { + retry--; + Thread.Sleep(100); + } + temp.Add(dataStorage.GetData()); + temp.Add(dataStorage.GetData()); + ReciveCallback?.Invoke(BitConverter.ToString(temp.ToArray())); + MorkIStatus.GetInstance().ProcessMsg(temp.ToArray()); + currentStep = MSG_RESOLVE_STEP.NONE; + continue; + } + Thread.Sleep(5); + //} + } + } + +} diff --git a/BPASmartClient.GSIceCream/MorkIStatus.cs b/BPASmartClient.GSIceCream/MorkIStatus.cs new file mode 100644 index 00000000..0057533b --- /dev/null +++ b/BPASmartClient.GSIceCream/MorkIStatus.cs @@ -0,0 +1,130 @@ +using BPASmartClient.Helper; +using BPASmartClient.Message; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + public class MorkIStatus + { + private volatile static MorkIStatus _Instance; + public static MorkIStatus GetInstance() => _Instance ?? (_Instance = new MorkIStatus()); + private MorkIStatus() { } + private DateTime lastRefreshTime = DateTime.MinValue; + /// + /// 是否在线 + /// + public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } + /// + /// 预冷温度 + /// + public short YLWD { get; set; } + /// + /// 回气温度 + /// + public short HQWD { get; set; } + /// + /// 环境温度 + /// + public short HJWD { get; set; } + /// + /// 电流 + /// + public short DL { get; set; } + /// + /// 电压 + /// + public short DY { get; set; } + /// + /// 当前模式 + /// + public MORKI_MODE CurrentMode { get; set; } + /// + /// 故障 + /// + public MORKI_FAULT Fault { get; set; } + /// + /// 成型比 + /// + public byte CXB { get; set; } + /// + /// 成型比(门限) + /// + public byte CXB_Threshold { get; set; } + /// + /// 打料完成(完成为true,正在打料为false) + /// + public bool DLCompleted { get; set; } + + + public bool CanDo + { + get + { + if (!OnLine) + return false; + if (Fault != MORKI_FAULT.未发生故障) + return false; + if (CXB < CXB_Threshold) + return false; + return true; + } + } + + private void ProcessHeart(ICMSG_Heart_UP heartUpMsg) + { + CurrentMode = heartUpMsg.MS; + YLWD = BitConverter.ToInt16(new byte[] { heartUpMsg.YLWD_L, heartUpMsg.YLWD_H }, 0); + HQWD = BitConverter.ToInt16(new byte[] { heartUpMsg.HQWD_L, heartUpMsg.HQWD_H }, 0); + HJWD = BitConverter.ToInt16(new byte[] { heartUpMsg.HJWD_L, heartUpMsg.HJWD_H }, 0); + DL = BitConverter.ToInt16(new byte[] { heartUpMsg.DL_L, heartUpMsg.DL_H }, 0); + Fault = (MORKI_FAULT)BitConverter.ToInt16(new byte[] { heartUpMsg.GZ_L, heartUpMsg.GZ_H }, 0); + CXB = heartUpMsg.CXB; + DLCompleted = (heartUpMsg.DLTJ >> 4 & 1) == 1; + + if (RTrig.GetInstance("打料完成检测").Start(DLCompleted)) + { + MessageLog.GetInstance.Show("打料完成"); + } + + if(RTrig.GetInstance("打料中检测").Start(!DLCompleted)) + { + MessageLog.GetInstance.Show("打料中"); + } + } + + private void ProcessModeUp(ICMSG_MODE_UP modeUpMsg) + { + MessageLog.GetInstance.Show(string.Format("模式返回为:{0}", modeUpMsg.Mode)); + } + + public void ProcessMsg(byte[] data) + { + lastRefreshTime = DateTime.Now; + try + { + if (data.Length < 5) + return; + switch (data[2]) + { + case (byte)IC_CMD.HEART: + var msg = IcPack.ByteToStructure(data.ToArray()); + ProcessHeart(msg); + break; + case (byte)IC_CMD.MODE: + var modeUp = IcPack.ByteToStructure(data.ToArray()); + ProcessModeUp(modeUp); + break; + } + } + catch (Exception ex) + { + + } + } + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_DW.cs b/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_DW.cs new file mode 100644 index 00000000..e3bb0f30 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_DW.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public class ICMSG_Heart_DW + { + public byte Header1; + public byte Header2; + public IC_CMD Cmd; + public MORKI_MODE Mode; + public byte CalcCode1 ; + public byte CalcCode2 ; + + public ICMSG_Heart_DW() + { + Header1 = MessageDefine.HEADER1; + Header2 = MessageDefine.HEADER2_DW; + Cmd = IC_CMD.HEART; + Mode = MORKI_MODE.未知; + CalcCode1 = 0x00; + CalcCode2 = 0x09; + + } + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_UP.cs b/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_UP.cs new file mode 100644 index 00000000..90a127fb --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/ICMSG_Heart_UP.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + /// + /// 心跳下发 + /// + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public class ICMSG_Heart_UP + { + public byte Header1; + public byte Header2; + public IC_CMD Cmd; + public MORKI_MODE Mode; + + public byte YLWD_H; + public byte YLWD_L; + public byte HQWD_H; + public byte HQWD_L; + public byte HJWD_H; + public byte HJWD_L; + public byte DL_H; + public byte DL_L; + public byte DY_H; + public byte DY_L; + public byte GZ_H; + public byte GZ_L; + public MORKI_MODE MS; + public byte DLTJ; + public byte CXB; + public byte DLBS_H; + public byte DLBS_L; + + public short CalcCode; + + public ICMSG_Heart_UP() + { + Header1 = HEADER1; + Header2 = HEADER2_UP; + Cmd = IC_CMD.HEART; + } + + public bool HasGZ(out string msg) + { + msg = string.Empty; + msg += ((GZ_H >> 7) & 1) == 1 ? "通讯故障" : string.Empty; + msg += ((GZ_H >> 6) & 1) == 1 ? "电流过载" : string.Empty; + msg += ((GZ_H >> 5) & 1) == 1 ? "环境温度过高" : string.Empty; + msg += ((GZ_H >> 4) & 1) == 1 ? "环境温度异常" : string.Empty; + msg += ((GZ_H >> 3) & 1) == 1 ? "进气温度故障" : string.Empty; + msg += ((GZ_H >> 2) & 1) == 1 ? "保鲜温度异常" : string.Empty; + msg += ((GZ_H >> 1) & 1) == 1 ? "冷冻温度异常" : string.Empty; + + msg += ((GZ_L >> 7) & 1) == 1 ? "电压过高" : string.Empty; + msg += ((GZ_L >> 6) & 1) == 1 ? "电压过低" : string.Empty; + msg += ((GZ_L >> 5) & 1) == 1 ? "制冷不良" : string.Empty; + msg += ((GZ_L >> 4) & 1) == 1 ? "转速传感器异常" : string.Empty; + msg += ((GZ_L >> 3) & 1) == 1 ? "皮带打滑" : string.Empty; + msg += ((GZ_L >> 2) & 1) == 1 ? "冻缸报警" : string.Empty; + msg += ((GZ_L >> 1) & 1) == 1 ? "缺料报警" : string.Empty; + + return string.IsNullOrEmpty(msg); + } + + public string DLTJ_Desc() + { + if ((DLTJ >> 7 & 1) == 1) return "有料"; + if ((DLTJ >> 6 & 1) == 1) return "缺料"; + if ((DLTJ >> 5 & 1) == 1) return "未使用"; + if ((DLTJ >> 4 & 1) == 1) return "未使用"; + if ((DLTJ >> 3 & 1) == 1) return "未使用"; + if ((DLTJ >> 2 & 1) == 1) return "打料电机复位完成"; + if ((DLTJ >> 1 & 1) == 1) return "未使用"; + if ((DLTJ & 1) == 1) return "成型比大于或等于87"; + return string.Empty; + } + + } + +} diff --git a/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_DW.cs b/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_DW.cs new file mode 100644 index 00000000..eb0fb4a4 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_DW.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public class ICMSG_MODE_DW + { + public byte Header1; + public byte Header2; + public IC_CMD Cmd; + public MORKI_MODE Mode; + public short CalcCode; + + public ICMSG_MODE_DW() { + Header1 = MessageDefine.HEADER1; + Header2 = MessageDefine.HEADER2_DW; + Cmd = IC_CMD.MODE; + } + + public static ICMSG_MODE_DW Build(MORKI_MODE mode) { + ICMSG_MODE_DW temp = new ICMSG_MODE_DW(); + temp.Mode = mode; + temp.CalcCode = (short)((byte)temp.Cmd + (byte)temp.Mode); + return temp; + } + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_UP.cs b/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_UP.cs new file mode 100644 index 00000000..3f16a278 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/ICMSG_MODE_UP.cs @@ -0,0 +1,28 @@ +using System.Runtime.InteropServices; +using static BPASmartClient.GSIceCream.MessageDefine; + +namespace BPASmartClient.GSIceCream +{ + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public class ICMSG_MODE_UP + { + public byte Header1; + public byte Header2; + public IC_CMD Cmd; + public MORKI_MODE Mode; + public short CalcCode; + + public ICMSG_MODE_UP() { + Header1 = MessageDefine.HEADER1; + Header2 = MessageDefine.HEADER2_DW; + Cmd = IC_CMD.MODE; + } + + public static ICMSG_MODE_DW Build(MORKI_MODE mode) { + ICMSG_MODE_DW temp = new ICMSG_MODE_DW(); + temp.Mode = mode; + temp.CalcCode = (short)((byte)temp.Cmd + (byte)temp.Mode); + return temp; + } + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/IcPack.cs b/BPASmartClient.GSIceCream/Protocal/IcPack.cs new file mode 100644 index 00000000..e7f9d413 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/IcPack.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.GSIceCream +{ + public class IcPack + { + private const int BASIC_LENGTH = 5; + public static byte[] StructureToByte(T structure) + { + int size = Marshal.SizeOf(typeof(T)); + byte[] buffer = new byte[size]; + IntPtr bufferIntPtr = Marshal.AllocHGlobal(size); + try + { + Marshal.StructureToPtr(structure, bufferIntPtr, true); + Marshal.Copy(bufferIntPtr, buffer, 0, size); + } + finally + { + Marshal.FreeHGlobal(bufferIntPtr); + } + return buffer; + } + + /// + /// 由byte数组转换为结构体 + /// + public static T ByteToStructure(byte[] dataBuffer) + { + object structure = null; + int size = Marshal.SizeOf(typeof(T)); + IntPtr allocIntPtr = Marshal.AllocHGlobal(size); + try + { + Marshal.Copy(dataBuffer, 0, allocIntPtr, size); + structure = Marshal.PtrToStructure(allocIntPtr, typeof(T)); + } + finally + { + Marshal.FreeHGlobal(allocIntPtr); + } + return (T)structure; + } + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/MORKI_FAULT.cs b/BPASmartClient.GSIceCream/Protocal/MORKI_FAULT.cs new file mode 100644 index 00000000..161aabc2 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/MORKI_FAULT.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.GSIceCream +{ + /// + /// 故障 + /// + public enum MORKI_FAULT + { + 未发生故障 = 0, + + 通讯故障 = 1 >> 15, + 电流过载 = 1 >> 14, + 环境温度过高 = 1 >> 13, + 环境温度异常 = 1 >> 12, + 进气温度故障 = 1 >> 11, + 保鲜温度异常 = 1 >> 10, + 冷冻温度异常 = 1 >> 9, + + 电压过高 = 1, + 电压过低 = 1 >> 1, + 制冷不良 = 1 >> 2, + 转速传感器异常 = 1 >> 3, + 皮带打滑 = 1 >> 4, + 冻缸报警 = 1 >> 5, + 缺料报警 = 1 >> 6, + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/MORKI_MODE.cs b/BPASmartClient.GSIceCream/Protocal/MORKI_MODE.cs new file mode 100644 index 00000000..85e40580 --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/MORKI_MODE.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.GSIceCream +{ + /* + * 模式 参数 + 制冷模式 0x01 + 清洗模式 0x02 + 保鲜模式 0x03 + 解冻模式 0x04 + 待机模式 0x05 + 清除故障 0x06 + 恢复出厂设置 0x09 + 重启制冷模式 0x10 + 打料(只在制冷模式有效) 0x11 + 清空杯数 0x12 + 开始打料(在制冷模式下无效) 0x13 + 结束打料(在制冷模式下无效) 0x14 + * */ + public enum MORKI_MODE : byte + { + 未知 = 0x00, + 制冷模式 = 0x01, + 清洗模式 = 0x02, + 保鲜模式 = 0x03, + 解冻模式 = 0x04, + 待机模式 = 0x05, + 清除故障 = 0x06, + 恢复出厂设置 = 0x09, + 重启制冷模式 = 0x10, + 打料 = 0x11, + 清空杯数 = 0x12, + 开始打料 = 0x13, + 结束打料 = 0x14 + } +} diff --git a/BPASmartClient.GSIceCream/Protocal/MessageDefine.cs b/BPASmartClient.GSIceCream/Protocal/MessageDefine.cs new file mode 100644 index 00000000..9e11ff6c --- /dev/null +++ b/BPASmartClient.GSIceCream/Protocal/MessageDefine.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.GSIceCream +{ + public class MessageDefine + { + /// + /// 帧头1 + /// + public static byte HEADER1 = 0xAA; + /// + /// 帧头2 + /// + public static byte HEADER2_DW = 0xA5; + public static byte HEADER2_UP = 0x5A; + + public enum IC_CMD : byte + { + HEART = 0x09, + MODE=0x01, + } + + public enum ICMSG_TYPE : byte + { + UP = 0x5A, + DOWN = 0xA5, + } + + + + + public static Dictionary MSG_LENGTH = new Dictionary() { + { IC_CMD.HEART,18}, + { IC_CMD.MODE,2}, + }; + + } + + public enum MSG_RESOLVE_STEP + { + NONE, + HEADER1, + HEADER2, + CMD, + CONTENT, + VALIDATE1, + VALIDATE2 + } +} + + + diff --git a/BPASmartClient.MessageCommunication/BPASmartClient.MessageCommunication.csproj b/BPASmartClient.MessageCommunication/BPASmartClient.MessageCommunication.csproj new file mode 100644 index 00000000..f208d303 --- /dev/null +++ b/BPASmartClient.MessageCommunication/BPASmartClient.MessageCommunication.csproj @@ -0,0 +1,7 @@ + + + + net5.0 + + + diff --git a/BPASmartClient.MessageCommunication/Class_InnerMessageBus.cs b/BPASmartClient.MessageCommunication/Class_InnerMessageBus.cs new file mode 100644 index 00000000..28c8ddb7 --- /dev/null +++ b/BPASmartClient.MessageCommunication/Class_InnerMessageBus.cs @@ -0,0 +1,65 @@ +using BPASmartClient.MessageCommunication.MsgControl; +using System; + +namespace BPASmartClient.MessageCommunication +{ + /// + /// 该类实现客户端构件间消息的传递,底层使用整编的构件消息API + /// 创建人:奉友福 + /// 创建时间:2022-04-18 + /// Class_InnerMessageBus.GetInstance().ListenMessage(this, MessageName.xxname, "xxnameHandler"); + /// Class_InnerMessageBus.GetInstance().PostMessage(this, MessageName.xxname, "12321"); + /// public void xxnameHandler(object sender, InnerMessageEventArgs e) { } + /// + public class Class_InnerMessageBus + { + public static Class_InnerMessageBus _MessageBus = null; + static InnerMessageBus Bus = null; + public static Class_InnerMessageBus GetInstance() + { + if (_MessageBus == null) + { + _MessageBus = new Class_InnerMessageBus(); + Bus = new InnerMessageBus(); + } + return _MessageBus; + } + + /// + /// 监听消息方法 + /// + /// 订阅消息构件 + /// 消息名称 + /// 接收消息后回调处理函数 注意:该函数必须为Public + public void ListenMessage(object sender,string str_MessageString,string str_MessageName) + { + Bus.ListenMessage(sender,str_MessageString,str_MessageName); + } + + /// + /// 消息发送函数 + /// + /// 发送消息构件 + /// 消息名称 + /// 消息体 + public void PostMessage(object sender,string str_Msg,object obj_Data) + { + Bus.PostMessage(sender,str_Msg,obj_Data); + } + + /// + /// 移除消息方法 + /// + /// 消息名称 + /// 接收消息后回调处理函数 + public void RemoveMessage(string str_MessageString,string str_MessageName) + { + Bus.ListenMessage_trunOff(str_MessageString,str_MessageName); + } + + public int GetdRountCount() + { + return Bus.__Debug_RoutTable.Count; + } + } +} diff --git a/BPASmartClient.MessageCommunication/Class_MessageName.cs b/BPASmartClient.MessageCommunication/Class_MessageName.cs new file mode 100644 index 00000000..e4d38c78 --- /dev/null +++ b/BPASmartClient.MessageCommunication/Class_MessageName.cs @@ -0,0 +1,67 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication +{ + /// + /// 消息名称管理 + /// + public class Class_MessageName + { + #region 咖博士咖啡机消息名称 + /// + /// 咖博士咖啡机制作 + /// + public static string DRCoffee_MakeCoffee = "DRCoffee_MakeCoffee"; + /// + /// 咖博士咖啡机取消制作咖啡 + /// + public static string DRCoffee_CancelMakeCoffee = "DRCoffee_CancelMakeCoffee"; + /// + /// 咖博士咖啡机模式设置 + /// + public static string DRCoffee_CoffeeCommCmd = "DRCoffee_CoffeeCommCmd"; + /// + /// 咖博士咖啡机结束制作 + /// + public static string DRCoffee_CoffeEndCook = "DRCoffee_CoffeEndCook"; + #endregion + + #region 广深冰淇淋消息名称 + /// + /// 广深冰淇淋机模式设置 + /// + public static string GSIceCream_ModeSet = "DRCoffee_CoffeEndCook"; + /// + /// 广深冰淇淋机打料 + /// + public static string GSIceCream_Discharge = "GSIceCream_Discharge"; + /// + /// 广深冰淇淋机结束制作 + /// + public static string GSIceCream_EndCook = "GSIceCream_EndCook"; + #endregion + + #region STM32F103RCT6单片机消息名称 + /// + /// STM32F103RCT6单片机下杯 + /// + public static string SCChip_TakeCup = "SCChip_TakeCup"; + /// + /// STM32F103RCT6单片机舵机打料 + /// + public static string SCChip_MakeIceCream = "SCChip_MakeIceCream"; + /// + /// STM32F103RCT6单片机舵机打开或者关闭 + /// + public static string SCChip_SESwitchCream = "SCChip_SESwitchCream"; + /// + /// STM32F103RCT6单片机控制冰淇淋机器转 + /// + public static string SCChip_RotorSwitch = "SCChip_RotorSwitch"; + #endregion + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/Enum/enum_MsgOptType.cs b/BPASmartClient.MessageCommunication/MsgControl/Enum/enum_MsgOptType.cs new file mode 100644 index 00000000..93a00de9 --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/Enum/enum_MsgOptType.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl.Enum +{ + /// + /// 消息通知枚举 + /// + public enum enum_MsgOptType + { + Sender, + Getter + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/InnerMessageBus.cs b/BPASmartClient.MessageCommunication/MsgControl/InnerMessageBus.cs new file mode 100644 index 00000000..289191dc --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/InnerMessageBus.cs @@ -0,0 +1,278 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl +{ + /// + /// 内部消息总线 + /// + public class InnerMessageBus + { + static InnerMessageBus _bus; + const int TimeOut = 2000; + static public InnerMessageBus Get_Instance() + { + if (_bus == null) + { + _bus = new InnerMessageBus(); + } + return _bus; + } + + #region 委托事件的定义 + /// + /// 当触发引用事件时执行的委托 + /// + public delegate void MessageEventHandler(object sender,InnerMessageEventArgs e); + #endregion + + #region 自定义各类响应事件 + /// + /// 返回为整数型的结果事件响应 + /// + public event MessageEventHandler M_Event_消息事件; + #endregion + + private readonly Object thisLock = new Object(); + + /// + /// 发送消息方法 + /// ---------------------------------------------- + /// + /// 消息发送者 + /// 消息名称串 + /// 消息体数据区 + public void PostMessage(object sender,string str_Msg,object obj_Data) + { + bool isLock = false; + System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock); + if (!isLock)//理论上不可能出现 + { + return; + } + try + { + var temp = RouteTable.ToList(); + + foreach (ListenPointInfo item in temp) + { + if (MachMessageName(str_Msg,item)) + { + InnerMessageEventArgs temp_arg = new InnerMessageEventArgs(); + temp_arg.obj_Sender = sender; + temp_arg.obj_MessageObj = obj_Data; + temp_arg.str_MessageStr = str_Msg; + TypeHelper helper = new TypeHelper(); + object[] args = new object[2]; + args[0] = sender; + args[1] = temp_arg; + + if (sender != null) + { + try + { + helper.M_Call_InstancMethod(item.PointObj,item.MethodName,args); + } + catch (Exception exp) + { + + } + } + } + } + } + catch (Exception exp) + { + //接收消息的调用方法发生异常 + } + finally + { + System.Threading.Monitor.Exit(thisLock); + } + } + + /// + /// 采用正则表达式匹配字符串 + /// + /// + /// + /// + private static bool MachMessageName(string MessageString,ListenPointInfo item) + { + string value; + string pattern; + value = MessageString; + try + { + pattern = item.str_Message.Replace("*",@"[-\.\w]*"); + ///使用正则表达式进行消息路由匹配; + if (pattern.Contains('*')) + { + if (Regex.IsMatch(value,pattern)) + { + //Console.WriteLine("路由消息" + MessageString + " * " + (((item.PointObj.GetType()).FullName + "匹配成功!"))); + return true; + } + else + { + return false; + } + } + else + { + if (value == pattern) + { + //Console.WriteLine("路由消息" + MessageString + "匹配成功!"); + return true; + } + else + { + return false; + } + } + + } + catch (Exception ex) + { + Console.WriteLine("InnerMessageBus类MachMessageName方法出错,原因:" + ex.Message); + + return false; + } + } + + /// + /// 消息路由表,内部的 + /// + List RouteTable = new List(); + + /// + /// 外部应用调用消息 + /// + /// 消息监听对象者 + /// + /// + public void ListenMessage(object obj_Listener,string str_MessageString,string str_处理方法名称) + { + // arg = new InnerMessageEventArgs(); + Type[] argTypes = new Type[2]; + argTypes[0] = typeof(object); + argTypes[1] = typeof(InnerMessageEventArgs); + + if (obj_Listener.GetType().GetMethod(str_处理方法名称,argTypes) != null) + { + ListenPointInfo info = new ListenPointInfo(); + info.PointObj = obj_Listener; + info.str_Message = str_MessageString; + info.MethodName = str_处理方法名称; + bool isLock = false; + System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock); + if (!isLock)//理论上不可能出现 + { + return; + } + try + { + RouteTable.Add(info); + } + finally + { + System.Threading.Monitor.Exit(thisLock); + } + + } + else + { + TypeHelper helper = new TypeHelper(); + if ((helper.M_GetMethodInfosByName(obj_Listener.GetType(),str_处理方法名称).Count != 1)) + { + //taoye modified + Console.WriteLine("在使用消息中间件时,希望执行ListenMessage方法,绑定" + obj_Listener.GetType().ToString() + "中方法:" + str_处理方法名称 + ",但该方法不唯一或不存在."); + } + } + + } + + /// + /// 关闭消息监听和事件的挂接关系 + /// + /// 消息名称 + /// 消息处理方法名称 + public void ListenMessage_trunOff(string str,string str_消息处理方法名称) + { + bool isLock = false; + System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock); + if (!isLock)//理论上不可能出现 + { + return; + } + try + { + for (int i = RouteTable.Count - 1; i >= 0; i--) + { + if (str == RouteTable[i].str_Message && str_消息处理方法名称 == RouteTable[i].MethodName) + { + RouteTable.RemoveAt(i); + break; + } + } + } + finally + { + System.Threading.Monitor.Exit(thisLock); + } + } + + /// + /// 采用对象方式直接释放指定对象的监听信息 + /// + /// + /// + private bool RemoveRouteTableByObject(object obj) + { + bool isLock = false; + System.Threading.Monitor.TryEnter(thisLock,TimeOut,ref isLock); + if (!isLock)//理论上不可能出现 + { + return false; + } + bool result = false; + int currentI = -1; + try + { + for (int i = 0; i < this.RouteTable.Count; i++) + { + if (RouteTable[i].PointObj == obj) + { + currentI = i; + } + } + + if (currentI != -1) + { + RouteTable.RemoveAt(currentI); + result = true; + } + } + finally + { + System.Threading.Monitor.Exit(thisLock); + } + return result; + } + + /// + /// 调试用属性,获取当前路由表所有的信息,只读 + /// + public List __Debug_RoutTable + { + get + { + return this.RouteTable; + } + } + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/InnerMessageEventArgs.cs b/BPASmartClient.MessageCommunication/MsgControl/InnerMessageEventArgs.cs new file mode 100644 index 00000000..c7d3cac4 --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/InnerMessageEventArgs.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl +{ + /// + /// 内部消息的事件参数 + /// + public class InnerMessageEventArgs :Object + { + public object obj_Sender; + public string str_MessageStr; + public object obj_MessageObj; + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/ListenPointInfo.cs b/BPASmartClient.MessageCommunication/MsgControl/ListenPointInfo.cs new file mode 100644 index 00000000..ad1b3ca7 --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/ListenPointInfo.cs @@ -0,0 +1,31 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl +{ + /// + /// 监听节点信息 + /// 创建人:奉友福 + /// + public class ListenPointInfo + { + public object PointObj + { + get; + set; + } + public string str_Message + { + get; + set; + } + public string MethodName + { + get; + set; + } + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/Model/MsgAttribute.cs b/BPASmartClient.MessageCommunication/MsgControl/Model/MsgAttribute.cs new file mode 100644 index 00000000..28f9448a --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/Model/MsgAttribute.cs @@ -0,0 +1,25 @@ +using BPASmartClient.MessageCommunication.MsgControl.Enum; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl.Model +{ + /// + /// 模型的类型中的属性的特性定义,是否是属于列表中的选择框字段项 + /// 创建人:奉友福 + /// + public class MsgAttribute :Attribute + { + public enum_MsgOptType enum_消息方向; + public Type type_数据对象类型; + public string str_发送方法名; + public string str_消息描述 + { + get; + set; + } + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/Model/方法描述.cs b/BPASmartClient.MessageCommunication/MsgControl/Model/方法描述.cs new file mode 100644 index 00000000..12751237 --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/Model/方法描述.cs @@ -0,0 +1,14 @@ +using System; +using System.Reflection; + +namespace BPASmartClient.MessageCommunication.MsgControl.Model +{ + public class 方法描述 + { + public Type Obj_Type; + + public MethodInfo M_MethodInfo; + + public ParameterInfo[] M_ParameterInfos; + } +} diff --git a/BPASmartClient.MessageCommunication/MsgControl/TypeHelper.cs b/BPASmartClient.MessageCommunication/MsgControl/TypeHelper.cs new file mode 100644 index 00000000..17709f9e --- /dev/null +++ b/BPASmartClient.MessageCommunication/MsgControl/TypeHelper.cs @@ -0,0 +1,244 @@ +using BPASmartClient.MessageCommunication.MsgControl.Model; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.MessageCommunication.MsgControl +{ + public class TypeHelper + { + public Type M_GetTypeByName(string filepath,string TypeName) + { + try + { + if (!File.Exists(filepath)) + { + return null; + } + + Assembly assembly = Assembly.LoadFrom(filepath); + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.Name == TypeName) + { + return type; + } + } + } + catch (Exception ex) + { + Exception ex2 = ex; + return null; + } + + return null; + } + + public Type M_GetTypeByFullName(string filepath,string TypeFullName) + { + try + { + if (!File.Exists(filepath)) + { + return null; + } + + Assembly assembly = Assembly.LoadFrom(filepath); + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + if (type.FullName == TypeFullName) + { + return type; + } + } + } + catch (Exception ex) + { + Exception ex2 = ex; + return null; + } + + return null; + } + + public object M_GetPropertyValue(object obj,string Str_PropertyName) + { + Type type = obj.GetType(); + PropertyInfo property = type.GetProperty(Str_PropertyName); + if (null != property) + { + return property.GetValue(obj,null); + } + + return null; + } + + public void M_SetFieldInfoValue(object Target_obj,string Str_PropertyName,object obj_Value) + { + Type type = Target_obj.GetType(); + FieldInfo field = type.GetField(Str_PropertyName); + field.SetValue(Target_obj,obj_Value); + } + + public FieldInfo[] M_Get_PublicFieldInfos(Type type) + { + return type.GetFields(); + } + + public FieldInfo[] M_Get_AllFieldInfosByObject(object obj) + { + Type type = obj.GetType(); + return type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); + } + + public FieldInfo[] M_Get_AllFieldInfos(Type type) + { + return type.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy); + } + + public Type M_GetPropertyType(object Target_obj,string Str_PropertyName) + { + Type type = Target_obj.GetType(); + PropertyInfo property = type.GetProperty(Str_PropertyName); + return property.PropertyType; + } + + public MethodInfo[] M_GetMethodInfos(Type userType) + { + return userType.GetMethods(); + } + + public List<方法描述> M_GetMethodInfosByName(Type userType,string str_MethedName) + { + List<方法描述> list = new List<方法描述>(); + MethodInfo[] methods = userType.GetMethods(); + foreach (MethodInfo methodInfo in methods) + { + if (methodInfo.Name == str_MethedName) + { + 方法描述 方法描述 = new 方法描述(); + 方法描述.Obj_Type = userType; + 方法描述.M_MethodInfo = methodInfo; + 方法描述.M_ParameterInfos = methodInfo.GetParameters(); + list.Add(方法描述); + } + } + + return list; + } + + public 方法描述 M_GetMethodInfosByNameandParmarTypes(Type userType,string str_MethedName,Type[] parmerTypes) + { + //IL_002b: Unknown result type (might be due to invalid IL or missing references) + MethodInfo method; + try + { + method = userType.GetMethod(str_MethedName,parmerTypes); + } + catch (Exception ex) + { + //MessageBox.Show("对" + userType.FullName + "执行: M_GetMethodInfosByNameandParmarTypes发生异常," + ex.Message); + return null; + } + + if (method == null) + { + return null; + } + + 方法描述 方法描述 = new 方法描述(); + 方法描述.Obj_Type = userType; + 方法描述.M_MethodInfo = method; + 方法描述.M_ParameterInfos = method.GetParameters(); + return 方法描述; + } + + public object M_Call_InstancMethod(object objInstance,string str_MethodName,object[] obj_Parmeters) + { + MethodInfo method; + if (obj_Parmeters != null) + { + Type[] array = new Type[obj_Parmeters.Count()]; + for (int i = 0; i < obj_Parmeters.Count(); i++) + { + array[i] = obj_Parmeters[i].GetType(); + } + + method = objInstance.GetType().GetMethod(str_MethodName,array); + return method.Invoke(objInstance,obj_Parmeters); + } + + method = objInstance.GetType().GetMethod(str_MethodName,new Type[0]); + return method.Invoke(objInstance,null); + } + + public EventInfo[] M_GetEvents(Type userType) + { + return userType.GetEvents(); + } + + public void M_AddEventProcess() + { + } + + public PropertyInfo[] M_GetPropertyInfos(Type userType) + { + return userType.GetProperties(); + } + + public PropertyInfo[] M_GetPropertyInfos(object userObject) + { + return userObject.GetType().GetProperties(); + } + + public void M_Set_InstancPropertiValue(object obj_Instanc,string str_PropertieName,object values) + { + PropertyInfo property = obj_Instanc.GetType().GetProperty(str_PropertieName); + property.SetValue(obj_Instanc,values,null); + } + + public object M_Get_InstancPropertiValue(object obj_Instanc,string str_PropertieName) + { + if (obj_Instanc == null) + { + return null; + } + + PropertyInfo property = obj_Instanc.GetType().GetProperty(str_PropertieName); + if (property != null) + { + return property.GetValue(obj_Instanc,null); + } + + return null; + } + + public bool M_SetEventPropressFun(object obj_targetInstance,string eventname,object obj_processInstance,string funname) + { + bool flag = false; + try + { + TypeHelper m_TypeHelper = new TypeHelper(); + obj_targetInstance.GetType(); + EventInfo @event = obj_targetInstance.GetType().GetEvent(eventname); + Type eventHandlerType = @event.EventHandlerType; + MethodInfo m_MethodInfo = m_TypeHelper.M_GetMethodInfosByName(obj_processInstance.GetType(),funname)[0].M_MethodInfo; + Delegate handler = Delegate.CreateDelegate(eventHandlerType,obj_processInstance,funname); + @event.AddEventHandler(obj_targetInstance,handler); + return true; + } + catch (Exception) + { + flag = false; + throw; + } + } + } + +} diff --git a/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj b/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj index dbc15171..e645d6a1 100644 --- a/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj +++ b/BPASmartClient.SCChip/BPASmartClient.SCChip.csproj @@ -4,4 +4,9 @@ net6.0 + + + + + diff --git a/BPASmartClient.SCChip/ChipStatus.cs b/BPASmartClient.SCChip/ChipStatus.cs new file mode 100644 index 00000000..38f6a68f --- /dev/null +++ b/BPASmartClient.SCChip/ChipStatus.cs @@ -0,0 +1,128 @@ +using System; + +namespace BPASmartClient.SCChip +{ + public class ChipStatus + { + private volatile static ChipStatus _Instance; + public static ChipStatus GetInstance() => _Instance ?? (_Instance = new ChipStatus()); + private ChipStatus() { } + + private DateTime lastRefreshTime = DateTime.MinValue; + /// + /// 是否在线 + /// + public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } + /// + /// 取冰淇淋杯完成 + /// + public bool CompletedTake_CPU_CUP_ICECREAM { get; set; } + /// + /// 取咖啡杯完成 + /// + public bool CompletedTake_CPU_CUP_COFFEE { get; set; } + /// + /// 1号舵机打开完成 + /// + public bool CompletedOpen_SE_1 { get; set; } + /// + /// 2号舵机打开完成 + /// + public bool CompletedOpen_SE_2 { get; set; } + /// + /// 3号舵机打开完成 + /// + public bool CompletedOpen_SE_3 { get; set; } + /// + /// 1号舵机关闭完成 + /// + public bool CompletedClose_SE_1 { get; set; } + /// + /// 2号舵机关闭完成 + /// + public bool CompletedClose_SE_2 { get; set; } + /// + /// 3号舵机关闭完成 + /// + public bool CompletedClose_SE_3 { get; set; } + /// + /// 是否存在物品 + /// + public bool ArticleExits { get; set; } + /// + /// 物品距离 + /// + public byte ArticleDist { get; set; } + + public bool CanDo + { + get + { + if (!OnLine) + return false; + return true; + } + } + + public void ProcessMsg(ICChipPackage data) + { + try + { + switch (data.Cmd) + { + case IC_CMD.HEART_BEAT: + lastRefreshTime = DateTime.Now; + break; + case IC_CMD.TAKE_CUP: + switch ((IC_CUP)data.Value) { + case IC_CUP.CUP_COFFEE: + CompletedTake_CPU_CUP_COFFEE = true; + break; + case IC_CUP.CUP_ICECREAM: + CompletedTake_CPU_CUP_ICECREAM = true; + break; + } + break; + case IC_CMD.OPEN_SE: + switch ((IC_SE)data.Value) + { + case IC_SE.SE_1: + CompletedOpen_SE_1 = true; + break; + case IC_SE.SE_2: + CompletedOpen_SE_2 = true; + break; + case IC_SE.SE_3: + CompletedOpen_SE_3 = true; + break; + } + break; + case IC_CMD.CLOSE_SE: + switch ((IC_SE)data.Value) + { + case IC_SE.SE_1: + CompletedClose_SE_1 = true; + break; + case IC_SE.SE_2: + CompletedClose_SE_2 = true; + break; + case IC_SE.SE_3: + CompletedClose_SE_3 = true; + break; + } + break; + case IC_CMD.ARTICLE_EXITS: + ArticleExits = data.Value > 0; + break; + case IC_CMD.ARTICLE_DIST: + ArticleDist = data.Value; + break; + } + } + catch (Exception ex) + { + + } + } + } +} diff --git a/BPASmartClient.SCChip/Class1.cs b/BPASmartClient.SCChip/Class1.cs deleted file mode 100644 index 9e542251..00000000 --- a/BPASmartClient.SCChip/Class1.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -namespace BPASmartClient.SCChip -{ - public class Class1 - { - } -} diff --git a/BPASmartClient.SCChip/CommandEvent.cs b/BPASmartClient.SCChip/CommandEvent.cs new file mode 100644 index 00000000..e7d500f8 --- /dev/null +++ b/BPASmartClient.SCChip/CommandEvent.cs @@ -0,0 +1,42 @@ +using BPASmartClient.SCChip; + +namespace BPASmartClient.SCChip +{ + public class TakeCupEvent + { + /// + /// 杯 + /// + public IC_CUP Cup { get; set; } + } + + public class MakeIceCreamEvent + { + public IC_SE SteeringEngine { get; set; } + } + + public class SESwitchCreamEvent + { + public IC_SE SteeringEngine { get; set; } + public bool IsOpen { get; set; } + } + + public class RotorSwitchEvent + { + public bool TurnOn { get; set; } + } + /// + /// 检测有无杯子 + /// + public class ArticleExitsEvent + { + + } + /// + /// 检测物品距离 + /// + public class ArticleDistEvent + { + + } +} diff --git a/BPASmartClient.SCChip/CommandHandler.cs b/BPASmartClient.SCChip/CommandHandler.cs new file mode 100644 index 00000000..157670ba --- /dev/null +++ b/BPASmartClient.SCChip/CommandHandler.cs @@ -0,0 +1,225 @@ +using BPASmartClient.Message; +using BPASmartClient.MessageCommunication; +using BPASmartClient.MessageCommunication.MsgControl; +using BPASmartClient.SerialPort; +using System; +using System.Runtime.InteropServices; +using System.Threading; + +namespace BPASmartClient.SCChip +{ + /// + /// 指令封装 + /// + internal class CommandHandler + { + private SerialPortClient commProxy; + private ICChipPackage package = new ICChipPackage(); + + /// + /// 初始化 + /// + internal void Init(SerialPortClient commProxy) + { + this.commProxy = commProxy; + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.SCChip_TakeCup,"TakeCupHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.SCChip_MakeIceCream,"MakeIceCreamHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.SCChip_SESwitchCream,"SESwitchCreamHandler"); + Class_InnerMessageBus.GetInstance().ListenMessage(this,Class_MessageName.SCChip_RotorSwitch,"RotorSwitchHandler"); + + } + + /// + /// STM32F103RCT6单片机舵机打开或者关闭 + /// + public void SESwitchCreamHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is TakeCupEvent) + { + ChipStatus.GetInstance().ArticleDist = 0; + package.Cmd = (e.obj_MessageObj as SESwitchCreamEvent).IsOpen ? IC_CMD.OPEN_SE : IC_CMD.CLOSE_SE; + package.Value = (byte)(e.obj_MessageObj as SESwitchCreamEvent).SteeringEngine; + commProxy.SendData(StructureToByte(package)); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.SCChip 中引发错误,SESwitchCreamHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// STM32F103RCT6单片机控制冰淇淋机器转 + /// + public void RotorSwitchHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is RotorSwitchEvent) + { + package.Cmd = IC_CMD.ROTOR; + package.Value = (e.obj_MessageObj as RotorSwitchEvent).TurnOn ? (byte)IC_ROTOR.OPEN_ROTOR : (byte)IC_ROTOR.CLOSE_ROTOR; + commProxy.SendData(StructureToByte(package)); + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.SCChip 中引发错误,RotorSwitchHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// STM32F103RCT6单片机舵机打料 + /// + public void MakeIceCreamHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is MakeIceCreamEvent) + { + switch ((e.obj_MessageObj as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + ChipStatus.GetInstance().CompletedOpen_SE_1 = false; + break; + case IC_SE.SE_2: + ChipStatus.GetInstance().CompletedOpen_SE_2 = false; + break; + case IC_SE.SE_3: + ChipStatus.GetInstance().CompletedOpen_SE_3 = false; + break; + } + package.Cmd = IC_CMD.OPEN_SE; + package.Value = (byte)(e.obj_MessageObj as MakeIceCreamEvent).SteeringEngine; + commProxy.SendData(StructureToByte(package)); + + bool wait = true; + DateTime waitTimeout = DateTime.Now.AddSeconds(3); + while (wait) + { + wait = DateTime.Now < waitTimeout; + if (wait) + { + switch ((e.obj_MessageObj as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + wait = !ChipStatus.GetInstance().CompletedOpen_SE_1; + break; + case IC_SE.SE_2: + wait = !ChipStatus.GetInstance().CompletedOpen_SE_2; + break; + case IC_SE.SE_3: + wait = !ChipStatus.GetInstance().CompletedOpen_SE_3; + break; + } + } + Thread.Sleep(10); + } + Thread.Sleep(2000); + package.Cmd = IC_CMD.CLOSE_SE; + package.Value = (byte)(e.obj_MessageObj as MakeIceCreamEvent).SteeringEngine; + commProxy.SendData(StructureToByte(package)); + + wait = true; + waitTimeout = DateTime.Now.AddSeconds(3); + while (wait) + { + wait = DateTime.Now < waitTimeout; + if (wait) + { + switch ((e.obj_MessageObj as MakeIceCreamEvent).SteeringEngine) + { + case IC_SE.SE_1: + wait = !ChipStatus.GetInstance().CompletedClose_SE_1; + break; + case IC_SE.SE_2: + wait = !ChipStatus.GetInstance().CompletedClose_SE_2; + break; + case IC_SE.SE_3: + wait = !ChipStatus.GetInstance().CompletedClose_SE_3; + break; + } + } + Thread.Sleep(10); + } + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.SCChip 中引发错误,MakeIceCreamHandler 类,描述:[{ex.Message}]"); + } + } + + /// + /// STM32F103RCT6单片机下杯 + /// + public void TakeCupHandler(object sender,InnerMessageEventArgs e) + { + try + { + if (e.obj_MessageObj is TakeCupEvent) + { + switch ((e.obj_MessageObj as TakeCupEvent).Cup) + { + case IC_CUP.CUP_ICECREAM: + ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM = false; + break; + case IC_CUP.CUP_COFFEE: + ChipStatus.GetInstance().CompletedTake_CPU_CUP_COFFEE = false; + break; + } + package.Cmd = IC_CMD.TAKE_CUP; + package.Value = (byte)(e.obj_MessageObj as TakeCupEvent).Cup; + commProxy.SendData(StructureToByte(package)); + + bool wait = true; + var waitTimeout = DateTime.Now.AddSeconds(3); + while (wait) + { + wait = DateTime.Now < waitTimeout; + if (wait) + { + switch ((e.obj_MessageObj as TakeCupEvent).Cup) + { + case IC_CUP.CUP_ICECREAM: + wait = !ChipStatus.GetInstance().CompletedTake_CPU_CUP_ICECREAM; + break; + case IC_CUP.CUP_COFFEE: + wait = !ChipStatus.GetInstance().CompletedTake_CPU_CUP_COFFEE; + break; + } + } + Thread.Sleep(10); + } + } + } + catch (Exception ex) + { + MessageLog.GetInstance.Show($"BPASmartClient.SCChip 中引发错误,TakeCupHandler 类,描述:[{ex.Message}]"); + } + } + + private byte[] StructureToByte(ICChipPackage structure) + { + structure.Header = 0xAA; + structure.Sender = IC_SENDER.CONSOLE; + structure.End = 0xBB; + + int size = Marshal.SizeOf(typeof(ICChipPackage)); + byte[] buffer = new byte[size]; + IntPtr bufferIntPtr = Marshal.AllocHGlobal(size); + try + { + Marshal.StructureToPtr(structure, bufferIntPtr, true); + Marshal.Copy(bufferIntPtr, buffer, 0, size); + } + finally + { + Marshal.FreeHGlobal(bufferIntPtr); + } + return buffer; + } + } +} diff --git a/BPASmartClient.SCChip/ICChipMachine.cs b/BPASmartClient.SCChip/ICChipMachine.cs new file mode 100644 index 00000000..4b0eeb9e --- /dev/null +++ b/BPASmartClient.SCChip/ICChipMachine.cs @@ -0,0 +1,101 @@ +using BPASmartClient.Helper; +using BPASmartClient.SerialPort; +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; + +namespace BPASmartClient.SCChip +{ + public class ICChipMachine + { + //指令组装 + private CommandHandler commandHandler = new CommandHandler(); + //通讯代理 + SerialPortClient commProxy = null; + //数据仓库 + private DataStorage dataStorage = new DataStorage(); + //主线程运行标识 + private bool running = false; + //是否下发指令,主线程等待 + public Action SendCallback; + public Action ReciveCallback; + + + + public ICChipMachine(string portName, BaudRates baud) + { + commProxy = new SerialPortClient(portName, baud); + commProxy.SetDataStorage(dataStorage); + commandHandler.Init(commProxy); + } + + public void Start() + { + commProxy.Start(); + running = true; + MainLoop(); + } + + public void Stop() + { + } + + private void MainLoop() + { + ThreadManage.GetInstance.StartLong(new Action(() => + { + ResolveMsg(); + //Thread.Sleep(2000); + }), "单片机解析线程"); + } + + private void ResolveMsg() + { + List temp = new List(); + //一系列解包 + while (dataStorage.GetSize() > 0) + { + byte item = dataStorage.GetData(); + if (item == 0xAA) + { + temp.Add(item); + while (dataStorage.GetSize() < 4) { Thread.Sleep(5); } + while (temp.Count < 5) + { + temp.Add(dataStorage.GetData()); + } + if (temp[4] == 0xBB) + { + var package = ByteToStructure(temp.ToArray()); + ChipStatus.GetInstance().ProcessMsg(package); + } + temp.Clear(); + } + continue; + } + Thread.Sleep(5); + } + + /// + /// 由byte数组转换为结构体 + /// + private ICChipPackage ByteToStructure(byte[] dataBuffer) + { + ICChipPackage structure = new ICChipPackage(); + int size = Marshal.SizeOf(typeof(ICChipPackage)); + IntPtr allocIntPtr = Marshal.AllocHGlobal(size); + try + { + Marshal.Copy(dataBuffer, 0, allocIntPtr, size); + structure = (ICChipPackage)Marshal.PtrToStructure(allocIntPtr, typeof(ICChipPackage)); + } + finally + { + Marshal.FreeHGlobal(allocIntPtr); + } + return structure; + } + } + +} diff --git a/BPASmartClient.SCChip/Protocal/ICChipPackage.cs b/BPASmartClient.SCChip/Protocal/ICChipPackage.cs new file mode 100644 index 00000000..3496f161 --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/ICChipPackage.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// Dr咖啡机基础协议 + /// + [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] + public struct ICChipPackage + { + /// + /// 包头(固定0xAA) + /// + public byte Header; + /// + /// 发送方 + /// + public IC_SENDER Sender; + /// + /// 命令 + /// + public IC_CMD Cmd; + /// + /// 值 + /// + public byte Value; + /// + /// 包尾(固定为0xBB) + /// + public byte End; + } +} diff --git a/BPASmartClient.SCChip/Protocal/IC_CMD.cs b/BPASmartClient.SCChip/Protocal/IC_CMD.cs new file mode 100644 index 00000000..41523526 --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/IC_CMD.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// 命令 + /// + public enum IC_CMD : byte + { + /// + /// 心跳 + /// + HEART_BEAT = 0x00, + /// + /// 下杯(带上碗参数) + /// + TAKE_CUP = 0x01, + /// + /// 打开舵机(带上舵机参数) + /// + OPEN_SE = 0x02, + /// + /// 关闭舵机(带上舵机参数) + /// + CLOSE_SE = 0x03, + /// + /// 使能冰淇淋转子(带上开关参数) + /// + ROTOR = 0x04, + /// + /// 检测是否有物品 + /// + ARTICLE_EXITS = 0x05, + /// + /// 检测物品距离 + /// + ARTICLE_DIST = 0x06 + } +} diff --git a/BPASmartClient.SCChip/Protocal/IC_CUP.cs b/BPASmartClient.SCChip/Protocal/IC_CUP.cs new file mode 100644 index 00000000..a85f0e58 --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/IC_CUP.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// 杯子 + /// + public enum IC_CUP : byte + { + /// + /// 冰淇淋杯 + /// + CUP_ICECREAM = 0x01, + /// + /// 咖啡杯 + /// + CUP_COFFEE = 0x02 + } +} diff --git a/BPASmartClient.SCChip/Protocal/IC_ROTOR.cs b/BPASmartClient.SCChip/Protocal/IC_ROTOR.cs new file mode 100644 index 00000000..4f642f77 --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/IC_ROTOR.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// 搅拌器 + /// + public enum IC_ROTOR + { + /// + /// 开始搅拌 + /// + OPEN_ROTOR = 0x01, + /// + /// 停止搅拌 + /// + CLOSE_ROTOR = 0x00 + } +} diff --git a/BPASmartClient.SCChip/Protocal/IC_SE.cs b/BPASmartClient.SCChip/Protocal/IC_SE.cs new file mode 100644 index 00000000..5d3e073a --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/IC_SE.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// 冰淇淋舵机 + /// + public enum IC_SE:byte + { + /// + /// 舵机1 + /// + SE_1=0x01, + /// + /// 舵机2 + /// + SE_2=0x02, + /// + /// 舵机3 + /// + SE_3=0x03, + } +} diff --git a/BPASmartClient.SCChip/Protocal/IC_SENDER.cs b/BPASmartClient.SCChip/Protocal/IC_SENDER.cs new file mode 100644 index 00000000..0ab8fa65 --- /dev/null +++ b/BPASmartClient.SCChip/Protocal/IC_SENDER.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.SCChip +{ + /// + /// 命令发送方 + /// + public enum IC_SENDER:byte + { + /// + /// 上位机 + /// + CONSOLE=0x01, + /// + /// 单片机 + /// + DEVICE=0x02, + } +} diff --git a/SmartClient.sln b/SmartClient.sln index 6b900df6..eb685d14 100644 --- a/SmartClient.sln +++ b/SmartClient.sln @@ -3,33 +3,33 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.32002.185 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DRCoffee", "BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj", "{31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.DRCoffee", "BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj", "{31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.Driver", "4.Driver", "{666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.KLMCoffee", "BPASmartClient.KLMCoffee\BPASmartClient.KLMCoffee.csproj", "{BA543940-3C97-410D-B66C-1B928FCBB567}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.KLMCoffee", "BPASmartClient.KLMCoffee\BPASmartClient.KLMCoffee.csproj", "{BA543940-3C97-410D-B66C-1B928FCBB567}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.GSIceCream", "BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj", "{51E93537-DE9A-460C-B2B6-5FCB7A616A94}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.GSIceCream", "BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj", "{51E93537-DE9A-460C-B2B6-5FCB7A616A94}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SCChip", "BPASmartClient.SCChip\BPASmartClient.SCChip.csproj", "{F57AF771-8514-4020-BBF3-1708388DD4B3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.SCChip", "BPASmartClient.SCChip\BPASmartClient.SCChip.csproj", "{F57AF771-8514-4020-BBF3-1708388DD4B3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Lebai", "BPASmartClient.Lebai\BPASmartClient.Lebai.csproj", "{69F90530-ADA4-4A0C-8068-AAC5584072D7}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Lebai", "BPASmartClient.Lebai\BPASmartClient.Lebai.csproj", "{69F90530-ADA4-4A0C-8068-AAC5584072D7}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Communication", "5.Communication", "{3D1D0E04-03FD-480A-8CF8-6E01A2E28625}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SerialPort", "BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj", "{2344EB60-1760-4DF0-961A-FA5BE5BC47CC}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.SerialPort", "BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj", "{2344EB60-1760-4DF0-961A-FA5BE5BC47CC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Http", "BPASmartClient.Http\BPASmartClient.Http.csproj", "{202763AA-4C4C-4738-B530-93A9A1ECE578}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Http", "BPASmartClient.Http\BPASmartClient.Http.csproj", "{202763AA-4C4C-4738-B530-93A9A1ECE578}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Modbus", "BPASmartClient.Modbus\BPASmartClient.Modbus.csproj", "{13C86146-CD3C-4CD3-AB7F-7A155E222832}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Modbus", "BPASmartClient.Modbus\BPASmartClient.Modbus.csproj", "{13C86146-CD3C-4CD3-AB7F-7A155E222832}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.Device", "3.Device", "{9FB27073-61A0-4FE3-94DB-5FDDE062332F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkS", "BPASmartClient.MorkS\BPASmartClient.MorkS.csproj", "{0827FA85-8180-4A85-BE58-9483AC4BB3BA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkS", "BPASmartClient.MorkS\BPASmartClient.MorkS.csproj", "{0827FA85-8180-4A85-BE58-9483AC4BB3BA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkD", "BPASmartClient.MorkD\BPASmartClient.MorkD.csproj", "{8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkD", "BPASmartClient.MorkD\BPASmartClient.MorkD.csproj", "{8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkT", "BPASmartClient.MorkT\BPASmartClient.MorkT.csproj", "{B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkT", "BPASmartClient.MorkT\BPASmartClient.MorkT.csproj", "{B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Business", "2.Business", "{6CEA3385-6F62-452A-8275-033A6037235D}" EndProject @@ -37,25 +37,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.UI", "1.UI", "{8712125E-1 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.Uitility", "6.Uitility", "{1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Helper", "BPASmartClient.Helper\BPASmartClient.Helper.csproj", "{A2A5CB83-11C7-4534-A65D-6F957B60EEFF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Helper", "BPASmartClient.Helper\BPASmartClient.Helper.csproj", "{A2A5CB83-11C7-4534-A65D-6F957B60EEFF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Message", "BPASmartClient.Message\BPASmartClient.Message.csproj", "{C517D33F-8800-405E-9D59-E1F6CA201431}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Message", "BPASmartClient.Message\BPASmartClient.Message.csproj", "{C517D33F-8800-405E-9D59-E1F6CA201431}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DeviceProxy", "BPASmartClient.DeviceProxy\BPASmartClient.DeviceProxy.csproj", "{9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.DeviceProxy", "BPASmartClient.DeviceProxy\BPASmartClient.DeviceProxy.csproj", "{9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Status", "BPASmartClient.Status\BPASmartClient.Status.csproj", "{2C8DAB92-D5EB-4462-87C1-0BED75B26C54}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Status", "BPASmartClient.Status\BPASmartClient.Status.csproj", "{2C8DAB92-D5EB-4462-87C1-0BED75B26C54}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.IoT", "BPASmartClient.IoT\BPASmartClient.IoT.csproj", "{D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.IoT", "BPASmartClient.IoT\BPASmartClient.IoT.csproj", "{D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient", "BPASmartClient\BPASmartClient.csproj", "{2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient", "BPASmartClient\BPASmartClient.csproj", "{2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.ViewModel", "BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj", "{4E393E60-D39A-4118-8BD5-427DC72E9ACE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.ViewModel", "BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj", "{4E393E60-D39A-4118-8BD5-427DC72E9ACE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Device", "BPASmartClient.Device\BPASmartClient.Device.csproj", "{FFECD10B-FE66-4331-A915-409F5BE04480}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Device", "BPASmartClient.Device\BPASmartClient.Device.csproj", "{FFECD10B-FE66-4331-A915-409F5BE04480}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MQTT", "BPASmartClient.MQTT\BPASmartClient.MQTT.csproj", "{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MQTT", "BPASmartClient.MQTT\BPASmartClient.MQTT.csproj", "{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Socket", "BPASmartClient.Socket\BPASmartClient.Socket.csproj", "{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Socket", "BPASmartClient.Socket\BPASmartClient.Socket.csproj", "{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MessageCommunication", "BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj", "{74CCEC18-E602-4147-899C-05CD3651170C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -147,6 +149,10 @@ Global {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Debug|Any CPU.Build.0 = Debug|Any CPU {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.ActiveCfg = Release|Any CPU {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.Build.0 = Release|Any CPU + {74CCEC18-E602-4147-899C-05CD3651170C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {74CCEC18-E602-4147-899C-05CD3651170C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {74CCEC18-E602-4147-899C-05CD3651170C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {74CCEC18-E602-4147-899C-05CD3651170C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -173,6 +179,7 @@ Global {FFECD10B-FE66-4331-A915-409F5BE04480} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} {F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {74CCEC18-E602-4147-899C-05CD3651170C} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}