@@ -4,4 +4,9 @@ | |||||
<TargetFramework>net6.0</TargetFramework> | <TargetFramework>net6.0</TargetFramework> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -1,8 +0,0 @@ | |||||
using System; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
public class Class1 | |||||
{ | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 咖啡机 | |||||
/// </summary> | |||||
public class CoffeeMachine | |||||
{ | |||||
//通讯代理 | |||||
SerialPortClient commProxy = null; | |||||
//数据仓库 | |||||
private DataStorage<byte> dataStorage = new DataStorage<byte>(); | |||||
//指令组装 | |||||
private CommandHandler commandHandler = new CommandHandler(); | |||||
//主线程运行标识 | |||||
private bool running = false; | |||||
//是否下发指令,主线程等待 | |||||
private bool free = true; | |||||
private DrCoffeeStatus drCoffeeStatus; | |||||
/// <summary> | |||||
/// 咖啡机状态 | |||||
/// </summary> | |||||
public DrCoffeeStatus CurrentCoffeeStatus | |||||
{ | |||||
get { return drCoffeeStatus; } | |||||
set | |||||
{ | |||||
if (drCoffeeStatus != value) | |||||
{ | |||||
drCoffeeStatus = value; | |||||
CoffeeStatusChanged?.Invoke(value); | |||||
} | |||||
} | |||||
} | |||||
private DrCoffeeAppStatus coffeeAppStatus; | |||||
/// <summary> | |||||
/// 应用状态 | |||||
/// </summary> | |||||
public DrCoffeeAppStatus CurrentCoffeeAppStatus | |||||
{ | |||||
get { return coffeeAppStatus; } | |||||
set | |||||
{ | |||||
if (coffeeAppStatus != value) | |||||
{ | |||||
coffeeAppStatus = value; | |||||
CoffeeAppStatusChanged?.Invoke(value); | |||||
} | |||||
} | |||||
} | |||||
public Action<string> SendCallback; | |||||
public Action<string> ReciveCallback; | |||||
/// <summary> | |||||
/// 咖啡机状态改变回调 | |||||
/// </summary> | |||||
public Action<DrCoffeeStatus> CoffeeStatusChanged; | |||||
/// <summary> | |||||
/// 应用状态改变回调 | |||||
/// </summary> | |||||
public Action<DrCoffeeAppStatus> 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; | |||||
}; | |||||
} | |||||
/// <summary> | |||||
/// 主线程开始运行 | |||||
/// </summary> | |||||
public void Start() | |||||
{ | |||||
commProxy.Start(); | |||||
running = true; | |||||
MainLoop(); | |||||
} | |||||
/// <summary> | |||||
/// 停止运行 | |||||
/// </summary> | |||||
public void Stop() | |||||
{ | |||||
commProxy.Stop(); | |||||
running = false; | |||||
} | |||||
/// <summary> | |||||
/// 主循环,循环询问状态 | |||||
/// </summary> | |||||
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<byte> temp = new List<byte>(); | |||||
//一系列解包 | |||||
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); | |||||
}), "咖啡机解析线程"); | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 指令封装 | |||||
/// </summary> | |||||
internal class CommandHandler | |||||
{ | |||||
byte[] cmdAsk; | |||||
private SerialPortClient commProxy; | |||||
private DrCoffeePackage drinksOrder = new DrCoffeePackage(); | |||||
public Action<bool> PauseAsk { get; set; } | |||||
/// <summary> | |||||
/// 初始化 | |||||
/// </summary> | |||||
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"); | |||||
} | |||||
/// <summary> | |||||
/// 制作咖啡 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 取消制作 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 模式设置 | |||||
/// </summary> | |||||
/// <param name="sender"></param> | |||||
/// <param name="e"></param> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 发送状态询问 | |||||
/// </summary> | |||||
internal byte[] GetStatusAsk() | |||||
{ | |||||
return cmdAsk; | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
/// <summary> | |||||
/// 是否在线 | |||||
/// </summary> | |||||
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } | |||||
/// <summary> | |||||
/// 咖啡机状态 | |||||
/// </summary> | |||||
public DrCoffeeStatus CoffeeStatus { get; set; } | |||||
/// <summary> | |||||
/// 应用状态 | |||||
/// </summary> | |||||
public DrCoffeeAppStatus AppStatus { get; set; } | |||||
/// <summary> | |||||
/// 警告信息 | |||||
/// </summary> | |||||
public DrCoffeeWarning Warning { get; set; } | |||||
/// <summary> | |||||
/// 故障信息 | |||||
/// </summary> | |||||
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; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 咖啡机状态解析 | |||||
/// </summary> | |||||
/// <param name="package"></param> | |||||
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; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,38 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 应用编号 | |||||
/// </summary> | |||||
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, | |||||
} | |||||
} |
@@ -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); | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
} | |||||
} |
@@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 通信指令 | |||||
/// </summary> | |||||
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, | |||||
} | |||||
} |
@@ -0,0 +1,40 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 饮品编号 | |||||
/// </summary> | |||||
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, | |||||
} | |||||
} |
@@ -0,0 +1,33 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 故障 | |||||
/// </summary> | |||||
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 | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// Dr咖啡机基础协议 | |||||
/// </summary> | |||||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] | |||||
public struct DrCoffeePackage | |||||
{ | |||||
/// <summary> | |||||
/// 包头(固定0x7E) | |||||
/// </summary> | |||||
public byte Header; | |||||
/// <summary> | |||||
/// 包长度: 固定为26个字节 | |||||
/// </summary> | |||||
public byte Length; | |||||
/// <summary> | |||||
/// 警告(咖啡机负责写,工控机负责读) | |||||
/// </summary> | |||||
public DrCoffeeWarning Warning; | |||||
/// <summary> | |||||
/// 故障(咖啡机负责写,工控机负责读) | |||||
/// </summary> | |||||
public DrCoffeeFault Fault; | |||||
/// <summary> | |||||
/// 咖啡机状态(咖啡机负责写,工控机负责读) | |||||
/// </summary> | |||||
public DrCoffeeStatus Status; | |||||
/// <summary> | |||||
/// 通信指令(咖啡机负责读,工控机负责写) | |||||
/// </summary> | |||||
public DrCoffeeCommCmd CommCmd; | |||||
/// <summary> | |||||
/// 应用状态(咖啡机负责写,工控机负责读) | |||||
/// </summary> | |||||
public DrCoffeeAppStatus ApplicationStatus; | |||||
/// <summary> | |||||
/// 饮品编号(咖啡机负责读,工控机负责写) | |||||
/// </summary> | |||||
public DrCoffeeDrinksCode DrinksCode; | |||||
/// <summary> | |||||
/// 应用编号(咖啡机负责写,工控机负责读) | |||||
/// </summary> | |||||
public DrCoffeAppCode ApplicationCode; | |||||
/// <summary> | |||||
/// 预留 | |||||
/// </summary> | |||||
public byte Retain; | |||||
/// <summary> | |||||
/// 校验和(除去包头包尾和校验和以外的 所有字节累加和的低字节) | |||||
/// </summary> | |||||
public byte CalcCode; | |||||
/// <summary> | |||||
/// 包尾(固定为0x7E) | |||||
/// </summary> | |||||
public byte End; | |||||
} | |||||
} |
@@ -0,0 +1,35 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 状态 | |||||
/// </summary> | |||||
public enum DrCoffeeStatus:byte | |||||
{ | |||||
/// <summary> | |||||
/// 待机状态 拒绝制作饮品命令 | |||||
/// </summary> | |||||
Wait = 0x01, | |||||
/// <summary> | |||||
/// 空闲状态 接受制作饮品命令 | |||||
/// </summary> | |||||
Free = 0x02, | |||||
/// <summary> | |||||
/// 运行状态 拒绝制作饮品命令 | |||||
/// </summary> | |||||
Running = 0x03, | |||||
/// <summary> | |||||
/// 警告状态 拒绝制作饮品命令 | |||||
/// </summary> | |||||
Warning = 0x04, | |||||
/// <summary> | |||||
/// 故障状态 拒绝制作饮品命令 | |||||
/// </summary> | |||||
Fault = 0x05 | |||||
} | |||||
} |
@@ -0,0 +1,62 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.DRCoffee | |||||
{ | |||||
/// <summary> | |||||
/// 警告 | |||||
/// </summary> | |||||
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 | |||||
} | |||||
} |
@@ -1,7 +1,12 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | <PropertyGroup> | ||||
<TargetFramework>net6.0</TargetFramework> | <TargetFramework>net6.0</TargetFramework> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -1,8 +0,0 @@ | |||||
using System; | |||||
namespace BPASmartClient.GSIceCream | |||||
{ | |||||
public class Class1 | |||||
{ | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 指令封装 | |||||
/// </summary> | |||||
internal class CommandHandler | |||||
{ | |||||
byte[] cmdHeartDW; | |||||
private SerialPortClient commProxy; | |||||
public Action<bool> PauseAsk { get; set; } | |||||
/// <summary> | |||||
/// 初始化 | |||||
/// </summary> | |||||
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"); | |||||
} | |||||
/// <summary> | |||||
/// 发送心跳 | |||||
/// </summary> | |||||
internal byte[] GetHeartDW() | |||||
{ | |||||
return cmdHeartDW; | |||||
} | |||||
/// <summary> | |||||
/// 模式设置 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 打料 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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<byte> dataStorage = new DataStorage<byte>(); | |||||
//主线程运行标识 | |||||
private bool running = false; | |||||
//是否下发指令,主线程等待 | |||||
private bool free = true; | |||||
public Action<string> SendCallback; | |||||
public Action<string> 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<byte> temp = new List<byte>(); | |||||
//一系列解包 | |||||
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); | |||||
//} | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
/// <summary> | |||||
/// 是否在线 | |||||
/// </summary> | |||||
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } | |||||
/// <summary> | |||||
/// 预冷温度 | |||||
/// </summary> | |||||
public short YLWD { get; set; } | |||||
/// <summary> | |||||
/// 回气温度 | |||||
/// </summary> | |||||
public short HQWD { get; set; } | |||||
/// <summary> | |||||
/// 环境温度 | |||||
/// </summary> | |||||
public short HJWD { get; set; } | |||||
/// <summary> | |||||
/// 电流 | |||||
/// </summary> | |||||
public short DL { get; set; } | |||||
/// <summary> | |||||
/// 电压 | |||||
/// </summary> | |||||
public short DY { get; set; } | |||||
/// <summary> | |||||
/// 当前模式 | |||||
/// </summary> | |||||
public MORKI_MODE CurrentMode { get; set; } | |||||
/// <summary> | |||||
/// 故障 | |||||
/// </summary> | |||||
public MORKI_FAULT Fault { get; set; } | |||||
/// <summary> | |||||
/// 成型比 | |||||
/// </summary> | |||||
public byte CXB { get; set; } | |||||
/// <summary> | |||||
/// 成型比(门限) | |||||
/// </summary> | |||||
public byte CXB_Threshold { get; set; } | |||||
/// <summary> | |||||
/// 打料完成(完成为true,正在打料为false) | |||||
/// </summary> | |||||
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<ICMSG_Heart_UP>(data.ToArray()); | |||||
ProcessHeart(msg); | |||||
break; | |||||
case (byte)IC_CMD.MODE: | |||||
var modeUp = IcPack.ByteToStructure<ICMSG_MODE_UP>(data.ToArray()); | |||||
ProcessModeUp(modeUp); | |||||
break; | |||||
} | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 心跳下发 | |||||
/// </summary> | |||||
[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; | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} | |||||
} |
@@ -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>(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; | |||||
} | |||||
/// <summary> | |||||
/// 由byte数组转换为结构体 | |||||
/// </summary> | |||||
public static T ByteToStructure<T>(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; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,32 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.GSIceCream | |||||
{ | |||||
/// <summary> | |||||
/// 故障 | |||||
/// </summary> | |||||
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, | |||||
} | |||||
} |
@@ -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 | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 帧头1 | |||||
/// </summary> | |||||
public static byte HEADER1 = 0xAA; | |||||
/// <summary> | |||||
/// 帧头2 | |||||
/// </summary> | |||||
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<IC_CMD, int> MSG_LENGTH = new Dictionary<IC_CMD, int>() { | |||||
{ IC_CMD.HEART,18}, | |||||
{ IC_CMD.MODE,2}, | |||||
}; | |||||
} | |||||
public enum MSG_RESOLVE_STEP | |||||
{ | |||||
NONE, | |||||
HEADER1, | |||||
HEADER2, | |||||
CMD, | |||||
CONTENT, | |||||
VALIDATE1, | |||||
VALIDATE2 | |||||
} | |||||
} | |||||
@@ -0,0 +1,7 @@ | |||||
<Project Sdk="Microsoft.NET.Sdk"> | |||||
<PropertyGroup> | |||||
<TargetFramework>net5.0</TargetFramework> | |||||
</PropertyGroup> | |||||
</Project> |
@@ -0,0 +1,65 @@ | |||||
using BPASmartClient.MessageCommunication.MsgControl; | |||||
using System; | |||||
namespace BPASmartClient.MessageCommunication | |||||
{ | |||||
/// <summary> | |||||
/// 该类实现客户端构件间消息的传递,底层使用整编的构件消息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) { } | |||||
/// </summary> | |||||
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; | |||||
} | |||||
/// <summary> | |||||
/// 监听消息方法 | |||||
/// </summary> | |||||
/// <param name="sender">订阅消息构件</param> | |||||
/// <param name="str_MessageString">消息名称</param> | |||||
/// <param name="str_MessageName">接收消息后回调处理函数 注意:该函数必须为Public</param> | |||||
public void ListenMessage(object sender,string str_MessageString,string str_MessageName) | |||||
{ | |||||
Bus.ListenMessage(sender,str_MessageString,str_MessageName); | |||||
} | |||||
/// <summary> | |||||
/// 消息发送函数 | |||||
/// </summary> | |||||
/// <param name="sender">发送消息构件</param> | |||||
/// <param name="str_Msg">消息名称</param> | |||||
/// <param name="obj_Data">消息体</param> | |||||
public void PostMessage(object sender,string str_Msg,object obj_Data) | |||||
{ | |||||
Bus.PostMessage(sender,str_Msg,obj_Data); | |||||
} | |||||
/// <summary> | |||||
/// 移除消息方法 | |||||
/// </summary> | |||||
/// <param name="str_MessageString">消息名称</param> | |||||
/// <param name="str_处理方法名称">接收消息后回调处理函数</param> | |||||
public void RemoveMessage(string str_MessageString,string str_MessageName) | |||||
{ | |||||
Bus.ListenMessage_trunOff(str_MessageString,str_MessageName); | |||||
} | |||||
public int GetdRountCount() | |||||
{ | |||||
return Bus.__Debug_RoutTable.Count; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,67 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.MessageCommunication | |||||
{ | |||||
/// <summary> | |||||
/// 消息名称管理 | |||||
/// </summary> | |||||
public class Class_MessageName | |||||
{ | |||||
#region 咖博士咖啡机消息名称 | |||||
/// <summary> | |||||
/// 咖博士咖啡机制作 | |||||
/// </summary> | |||||
public static string DRCoffee_MakeCoffee = "DRCoffee_MakeCoffee"; | |||||
/// <summary> | |||||
/// 咖博士咖啡机取消制作咖啡 | |||||
/// </summary> | |||||
public static string DRCoffee_CancelMakeCoffee = "DRCoffee_CancelMakeCoffee"; | |||||
/// <summary> | |||||
/// 咖博士咖啡机模式设置 | |||||
/// </summary> | |||||
public static string DRCoffee_CoffeeCommCmd = "DRCoffee_CoffeeCommCmd"; | |||||
/// <summary> | |||||
/// 咖博士咖啡机结束制作 | |||||
/// </summary> | |||||
public static string DRCoffee_CoffeEndCook = "DRCoffee_CoffeEndCook"; | |||||
#endregion | |||||
#region 广深冰淇淋消息名称 | |||||
/// <summary> | |||||
/// 广深冰淇淋机模式设置 | |||||
/// </summary> | |||||
public static string GSIceCream_ModeSet = "DRCoffee_CoffeEndCook"; | |||||
/// <summary> | |||||
/// 广深冰淇淋机打料 | |||||
/// </summary> | |||||
public static string GSIceCream_Discharge = "GSIceCream_Discharge"; | |||||
/// <summary> | |||||
/// 广深冰淇淋机结束制作 | |||||
/// </summary> | |||||
public static string GSIceCream_EndCook = "GSIceCream_EndCook"; | |||||
#endregion | |||||
#region STM32F103RCT6单片机消息名称 | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机下杯 | |||||
/// </summary> | |||||
public static string SCChip_TakeCup = "SCChip_TakeCup"; | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机舵机打料 | |||||
/// </summary> | |||||
public static string SCChip_MakeIceCream = "SCChip_MakeIceCream"; | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机舵机打开或者关闭 | |||||
/// </summary> | |||||
public static string SCChip_SESwitchCream = "SCChip_SESwitchCream"; | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机控制冰淇淋机器转 | |||||
/// </summary> | |||||
public static string SCChip_RotorSwitch = "SCChip_RotorSwitch"; | |||||
#endregion | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 消息通知枚举 | |||||
/// </summary> | |||||
public enum enum_MsgOptType | |||||
{ | |||||
Sender, | |||||
Getter | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 内部消息总线 | |||||
/// </summary> | |||||
public class InnerMessageBus | |||||
{ | |||||
static InnerMessageBus _bus; | |||||
const int TimeOut = 2000; | |||||
static public InnerMessageBus Get_Instance() | |||||
{ | |||||
if (_bus == null) | |||||
{ | |||||
_bus = new InnerMessageBus(); | |||||
} | |||||
return _bus; | |||||
} | |||||
#region 委托事件的定义 | |||||
/// <summary> | |||||
/// 当触发引用事件时执行的委托 | |||||
/// </summary> | |||||
public delegate void MessageEventHandler(object sender,InnerMessageEventArgs e); | |||||
#endregion | |||||
#region 自定义各类响应事件 | |||||
/// <summary> | |||||
/// 返回为整数型的结果事件响应 | |||||
/// </summary> | |||||
public event MessageEventHandler M_Event_消息事件; | |||||
#endregion | |||||
private readonly Object thisLock = new Object(); | |||||
/// <summary> | |||||
/// 发送消息方法 | |||||
/// ---------------------------------------------- | |||||
/// </summary> | |||||
/// <param name="sender">消息发送者</param> | |||||
/// <param name="str_Msg">消息名称串</param> | |||||
/// <param name="obj_Data">消息体数据区</param> | |||||
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); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 采用正则表达式匹配字符串 | |||||
/// </summary> | |||||
/// <param name="MessageString"></param> | |||||
/// <param name="item"></param> | |||||
/// <returns></returns> | |||||
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; | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 消息路由表,内部的 | |||||
/// </summary> | |||||
List<ListenPointInfo> RouteTable = new List<ListenPointInfo>(); | |||||
/// <summary> | |||||
/// 外部应用调用消息 | |||||
/// </summary> | |||||
/// <param name="obj_Listener">消息监听对象者</param> | |||||
/// <param name="str_MessageString"></param> | |||||
/// <param name="handler"></param> | |||||
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_处理方法名称 + ",但该方法不唯一或不存在."); | |||||
} | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 关闭消息监听和事件的挂接关系 | |||||
/// </summary> | |||||
/// <param name="str">消息名称</param> | |||||
/// <param name="str_消息处理方法名称">消息处理方法名称</param> | |||||
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); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// 采用对象方式直接释放指定对象的监听信息 | |||||
/// </summary> | |||||
/// <param name="obj"></param> | |||||
/// <returns></returns> | |||||
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; | |||||
} | |||||
/// <summary> | |||||
/// 调试用属性,获取当前路由表所有的信息,只读 | |||||
/// </summary> | |||||
public List<ListenPointInfo> __Debug_RoutTable | |||||
{ | |||||
get | |||||
{ | |||||
return this.RouteTable; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.MessageCommunication.MsgControl | |||||
{ | |||||
/// <summary> | |||||
/// 内部消息的事件参数 | |||||
/// </summary> | |||||
public class InnerMessageEventArgs :Object | |||||
{ | |||||
public object obj_Sender; | |||||
public string str_MessageStr; | |||||
public object obj_MessageObj; | |||||
} | |||||
} |
@@ -0,0 +1,31 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.MessageCommunication.MsgControl | |||||
{ | |||||
/// <summary> | |||||
/// 监听节点信息 | |||||
/// 创建人:奉友福 | |||||
/// </summary> | |||||
public class ListenPointInfo | |||||
{ | |||||
public object PointObj | |||||
{ | |||||
get; | |||||
set; | |||||
} | |||||
public string str_Message | |||||
{ | |||||
get; | |||||
set; | |||||
} | |||||
public string MethodName | |||||
{ | |||||
get; | |||||
set; | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 模型的类型中的属性的特性定义,是否是属于列表中的选择框字段项 | |||||
/// 创建人:奉友福 | |||||
/// </summary> | |||||
public class MsgAttribute :Attribute | |||||
{ | |||||
public enum_MsgOptType enum_消息方向; | |||||
public Type type_数据对象类型; | |||||
public string str_发送方法名; | |||||
public string str_消息描述 | |||||
{ | |||||
get; | |||||
set; | |||||
} | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -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; | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -4,4 +4,9 @@ | |||||
<TargetFramework>net6.0</TargetFramework> | <TargetFramework>net6.0</TargetFramework> | ||||
</PropertyGroup> | </PropertyGroup> | ||||
<ItemGroup> | |||||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||||
</ItemGroup> | |||||
</Project> | </Project> |
@@ -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; | |||||
/// <summary> | |||||
/// 是否在线 | |||||
/// </summary> | |||||
public bool OnLine { get { return DateTime.Now.Subtract(lastRefreshTime).TotalSeconds <= 3; } } | |||||
/// <summary> | |||||
/// 取冰淇淋杯完成 | |||||
/// </summary> | |||||
public bool CompletedTake_CPU_CUP_ICECREAM { get; set; } | |||||
/// <summary> | |||||
/// 取咖啡杯完成 | |||||
/// </summary> | |||||
public bool CompletedTake_CPU_CUP_COFFEE { get; set; } | |||||
/// <summary> | |||||
/// 1号舵机打开完成 | |||||
/// </summary> | |||||
public bool CompletedOpen_SE_1 { get; set; } | |||||
/// <summary> | |||||
/// 2号舵机打开完成 | |||||
/// </summary> | |||||
public bool CompletedOpen_SE_2 { get; set; } | |||||
/// <summary> | |||||
/// 3号舵机打开完成 | |||||
/// </summary> | |||||
public bool CompletedOpen_SE_3 { get; set; } | |||||
/// <summary> | |||||
/// 1号舵机关闭完成 | |||||
/// </summary> | |||||
public bool CompletedClose_SE_1 { get; set; } | |||||
/// <summary> | |||||
/// 2号舵机关闭完成 | |||||
/// </summary> | |||||
public bool CompletedClose_SE_2 { get; set; } | |||||
/// <summary> | |||||
/// 3号舵机关闭完成 | |||||
/// </summary> | |||||
public bool CompletedClose_SE_3 { get; set; } | |||||
/// <summary> | |||||
/// 是否存在物品 | |||||
/// </summary> | |||||
public bool ArticleExits { get; set; } | |||||
/// <summary> | |||||
/// 物品距离 | |||||
/// </summary> | |||||
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) | |||||
{ | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -1,8 +0,0 @@ | |||||
using System; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
public class Class1 | |||||
{ | |||||
} | |||||
} |
@@ -0,0 +1,42 @@ | |||||
using BPASmartClient.SCChip; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
public class TakeCupEvent | |||||
{ | |||||
/// <summary> | |||||
/// 杯 | |||||
/// </summary> | |||||
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; } | |||||
} | |||||
/// <summary> | |||||
/// 检测有无杯子 | |||||
/// </summary> | |||||
public class ArticleExitsEvent | |||||
{ | |||||
} | |||||
/// <summary> | |||||
/// 检测物品距离 | |||||
/// </summary> | |||||
public class ArticleDistEvent | |||||
{ | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// 指令封装 | |||||
/// </summary> | |||||
internal class CommandHandler | |||||
{ | |||||
private SerialPortClient commProxy; | |||||
private ICChipPackage package = new ICChipPackage(); | |||||
/// <summary> | |||||
/// 初始化 | |||||
/// </summary> | |||||
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"); | |||||
} | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机舵机打开或者关闭 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机控制冰淇淋机器转 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机舵机打料 | |||||
/// </summary> | |||||
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}]"); | |||||
} | |||||
} | |||||
/// <summary> | |||||
/// STM32F103RCT6单片机下杯 | |||||
/// </summary> | |||||
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; | |||||
} | |||||
} | |||||
} |
@@ -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<byte> dataStorage = new DataStorage<byte>(); | |||||
//主线程运行标识 | |||||
private bool running = false; | |||||
//是否下发指令,主线程等待 | |||||
public Action<string> SendCallback; | |||||
public Action<string> 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<byte> temp = new List<byte>(); | |||||
//一系列解包 | |||||
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); | |||||
} | |||||
/// <summary> | |||||
/// 由byte数组转换为结构体 | |||||
/// </summary> | |||||
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; | |||||
} | |||||
} | |||||
} |
@@ -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 | |||||
{ | |||||
/// <summary> | |||||
/// Dr咖啡机基础协议 | |||||
/// </summary> | |||||
[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)] | |||||
public struct ICChipPackage | |||||
{ | |||||
/// <summary> | |||||
/// 包头(固定0xAA) | |||||
/// </summary> | |||||
public byte Header; | |||||
/// <summary> | |||||
/// 发送方 | |||||
/// </summary> | |||||
public IC_SENDER Sender; | |||||
/// <summary> | |||||
/// 命令 | |||||
/// </summary> | |||||
public IC_CMD Cmd; | |||||
/// <summary> | |||||
/// 值 | |||||
/// </summary> | |||||
public byte Value; | |||||
/// <summary> | |||||
/// 包尾(固定为0xBB) | |||||
/// </summary> | |||||
public byte End; | |||||
} | |||||
} |
@@ -0,0 +1,43 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
/// <summary> | |||||
/// 命令 | |||||
/// </summary> | |||||
public enum IC_CMD : byte | |||||
{ | |||||
/// <summary> | |||||
/// 心跳 | |||||
/// </summary> | |||||
HEART_BEAT = 0x00, | |||||
/// <summary> | |||||
/// 下杯(带上碗参数) | |||||
/// </summary> | |||||
TAKE_CUP = 0x01, | |||||
/// <summary> | |||||
/// 打开舵机(带上舵机参数) | |||||
/// </summary> | |||||
OPEN_SE = 0x02, | |||||
/// <summary> | |||||
/// 关闭舵机(带上舵机参数) | |||||
/// </summary> | |||||
CLOSE_SE = 0x03, | |||||
/// <summary> | |||||
/// 使能冰淇淋转子(带上开关参数) | |||||
/// </summary> | |||||
ROTOR = 0x04, | |||||
/// <summary> | |||||
/// 检测是否有物品 | |||||
/// </summary> | |||||
ARTICLE_EXITS = 0x05, | |||||
/// <summary> | |||||
/// 检测物品距离 | |||||
/// </summary> | |||||
ARTICLE_DIST = 0x06 | |||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
/// <summary> | |||||
/// 杯子 | |||||
/// </summary> | |||||
public enum IC_CUP : byte | |||||
{ | |||||
/// <summary> | |||||
/// 冰淇淋杯 | |||||
/// </summary> | |||||
CUP_ICECREAM = 0x01, | |||||
/// <summary> | |||||
/// 咖啡杯 | |||||
/// </summary> | |||||
CUP_COFFEE = 0x02 | |||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
/// <summary> | |||||
/// 搅拌器 | |||||
/// </summary> | |||||
public enum IC_ROTOR | |||||
{ | |||||
/// <summary> | |||||
/// 开始搅拌 | |||||
/// </summary> | |||||
OPEN_ROTOR = 0x01, | |||||
/// <summary> | |||||
/// 停止搅拌 | |||||
/// </summary> | |||||
CLOSE_ROTOR = 0x00 | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
/// <summary> | |||||
/// 冰淇淋舵机 | |||||
/// </summary> | |||||
public enum IC_SE:byte | |||||
{ | |||||
/// <summary> | |||||
/// 舵机1 | |||||
/// </summary> | |||||
SE_1=0x01, | |||||
/// <summary> | |||||
/// 舵机2 | |||||
/// </summary> | |||||
SE_2=0x02, | |||||
/// <summary> | |||||
/// 舵机3 | |||||
/// </summary> | |||||
SE_3=0x03, | |||||
} | |||||
} |
@@ -0,0 +1,23 @@ | |||||
using System; | |||||
using System.Collections.Generic; | |||||
using System.Linq; | |||||
using System.Text; | |||||
using System.Threading.Tasks; | |||||
namespace BPASmartClient.SCChip | |||||
{ | |||||
/// <summary> | |||||
/// 命令发送方 | |||||
/// </summary> | |||||
public enum IC_SENDER:byte | |||||
{ | |||||
/// <summary> | |||||
/// 上位机 | |||||
/// </summary> | |||||
CONSOLE=0x01, | |||||
/// <summary> | |||||
/// 单片机 | |||||
/// </summary> | |||||
DEVICE=0x02, | |||||
} | |||||
} |
@@ -3,33 +3,33 @@ Microsoft Visual Studio Solution File, Format Version 12.00 | |||||
# Visual Studio Version 17 | # Visual Studio Version 17 | ||||
VisualStudioVersion = 17.0.32002.185 | VisualStudioVersion = 17.0.32002.185 | ||||
MinimumVisualStudioVersion = 10.0.40219.1 | 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 | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.Driver", "4.Driver", "{666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.Driver", "4.Driver", "{666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}" | ||||
EndProject | 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 | 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 | 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 | 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 | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Communication", "5.Communication", "{3D1D0E04-03FD-480A-8CF8-6E01A2E28625}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Communication", "5.Communication", "{3D1D0E04-03FD-480A-8CF8-6E01A2E28625}" | ||||
EndProject | 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 | 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 | 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 | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.Device", "3.Device", "{9FB27073-61A0-4FE3-94DB-5FDDE062332F}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.Device", "3.Device", "{9FB27073-61A0-4FE3-94DB-5FDDE062332F}" | ||||
EndProject | 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 | 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 | 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 | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Business", "2.Business", "{6CEA3385-6F62-452A-8275-033A6037235D}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Business", "2.Business", "{6CEA3385-6F62-452A-8275-033A6037235D}" | ||||
EndProject | EndProject | ||||
@@ -37,25 +37,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.UI", "1.UI", "{8712125E-1 | |||||
EndProject | EndProject | ||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.Uitility", "6.Uitility", "{1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF}" | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.Uitility", "6.Uitility", "{1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF}" | ||||
EndProject | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | 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 | EndProject | ||||
Global | Global | ||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | 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}.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.ActiveCfg = Release|Any CPU | ||||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.Build.0 = 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 | EndGlobalSection | ||||
GlobalSection(SolutionProperties) = preSolution | GlobalSection(SolutionProperties) = preSolution | ||||
HideSolutionNode = FALSE | HideSolutionNode = FALSE | ||||
@@ -173,6 +179,7 @@ Global | |||||
{FFECD10B-FE66-4331-A915-409F5BE04480} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} | {FFECD10B-FE66-4331-A915-409F5BE04480} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} | ||||
{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} | {7D290C8E-ACA7-4F03-91DF-D507FB3E2E87} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} | ||||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0} = {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 | EndGlobalSection | ||||
GlobalSection(ExtensibilityGlobals) = postSolution | GlobalSection(ExtensibilityGlobals) = postSolution | ||||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | ||||