diff --git a/BPASmartClient.CustomResource/Pages/Model/Config.cs b/BPASmartClient.CustomResource/Pages/Model/Config.cs index e07be50c..cf2e3fe3 100644 --- a/BPASmartClient.CustomResource/Pages/Model/Config.cs +++ b/BPASmartClient.CustomResource/Pages/Model/Config.cs @@ -38,7 +38,7 @@ namespace BPASmartClient.CustomResource.Pages.Model private void AddData() { - Global.userManager.userInfos.Add(new UserInfo() {Id= IdProcess(), permission = Permission.管理员, UserName = "admin", Password = "admin" }); ; + Global.userManager.userInfos.Add(new UserInfo() { Id = IdProcess(), permission = Permission.管理员, UserName = "admin", Password = "admin" }); ; Global.userManager.userInfos.Add(new UserInfo() { Id = IdProcess(), permission = Permission.操作员, UserName = "czy", Password = "123456" }); Global.userManager.userInfos.Add(new UserInfo() { Id = IdProcess(), permission = Permission.观察员, UserName = "gcy", Password = "654321" }); Global.userManager.userInfos.Add(new UserInfo() { Id = IdProcess(), permission = Permission.技术员, UserName = "jsy", Password = "88888888" }); diff --git a/BPASmartClient.JXJFoodBigStation/App.config b/BPASmartClient.JXJFoodBigStation/App.config new file mode 100644 index 00000000..5ff78b1a --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/BPASmartClient.JXJFoodBigStation/App.xaml b/BPASmartClient.JXJFoodBigStation/App.xaml new file mode 100644 index 00000000..07a8c441 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/App.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodBigStation/App.xaml.cs b/BPASmartClient.JXJFoodBigStation/App.xaml.cs new file mode 100644 index 00000000..02b20491 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/App.xaml.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using System.Windows; +using BPASmartClient.CustomResource.Pages.Enums; +using BPASmartClient.CustomResource.Pages.Model; +using BPASmartClient.CustomResource.Pages.View; +using BPASmartClient.CustomResource.Pages.ViewModel; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodBigStation.Model; +using BPASmartClient.Nfc; + +namespace BPASmartClient.JXJFoodBigStation +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public static Window MainWindow; + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + MenuInit(); + DataInit(); + ProcessControl.GetInstance.Init(); + MainView mv = new MainView(); + //mv.Show(); + LoginView lv = new LoginView(); + var res = lv.ShowDialog(); + if (res != null && res == true) + { + MessageLog.GetInstance.ShowUserLog("用户登录"); + mv.Show(); + } + else + mv.Close(); + MainWindow = mv; + } + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + MessageLog.GetInstance.LogSave(); + ThreadManage.GetInstance().Dispose(); + } + + private void MenuInit() + { + NfcServer.GetInstance.Init(); + + #region 配方管理菜单 + ObservableCollection RecipeManage = new ObservableCollection(); + RecipeManage.Add(new SubMenumodel() + { + SubMenuName = "服务配方管理", + SubMenuPermission = new Permission[] { Permission.管理员 }, + AssemblyName = "BPASmartClient.JXJFoodBigStation", + ToggleWindowPath = "View.RecipeReceiveView" + }); + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "配方管理", + Alias = "Recipe Management", + subMenumodels = RecipeManage, + }); + #endregion + + #region 消息日志 + ObservableCollection InfoLog = new ObservableCollection(); + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "操作日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.UserLogView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "运行日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.RunLogView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "报警记录", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.AlarmView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "调试日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.DebugLogView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "消息日志", + Alias = "Message Log", + subMenumodels = InfoLog, + }); + #endregion + + #region 硬件设备监控 + ObservableCollection DeviceMonitor = new ObservableCollection(); + DeviceMonitor.Add(new SubMenumodel() + { + SubMenuName = "原料设备列表", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.DosingSystem", + ToggleWindowPath = "View.DeviceListView" + }); + + DeviceMonitor.Add(new SubMenumodel() + { + SubMenuName = "设备状态", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.DosingSystem", + ToggleWindowPath = "View.HardwareStatusView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "设备监控", + Alias = "Device Monitor", + subMenumodels = DeviceMonitor, + }); + #endregion + + #region 用户管理 + ObservableCollection UserManager = new ObservableCollection(); + UserManager.Add(new SubMenumodel() + { + SubMenuName = "用户登录", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.SubPagLoginView" + }); + + UserManager.Add(new SubMenumodel() + { + SubMenuName = "密码修改", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.PasswordChangeView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "用户管理", + Alias = "User Management", + subMenumodels = UserManager, + }); + #endregion + } + + private void DataInit() + { + Config.GetInstance.Init(); + //Json.Read(); + } + + } +} diff --git a/BPASmartClient.JXJFoodBigStation/AssemblyInfo.cs b/BPASmartClient.JXJFoodBigStation/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/BPASmartClient.JXJFoodBigStation/BPASmartClient.JXJFoodBigStation.csproj b/BPASmartClient.JXJFoodBigStation/BPASmartClient.JXJFoodBigStation.csproj new file mode 100644 index 00000000..18cc382e --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/BPASmartClient.JXJFoodBigStation.csproj @@ -0,0 +1,30 @@ + + + + WinExe + net6.0-windows + enable + true + + + + + + + + + + $(DefaultXamlRuntime) + Designer + + + $(DefaultXamlRuntime) + Designer + + + $(DefaultXamlRuntime) + Designer + + + + diff --git a/BPASmartClient.JXJFoodBigStation/Model/DeviceCurrentStatus.cs b/BPASmartClient.JXJFoodBigStation/Model/DeviceCurrentStatus.cs new file mode 100644 index 00000000..864395d9 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/DeviceCurrentStatus.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; + +namespace BPASmartClient.JXJFoodBigStation.Model +{ + public class DeviceCurrentStatus : ObservableObject + { + + public double Weight { get { return _mWeight; } set { _mWeight = value; OnPropertyChanged(); } } + private double _mWeight; + + + public bool RunStatus { get { return _mRunStatus; } set { _mRunStatus = value; OnPropertyChanged(); } } + private bool _mRunStatus; + + + public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } + private string _mDeviceName; + + + + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/DataComm.cs b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/DataComm.cs new file mode 100644 index 00000000..df85bc0c --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/DataComm.cs @@ -0,0 +1,41 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC +{ + public class DataComm + { + public volatile static DataComm Instance; + public static DataComm GetInstance => Instance ?? (new DataComm()); + public DataComm() { } + /// + /// 是否允许配料 + /// + public bool IsAllowDosing { get { return _mIsAllowDosing; } set { _mIsAllowDosing = value; } } + private bool _mIsAllowDosing; + + public bool DosingFinishToPLC { get { return _mDosingFinishToPLC; } set { _mDosingFinishToPLC = value; } } + private bool _mDosingFinishToPLC; + + private int _mStockBinLocationToPLC; + public int StockBinLocationToPLC { get { return _mStockBinLocationToPLC; } set { _mStockBinLocationToPLC = value; } } + + public bool StatusSignToBPA { get { return _mStatusSignToBPA; } set { _mStatusSignToBPA = value; } } + private bool _mStatusSignToBPA; + + private int _mStockBinLocationToBPA; + public int StockBinLocationToBPA { get { return _mStockBinLocationToBPA; } set { _mStockBinLocationToBPA = value; } } + + private int _mBarrelNumToPLC; + public int BarrelNumToPLC { get { return _mBarrelNumToPLC; } set { _mBarrelNumToPLC = value; } } + + /*public ConcurrentDictionary DeviceLists = new ConcurrentDictionary();*/ + } + +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKDeviceStatus.cs b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKDeviceStatus.cs new file mode 100644 index 00000000..7b5fbaa2 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKDeviceStatus.cs @@ -0,0 +1,74 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC +{ + public class HKDeviceStatus + { + public ModbusTcp ModBusHK = new ModbusTcp(); + public string IpAddress => ModBusHK.IPAdress; + public bool IsConnected => ModBusHK.Connected; + + public void Init() + { + if (IsConnected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + + }),"信号收发处理"); + } + } + /// + /// 单个配料机配料完成 + /// + /// + public void SingleDosing(uint value) + { + if (IsConnected) + { + ModBusHK.SetUint(HKPlcCommAddress.SingleStockBinLocationToPLC, value); + ModBusHK.Write(HKPlcCommAddress.SingleDosingFinishToPLC, (ushort)1); + } + } + /// + /// 复位plc允许接料信号 + /// + public void AllowDosingSignReset() + { + ModBusHK.Write(HKPlcCommAddress.IsAllowDosing,(ushort)0); + } + /// + /// 复位plc到达某料仓信号 + /// + public void StockStateSignReset() + { + ModBusHK.Write(HKPlcCommAddress.StockState, (ushort)0); + } + /// + /// 复位一个配方配料完成信号 + /// + public void RecipeDosingFinishReset() + { + ModBusHK.Write(HKPlcCommAddress.RecipeDosingFinish, (ushort)0); + } + /// + /// 下发配方数据 + /// + /// 单个桶的编号 + /// 单个桶对应的料仓位置 + public void StockBinPar(uint BarrelNum, ushort StockBinLocation) + { + if (IsConnected) + { + ModBusHK.SetUint(HKPlcCommAddress.BarrelNumToPLC, BarrelNum); + ModBusHK.Write(HKPlcCommAddress.StockBinLocationToPLC, StockBinLocation); + } + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKPlcCommAddress.cs b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKPlcCommAddress.cs new file mode 100644 index 00000000..4cb3917d --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/HK_PLC/HKPlcCommAddress.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.HK_PLC +{ + public class HKPlcCommAddress + { + #region 海科PLC ==> 上位机 + /// + /// 是否允许配料 + /// + public static string IsAllowDosing { get; set; } = ""; + /// + /// 当前料仓位置 + /// + public static string StockBinLocation { get; set; } = ""; + /// + /// 当前料仓的状态(0:无意义,1:到达接料位置) + /// + public static string StockState { get; set; } = ""; + #endregion + + #region 上位机 ==> 海科PLC + /// + /// 料仓位置(配置该配方,所需要多个原料桶,每个原料桶有多个料仓位置) + /// + public static string StockBinLocationToPLC { get; set; } = ""; + /// + /// 对应桶号 + /// + public static string BarrelNumToPLC { get; set; } = ""; + /// + /// 当前配料机配料完成 + /// + public static string SingleDosingFinishToPLC { get; set; } = ""; + /// + /// 当前配料料仓的位置 + /// + public static string SingleStockBinLocationToPLC { get; set; } = ""; + + public static string RecipeDosingFinish { get; set; } = ""; + #endregion + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/ProcessControl.cs b/BPASmartClient.JXJFoodBigStation/Model/ProcessControl.cs new file mode 100644 index 00000000..e3008fd8 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/ProcessControl.cs @@ -0,0 +1,154 @@ +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodBigStation.Model.HK_PLC; +using BPASmartClient.JXJFoodBigStation.Model.Siemens; +using BPASmartClient.Modbus; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model +{ + public class ProcessControl + { + private volatile static ProcessControl _Instance; + public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl()); + private ProcessControl() { } + + public ObservableCollection RemoteRecipes; + ConcurrentQueue RecipeQueue = new ConcurrentQueue(); + ConcurrentQueue DeviceQueue = new ConcurrentQueue(); + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus(); + public HKDeviceStatus HKDevice = new HKDeviceStatus(); + public void Init() + { + string HK_PLC_IP = ConfigurationManager.AppSettings["HKPlc_IP"]; + string HK_PLC_Port = ConfigurationManager.AppSettings["HKPlc_Port"]; + string Siemens_PLC_IP = ConfigurationManager.AppSettings["Siemens_IP"]; + string Siemens_PLC_Port = ConfigurationManager.AppSettings["Siemens_Port"]; + Task.Run(new Action(() => + { + HKDevice.ModBusHK.ModbusTcpConnect(HK_PLC_IP, int.Parse(HK_PLC_Port)); + SiemensDevice.SiemensTcp.ModbusTcpConnect(Siemens_PLC_IP, int.Parse(Siemens_PLC_Port)); + if (HKDevice.IsConnected) + { + HKDevice.Init(); + } + if (SiemensDevice.IsConnected) + { + SiemensDevice.Init(); + } + })); + ActionManage.GetInstance.Register(new Action(()=> + { + + }), "给流水线下发配方数据", true); + ActionManage.GetInstance.Register(new Action(() => + { + if (SiemensDevice.IsConnected) + { + var res = SiemensDevice.SiemensTcp.GetString(SiemensCommAddress.RecipeName, (ushort)20); + var res1 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RecipeID); + var res2 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RawMaterial); + if ((res != null && res is string recipeName) && + (res1 != null && res1 is uint recipeID) && + (res2 != null && res2 is ushort[] rawMaterial)) + { + RawMaterials.Clear(); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + RawMaterialBarrelNum = rawMaterial[0], + RawMaterialLocation= rawMaterial[1], + RawMaterialWeight= rawMaterial[2] + }); + Json.Data.Recipes.Add(new RemoteRecipeData() + { + RecipeName = recipeName, + RecipeCode = recipeID, + RawMaterial = RawMaterials + }); + } + } + }), "西门子下发配方", true); + ActionManage.GetInstance.Register(new Action(() => + { + if (SiemensDevice.IsConnected) + { + var res = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.TrayLocationNum); + var res1 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RecipeID); + if (res != null && res is int TrayLocation && res1 != null && res1 is int recipeId) + { + int index = Array.FindIndex(Json.Data.Recipes.ToArray(), p => p.RecipeCode == recipeId); + if (index >= 0 && index < Json.Data.Recipes.Count) + { + Json.Data.Recipes.ElementAt(index).TrayCode = TrayLocation; + } + } + } + }), "AGV到位信号", true);//根据下发的配方ID将 托盘的位置信息添加到配方中 + + RecipeQueue.Clear(); + ReceviceData(); + ThreadManage.GetInstance().StartLong(new Action(() => + { + RecipeInfoToHKPLC(); + }), "流程处理", true); + } + + private void ReceviceData() + { + RemoteRecipes = Json.Data.Recipes; + RawMaterials = TestData.GetInstance.RawMaterials;//添加测试数据 + if (Json.Data.Recipes.Count > 0) + { + foreach (var data in Json.Data.Recipes) + { + if(!(RecipeQueue.Contains(data.RecipeCode))) + RecipeQueue.Enqueue(data.RecipeCode); + } + } + } + /// + /// 当前料仓的位置 + /// + private int StockInIsWork; + /// + /// 单个配方执行完成标志 + /// + private bool RecipeFinfish; + private void RecipeInfoToHKPLC() + { + if (RecipeQueue.Count > 0) + { + int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueue.ElementAt(0)); + if (index >= 0 && index <= RemoteRecipes.Count) + { + long code = RemoteRecipes.ElementAt(index).RecipeCode; + if (RTrig.GetInstance("IsAllowDosing").Start(HKDevice.ModBusHK.Read(HKPlcCommAddress.IsAllowDosing) is bool a)) + { + foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial) + { + HKDevice.StockBinPar((uint)item.RawMaterialBarrelNum, (ushort)item.RawMaterialLocation); + } + HKDevice.AllowDosingSignReset(); + + } + + if (RTrig.GetInstance("StockState").Start(HKDevice.ModBusHK.Read(HKPlcCommAddress.RecipeDosingFinish) is bool)) + { + HKDevice.RecipeDosingFinishReset(); + RecipeQueue.TryDequeue(out code); + } + } + } + } + private void HKPLCIsWork() + { + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeData.cs b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeData.cs new file mode 100644 index 00000000..19d26ded --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeData.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model +{ + public class RemoteRecipeData + { + /// + /// 配方名称 + /// + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; } } + private string _mRecipeName; + + /// + /// 配方ID + /// + public long RecipeCode { get { return _mRecipeCode; } set { _mRecipeCode = value; } } + private long _mRecipeCode; + + /// + /// 托盘编号 + /// + public int TrayCode { get { return _mTrayCode; } set { _mTrayCode = value; } } + private int _mTrayCode; + + /// + /// 原料数据 + /// + public ObservableCollection RawMaterial { get; set; } = new ObservableCollection(); + + + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeDataColl.cs b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeDataColl.cs new file mode 100644 index 00000000..0d65fdad --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeDataColl.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.Siemens +{ + public class RemoteRecipeDataColl + { + public ObservableCollection Recipes { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeRawMaterial.cs b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeRawMaterial.cs new file mode 100644 index 00000000..47112da9 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/Siemens/RemoteRecipeRawMaterial.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model +{ + public class RemoteRecipeRawMaterial + { + private int _mIp; + public int DeviceIp { get { return _mIp; } set { _mIp = value; } } + + private int _mRawMaterialBarrelNum; + /// + /// 原料对应的桶号 + /// + public int RawMaterialBarrelNum { get { return _mRawMaterialBarrelNum; } set { _mRawMaterialBarrelNum = value; } } + + private double _mRawMaterialWeight; + /// + /// 需要原料重量 + /// + public double RawMaterialWeight { get { return _mRawMaterialWeight; } set { _mRawMaterialWeight = value;} } + + + private int _mRawMaterialLocation; + /// + /// 原料对应料仓的位置 + /// + public int RawMaterialLocation { get { return _mRawMaterialLocation; } set { _mRawMaterialLocation = value;} } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensCommAddress.cs b/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensCommAddress.cs new file mode 100644 index 00000000..8288bc9b --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensCommAddress.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.Siemens +{ + public class SiemensCommAddress + { + #region 配方地址 + /// + /// 配方状态 + /// + public static string RecipeState { get; set; } = ""; + /// + /// 配方名称 + /// + public static string RecipeName { get; set; } = ""; + /// + /// 配方ID + /// + public static string RecipeID { get; set; } = ""; + /// + /// 原料信息 + /// + public static string RawMaterial { get; set; } = ""; + #endregion + + #region AGV到位(与西门子PLC交互)西门子PLC ==> 上位机 + public static string TrayLocationNum { get; set; } = ""; + public static string TrayRecipeID { get; set; } = ""; + public static string TrayState { get; set; } = ""; + #endregion + + #region Tray配料完成(与西门子PLC交互)上位机 ==> 西门子PLC + public static string TrayLocationNumToPLC { get; set; } = ""; + public static string TrayRecipeIDToPLC { get; set; } = ""; + public static string TrayStateToPLC { get; set; } = ""; + #endregion + } + + +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensDeviceStatus.cs b/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensDeviceStatus.cs new file mode 100644 index 00000000..ac0106bf --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/Siemens/SiemensDeviceStatus.cs @@ -0,0 +1,64 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model.Siemens +{ + public class SiemensDeviceStatus + { + public ModbusTcp SiemensTcp = new ModbusTcp(); + public bool IsConnected => SiemensTcp.Connected; + public string IpAddress => SiemensTcp.IPAdress; + + /// + /// 配方接收信号复位 + /// + public void RecipeSignReset() + { + this.SiemensTcp.Write(SiemensCommAddress.RecipeState, (ushort)0); + } + /// + /// AGV到位信号复位 + /// + public void AgvSignReset() + { + this.SiemensTcp.Write(SiemensCommAddress.TrayState, (ushort)0); + } + public void Init() + { + if (IsConnected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + var res = this.SiemensTcp.Read(SiemensCommAddress.RecipeState); + if (res != null && RTrig.GetInstance("RecipeTrig").Start(res is bool SignTrig)) + { + ActionManage.GetInstance.Send("西门子下发配方"); + RecipeSignReset(); + } + var AgvState = this.SiemensTcp.Read(SiemensCommAddress.TrayState); + if (AgvState != null && RTrig.GetInstance("AgvTrig").Start(res is bool AgvSignTrig)) + { + ActionManage.GetInstance.Send("AGV到位信号"); + AgvSignReset(); + } + }),"监听服务数据"); + } + } + /// + /// 配方配料完成信号 + /// + /// + /// + private void DosingFinsih(int TrayLocation,int recipeID) + { + this.SiemensTcp.Write(SiemensCommAddress.TrayLocationNumToPLC, TrayLocation); + this.SiemensTcp.Write(SiemensCommAddress.TrayStateToPLC, 1); + this.SiemensTcp.Write(SiemensCommAddress.TrayRecipeIDToPLC, recipeID); + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/Model/TestData.cs b/BPASmartClient.JXJFoodBigStation/Model/TestData.cs new file mode 100644 index 00000000..d28bf9d5 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/Model/TestData.cs @@ -0,0 +1,111 @@ +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodBigStation.Model.Siemens; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodBigStation.Model +{ + public class TestData + { + public volatile static TestData Instance; + public static TestData GetInstance => Instance ?? (Instance = new TestData()); + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + public TestData() + { + string recipeName = "配方1"; + long recipeCode = 10001; + int Traycode = 1; + + double RawmaterialWeight = 10; + int RawMaterialbarrelNum = 1; + int RawMaterialLocation = 5; + + double RawmaterialWeight1 = 20; + int RawMaterialbarrelNum1 = 2; + int RawMaterialLocation1 = 7; + + double RawmaterialWeight2 = 30; + int RawMaterialbarrelNum2 = 3; + int RawMaterialLocation2 = 9; + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight, + RawMaterialBarrelNum = RawMaterialbarrelNum, + RawMaterialLocation = RawMaterialLocation + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight1, + RawMaterialBarrelNum = RawMaterialbarrelNum1, + RawMaterialLocation = RawMaterialLocation1 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight2, + RawMaterialBarrelNum = RawMaterialbarrelNum2, + RawMaterialLocation = RawMaterialLocation2 + }); + + Json.Data.Recipes.Add(new Model.RemoteRecipeData() + { + RecipeName = recipeName, + RecipeCode = recipeCode, + TrayCode = Traycode, + RawMaterial = RawMaterials + }); + + RawMaterials.Clear(); + string recipeName_2 = "配方2"; + long recipeCode_2 = 20001; + int Traycode_2 = 3; + + double RawmaterialWeight_2 = 10; + int RawMaterialbarrelNum_2 = 1; + int RawMaterialLocation_2 = 5; + + double RawmaterialWeight1_2 = 20; + int RawMaterialbarrelNum1_2 = 2; + int RawMaterialLocation1_2 = 7; + + double RawmaterialWeight2_2 = 30; + int RawMaterialbarrelNum2_2 = 3; + int RawMaterialLocation2_2 = 9; + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight_2, + RawMaterialBarrelNum = RawMaterialbarrelNum_2, + RawMaterialLocation = RawMaterialLocation_2 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight1_2, + RawMaterialBarrelNum = RawMaterialbarrelNum1_2, + RawMaterialLocation = RawMaterialLocation1_2 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight2_2, + RawMaterialBarrelNum = RawMaterialbarrelNum2_2, + RawMaterialLocation = RawMaterialLocation2_2 + }); + + Json.Data.Recipes.Add(new Model.RemoteRecipeData() + { + RecipeName = recipeName_2, + RecipeCode = recipeCode_2, + TrayCode = Traycode_2, + RawMaterial = RawMaterials + }); + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml b/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml new file mode 100644 index 00000000..833cae7a --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml @@ -0,0 +1,314 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml.cs b/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml.cs new file mode 100644 index 00000000..5be01d0b --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/HardwareStatusView.xaml.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodBigStation.View +{ + /// + /// HardwareStatusView.xaml 的交互逻辑 + /// + public partial class HardwareStatusView : UserControl + { + public HardwareStatusView() + { + InitializeComponent(); + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml b/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml new file mode 100644 index 00000000..4256a586 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 小料 + + + + + + + + + + + + 原料桶号 + 原料位置 + 原料重量 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml.cs b/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml.cs new file mode 100644 index 00000000..5742f815 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/RecipeInfosView.xaml.cs @@ -0,0 +1,31 @@ +using BPASmartClient.Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodBigStation.View +{ + /// + /// NewRecipeView.xaml 的交互逻辑 + /// + public partial class RecipeInfosView : Window + { + public RecipeInfosView() + { + InitializeComponent(); + + ActionManage.GetInstance.CancelRegister("CloseRecipeInfosView"); + ActionManage.GetInstance.Register(new Action(() => { this.Close(); }), "CloseRecipeInfosView"); + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml b/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml new file mode 100644 index 00000000..2713578d --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml.cs b/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml.cs new file mode 100644 index 00000000..6201e8df --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/View/RecipeReceiveView.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodBigStation.View +{ + /// + /// RecipeSettingsView.xaml 的交互逻辑 + /// + public partial class RecipeReceiveView : UserControl + { + public RecipeReceiveView() + { + InitializeComponent(); + } + } +} diff --git a/BPASmartClient.JXJFoodBigStation/ViewModel/HardwareStatusViewModel.cs b/BPASmartClient.JXJFoodBigStation/ViewModel/HardwareStatusViewModel.cs new file mode 100644 index 00000000..4a082b5f --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/ViewModel/HardwareStatusViewModel.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodBigStation.Model; + +namespace BPASmartClient.JXJFoodBigStation.ViewModel +{ + public class HardwareStatusViewModel : ObservableObject + { + public HardwareStatusViewModel() + { + for (int i = 0; i < 8; i++) + { + TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() + { + DeviceName = i.ToString(), + RunStatus = false, + Weight = new Random().Next(0, 100) + }); + } + } + + public ObservableCollection TopDeviceCurrentStatuses { get; set; } = new ObservableCollection(); + public ObservableCollection BottomDeviceCurrentStatuses { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeInfosViewModel.cs b/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeInfosViewModel.cs new file mode 100644 index 00000000..65ad9e20 --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeInfosViewModel.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.ObjectModel; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodBigStation.Model; +using BPASmartClient.CustomResource.Pages.Model; + +namespace BPASmartClient.JXJFoodBigStation.ViewModel +{ + public class RecipeInfosViewModel : ObservableObject + { + public RecipeInfosViewModel() + { + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is RemoteRecipeData rm) + { + RecipeName = rm.RecipeName; + RecipeCode = rm.RecipeCode; + RawMaterials = rm.RawMaterial; + } + }), "RecipeInfo"); + ReturnPage = new RelayCommand(() => + { + ActionManage.GetInstance.Send("CloseRecipeInfosView"); + }); + } + + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } } + private string _mRecipeName; + + public long RecipeCode { get { return _mRecipeCode; } set { _mRecipeCode = value; OnPropertyChanged(); } } + private long _mRecipeCode; + + public RelayCommand ReturnPage { get; set; } + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeReceiveViewModel.cs b/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeReceiveViewModel.cs new file mode 100644 index 00000000..deb0d14f --- /dev/null +++ b/BPASmartClient.JXJFoodBigStation/ViewModel/RecipeReceiveViewModel.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodBigStation.Model; +using BPASmartClient.JXJFoodBigStation.View; +using BPASmartClient.CustomResource.UserControls; +using BPASmartClient.CustomResource.UserControls.Model; +using BPASmartClient.CustomResource.UserControls.Enum; +using System.Windows.Media; +using BPASmartClient.CustomResource.UserControls.MessageShow; +using BPASmartClient.CustomResource.Pages.Model; +using BPASmartClient.JXJFoodBigStation.Model.Siemens; + +namespace BPASmartClient.JXJFoodBigStation.ViewModel +{ + public class RecipeReceiveViewModel : ObservableObject + { + public RecipeReceiveViewModel() + { + //Json.Read(); + Recipes = Json.Data.Recipes; + DetailsCommand = new RelayCommand((o) => + { + if (o != null && o is long num) + { + ActionManage.GetInstance.CancelRegister("RecipeInfo"); + RecipeInfosView nrv = new RecipeInfosView(); + var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipeCode == num); + ActionManage.GetInstance.Send("RecipeInfo", res); + nrv.ShowDialog(); + MessageLog.GetInstance.ShowUserLog($"查看配方——{res.RecipeName}"); + } + }); + } + + public RelayCommand DetailsCommand { get; set; } + + public ObservableCollection Recipes { get; set; } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/App.config b/BPASmartClient.JXJFoodSmallStation/App.config new file mode 100644 index 00000000..5ff78b1a --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/App.config @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/BPASmartClient.JXJFoodSmallStation/App.xaml b/BPASmartClient.JXJFoodSmallStation/App.xaml new file mode 100644 index 00000000..ee356c33 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/App.xaml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodSmallStation/App.xaml.cs b/BPASmartClient.JXJFoodSmallStation/App.xaml.cs new file mode 100644 index 00000000..ee7287db --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/App.xaml.cs @@ -0,0 +1,204 @@ +using BPASmartClient.JXJFoodSmallStation.Model; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Configuration; +using System.Data; +using System.Linq; +using System.Threading.Tasks; +using System.Windows; +using BPASmartClient.CustomResource.Pages.Enums; +using BPASmartClient.CustomResource.Pages.Model; +using BPASmartClient.CustomResource.Pages.View; +using BPASmartClient.CustomResource.Pages.ViewModel; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model.Siemens; + +namespace BPASmartClient.JXJFoodSmallStation +{ + /// + /// Interaction logic for App.xaml + /// + public partial class App : Application + { + public static Window MainWindow; + protected override void OnStartup(StartupEventArgs e) + { + base.OnStartup(e); + MenuInit(); + DataInit(); + DeviceInquire.GetInstance.Init();//配料机设备上线监听,设备列表初始化 + ProcessControl.GetInstance.Init(); + MainView mv = new MainView(); + //mv.Show(); + LoginView lv = new LoginView(); + var res = lv.ShowDialog(); + if (res != null && res == true) + { + MessageLog.GetInstance.ShowUserLog("用户登录"); + mv.Show(); + } + else + mv.Close(); + MainWindow = mv; + } + + protected override void OnExit(ExitEventArgs e) + { + base.OnExit(e); + Json.Save(); + MessageLog.GetInstance.LogSave(); + ThreadManage.GetInstance().Dispose(); + } + + private void MenuInit() + { + NfcServer.GetInstance.Init(); + + #region 配方管理菜单 + ObservableCollection RecipeManage = new ObservableCollection(); + RecipeManage.Add(new SubMenumodel() + { + SubMenuName = "本地配方管理", + SubMenuPermission = new Permission[] { Permission.管理员 }, + AssemblyName = "BPASmartClient.JXJFoodSmallStation", + ToggleWindowPath = "View.RecipeSettingsView" + }); + + RecipeManage.Add(new SubMenumodel() + { + SubMenuName = "本地配方下发", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员 }, + AssemblyName = "BPASmartClient.JXJFoodSmallStation", + ToggleWindowPath = "View.RecipeControlView" + }); + RecipeManage.Add(new SubMenumodel() + { + SubMenuName = "服务配方管理", + SubMenuPermission = new Permission[] { Permission.管理员 }, + AssemblyName = "BPASmartClient.JXJFoodSmallStation", + ToggleWindowPath = "View.RecipeReceiveView" + }); + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "配方管理", + Alias = "Recipe Management", + subMenumodels = RecipeManage, + }); + #endregion + + #region 消息日志 + ObservableCollection InfoLog = new ObservableCollection(); + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "操作日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.UserLogView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "运行日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.RunLogView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "报警记录", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.AlarmView" + }); + + InfoLog.Add(new SubMenumodel() + { + SubMenuName = "调试日志", + SubMenuPermission = new Permission[] { Permission.操作员, Permission.管理员, Permission.技术员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.DebugLogView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "消息日志", + Alias = "Message Log", + subMenumodels = InfoLog, + }); + #endregion + + #region 硬件设备监控 + ObservableCollection DeviceMonitor = new ObservableCollection(); + DeviceMonitor.Add(new SubMenumodel() + { + SubMenuName = "原料设备列表", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.JXJFoodSmallStation", + ToggleWindowPath = "View.DeviceListView" + }); + + DeviceMonitor.Add(new SubMenumodel() + { + SubMenuName = "设备状态", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.JXJFoodSmallStation", + ToggleWindowPath = "View.HardwareStatusView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "设备监控", + Alias = "Device Monitor", + subMenumodels = DeviceMonitor, + }); + #endregion + + #region 用户管理 + ObservableCollection UserManager = new ObservableCollection(); + UserManager.Add(new SubMenumodel() + { + SubMenuName = "用户登录", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.SubPagLoginView" + }); + + UserManager.Add(new SubMenumodel() + { + SubMenuName = "密码修改", + SubMenuPermission = new Permission[] { Permission.管理员, Permission.操作员, Permission.技术员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.PasswordChangeView" + }); + + UserManager.Add(new SubMenumodel() + { + SubMenuName = "NFC登录设置", + SubMenuPermission = new Permission[] { Permission.管理员 }, + AssemblyName = "BPASmartClient.CustomResource", + ToggleWindowPath = "Pages.View.NfcSetView" + }); + + MenuManage.GetInstance.menuModels.Add(new MenuModel() + { + MainMenuIcon = "", + MainMenuName = "用户管理", + Alias = "User Management", + subMenumodels = UserManager, + }); + #endregion + } + + private void DataInit() + { + Config.GetInstance.Init(); + Json.Read(); + } + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/AssemblyInfo.cs b/BPASmartClient.JXJFoodSmallStation/AssemblyInfo.cs new file mode 100644 index 00000000..8b5504ec --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Windows; + +[assembly: ThemeInfo( + ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located + //(used if a resource is not found in the page, + // or application resource dictionaries) + ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located + //(used if a resource is not found in the page, + // app, or any theme specific resource dictionaries) +)] diff --git a/BPASmartClient.JXJFoodSmallStation/BPASmartClient.JXJFoodSmallStation.csproj b/BPASmartClient.JXJFoodSmallStation/BPASmartClient.JXJFoodSmallStation.csproj new file mode 100644 index 00000000..1305e32f --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/BPASmartClient.JXJFoodSmallStation.csproj @@ -0,0 +1,50 @@ + + + + WinExe + net6.0-windows + enable + true + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodSmallStation/Model/DeviceCurrentStatus.cs b/BPASmartClient.JXJFoodSmallStation/Model/DeviceCurrentStatus.cs new file mode 100644 index 00000000..299ada75 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/DeviceCurrentStatus.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class DeviceCurrentStatus : ObservableObject + { + + public double Weight { get { return _mWeight; } set { _mWeight = value; OnPropertyChanged(); } } + private double _mWeight; + + + public bool RunStatus { get { return _mRunStatus; } set { _mRunStatus = value; OnPropertyChanged(); } } + private bool _mRunStatus; + + + public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } + private string _mDeviceName; + + + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/DeviceInquire.cs b/BPASmartClient.JXJFoodSmallStation/Model/DeviceInquire.cs new file mode 100644 index 00000000..1f24e6bb --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/DeviceInquire.cs @@ -0,0 +1,233 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using BPASmartClient.JXJFoodSmallStation.ViewModel; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Net.NetworkInformation; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using BPASmartClient.CustomResource.UserControls.MessageShow; +using BPASmartClient.CustomResource.Pages.Model; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class DeviceInquire + { + private volatile static DeviceInquire _Instance; + public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire()); + private DeviceInquire() { } + + string IPSegment = "192.168.0."; + + ConcurrentDictionary DeviceLists = new ConcurrentDictionary(); + List InvalidIP = new List();//无效 IP 集合 + List IPLists = new List();//启动 Ping 任务IP集合 + ConcurrentQueue IPQueues = new ConcurrentQueue();//pincomplete 完成队列 + ConcurrentDictionary DeviceLocation = new ConcurrentDictionary(); + public void Init() + { + IpAddressLines(); + ThreadManage.GetInstance().StartLong(new Action(() => + { + if (IPQueues.Count >= IPLists.Count) + IpAddressLines(); + Thread.Sleep(5000); + }), "配料机设备上线监听", true); + } + + public void Rescan() + { + InvalidIP.Clear(); + } + + public DeviceStatus GetDevice(string ip) + { + if (ip != null) + { + var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip); + if (res != null) return res; + } + return new DeviceStatus(); + } + + public DeviceStatus GetDeviceObject(int location) + { + if (location >= 1 && location <= 15) + { + var res = DeviceLists.Values.FirstOrDefault(p => p.RawMaterialLocation == location); + if (res != null) return res; + } + return new DeviceStatus(); + } + + private void IpAddressLines() + { + IPLists.Clear(); + IPQueues.Clear(); + for (int i = 1; i <= 255; i++) + { + if (!InvalidIP.Contains($"{IPSegment}{i}") && !DeviceLists.ContainsKey($"{IPSegment}{i}")) + { + IPLists.Add($"{IPSegment}{i}"); + } + } + + IPLists.ForEach((item) => + { + Ping myPing = new Ping(); + myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted); + myPing.SendAsync(item, 1000, null); + }); + } + + private void _myPing_PingCompleted(object sender, PingCompletedEventArgs e) + { + if (e.Reply.Status == IPStatus.Success) + { + string ip = e.Reply.Address.ToString(); + if (!DeviceLists.ContainsKey(ip)) + { + DeviceStatus DS = new DeviceStatus(); + DS.modbusTcp.IsReconnect = false; + + DS.modbusTcp.ConnectOk = new Action(() => + { + string DeviceName = DS.modbusTcp.GetString(DeviceAddress.DeviceName, 20);//读取设备名称 + int rawMaterialLocation = DS.modbusTcp.GetAddress(DeviceAddress.Location); + if (DeviceName.Length > 0) + { + DeviceLists.TryAdd(ip, DS); + DeviceLists[ip].Init(DeviceName, rawMaterialLocation); + DeviceLists[ip].modbusTcp.IsReconnect = false; + App.Current.Dispatcher.Invoke(new Action(() => + { + DeviceListViewModel.devices.Add(new Devices() + { + DeviceName = DeviceName, + IpAddress = ip + });//加入连接的(有名称的)设备列表 + + for (int i = 0; i < Json.Data.Recipes.Count; i++) + { + for (int m = 0; m < Json.Data.Recipes.ElementAt(i).RawMaterials.Count; m++) + { + if (Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip) + { + Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName; + Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMateriaLocation = rawMaterialLocation; + } + } + } + if (!NewRecipeViewModel.RawMaterialNames.Contains(DeviceName)) + NewRecipeViewModel.RawMaterialNames.Add(DeviceName); + })); + } + else + { + if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); + } + }); + + DS.modbusTcp.ConnectFail = new Action(() => + { + if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); + //MessageLog.GetInstance.ShowAlarmLog($"设备{ip}连接失败"); + }); + + DS.modbusTcp.Disconnect = new Action(() => + { + if (InvalidIP.Contains(ip)) InvalidIP.Remove(ip); + var res = DeviceListViewModel.devices.FirstOrDefault(P => P.IpAddress == ip); + if (res != null && DeviceListViewModel.devices.Contains(res)) + App.Current.Dispatcher.Invoke(new Action(() => + { + DeviceListViewModel.devices.Remove(res); + if (NewRecipeViewModel.RawMaterialNames.Contains(res.DeviceName)) + NewRecipeViewModel.RawMaterialNames.Remove(res.DeviceName); + })); + if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose(); + }); + + Task.Run(new Action(() => + { + DS.modbusTcp.ModbusTcpConnect(ip, 502);//PLC连接 + IPQueues.Enqueue(e.Reply.Address.ToString()); + })); + } + else IPQueues.Enqueue(e.Reply.Address.ToString()); + } + else IPQueues.Enqueue(e.Reply.Address.ToString()); + } + } + + public class DeviceStatus + { + #region 对象属性声明 + public string DeviceName = String.Empty; + public string IpAddress => modbusTcp.IPAdress; + public bool IsConnected => modbusTcp.Connected; + public int RawMaterialLocation { get; set; } + /// + /// 设备状态 + /// + public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus(); + public ModbusTcp modbusTcp = new ModbusTcp(); + #endregion + public void Init(string DeviceName,int rawMaterialLocation) + { + this.DeviceName = DeviceName; + this.RawMaterialLocation = rawMaterialLocation; + if (modbusTcp.Connected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + //获取设备运行状态 + var res = this.modbusTcp.Read(DeviceAddress.RunStatus); + if (res != null && res is ushort[] ushortValue) + { + if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0]; + } + //获取设备料仓剩余重量 + deviceStatus.WeightFeedback = this.modbusTcp.GetUint(DeviceAddress.WeightFeedback); + deviceStatus.CutWeightFeedback = this.modbusTcp.GetUint(DeviceAddress.CutWeightFeedback); + deviceStatus.RawMaterialType =(ushort) this.modbusTcp.GetUint(DeviceAddress.RawMaterialType); + Thread.Sleep(100); + }), $"{DeviceName} 开始监听", true); + } + } + + public void SetDeviceName(string name) + { + this.modbusTcp.Write(DeviceAddress.DeviceName, new ushort[20]); + this.modbusTcp.SetString(DeviceAddress.DeviceName, name); + } + public void StatusReset() + { + this.modbusTcp.Write(DeviceAddress.RunStatus, (ushort)0); + } + public void OutRawMaterialReset() + { + this.modbusTcp.Write(DeviceAddress.OutRawMaterialFinish, (ushort)0); + } + public void Dispose() + { + ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听"); + } + /// + /// 设置出料重量,触发出料信号 + /// + /// + public void Start(uint Value) + { + if (modbusTcp.Connected) + { + modbusTcp.SetUint(DeviceAddress.WeightSet, Value);//写入配方量 + modbusTcp.Write(DeviceAddress.Start, (ushort)1);//设备启动写入 + } + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/DataComm.cs b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/DataComm.cs new file mode 100644 index 00000000..f47bd894 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/DataComm.cs @@ -0,0 +1,41 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.HK_PLC +{ + public class DataComm + { + public volatile static DataComm Instance; + public static DataComm GetInstance => Instance ?? (new DataComm()); + public DataComm() { } + /// + /// 是否允许配料 + /// + public bool IsAllowDosing { get { return _mIsAllowDosing; } set { _mIsAllowDosing = value; } } + private bool _mIsAllowDosing; + + public bool DosingFinishToPLC { get { return _mDosingFinishToPLC; } set { _mDosingFinishToPLC = value; } } + private bool _mDosingFinishToPLC; + + private int _mStockBinLocationToPLC; + public int StockBinLocationToPLC { get { return _mStockBinLocationToPLC; } set { _mStockBinLocationToPLC = value; } } + + public bool StatusSignToBPA { get { return _mStatusSignToBPA; } set { _mStatusSignToBPA = value; } } + private bool _mStatusSignToBPA; + + private int _mStockBinLocationToBPA; + public int StockBinLocationToBPA { get { return _mStockBinLocationToBPA; } set { _mStockBinLocationToBPA = value; } } + + private int _mBarrelNumToPLC; + public int BarrelNumToPLC { get { return _mBarrelNumToPLC; } set { _mBarrelNumToPLC = value; } } + + /*public ConcurrentDictionary DeviceLists = new ConcurrentDictionary();*/ + } + +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKDeviceStatus.cs b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKDeviceStatus.cs new file mode 100644 index 00000000..29b9411c --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKDeviceStatus.cs @@ -0,0 +1,74 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.HK_PLC +{ + public class HKDeviceStatus + { + public ModbusTcp ModBusHK = new ModbusTcp(); + public string IpAddress => ModBusHK.IPAdress; + public bool IsConnected => ModBusHK.Connected; + + public void Init() + { + if (IsConnected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + + }),"信号收发处理"); + } + } + /// + /// 单个配料机配料完成 + /// + /// + public void SingleDosing(uint value) + { + if (IsConnected) + { + ModBusHK.SetUint(HKPlcCommAddress.SingleStockBinLocationToPLC, value); + ModBusHK.Write(HKPlcCommAddress.SingleDosingFinishToPLC, (ushort)1); + } + } + /// + /// 复位plc允许接料信号 + /// + public void AllowDosingSignReset() + { + ModBusHK.Write(HKPlcCommAddress.IsAllowDosing,(ushort)0); + } + /// + /// 复位plc到达某料仓信号 + /// + public void StockStateSignReset() + { + ModBusHK.Write(HKPlcCommAddress.StockState, (ushort)0); + } + /// + /// 复位一个配方配料完成信号 + /// + public void RecipeDosingFinishReset() + { + ModBusHK.Write(HKPlcCommAddress.RecipeDosingFinish, (ushort)0); + } + /// + /// 下发配方数据 + /// + /// 单个桶的编号 + /// 单个桶对应的料仓位置 + public void StockBinPar(uint BarrelNum, ushort StockBinLocation) + { + if (IsConnected) + { + ModBusHK.SetUint(HKPlcCommAddress.BarrelNumToPLC, BarrelNum); + ModBusHK.Write(HKPlcCommAddress.StockBinLocationToPLC, StockBinLocation); + } + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKPlcCommAddress.cs b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKPlcCommAddress.cs new file mode 100644 index 00000000..0445b1db --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/HK_PLC/HKPlcCommAddress.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.HK_PLC +{ + public class HKPlcCommAddress + { + #region 海科PLC ==> 上位机 + /// + /// 是否允许配料 + /// + public static string IsAllowDosing { get; set; } = ""; + /// + /// 当前料仓位置 + /// + public static string StockBinLocation { get; set; } = ""; + /// + /// 当前料仓的状态(0:无意义,1:到达接料位置) + /// + public static string StockState { get; set; } = ""; + #endregion + + #region 上位机 ==> 海科PLC + /// + /// 料仓位置(配置该配方,所需要多个原料桶,每个原料桶有多个料仓位置) + /// + public static string StockBinLocationToPLC { get; set; } = ""; + /// + /// 对应桶号 + /// + public static string BarrelNumToPLC { get; set; } = ""; + /// + /// 当前配料机配料完成 + /// + public static string SingleDosingFinishToPLC { get; set; } = ""; + /// + /// 当前配料料仓的位置 + /// + public static string SingleStockBinLocationToPLC { get; set; } = ""; + + public static string RecipeDosingFinish { get; set; } = ""; + #endregion + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/ProcessControl.cs b/BPASmartClient.JXJFoodSmallStation/Model/ProcessControl.cs new file mode 100644 index 00000000..ba8fedc5 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/ProcessControl.cs @@ -0,0 +1,171 @@ +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model.HK_PLC; +using BPASmartClient.JXJFoodSmallStation.Model.Siemens; +using BPASmartClient.Modbus; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Configuration; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class ProcessControl + { + private volatile static ProcessControl _Instance; + public static ProcessControl GetInstance => _Instance ?? (_Instance = new ProcessControl()); + private ProcessControl() { } + + public ObservableCollection RemoteRecipes = new ObservableCollection(); + ConcurrentQueue RecipeQueue = new ConcurrentQueue(); + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + + public SiemensDeviceStatus SiemensDevice = new SiemensDeviceStatus(); + public HKDeviceStatus HKDevice = new HKDeviceStatus(); + public void Init() + { + ActionManage.GetInstance.Register(new Action(() => + { + if (SiemensDevice.IsConnected) + { + var res = SiemensDevice.SiemensTcp.GetString(SiemensCommAddress.RecipeName, (ushort)20); + var res1 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RecipeID); + var res2 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RawMaterial); + if ((res != null && res is string recipeName) && + (res1 != null && res1 is uint recipeID) && + (res2 != null && res2 is ushort[] rawMaterial)) + { + RawMaterials.Clear(); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + RawMaterialBarrelNum = rawMaterial[0], + RawMaterialLocation = rawMaterial[1], + RawMaterialWeight = rawMaterial[2] + }); + Json.Data.Recipes.Add(new RemoteRecipeData() + { + RecipeName = recipeName, + RecipeCode = recipeID, + RawMaterial = RawMaterials + }); + } + } + }), "西门子下发配方", true); + ActionManage.GetInstance.Register(new Action(() => + { + if (SiemensDevice.IsConnected) + { + var res = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.TrayLocationNum); + var res1 = SiemensDevice.SiemensTcp.Read(SiemensCommAddress.RecipeID); + if (res != null && res is int TrayLocation && res1 != null && res1 is int recipeId) + { + int index = Array.FindIndex(Json.Data.Recipes.ToArray(), p => p.RecipeCode == recipeId); + if (index >= 0 && index < Json.Data.Recipes.Count) + { + Json.Data.Recipes.ElementAt(index).TrayCode = TrayLocation; + } + } + } + }), "AGV到位信号", true);//根据下发的配方ID将 托盘的位置信息添加到配方中 + string HK_PLC_IP = ConfigurationManager.AppSettings["HKPlc_IP"]; + string HK_PLC_Port = ConfigurationManager.AppSettings["HKPlc_Port"]; + string Siemens_PLC_IP = ConfigurationManager.AppSettings["Siemens_IP"]; + string Siemens_PLC_Port = ConfigurationManager.AppSettings["Siemens_Port"]; + Task.Run(new Action(() => + { + HKDevice.ModBusHK.ModbusTcpConnect(HK_PLC_IP, int.Parse(HK_PLC_Port)); + SiemensDevice.SiemensTcp.ModbusTcpConnect(Siemens_PLC_IP, int.Parse(Siemens_PLC_Port)); + if (HKDevice.IsConnected) + { + HKDevice.Init(); + } + if (SiemensDevice.IsConnected) + { + SiemensDevice.Init(); + } + })); + RecipeQueue.Clear(); + RawMaterials = TestData.GetInstance.RawMaterials;//添加测试数据 + ThreadManage.GetInstance().StartLong(new Action(() => + { + RemoteRecipes = Json.Data.Recipes; + ReceviceData(); + RecipeInfoToHKPLC(); + Thread.Sleep(10); + }), "流程处理", true); + } + + private void ReceviceData() + { + if (Json.Data.Recipes.Count > 0) + { + foreach (var data in Json.Data.Recipes) + { + if(!(RecipeQueue.Contains(data.RecipeCode))) + RecipeQueue.Enqueue(data.RecipeCode); + } + } + } + /// + /// 当前料仓的位置 + /// + private int StockInIsWork; + /// + /// 单个配方执行完成标志 + /// + private bool RecipeFinfish; + private void RecipeInfoToHKPLC() + { + if (RecipeQueue.Count > 0) + { + int index = Array.FindIndex(RemoteRecipes.ToArray(), p => p.RecipeCode == RecipeQueue.ElementAt(0)); + if (index >= 0 && index <= RemoteRecipes.Count) + { + long code = RemoteRecipes.ElementAt(index).RecipeCode; + if (RTrig.GetInstance("IsAllowDosing").Start(HKDevice.ModBusHK.Read(HKPlcCommAddress.IsAllowDosing) is bool a)) + { + foreach (var item in RemoteRecipes.ElementAt(index).RawMaterial) + { + HKDevice.StockBinPar((uint)item.RawMaterialBarrelNum, (ushort)item.RawMaterialLocation); + } + HKDevice.AllowDosingSignReset(); + + } + if (RTrig.GetInstance("StockState").Start(HKDevice.ModBusHK.Read(HKPlcCommAddress.StockState) is bool)) + { + var res = HKDevice.ModBusHK.Read(HKPlcCommAddress.StockBinLocation); + if (res != null && res is int loc) + { + + int loc_index = Array.FindIndex(RemoteRecipes.ElementAt(index).RawMaterial.ToArray(), p => p.RawMaterialLocation == loc); + double weight = RemoteRecipes.ElementAt(index).RawMaterial.ElementAt(loc_index).RawMaterialWeight; + if (loc_index >= 1 && loc_index <= 15) + { + DeviceInquire.GetInstance.GetDeviceObject(loc_index)?.Start((uint)weight);//启动并写入每个原料重量 + StockInIsWork = loc_index; + HKDevice.StockStateSignReset(); + } + } + } + if (RTrig.GetInstance("OutRawMaterialFinish").Start(DeviceInquire.GetInstance.GetDeviceObject(StockInIsWork).modbusTcp.Read(DeviceAddress.OutRawMaterialFinish) is bool)) + { + HKDevice.SingleDosing((uint)StockInIsWork); + DeviceInquire.GetInstance.GetDeviceObject(StockInIsWork).OutRawMaterialReset(); + } + if (RTrig.GetInstance("StockState").Start(HKDevice.ModBusHK.Read(HKPlcCommAddress.RecipeDosingFinish) is bool)) + { + HKDevice.RecipeDosingFinishReset(); + RecipeQueue.TryDequeue(out code); + } + } + } + } + private void HKPLCIsWork() + { + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceAddress.cs b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceAddress.cs new file mode 100644 index 00000000..46afc716 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/DeviceAddress.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class DeviceAddress + { + #region 源地址 + ///// + ///// 设备名称起始地址 + ///// + //public static string DeviceName { get; set; } = "LW0"; + + ///// + ///// 料仓重量反馈起始地址 + ///// + //public static string WeightFeedback { get; set; } = "LW52";//LW204 + + ///// + ///// 重量设置地址 + ///// + //public static string WeightSet { get; set; } = "LW21";//LW200 + + ///// + ///// 启动信号地址 + ///// + //public static string Start { get; set; } = "LW20";//LW210 + + ///// + ///// 下料重量反馈地址 + ///// + //public static string CutWeightFeedback { get; set; } = "LW54";//LW202 + + ///// + ///// 设备运行状态地址 + ///// + //public static string RunStatus { get; set; } = "LW55";//LW206 + + ///// + ///// 料仓的位置 + ///// + //public static string Location { get; set; } = "LW53"; + #endregion + + #region 上位机下发 + /// + /// 原料出料重量 + /// + public static string WeightSet { get; set; } = "LW11"; + /// + /// 启动开始配料 + /// + public static string Start { get; set; } = "LW12"; + #endregion + #region 上位机读取 + /// + /// 设备运行状态地址 + /// + public static string RunStatus { get; set; } = "LW50"; + /// + /// 报警字 + /// + public static string AlarmInfo { get; set; } = "LW51"; + /// + /// 原料名称 + /// + public static string DeviceName { get; set; } = "LW52"; + /// + /// 料仓的位置 + /// + public static string Location { get; set; } = "LW53"; + /// + /// 原料类型 + /// + public static string RawMaterialType { get; set; } = "LW54"; + /// + /// 出料完成信号 + /// + public static string OutRawMaterialFinish { get; set; } = "LW55"; + /// + /// 料仓重量反馈起始地址 + /// + public static string WeightFeedback { get; set; } = "LW56"; + /// + /// 下料重量反馈地址 + /// + public static string CutWeightFeedback { get; set; } = "LW57"; + #endregion + + + + + + + + + } + + + +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/LocaPar.cs b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/LocaPar.cs new file mode 100644 index 00000000..c293856c --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/LocaPar.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Collections.ObjectModel; +using BPASmartClient.JXJFoodSmallStation.ViewModel; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class LocaPar + { + public ObservableCollection Recipes { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialDeviceStatus.cs b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialDeviceStatus.cs new file mode 100644 index 00000000..6bc51f52 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialDeviceStatus.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class RawMaterialDeviceStatus + { + + /// + /// 原料类型 + /// 1:液体 + /// 2:膏体 + /// 3:粉体 + /// + public ushort RawMaterialType { get; set; } + + /// + /// 料仓重量反馈 + /// + public float WeightFeedback { get; set; } + + /// + /// 上限反馈 + /// + public bool UpLimitFeedback { get; set; } + + /// + /// 下限反馈 + /// + public bool DownLimitFeedback { get; set; } + + /// + /// 下料重量反馈 + /// + public float CutWeightFeedback { get; set; } + + /// + /// 设备运行状态 + /// + public ushort RunStatus { get; set; } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialModel.cs b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialModel.cs new file mode 100644 index 00000000..e116bd12 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RawMaterialModel.cs @@ -0,0 +1,93 @@ +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + /// + /// 原料模块 + /// + public class RawMaterialModel : ObservableObject + { + /// + /// 原料名称 + /// + public string RawMaterialName { get { return _mRawMaterialName; } set { _mRawMaterialName = value; OnPropertyChanged(); } } + private string _mRawMaterialName; + + /// + /// 原料编号 + /// + public int RawMateriaLocation { get { return _mRawMaterialLocation; } set { _mRawMaterialLocation = value; OnPropertyChanged(); } } + private int _mRawMaterialLocation; + + /// + /// 原料设备IP + /// + public string DeviceIp { get; set; } + + /// + /// 原料重量设置 + /// + public uint RawMaterialWeight { get { return _mRawMaterialWeight; } set { _mRawMaterialWeight = value; OnPropertyChanged(); } } + private uint _mRawMaterialWeight; + + /// + /// 原料类型 MW18 + /// 1:液体 + /// 2:膏体 + /// 3:粉体 + /// + [Newtonsoft.Json.JsonIgnore] + public ushort RawMaterialType { get { return _mRawMaterialType; } set { _mRawMaterialType = value; OnPropertyChanged(); } } + private ushort _mRawMaterialType; + + /// + /// 料仓重量反馈 MD40 + /// + [Newtonsoft.Json.JsonIgnore] + public float WeightFeedback { get { return _mWeightFeedback; } set { _mWeightFeedback = value; OnPropertyChanged(); } } + private float _mWeightFeedback; + + /// + /// 上限反馈 + /// + [Newtonsoft.Json.JsonIgnore] + public bool UpLimtFeedback { get { return _mUpLimtFeedback; } set { _mUpLimtFeedback = value; OnPropertyChanged(); } } + private bool _mUpLimtFeedback; + + /// + /// 下限反馈 + /// + [Newtonsoft.Json.JsonIgnore] + public bool DownLimtFeedback { get { return _mDownLimtFeedback; } set { _mDownLimtFeedback = value; OnPropertyChanged(); } } + private bool _mDownLimtFeedback; + + /// + /// 下料重量反馈 MD52 + /// + [Newtonsoft.Json.JsonIgnore] + public float UpLimtWeightFeedback { get { return _mUpLimtWeightFeedback; } set { _mUpLimtWeightFeedback = value; OnPropertyChanged(); } } + private float _mUpLimtWeightFeedback; + + + /// + /// 原料ID + /// + public string RawMaterialId { get { return _mRawMaterialId; } set { _mRawMaterialId = value; OnPropertyChanged(); } } + private string _mRawMaterialId; + + /// + /// 原料设备执行状态 + /// 1:空闲状态 + /// 2:下料中 + /// 3:下料完成 + /// + [Newtonsoft.Json.JsonIgnore] + public ushort RecipeStatus { get { return _mRecipeStatus; } set { _mRecipeStatus = value; OnPropertyChanged(); } } + private ushort _mRecipeStatus = 1; + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RecipeModel.cs b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RecipeModel.cs new file mode 100644 index 00000000..f9c56b47 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/RawMaterial/RecipeModel.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using BPASmartClient.JXJFoodSmallStation.ViewModel; +using Microsoft.Toolkit.Mvvm.ComponentModel; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + /// + /// 配方模块 + /// + public class RecipeModel : ObservableObject + { + [Newtonsoft.Json.JsonIgnore] + public bool IsEnable { get { return _mIsEnable; } set { _mIsEnable = value; OnPropertyChanged(); } } + private bool _mIsEnable = true; + + /// + /// 序号 + /// + public int SerialNum { get { return _mSerialNum; } set { _mSerialNum = value; OnPropertyChanged(); } } + private int _mSerialNum; + + /// + /// 配方名称 + /// + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } } + private string _mRecipeName; + + /// + /// 配方编码 + /// + public string RecipCode { get { return _mRecipCode; } set { _mRecipCode = value; OnPropertyChanged(); } } + private string _mRecipCode; + + [Newtonsoft.Json.JsonIgnore] + public AutoResetEvent Are { get; set; } = new AutoResetEvent(false); + + /// + /// 原料集合 + /// + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeData.cs b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeData.cs new file mode 100644 index 00000000..d08b6b7b --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeData.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class RemoteRecipeData + { + /// + /// 配方名称 + /// + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; } } + private string _mRecipeName; + + /// + /// 配方ID + /// + public long RecipeCode { get { return _mRecipeCode; } set { _mRecipeCode = value; } } + private long _mRecipeCode; + + /// + /// 托盘编号 + /// + public int TrayCode { get { return _mTrayCode; } set { _mTrayCode = value; } } + private int _mTrayCode; + + /// + /// 原料数据 + /// + public ObservableCollection RawMaterial { get; set; } = new ObservableCollection(); + + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeDataColl.cs b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeDataColl.cs new file mode 100644 index 00000000..b412208c --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeDataColl.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.Siemens +{ + public class RemoteRecipeDataColl + { + public ObservableCollection Recipes { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeRawMaterial.cs b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeRawMaterial.cs new file mode 100644 index 00000000..dd524cfa --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/RemoteRecipeRawMaterial.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class RemoteRecipeRawMaterial + { + private int _mIp; + public int DeviceIp { get { return _mIp; } set { _mIp = value; } } + + private int _mRawMaterialBarrelNum; + /// + /// 原料对应的桶号 + /// + public int RawMaterialBarrelNum { get { return _mRawMaterialBarrelNum; } set { _mRawMaterialBarrelNum = value; } } + + private double _mRawMaterialWeight; + /// + /// 需要原料重量 + /// + public double RawMaterialWeight { get { return _mRawMaterialWeight; } set { _mRawMaterialWeight = value;} } + + + private int _mRawMaterialLocation; + /// + /// 原料对应料仓的位置 + /// + public int RawMaterialLocation { get { return _mRawMaterialLocation; } set { _mRawMaterialLocation = value;} } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensCommAddress.cs b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensCommAddress.cs new file mode 100644 index 00000000..341c2f44 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensCommAddress.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.Siemens +{ + public class SiemensCommAddress + { + #region 配方地址 + /// + /// 配方状态 + /// + public static string RecipeState { get; set; } = ""; + /// + /// 配方名称 + /// + public static string RecipeName { get; set; } = ""; + /// + /// 配方ID + /// + public static string RecipeID { get; set; } = ""; + /// + /// 原料信息 + /// + public static string RawMaterial { get; set; } = ""; + #endregion + + #region AGV到位(与西门子PLC交互)西门子PLC ==> 上位机 + public static string TrayLocationNum { get; set; } = ""; + public static string TrayRecipeID { get; set; } = ""; + public static string TrayState { get; set; } = ""; + #endregion + + #region Tray配料完成(与西门子PLC交互)上位机 ==> 西门子PLC + public static string TrayLocationNumToPLC { get; set; } = ""; + public static string TrayRecipeIDToPLC { get; set; } = ""; + public static string TrayStateToPLC { get; set; } = ""; + #endregion + } + + +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensDeviceStatus.cs b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensDeviceStatus.cs new file mode 100644 index 00000000..69d4788e --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/Siemens/SiemensDeviceStatus.cs @@ -0,0 +1,64 @@ +using BPASmartClient.Helper; +using BPASmartClient.Modbus; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model.Siemens +{ + public class SiemensDeviceStatus + { + public ModbusTcp SiemensTcp = new ModbusTcp(); + public bool IsConnected => SiemensTcp.Connected; + public string IpAddress => SiemensTcp.IPAdress; + + /// + /// 配方接收信号复位 + /// + public void RecipeSignReset() + { + this.SiemensTcp.Write(SiemensCommAddress.RecipeState, (ushort)0); + } + /// + /// AGV到位信号复位 + /// + public void AgvSignReset() + { + this.SiemensTcp.Write(SiemensCommAddress.TrayState, (ushort)0); + } + public void Init() + { + if (IsConnected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + var res = this.SiemensTcp.Read(SiemensCommAddress.RecipeState); + if (res != null && RTrig.GetInstance("RecipeTrig").Start(res is bool SignTrig)) + { + ActionManage.GetInstance.Send("西门子下发配方"); + RecipeSignReset(); + } + var AgvState = this.SiemensTcp.Read(SiemensCommAddress.TrayState); + if (AgvState != null && RTrig.GetInstance("AgvTrig").Start(res is bool AgvSignTrig)) + { + ActionManage.GetInstance.Send("AGV到位信号"); + AgvSignReset(); + } + }),"监听服务数据"); + } + } + /// + /// 配方配料完成信号 + /// + /// + /// + private void DosingFinsih(int TrayLocation,int recipeID) + { + this.SiemensTcp.Write(SiemensCommAddress.TrayLocationNumToPLC, TrayLocation); + this.SiemensTcp.Write(SiemensCommAddress.TrayStateToPLC, 1); + this.SiemensTcp.Write(SiemensCommAddress.TrayRecipeIDToPLC, recipeID); + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/Model/TestData.cs b/BPASmartClient.JXJFoodSmallStation/Model/TestData.cs new file mode 100644 index 00000000..ae9576f8 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/Model/TestData.cs @@ -0,0 +1,111 @@ +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model.Siemens; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BPASmartClient.JXJFoodSmallStation.Model +{ + public class TestData + { + public volatile static TestData Instance; + public static TestData GetInstance => Instance ?? (Instance = new TestData()); + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + public TestData() + { + string recipeName = "配方1"; + long recipeCode = 10001; + int Traycode = 1; + + double RawmaterialWeight = 10; + int RawMaterialbarrelNum = 1; + int RawMaterialLocation = 5; + + double RawmaterialWeight1 = 20; + int RawMaterialbarrelNum1 = 2; + int RawMaterialLocation1 = 7; + + double RawmaterialWeight2 = 30; + int RawMaterialbarrelNum2 = 3; + int RawMaterialLocation2 = 9; + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight, + RawMaterialBarrelNum = RawMaterialbarrelNum, + RawMaterialLocation = RawMaterialLocation + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight1, + RawMaterialBarrelNum = RawMaterialbarrelNum1, + RawMaterialLocation = RawMaterialLocation1 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight2, + RawMaterialBarrelNum = RawMaterialbarrelNum2, + RawMaterialLocation = RawMaterialLocation2 + }); + + Json.Data.Recipes.Add(new Model.RemoteRecipeData() + { + RecipeName = recipeName, + RecipeCode = recipeCode, + TrayCode = Traycode, + RawMaterial = RawMaterials + }); + + RawMaterials.Clear(); + string recipeName_2 = "配方2"; + long recipeCode_2 = 20001; + int Traycode_2 = 3; + + double RawmaterialWeight_2 = 10; + int RawMaterialbarrelNum_2 = 1; + int RawMaterialLocation_2 = 5; + + double RawmaterialWeight1_2 = 20; + int RawMaterialbarrelNum1_2 = 2; + int RawMaterialLocation1_2 = 7; + + double RawmaterialWeight2_2 = 30; + int RawMaterialbarrelNum2_2 = 3; + int RawMaterialLocation2_2 = 9; + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight_2, + RawMaterialBarrelNum = RawMaterialbarrelNum_2, + RawMaterialLocation = RawMaterialLocation_2 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight1_2, + RawMaterialBarrelNum = RawMaterialbarrelNum1_2, + RawMaterialLocation = RawMaterialLocation1_2 + }); + RawMaterials.Add(new RemoteRecipeRawMaterial() + { + DeviceIp = RawMaterials.Count + 1, + RawMaterialWeight = RawmaterialWeight2_2, + RawMaterialBarrelNum = RawMaterialbarrelNum2_2, + RawMaterialLocation = RawMaterialLocation2_2 + }); + + Json.Data.Recipes.Add(new Model.RemoteRecipeData() + { + RecipeName = recipeName_2, + RecipeCode = recipeCode_2, + TrayCode = Traycode_2, + RawMaterial = RawMaterials + }); + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/View/ChangeDeviceNameView.xaml b/BPASmartClient.JXJFoodSmallStation/View/ChangeDeviceNameView.xaml new file mode 100644 index 00000000..6ce96ca2 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/ChangeDeviceNameView.xaml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodSmallStation/View/RecipeInfosView.xaml.cs b/BPASmartClient.JXJFoodSmallStation/View/RecipeInfosView.xaml.cs new file mode 100644 index 00000000..7666ff5c --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/RecipeInfosView.xaml.cs @@ -0,0 +1,31 @@ +using BPASmartClient.Helper; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodSmallStation.View +{ + /// + /// NewRecipeView.xaml 的交互逻辑 + /// + public partial class RecipeInfosView : Window + { + public RecipeInfosView() + { + InitializeComponent(); + + ActionManage.GetInstance.CancelRegister("CloseRecipeInfosView"); + ActionManage.GetInstance.Register(new Action(() => { this.Close(); }), "CloseRecipeInfosView"); + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml b/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml new file mode 100644 index 00000000..82d32ea6 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml @@ -0,0 +1,143 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml.cs b/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml.cs new file mode 100644 index 00000000..aafe8fcb --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/RecipeReceiveView.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodSmallStation.View +{ + /// + /// RecipeSettingsView.xaml 的交互逻辑 + /// + public partial class RecipeReceiveView : UserControl + { + public RecipeReceiveView() + { + InitializeComponent(); + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml b/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml new file mode 100644 index 00000000..86af1192 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml @@ -0,0 +1,400 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml.cs b/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml.cs new file mode 100644 index 00000000..c2e09ea2 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/View/RecipeSettingsView.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; + +namespace BPASmartClient.JXJFoodSmallStation.View +{ + /// + /// RecipeSettingsView.xaml 的交互逻辑 + /// + public partial class RecipeSettingsView : UserControl + { + public RecipeSettingsView() + { + InitializeComponent(); + } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/ChangeDeviceNameViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/ChangeDeviceNameViewModel.cs new file mode 100644 index 00000000..c3379121 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/ChangeDeviceNameViewModel.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using Microsoft.Toolkit.Mvvm.Input; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class ChangeDeviceNameViewModel : ObservableObject + { + public ChangeDeviceNameViewModel() + { + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is string str) IpAddress = str; + }), "ChangeDeviceNameViewOpen"); + + CancleCommand = new RelayCommand(() => { ActionManage.GetInstance.Send("ChangeDeviceNameViewClose"); }); + ConfirmCommand = new RelayCommand(() => + { + if (string.IsNullOrEmpty(DeviceName)) + { + ErrorInfo = "设备名称不能为空"; + return; + } + int index = Array.FindIndex(DeviceListViewModel.devices.ToArray(), p => p.IpAddress == IpAddress); + if (index >= 0 && index < DeviceListViewModel.devices.Count) + { + if (DeviceListViewModel.devices.FirstOrDefault(p => p.DeviceName == DeviceName) != null) + ErrorInfo = "设备名称已存在"; + else + { + NewRecipeViewModel.RawMaterialNames.Remove(DeviceListViewModel.devices.ElementAt(index).DeviceName); + NewRecipeViewModel.RawMaterialNames.Add(DeviceName); + DeviceListViewModel.devices.ElementAt(index).DeviceName = DeviceName; + + DeviceInquire.GetInstance.GetDevice(IpAddress).SetDeviceName(DeviceName);//设置PLC名称 + for (int i = 0; i < Json.Data.Recipes.Count; i++) + { + for (int m = 0; m < Json.Data.Recipes.ElementAt(i).RawMaterials.Count; m++) + { + Json.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName; + } + } + ActionManage.GetInstance.Send("ChangeDeviceNameViewClose"); + } + } + + }); + } + + private static string IpAddress = string.Empty; + + public RelayCommand ConfirmCommand { get; set; } + + public RelayCommand CancleCommand { get; set; } + + + public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } } + private string _mErrorInfo; + + + public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } + private string _mDeviceName; + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/DeviceListViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/DeviceListViewModel.cs new file mode 100644 index 00000000..e54f9ad1 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/DeviceListViewModel.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodSmallStation.View; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class DeviceListViewModel : ObservableObject + { + public DeviceListViewModel() + { + ChangeNameCommand = new RelayCommand((o) => + { + if (o != null && o is string str) + { + ChangeDeviceNameView cdn = new ChangeDeviceNameView(); + ActionManage.GetInstance.Send("ChangeDeviceNameViewOpen", str); + cdn.ShowDialog(); + } + }); + } + + public RelayCommand ChangeNameCommand { get; set; } + + public static ObservableCollection devices { get; set; } = new ObservableCollection(); + } + + public class Devices : ObservableObject + { + public string IpAddress { get { return _mIpAddress; } set { _mIpAddress = value; OnPropertyChanged(); } } + private string _mIpAddress; + + public string DeviceName { get { return _mDeviceName; } set { _mDeviceName = value; OnPropertyChanged(); } } + private string _mDeviceName; + + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/HardwareStatusViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/HardwareStatusViewModel.cs new file mode 100644 index 00000000..a4605192 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/HardwareStatusViewModel.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodSmallStation.Model; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class HardwareStatusViewModel : ObservableObject + { + public HardwareStatusViewModel() + { + for (int i = 0; i < 8; i++) + { + TopDeviceCurrentStatuses.Add(new DeviceCurrentStatus() + { + DeviceName = i.ToString(), + RunStatus = false, + Weight = new Random().Next(0, 100) + }); + } + } + + public ObservableCollection TopDeviceCurrentStatuses { get; set; } = new ObservableCollection(); + public ObservableCollection BottomDeviceCurrentStatuses { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/NewRecipeViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/NewRecipeViewModel.cs new file mode 100644 index 00000000..05b41c32 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/NewRecipeViewModel.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.ObjectModel; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model; +using BPASmartClient.CustomResource.Pages.Model; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class NewRecipeViewModel : ObservableObject + { + public NewRecipeViewModel() + { + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is RecipeModel rm) + { + RecipeName = rm.RecipeName; + foreach (var item in rm.RawMaterials) + { + RawMaterials.Add(item); + } + RecipCode = rm.RecipCode; + } + }), "Details"); + + AddCommand = new RelayCommand(() => + { + p: + string guid = Guid.NewGuid().ToString(); + if (RawMaterials.FirstOrDefault(p => p.RawMaterialId == guid) == null) + { + RawMaterials.Add(new RawMaterialModel() + { + RawMaterialId = guid + }); + } + else goto p; + }); + + RemoveCommand = new RelayCommand((obj) => + { + if (obj is string rm) + { + var res = RawMaterials.FirstOrDefault(p => p.RawMaterialId == rm); + if (res != null) RawMaterials.Remove(res); + } + }); + + SaveCommand = new RelayCommand(() => + { + for (int i = 0; i < RawMaterials.Count; i++) + { + var res = DeviceListViewModel.devices.FirstOrDefault(p => p.DeviceName == RawMaterials.ElementAt(i).RawMaterialName); + if (res != null) RawMaterials.ElementAt(i).DeviceIp = res.IpAddress;//根据设备名称和原料名称的唯一匹配关系,给原料配置IP + } + + if (RecipCode.Length <= 0)//新建配方 + { + var res = Array.FindIndex(Json.Data.Recipes.ToArray(), p => p.RecipeName == RecipeName); + + if (res >= 0 && res < Json.Data.Recipes.Count) + { + ErrorInfo = "该配方已存在,请重新输入"; + } + else + { + AddRecipes(); + } + } + else//修改配方 + { + var res = Array.FindIndex(Json.Data.Recipes.ToArray(), p => p.RecipCode == RecipCode); + if (res >= 0 && res < Json.Data.Recipes.Count) + { + Json.Data.Recipes.ElementAt(res).RecipeName = RecipeName; + Json.Data.Recipes.ElementAt(res).RawMaterials.Clear(); + foreach (var item in RawMaterials) + { + Json.Data.Recipes.ElementAt(res).RawMaterials.Add(item); + } + } + } + + ActionManage.GetInstance.Send("CloseNewRecipeView"); + }); + } + + private void AddRecipes() + { + string date = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"); + var dates = date.Split("-").ToList(); + StringBuilder sb = new StringBuilder(); + dates?.ForEach((item) => { sb.Append(item); }); + Json.Data.Recipes.Add(new RecipeModel() + { + SerialNum = Json.Data.Recipes.Count + 1, + RawMaterials = RawMaterials, + RecipCode = sb.ToString(), + RecipeName = RecipeName, + }); + } + + static NewRecipeViewModel() + { + RawMaterialNames.Clear(); + //RawMaterialNames.Add("乳化剂"); + //RawMaterialNames.Add("酶制剂"); + //RawMaterialNames.Add("增味剂"); + RawMaterialNames.Add("营养强化剂"); + //RawMaterialNames.Add("抗结剂"); + //RawMaterialNames.Add("消泡剂"); + //RawMaterialNames.Add("膨松剂"); + //RawMaterialNames.Add("防腐剂"); + //RawMaterialNames.Add("着色剂"); + RawMaterialNames.Add("甜味剂"); + //RawMaterialNames.Add("酸味剂"); + //RawMaterialNames.Add("增白剂"); + //RawMaterialNames.Add("香料"); + RawMaterialNames.Add("抗氧化剂"); + RawMaterialNames.Add("食用香料"); + //RawMaterialNames.Add("增稠剂"); + } + + private string RecipCode = string.Empty; + + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } } + private string _mRecipeName; + + public string ErrorInfo { get { return _mErrorInfo; } set { _mErrorInfo = value; OnPropertyChanged(); } } + private string _mErrorInfo; + + public RelayCommand AddCommand { get; set; } + + public RelayCommand RemoveCommand { get; set; } + + public RelayCommand SaveCommand { get; set; } + + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + + public static ObservableCollection RawMaterialNames { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeControlViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeControlViewModel.cs new file mode 100644 index 00000000..d3463288 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeControlViewModel.cs @@ -0,0 +1,92 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodSmallStation.Model; +using System.Threading; +using BPASmartClient.CustomResource.Pages.Model; +using BPASmartClient.CustomResource.UserControls.MessageShow; +using BPASmartClient.CustomResource.UserControls; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class RecipeControlViewModel : ObservableObject + { + ConcurrentQueue devices = new ConcurrentQueue(); + + public RecipeControlViewModel() + { + Recipes = Json.Data.Recipes; + StartCommand = new RelayCommand((o) => + { + if (o != null && o is string deviceName) + { + int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == deviceName); + if (index >= 0 && index < Recipes.Count) + { + Recipes.ElementAt(index).IsEnable = false; + } + MessageLog.GetInstance.ShowUserLog($"下发工单 { Recipes.ElementAt(index).RecipeName}"); + devices.Enqueue(deviceName); + } + NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方下发成功!"); + MessageLog.GetInstance.ShowUserLog($"下发工单 {Guid.NewGuid().ToString()}"); + }); + + + ThreadManage.GetInstance().StartLong(new Action(() => + { + if (devices.Count > 0) + { + int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == devices.ElementAt(0));///??????? + if (index >= 0 && index < Recipes.Count) + { + Recipes.ElementAt(index).Are.Reset(); + Recipes.ElementAt(index).IsEnable = false; + foreach (var item in Recipes.ElementAt(index).RawMaterials) + { + DeviceInquire.GetInstance.GetDevice(item.DeviceIp)?.Start(item.RawMaterialWeight);//启动并写入每个原料重量 + } + Recipes.ElementAt(index).Are.WaitOne();//阻塞,直到当前配方完成 + devices.TryDequeue(out string deviceName); + } + } + Thread.Sleep(100); + }), "启动配方下发"); + + + ThreadManage.GetInstance().StartLong(new Action(() => + { + for (int i = 0; i < Recipes.Count; i++) + { + for (int m = 0; m < Recipes.ElementAt(i).RawMaterials.Count; m++) + { + var RunStatus = DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp).deviceStatus.RunStatus; + Recipes.ElementAt(i).RawMaterials.ElementAt(m).RecipeStatus = RunStatus; + var res = Recipes.ElementAt(i).RawMaterials.Where(p => p.RecipeStatus == 3).ToList(); + if (res != null && res.Count == Recipes.ElementAt(i).RawMaterials.Count)//配方所有配料完成下料 + { + for (int r = 0; r < Recipes.ElementAt(i).RawMaterials.Count; r++) + { + DeviceInquire.GetInstance.GetDevice(Recipes.ElementAt(i).RawMaterials.ElementAt(r).DeviceIp).StatusReset();//完成配料的设备运行状态地址写0 + } + Recipes.ElementAt(i).IsEnable = true; + Recipes.ElementAt(i).Are.Set(); + } + } + } + Thread.Sleep(100); + }), "RecipeControlViewModelStatusInquire"); + } + + public RelayCommand StartCommand { get; set; } + public ObservableCollection Recipes { get; set; } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeInfosViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeInfosViewModel.cs new file mode 100644 index 00000000..eb01cd0f --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeInfosViewModel.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.ObjectModel; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.Helper; +using BPASmartClient.JXJFoodSmallStation.Model; +using BPASmartClient.CustomResource.Pages.Model; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class RecipeInfosViewModel : ObservableObject + { + public RecipeInfosViewModel() + { + ActionManage.GetInstance.Register(new Action((o) => + { + if (o != null && o is RemoteRecipeData rm) + { + RecipeName = rm.RecipeName; + RecipeCode = rm.RecipeCode; + RawMaterials = rm.RawMaterial; + } + }), "RecipeInfo"); + ReturnPage = new RelayCommand(() => + { + ActionManage.GetInstance.Send("CloseRecipeInfosView"); + }); + } + + public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } } + private string _mRecipeName; + + public long RecipeCode { get { return _mRecipeCode; } set { _mRecipeCode = value; OnPropertyChanged(); } } + private long _mRecipeCode; + + public RelayCommand ReturnPage { get; set; } + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeReceiveViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeReceiveViewModel.cs new file mode 100644 index 00000000..501f4b8c --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeReceiveViewModel.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodSmallStation.Model; +using BPASmartClient.JXJFoodSmallStation.View; +using BPASmartClient.CustomResource.UserControls; +using BPASmartClient.CustomResource.UserControls.Model; +using BPASmartClient.CustomResource.UserControls.Enum; +using System.Windows.Media; +using BPASmartClient.CustomResource.UserControls.MessageShow; +using BPASmartClient.CustomResource.Pages.Model; +using BPASmartClient.JXJFoodSmallStation.Model.Siemens; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class RecipeReceiveViewModel : ObservableObject + { + public RecipeReceiveViewModel() + { + //Json.Read(); + Recipes = Json.Data.Recipes; + DetailsCommand = new RelayCommand((o) => + { + if (o != null && o is long num) + { + ActionManage.GetInstance.CancelRegister("RecipeInfo"); + RecipeInfosView nrv = new RecipeInfosView(); + var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipeCode == num); + ActionManage.GetInstance.Send("RecipeInfo", res); + nrv.ShowDialog(); + MessageLog.GetInstance.ShowUserLog($"查看配方——{res.RecipeName}"); + } + }); + } + + public RelayCommand DetailsCommand { get; set; } + + public ObservableCollection Recipes { get; set; } + } +} diff --git a/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeSettingsViewModel.cs b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeSettingsViewModel.cs new file mode 100644 index 00000000..3bcd3667 --- /dev/null +++ b/BPASmartClient.JXJFoodSmallStation/ViewModel/RecipeSettingsViewModel.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System.Collections.Concurrent; +using System.Collections.ObjectModel; +using System.Windows; +using BPASmartClient.Helper; +using Microsoft.Toolkit.Mvvm.Input; +using BPASmartClient.JXJFoodSmallStation.Model; +using BPASmartClient.JXJFoodSmallStation.View; +using BPASmartClient.CustomResource.UserControls; +using BPASmartClient.CustomResource.UserControls.Model; +using BPASmartClient.CustomResource.UserControls.Enum; +using System.Windows.Media; +using BPASmartClient.CustomResource.UserControls.MessageShow; +using BPASmartClient.CustomResource.Pages.Model; + +namespace BPASmartClient.JXJFoodSmallStation.ViewModel +{ + public class RecipeSettingsViewModel : ObservableObject + { + public RecipeSettingsViewModel() + { + //Json.Read(); + Recipes = Json.Data.Recipes; + NewRecipe = new RelayCommand(() => + { + NewRecipeView nrv = new NewRecipeView(); + nrv.ShowDialog(); + MessageLog.GetInstance.ShowUserLog("新建配方"); + }); + SaveRecipe = new RelayCommand(() => + { + Json.Save(); + MessageLog.GetInstance.ShowUserLog("保存配方"); + NoticeDemoViewModel.OpenMsg(EnumPromptType.Success, App.MainWindow, "提示", $"配方保存成功!"); + }); + RemoveCommand = new RelayCommand((o) => + { + if (o is string str) + { + var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipCode == str); + if (res != null) Json.Data.Recipes.Remove(res); + MessageLog.GetInstance.ShowUserLog($"删除名称——{res.RecipeName}"); + } + }); + + DetailsCommand = new RelayCommand((o) => + { + if (o != null && o is string str) + { + ActionManage.GetInstance.CancelRegister("Details"); + NewRecipeView nrv = new NewRecipeView(); + var res = Json.Data.Recipes.FirstOrDefault(p => p.RecipCode == str); + ActionManage.GetInstance.Send("Details",res); + nrv.ShowDialog(); + MessageLog.GetInstance.ShowUserLog($"编辑配方名称——{res.RecipeName}"); + } + }); + } + + public RelayCommand NewRecipe { get; set; } + + public RelayCommand SaveRecipe { get; set; } + + public RelayCommand EditCommand { get; set; } + + public RelayCommand DetailsCommand { get; set; } + + public RelayCommand RemoveCommand { get; set; } + + public ObservableCollection Recipes { get; set; } + } +} diff --git a/BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj b/BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj index 8282b987..a55223f5 100644 --- a/BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj +++ b/BPASmartClient.MilkWithTea/BPASmartClient.MilkWithTea.csproj @@ -20,7 +20,6 @@ - diff --git a/BPASmartClient.Modbus/ModbusTcp.cs b/BPASmartClient.Modbus/ModbusTcp.cs index d240fb1e..eae3d234 100644 --- a/BPASmartClient.Modbus/ModbusTcp.cs +++ b/BPASmartClient.Modbus/ModbusTcp.cs @@ -26,6 +26,9 @@ namespace BPASmartClient.Modbus public string IPAdress; public int Port; + /// + /// 连接plc 原料设备成功 + /// public Action ConnectOk { get; set; } public Action ConnectFail { get; set; } diff --git a/DosingSystem/App.xaml.cs b/DosingSystem/App.xaml.cs index 80d389af..ddc0a531 100644 --- a/DosingSystem/App.xaml.cs +++ b/DosingSystem/App.xaml.cs @@ -39,7 +39,6 @@ namespace BPASmartClient.DosingSystem { MessageLog.GetInstance.ShowUserLog("用户登录"); mv.Show(); - DeviceInquire.GetInstance.Init(); } else mv.Close(); diff --git a/DosingSystem/Model/DeviceInquire.cs b/DosingSystem/Model/DeviceInquire.cs index 0b236d81..82d9f4d6 100644 --- a/DosingSystem/Model/DeviceInquire.cs +++ b/DosingSystem/Model/DeviceInquire.cs @@ -220,5 +220,4 @@ namespace BPASmartClient.DosingSystem.Model } } } - } diff --git a/DosingSystem/Model/RawMaterialModel.cs b/DosingSystem/Model/RawMaterialModel.cs index 7b5f3eb5..1e44b2b3 100644 --- a/DosingSystem/Model/RawMaterialModel.cs +++ b/DosingSystem/Model/RawMaterialModel.cs @@ -83,6 +83,5 @@ namespace BPASmartClient.DosingSystem.Model [Newtonsoft.Json.JsonIgnore] public ushort RecipeStatus { get { return _mRecipeStatus; } set { _mRecipeStatus = value; OnPropertyChanged(); } } private ushort _mRecipeStatus = 1; - } } diff --git a/DosingSystem/Model/RecipeModel.cs b/DosingSystem/Model/RecipeModel.cs index 203d4658..408f4de0 100644 --- a/DosingSystem/Model/RecipeModel.cs +++ b/DosingSystem/Model/RecipeModel.cs @@ -45,7 +45,5 @@ namespace BPASmartClient.DosingSystem.Model /// public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); - - } } diff --git a/SmartClient.sln b/SmartClient.sln index 5cd109b1..f051cc5e 100644 --- a/SmartClient.sln +++ b/SmartClient.sln @@ -120,11 +120,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MilkWithTea" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ElectricCurrentTestDemo", "..\..\TEST\ElectricCurrentTestDemo\ElectricCurrentTestDemo.csproj", "{75B55300-ABC3-4CA1-B9B6-DF954E6C7B44}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.KHKJ", "BPASmartClient.KHKJ\BPASmartClient.KHKJ.csproj", "{C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.KHKJ", "BPASmartClient.KHKJ\BPASmartClient.KHKJ.csproj", "{C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Nfc", "BPASmartClient.Nfc\BPASmartClient.Nfc.csproj", "{42D35B7C-764C-4692-AA85-9B343A0F5B7F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.Argox", "BPASmartClient.Argox\BPASmartClient.Argox.csproj", "{B8D499BA-A18A-4FD6-B036-44F02B4D164B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.Argox", "BPASmartClient.Argox\BPASmartClient.Argox.csproj", "{B8D499BA-A18A-4FD6-B036-44F02B4D164B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.JXJFoodBigStation", "BPASmartClient.JXJFoodBigStation\BPASmartClient.JXJFoodBigStation.csproj", "{FA695D7E-6F12-4483-A16D-8494609FAE68}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.JXJFoodSmallStation", "BPASmartClient.JXJFoodSmallStation\BPASmartClient.JXJFoodSmallStation.csproj", "{D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -1200,6 +1204,46 @@ Global {B8D499BA-A18A-4FD6-B036-44F02B4D164B}.Release|x64.Build.0 = Release|Any CPU {B8D499BA-A18A-4FD6-B036-44F02B4D164B}.Release|x86.ActiveCfg = Release|Any CPU {B8D499BA-A18A-4FD6-B036-44F02B4D164B}.Release|x86.Build.0 = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|ARM.ActiveCfg = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|ARM.Build.0 = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|ARM64.Build.0 = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|x64.ActiveCfg = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|x64.Build.0 = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|x86.ActiveCfg = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Debug|x86.Build.0 = Debug|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|Any CPU.Build.0 = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|ARM.ActiveCfg = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|ARM.Build.0 = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|ARM64.ActiveCfg = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|ARM64.Build.0 = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|x64.ActiveCfg = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|x64.Build.0 = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|x86.ActiveCfg = Release|Any CPU + {FA695D7E-6F12-4483-A16D-8494609FAE68}.Release|x86.Build.0 = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|ARM.ActiveCfg = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|ARM.Build.0 = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|ARM64.ActiveCfg = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|ARM64.Build.0 = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|x64.ActiveCfg = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|x64.Build.0 = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|x86.ActiveCfg = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Debug|x86.Build.0 = Debug|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|Any CPU.Build.0 = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|ARM.ActiveCfg = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|ARM.Build.0 = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|ARM64.ActiveCfg = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|ARM64.Build.0 = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|x64.ActiveCfg = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|x64.Build.0 = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|x86.ActiveCfg = Release|Any CPU + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -1258,6 +1302,8 @@ Global {C0060FB3-7AEA-4D14-ADCE-DB78D3665D5B} = {666CB1A9-562E-453A-A2C7-FD9D77CFDFDD} {42D35B7C-764C-4692-AA85-9B343A0F5B7F} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} {B8D499BA-A18A-4FD6-B036-44F02B4D164B} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625} + {FA695D7E-6F12-4483-A16D-8494609FAE68} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} + {D609C4CF-FA5C-4D39-B12F-07A60FFE5E40} = {8712125E-14CD-4E1B-A1CE-4BDE03805942} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}