@@ -4,4 +4,9 @@ | |||
<TargetFramework>net6.0</TargetFramework> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||
</ItemGroup> | |||
</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> | |||
<TargetFramework>net6.0</TargetFramework> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||
</ItemGroup> | |||
</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> | |||
</PropertyGroup> | |||
<ItemGroup> | |||
<ProjectReference Include="..\BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj" /> | |||
<ProjectReference Include="..\BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj" /> | |||
</ItemGroup> | |||
</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 | |||
VisualStudioVersion = 17.0.32002.185 | |||
MinimumVisualStudioVersion = 10.0.40219.1 | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DRCoffee", "BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj", "{31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.DRCoffee", "BPASmartClient.DRCoffee\BPASmartClient.DRCoffee.csproj", "{31E9DC70-5889-4BA5-A5BA-FFDE66AFF314}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "4.Driver", "4.Driver", "{666CB1A9-562E-453A-A2C7-FD9D77CFDFDD}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.KLMCoffee", "BPASmartClient.KLMCoffee\BPASmartClient.KLMCoffee.csproj", "{BA543940-3C97-410D-B66C-1B928FCBB567}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.KLMCoffee", "BPASmartClient.KLMCoffee\BPASmartClient.KLMCoffee.csproj", "{BA543940-3C97-410D-B66C-1B928FCBB567}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.GSIceCream", "BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj", "{51E93537-DE9A-460C-B2B6-5FCB7A616A94}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.GSIceCream", "BPASmartClient.GSIceCream\BPASmartClient.GSIceCream.csproj", "{51E93537-DE9A-460C-B2B6-5FCB7A616A94}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SCChip", "BPASmartClient.SCChip\BPASmartClient.SCChip.csproj", "{F57AF771-8514-4020-BBF3-1708388DD4B3}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.SCChip", "BPASmartClient.SCChip\BPASmartClient.SCChip.csproj", "{F57AF771-8514-4020-BBF3-1708388DD4B3}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Lebai", "BPASmartClient.Lebai\BPASmartClient.Lebai.csproj", "{69F90530-ADA4-4A0C-8068-AAC5584072D7}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Lebai", "BPASmartClient.Lebai\BPASmartClient.Lebai.csproj", "{69F90530-ADA4-4A0C-8068-AAC5584072D7}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "5.Communication", "5.Communication", "{3D1D0E04-03FD-480A-8CF8-6E01A2E28625}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.SerialPort", "BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj", "{2344EB60-1760-4DF0-961A-FA5BE5BC47CC}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.SerialPort", "BPASmartClient.SerialPort\BPASmartClient.SerialPort.csproj", "{2344EB60-1760-4DF0-961A-FA5BE5BC47CC}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Http", "BPASmartClient.Http\BPASmartClient.Http.csproj", "{202763AA-4C4C-4738-B530-93A9A1ECE578}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Http", "BPASmartClient.Http\BPASmartClient.Http.csproj", "{202763AA-4C4C-4738-B530-93A9A1ECE578}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Modbus", "BPASmartClient.Modbus\BPASmartClient.Modbus.csproj", "{13C86146-CD3C-4CD3-AB7F-7A155E222832}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Modbus", "BPASmartClient.Modbus\BPASmartClient.Modbus.csproj", "{13C86146-CD3C-4CD3-AB7F-7A155E222832}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "3.Device", "3.Device", "{9FB27073-61A0-4FE3-94DB-5FDDE062332F}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkS", "BPASmartClient.MorkS\BPASmartClient.MorkS.csproj", "{0827FA85-8180-4A85-BE58-9483AC4BB3BA}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkS", "BPASmartClient.MorkS\BPASmartClient.MorkS.csproj", "{0827FA85-8180-4A85-BE58-9483AC4BB3BA}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkD", "BPASmartClient.MorkD\BPASmartClient.MorkD.csproj", "{8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkD", "BPASmartClient.MorkD\BPASmartClient.MorkD.csproj", "{8878BCFD-AC5E-4D84-8C63-CA99DDE036EE}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkT", "BPASmartClient.MorkT\BPASmartClient.MorkT.csproj", "{B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkT", "BPASmartClient.MorkT\BPASmartClient.MorkT.csproj", "{B399BCFF-82E8-4940-9CE5-B7DCDDFDC696}" | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "2.Business", "2.Business", "{6CEA3385-6F62-452A-8275-033A6037235D}" | |||
EndProject | |||
@@ -37,25 +37,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "1.UI", "1.UI", "{8712125E-1 | |||
EndProject | |||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "6.Uitility", "6.Uitility", "{1A9920BA-7C8D-4BDC-8D7D-6544A71AF3CF}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Helper", "BPASmartClient.Helper\BPASmartClient.Helper.csproj", "{A2A5CB83-11C7-4534-A65D-6F957B60EEFF}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Helper", "BPASmartClient.Helper\BPASmartClient.Helper.csproj", "{A2A5CB83-11C7-4534-A65D-6F957B60EEFF}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Message", "BPASmartClient.Message\BPASmartClient.Message.csproj", "{C517D33F-8800-405E-9D59-E1F6CA201431}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Message", "BPASmartClient.Message\BPASmartClient.Message.csproj", "{C517D33F-8800-405E-9D59-E1F6CA201431}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.DeviceProxy", "BPASmartClient.DeviceProxy\BPASmartClient.DeviceProxy.csproj", "{9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.DeviceProxy", "BPASmartClient.DeviceProxy\BPASmartClient.DeviceProxy.csproj", "{9D26C2D6-CF32-4FB6-A15E-8A1455DACD69}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Status", "BPASmartClient.Status\BPASmartClient.Status.csproj", "{2C8DAB92-D5EB-4462-87C1-0BED75B26C54}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Status", "BPASmartClient.Status\BPASmartClient.Status.csproj", "{2C8DAB92-D5EB-4462-87C1-0BED75B26C54}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.IoT", "BPASmartClient.IoT\BPASmartClient.IoT.csproj", "{D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.IoT", "BPASmartClient.IoT\BPASmartClient.IoT.csproj", "{D3DBCC2D-086E-4E3A-B70A-22A79FB295CF}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient", "BPASmartClient\BPASmartClient.csproj", "{2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient", "BPASmartClient\BPASmartClient.csproj", "{2BA531E8-7F85-4EBF-AE97-811CD7C83EF2}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.ViewModel", "BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj", "{4E393E60-D39A-4118-8BD5-427DC72E9ACE}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.ViewModel", "BPASmartClient.ViewModel\BPASmartClient.ViewModel.csproj", "{4E393E60-D39A-4118-8BD5-427DC72E9ACE}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Device", "BPASmartClient.Device\BPASmartClient.Device.csproj", "{FFECD10B-FE66-4331-A915-409F5BE04480}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Device", "BPASmartClient.Device\BPASmartClient.Device.csproj", "{FFECD10B-FE66-4331-A915-409F5BE04480}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MQTT", "BPASmartClient.MQTT\BPASmartClient.MQTT.csproj", "{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MQTT", "BPASmartClient.MQTT\BPASmartClient.MQTT.csproj", "{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Socket", "BPASmartClient.Socket\BPASmartClient.Socket.csproj", "{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}" | |||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Socket", "BPASmartClient.Socket\BPASmartClient.Socket.csproj", "{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}" | |||
EndProject | |||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MessageCommunication", "BPASmartClient.MessageCommunication\BPASmartClient.MessageCommunication.csproj", "{74CCEC18-E602-4147-899C-05CD3651170C}" | |||
EndProject | |||
Global | |||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | |||
@@ -147,6 +149,10 @@ Global | |||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0}.Release|Any CPU.Build.0 = Release|Any CPU | |||
{74CCEC18-E602-4147-899C-05CD3651170C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
{74CCEC18-E602-4147-899C-05CD3651170C}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
{74CCEC18-E602-4147-899C-05CD3651170C}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
{74CCEC18-E602-4147-899C-05CD3651170C}.Release|Any CPU.Build.0 = Release|Any CPU | |||
EndGlobalSection | |||
GlobalSection(SolutionProperties) = preSolution | |||
HideSolutionNode = FALSE | |||
@@ -173,6 +179,7 @@ Global | |||
{FFECD10B-FE66-4331-A915-409F5BE04480} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F} | |||
{7D290C8E-ACA7-4F03-91DF-D507FB3E2E87} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} | |||
{F9AD1657-7FF9-470F-BE7F-2379ADAC0BB0} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} | |||
{74CCEC18-E602-4147-899C-05CD3651170C} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} | |||
EndGlobalSection | |||
GlobalSection(ExtensibilityGlobals) = postSolution | |||
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC} | |||