diff --git a/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj b/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj index fb8cb381..c514ab2e 100644 --- a/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj +++ b/BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj @@ -93,6 +93,8 @@ + + @@ -173,6 +175,7 @@ + @@ -203,6 +206,8 @@ + + PreserveNewest @@ -221,6 +226,7 @@ + diff --git a/BPASmartClient.CustomResource/Converters/StatusConverter.cs b/BPASmartClient.CustomResource/Converters/StatusConverter.cs new file mode 100644 index 00000000..cf9a2c9d --- /dev/null +++ b/BPASmartClient.CustomResource/Converters/StatusConverter.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using System.Windows.Media; + +namespace BPASmartClient.CustomResource.Converters +{ + public class StatusConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + SolidColorBrush returnValue = new SolidColorBrush(Color.FromArgb(255, 0, 204, 255)); + if (value != null && value is ushort statusValue) + { + switch (statusValue) + { + case 0: + returnValue = new SolidColorBrush(Color.FromArgb(255, 0, 204, 255)); + break; + case 1: + returnValue = new SolidColorBrush(Color.FromArgb(255, 0, 255, 127)); + break; + case 2: + returnValue = new SolidColorBrush(Color.FromArgb(255, 255, 215, 00)); + break; + case 3: + returnValue = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)); + break; + default: + break; + } + } + return returnValue; + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/BPASmartClient.CustomResource/Image/工艺流程.jpg b/BPASmartClient.CustomResource/Image/工艺流程.jpg new file mode 100644 index 00000000..7863056e Binary files /dev/null and b/BPASmartClient.CustomResource/Image/工艺流程.jpg differ diff --git a/BPASmartClient.CustomResource/Image/工艺流程.png b/BPASmartClient.CustomResource/Image/工艺流程.png new file mode 100644 index 00000000..8a0e23ec Binary files /dev/null and b/BPASmartClient.CustomResource/Image/工艺流程.png differ diff --git a/BPASmartClient.CustomResource/Image/顶部切图/自动化产线上位机控制系统.png b/BPASmartClient.CustomResource/Image/顶部切图/自动化产线上位机控制系统.png new file mode 100644 index 00000000..245dd258 Binary files /dev/null and b/BPASmartClient.CustomResource/Image/顶部切图/自动化产线上位机控制系统.png differ diff --git a/BPASmartClient.CustomResource/Themes/MyStyle.xaml b/BPASmartClient.CustomResource/Themes/MyStyle.xaml index 98e7661c..2e7fbbb1 100644 --- a/BPASmartClient.CustomResource/Themes/MyStyle.xaml +++ b/BPASmartClient.CustomResource/Themes/MyStyle.xaml @@ -181,6 +181,14 @@ + + diff --git a/BPASmartClient.Modbus/ModbusTcp.cs b/BPASmartClient.Modbus/ModbusTcp.cs index a437ead2..c97dc4a8 100644 --- a/BPASmartClient.Modbus/ModbusTcp.cs +++ b/BPASmartClient.Modbus/ModbusTcp.cs @@ -49,11 +49,11 @@ namespace BPASmartClient.Modbus Port = port; modbusFactory = new ModbusFactory(); Connect(); - master.Transport.ReadTimeout = 2000;//读取超时时间 - master.Transport.WriteTimeout = 2000;//写入超时时间 - master.Transport.Retries = 10;//重试次数 if (Connected) { + master.Transport.ReadTimeout = 2000;//读取超时时间 + master.Transport.WriteTimeout = 2000;//写入超时时间 + master.Transport.Retries = 10;//重试次数 ConnectOk?.Invoke(); MessageLog.GetInstance.Show($"设备【{ip}:{port}】连接成功"); } diff --git a/BPASmartClient/Control/GYLCControl.xaml b/BPASmartClient/Control/GYLCControl.xaml new file mode 100644 index 00000000..0e415989 --- /dev/null +++ b/BPASmartClient/Control/GYLCControl.xaml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/BPASmartClient/Control/GYLCControl.xaml.cs b/BPASmartClient/Control/GYLCControl.xaml.cs new file mode 100644 index 00000000..cbe4884a --- /dev/null +++ b/BPASmartClient/Control/GYLCControl.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.Control +{ + /// + /// GYLCControl.xaml 的交互逻辑 + /// + public partial class GYLCControl : UserControl + { + public GYLCControl() + { + InitializeComponent(); + } + } +} diff --git a/BPASmartClient/MainWindow.xaml b/BPASmartClient/MainWindow.xaml index 68bf83b2..5a7f237d 100644 --- a/BPASmartClient/MainWindow.xaml +++ b/BPASmartClient/MainWindow.xaml @@ -152,6 +152,12 @@ Header="IOT监视" Tag="IOTView" /> + + + diff --git a/DosingSystem/Model/DeviceInquire.cs b/DosingSystem/Model/DeviceInquire.cs index f1c0671d..1a9cdaae 100644 --- a/DosingSystem/Model/DeviceInquire.cs +++ b/DosingSystem/Model/DeviceInquire.cs @@ -14,16 +14,15 @@ namespace DosingSystem.Model { public class DeviceInquire { - private volatile static DeviceInquire _Instance; public static DeviceInquire GetInstance => _Instance ?? (_Instance = new DeviceInquire()); private DeviceInquire() { } string IPSegment = "192.168.1."; - string NameAddress = "VW5000"; + string NameAddress = "VW0"; int count = 0; private static readonly object _lock = new object(); - ConcurrentDictionary modbusTcps = new ConcurrentDictionary(); + ConcurrentDictionary DeviceLists = new ConcurrentDictionary(); List InvalidIP = new List(); public void Init() @@ -36,10 +35,14 @@ namespace DosingSystem.Model }), "配料机设备上线监听", true); } - public ModbusTcp GetModbusTcp(string ip) + public DeviceStatus GetDevice(string deviceName) { - if (modbusTcps.ContainsKey(ip)) return modbusTcps[ip]; - else return default; + if (deviceName != null) + { + var res = DeviceLists.Values.FirstOrDefault(p => p.DeviceName == deviceName); + if (res != null) return res; + } + return default; } private void IpAddressLines() @@ -48,8 +51,7 @@ namespace DosingSystem.Model { if (!InvalidIP.Contains($"{IPSegment}{i}")) { - Ping myPing; - myPing = new Ping(); + Ping myPing = new Ping(); myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted); string pingIP = $"{IPSegment}{i}"; myPing.SendAsync(pingIP, 1000, null); @@ -69,17 +71,23 @@ namespace DosingSystem.Model if (e.Reply.Status == IPStatus.Success) { string ip = e.Reply.Address.ToString(); - if (!modbusTcps.ContainsKey(ip)) + if (!DeviceLists.ContainsKey(ip)) { - modbusTcps.TryAdd(ip, new ModbusTcp()); - modbusTcps[ip].IsReconnect = false; - Task.Run(new Action(() => { modbusTcps[ip].ModbusTcpConnect(ip); })); - - modbusTcps[ip].ConnectOk = new Action(() => + DeviceStatus DS = new DeviceStatus(); + //DeviceLists.TryAdd(ip, new DeviceStatus()); + //DeviceLists[ip].modbusTcp.IsReconnect = false; + //Task.Run(new Action(() => { DeviceLists[ip].modbusTcp.ModbusTcpConnect(ip, 508); })); + DS.modbusTcp.IsReconnect = false; + Task.Run(new Action(() => { DS.modbusTcp.ModbusTcpConnect(ip, 508); })); + DS.modbusTcp.ConnectOk = new Action(() => { - string DeviceName = modbusTcps[ip].GetString(NameAddress, 10); + //string DeviceName = DeviceLists[ip].modbusTcp.GetString(NameAddress, 20); + string DeviceName = DS.modbusTcp.GetString(NameAddress, 20); if (DeviceName.Length > 0) { + DeviceLists.TryAdd(ip, DS); + DeviceLists[ip].Init(DeviceName); + DeviceLists[ip].modbusTcp.IsReconnect = true; App.Current.Dispatcher.Invoke(new Action(() => { DeviceListViewModel.devices.Add(new Devices() @@ -87,6 +95,9 @@ namespace DosingSystem.Model DeviceName = DeviceName, IpAddress = ip }); + if (!NewRecipeViewModel.RawMaterialNames.Contains(DeviceName)) + NewRecipeViewModel.RawMaterialNames.Add(DeviceName); + })); } else @@ -95,23 +106,71 @@ namespace DosingSystem.Model } }); - modbusTcps[ip].ConnectFail = new Action(() => + DS.modbusTcp.ConnectFail = new Action(() => { if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip); }); - modbusTcps[ip].Disconnect = new Action(() => + 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); })); + App.Current.Dispatcher.Invoke(new Action(() => + { + DeviceListViewModel.devices.Remove(res); + if (!NewRecipeViewModel.RawMaterialNames.Contains(res.DeviceName)) + NewRecipeViewModel.RawMaterialNames.Remove(res.DeviceName); + })); + //DeviceLists[ip].Dispose(); + DS.Dispose(); }); } } CompleteCount(); } + } + public class DeviceStatus + { + public string DeviceName = String.Empty; + public ModbusTcp modbusTcp = new ModbusTcp(); + public void Init(string DeviceName) + { + this.DeviceName = DeviceName; + if (modbusTcp.Connected) + { + ThreadManage.GetInstance().StartLong(new Action(() => + { + var res = this.modbusTcp.Read("VW100"); + if (res is ushort ushortValue) + { + RunStatus = ushortValue; + } + Thread.Sleep(100); + }), $"{DeviceName} 开始监听", true); + } + } + + public void Dispose() + { + ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听"); + } + public bool IsConnected => modbusTcp.Connected; + + /// + /// 配料系统运行状态 + /// + public ushort RunStatus { get; private set; } + public void Start(float Value) + { + if (modbusTcp.Connected) + { + modbusTcp.SetReal("VW40", Value);//写入配方量 + modbusTcp.Write("M0.0", true);//设备启动写入 + } + } } + } diff --git a/DosingSystem/Model/LocaPar.cs b/DosingSystem/Model/LocaPar.cs index 3addd1f2..ab3a8c56 100644 --- a/DosingSystem/Model/LocaPar.cs +++ b/DosingSystem/Model/LocaPar.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections.ObjectModel; +using DosingSystem.ViewModel; namespace DosingSystem.Model { diff --git a/DosingSystem/Model/RawMaterialModel.cs b/DosingSystem/Model/RawMaterialModel.cs new file mode 100644 index 00000000..1378de4d --- /dev/null +++ b/DosingSystem/Model/RawMaterialModel.cs @@ -0,0 +1,48 @@ +using Microsoft.Toolkit.Mvvm.ComponentModel; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DosingSystem.Model +{ + /// + /// 原料模块 + /// + public class RawMaterialModel : ObservableObject + { + /// + /// 原料名称 + /// + public string RawMaterialName { get { return _mRawMaterialName; } set { _mRawMaterialName = value; OnPropertyChanged(); } } + private string _mRawMaterialName; + + /// + /// 原料设备IP + /// + public string DeviceIp { get; set; } + + /// + /// 原料重量 + /// + public float RawMaterialWeight { get { return _mRawMaterialWeight; } set { _mRawMaterialWeight = value; OnPropertyChanged(); } } + private float _mRawMaterialWeight; + + /// + /// 原料ID + /// + public string RawMaterialId { get { return _mRawMaterialId; } set { _mRawMaterialId = value; OnPropertyChanged(); } } + private string _mRawMaterialId; + + /// + /// 原料设备执行状态 + /// 1:等待下料 + /// 2:下料中 + /// 3:下料完成 + /// + public int RecipeStatus { get { return _mRecipeStatus; } set { _mRecipeStatus = value; OnPropertyChanged(); } } + private int _mRecipeStatus; + + } +} diff --git a/DosingSystem/Model/RecipeModel.cs b/DosingSystem/Model/RecipeModel.cs index 8fdeedba..de2d214e 100644 --- a/DosingSystem/Model/RecipeModel.cs +++ b/DosingSystem/Model/RecipeModel.cs @@ -9,8 +9,13 @@ using Microsoft.Toolkit.Mvvm.ComponentModel; namespace DosingSystem.Model { + /// + /// 配方模块 + /// public class RecipeModel : ObservableObject { + public bool IsEnable { get { return _mIsEnable; } set { _mIsEnable = value; OnPropertyChanged(); } } + private bool _mIsEnable = true; /// /// 序号 @@ -30,7 +35,11 @@ namespace DosingSystem.Model public string RecipCode { get { return _mRecipCode; } set { _mRecipCode = value; OnPropertyChanged(); } } private string _mRecipCode; - public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + /// + /// 原料集合 + /// + public ObservableCollection RawMaterials { get; set; } = new ObservableCollection(); + } diff --git a/DosingSystem/View/NewRecipeView.xaml b/DosingSystem/View/NewRecipeView.xaml index 2525f588..2673328f 100644 --- a/DosingSystem/View/NewRecipeView.xaml +++ b/DosingSystem/View/NewRecipeView.xaml @@ -139,7 +139,7 @@ - + Text="{Binding RawMaterialName}" />--> + - + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + +