pengliangyang 2 yıl önce
ebeveyn
işleme
22c013c6a1
65 değiştirilmiş dosya ile 2445 ekleme ve 420 silme
  1. +60
    -0
      BPASmartClient.AGV/AGVHelper.cs
  2. +19
    -0
      BPASmartClient.AGV/AGVLoadInteracteModel.cs
  3. +49
    -0
      BPASmartClient.AGV/AGVModel.cs
  4. +42
    -0
      BPASmartClient.AGV/AGVRequestUrl.cs
  5. +19
    -0
      BPASmartClient.AGV/AGVTaskCancelModel.cs
  6. +21
    -0
      BPASmartClient.AGV/AGVTaskCompleteNotifyModel.cs
  7. +27
    -0
      BPASmartClient.AGV/AGV_PointRollerJobData.cs
  8. +26
    -0
      BPASmartClient.AGV/AGV_SlotRollerJobData.cs
  9. +13
    -0
      BPASmartClient.AGV/BPASmartClient.AGV.csproj
  10. +17
    -0
      BPASmartClient.AGV/HttpRequestHeaderModel.cs
  11. +15
    -0
      BPASmartClient.AGV/HttpResponseData.cs
  12. +16
    -0
      BPASmartClient.AGV/HttpResponseModel.cs
  13. +13
    -0
      BPASmartClient.AGV/JobData.cs
  14. +1
    -1
      BPASmartClient.Business/BPASmartClient.Business.csproj
  15. +10
    -0
      BPASmartClient.Business/Plugin/DeviceMgr.cs
  16. +15
    -0
      BPASmartClient.Business/Plugin/OrderProxy.cs
  17. +7
    -1
      BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj
  18. +48
    -0
      BPASmartClient.CustomResource/Converters/StatusConverter.cs
  19. BIN
     
  20. BIN
     
  21. BIN
     
  22. +7
    -4
      BPASmartClient.CustomResource/Themes/Generic.xaml
  23. +9
    -1
      BPASmartClient.CustomResource/Themes/MyStyle.xaml
  24. +48
    -1
      BPASmartClient.CustomResource/UserControls/IcoButton.cs
  25. +1
    -1
      BPASmartClient.Device/BPASmartClient.Device.csproj
  26. +6
    -6
      BPASmartClient.Modbus/ModbusTcp.cs
  27. +1
    -1
      BPASmartClient.Model/BPASmartClient.Model.csproj
  28. +18
    -0
      BPASmartClient.Model/小炒机/StirFryGoodsEvent.cs
  29. +0
    -4
      BPASmartClient.MorkF/BPASmartClient.MorkF.csproj
  30. +228
    -107
      BPASmartClient.MorkF/Control_MorkF.cs
  31. +1
    -0
      BPASmartClient.MorkF/GVL_MorkF.cs
  32. +13
    -0
      BPASmartClient.MorkF/Model/General_Config.cs
  33. +1
    -1
      BPASmartClient.MorkF/OrderLocInfo.cs
  34. +1
    -0
      BPASmartClient.MorkF/View/DebugView.xaml
  35. +1
    -0
      BPASmartClient.MorkF/View/DebugView.xaml.cs
  36. +4
    -1
      BPASmartClient.MorkF/ViewModel/DebugViewModel.cs
  37. +3
    -1
      BPASmartClient.MorkM/Control_MORKM.cs
  38. +5
    -1
      BPASmartClient.MorkS/Control_Morks.cs
  39. +1
    -0
      BPASmartClient.MorkS/ViewModel/DebugViewModel.cs
  40. +4
    -4
      BPASmartClient/App.config
  41. +23
    -0
      BPASmartClient/Control/GYLCControl.xaml
  42. +28
    -0
      BPASmartClient/Control/GYLCControl.xaml.cs
  43. +7
    -1
      BPASmartClient/MainWindow.xaml
  44. +1
    -0
      DosingSystem/App.xaml
  45. +1
    -1
      DosingSystem/DosingSystem.csproj
  46. +133
    -32
      DosingSystem/Model/DeviceInquire.cs
  47. +15
    -0
      DosingSystem/Model/LocaPar.cs
  48. +45
    -0
      DosingSystem/Model/RawMaterialDeviceStatus.cs
  49. +89
    -0
      DosingSystem/Model/RawMaterialModel.cs
  50. +50
    -0
      DosingSystem/Model/RecipeModel.cs
  51. +122
    -0
      DosingSystem/View/ChangeDeviceNameView.xaml
  52. +31
    -0
      DosingSystem/View/ChangeDeviceNameView.xaml.cs
  53. +117
    -47
      DosingSystem/View/DeviceListView.xaml
  54. +1
    -183
      DosingSystem/View/MainWindow.xaml
  55. +222
    -0
      DosingSystem/View/NewRecipeView.xaml
  56. +32
    -0
      DosingSystem/View/NewRecipeView.xaml.cs
  57. +171
    -10
      DosingSystem/View/RecipeControlView.xaml
  58. +225
    -6
      DosingSystem/View/RecipeSettingsView.xaml
  59. +71
    -0
      DosingSystem/ViewModel/ChangeDeviceNameViewModel.cs
  60. +11
    -3
      DosingSystem/ViewModel/DeviceListViewModel.cs
  61. +3
    -1
      DosingSystem/ViewModel/MainViewModel.cs
  62. +131
    -0
      DosingSystem/ViewModel/NewRecipeViewModel.cs
  63. +76
    -0
      DosingSystem/ViewModel/RecipeControlViewModel.cs
  64. +46
    -0
      DosingSystem/ViewModel/RecipeSettingsViewModel.cs
  65. +24
    -1
      SmartClient.sln

+ 60
- 0
BPASmartClient.AGV/AGVHelper.cs Dosyayı Görüntüle

@@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Web;
using Newtonsoft.Json;
using System.Net.Http;


namespace BPASmartClient.AGV
{
public class AGVHelper
{
public static AGVHelper _Instance { get; set; }
public static AGVHelper GetInstance => _Instance ?? (_Instance = new AGVHelper());
public AGVHelper()
{
}

public string HttpRequest(string url, string head, string body)
{
return PostData(url, head, body);
}
public string PostData(string url, string head, string body)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "POST";
request.Headers["header"] = head;
//request.Proxy = new WebProxy("192.168.1.12",80);
byte[] bytes = Encoding.UTF8.GetBytes(body);
request.ContentType = "application/json; charset=UTF-8"; ;//窗体数据被编码为名称/值对形式
//request.ContentType = "application/json";
request.ContentLength = bytes.Length;
Stream myResponseStream = request.GetRequestStream();
myResponseStream.Write(bytes, 0, bytes.Length);
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader myStreamReader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
string retString = myStreamReader.ReadToEnd();
myStreamReader.Close();
myResponseStream.Close();

if (response != null)
{
response.Close();
}
if (request != null)
{
request.Abort();
}
return retString;//返回响应报文


}
}
}

+ 19
- 0
BPASmartClient.AGV/AGVLoadInteracteModel.cs Dosyayı Görüntüle

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// AGV上下料交互反馈接口(上游系统->快仓系统)
/// </summary>
internal class AGVLoadInteracteModel
{
public string agvCode { get; set;}
public string jobId { get; set; }
public string msgId { get; set; }
public bool? complete { get; set; }
}
}

+ 49
- 0
BPASmartClient.AGV/AGVModel.cs Dosyayı Görüntüle

@@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// AGV任务下发
/// </summary>
internal class AGVModel
{
/// <summary>
/// 必填项
/// </summary>
public string robotJobId { get; set; }
/// <summary>
/// 必填项
/// </summary>
public long warehouseId { get; set; }
public string? robotJobGroupId { get; set; }
public int? sequence { get; set; }
/// <summary>
/// 必填项
/// </summary>
public int jobPriority { get; set; }
/// <summary>
/// 必填项
/// </summary>
public int jobPriorityType { get; set; }
public string? deadline { get; set; }
public string? agvType { get; set; }
public string? agvEndPoint { get; set; }
public bool? needOperation { get; set; }
public string? agvCode { get; set; }
public int? taskCountDown { get; set; }
public string? businessType { get; set; }
/// <summary>
/// 必填项
/// </summary>
public string jobType { get; set; }
/// <summary>
/// 必填项
/// </summary>
public IJobData jobData { get; set; }
}
}

+ 42
- 0
BPASmartClient.AGV/AGVRequestUrl.cs Dosyayı Görüntüle

@@ -0,0 +1,42 @@
namespace BPASmartClient.AGV
{
public class AGVRequestUrl
{
//public string HttpHeader { get; set; }
//public string TaskSendBody { get; set; }
public AGVRequestUrl(string IpAddress)
{
TaskSendUrl= $"http://{IpAddress}/api/quicktron/wcs/standardized.robot.job.submit";
TaskCancelUrl= $"http://{IpAddress}/api/quicktron/wcs/standardized.robot.job.cancel";
TaskCompleteUrl= $"http://{IpAddress}/api/quicktron/wcs/standardized.operation.notice";
AGVInteracteUrl= $"http://{IpAddress}/api/quicktron/wcs/standardized.roller.job.upstream.response";
}


#region Url汇总
//各种AGV的移动及搬运任务。
// 本接口请求参数包含公共字段及具体任务字段两部分组成。
//支持批量任务下发。
public string TaskSendUrl { get; set; }

//货架搬运任务指令下发后,允许上游系统调用该接口取消移位任务,支持取消策略。不同车型允许取消的任务节点不同,具体信息见API文档
public string TaskCancelUrl { get; set; }

//工作站任务实操完成后调用该接口。如果bucket有其他任务去执行其他任务。在线工作站货架直接回库,离线工作站分配AGV回库。
public string TaskCompleteUrl { get; set; }

//1.辊筒AGV在手动上下料时请求上游交互后,上游下发的反馈接口
//2.料箱AGV在任务下发需要和上游进行交互时调用此接口
//3.翻板车AGV在投递点前确认时上游反馈接口
public string AGVInteracteUrl { get; set; }
#endregion
}
}









+ 19
- 0
BPASmartClient.AGV/AGVTaskCancelModel.cs Dosyayı Görüntüle

@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// AGV任务取消
/// </summary>
internal class AGVTaskCancelModel
{
public string robotJobId { get; set; }
public long warehouseId { get; set; }
public string? executeMode { get; set; }
public string? reason { get; set; }
}
}

+ 21
- 0
BPASmartClient.AGV/AGVTaskCompleteNotifyModel.cs Dosyayı Görüntüle

@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// AGV任务完成通知
/// </summary>
internal class AGVTaskCompleteNotifyModel
{
public string? robotJobId { get; set; }
public string? bucketCode { get; set; }
public string? bucketslotCode { get; set; }
public long warehouseId { get; set; }
public bool? nullFlag { get; set; }
public string? jobId { get; set; }
}
}

+ 27
- 0
BPASmartClient.AGV/AGV_PointRollerJobData.cs Dosyayı Görüntüle

@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// 辊筒点到点搬运
/// </summary>
internal class AGV_PointRollerJobData:IJobData
{
public string? containerCode { get; set; }
public string startPoint { get; set; }
public string endPoint { get; set; }
public bool autoLoad { get; set; }
public bool enableIOLoad { get; set; }
public bool autoUnload { get; set; }
public bool enableIOUnload { get; set; }
public long? loadEquipmentId { get; set; } = null;
public long? unloadEquipmentId { get; set; } = null;
public bool? loadInteractive { get; set; }
public int? loadHeight { get; set; }
public int? unloadHeight { get; set; }
}
}

+ 26
- 0
BPASmartClient.AGV/AGV_SlotRollerJobData.cs Dosyayı Görüntüle

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
/// <summary>
/// 辊筒货位到货位搬运
/// </summary>
internal class AGV_SlotRollerJobData:IJobData
{
public string? containerCode { get; set; }
public string startIotCode { get; set; }
public string endSlotCode { get; set; }
public bool autoLoad { get; set; }
public bool enableIOLoad { get; set; }
public bool autoUnload { get; set; }
public bool enableIOUnload { get; set; }
public long? loadEquipmentId { get; set; } = null;
public long? unLoadEquipmentId { get; set; } = null;

public bool? loadInteractive { get; set; }
}
}

+ 13
- 0
BPASmartClient.AGV/BPASmartClient.AGV.csproj Dosyayı Görüntüle

@@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>

</Project>

+ 17
- 0
BPASmartClient.AGV/HttpRequestHeaderModel.cs Dosyayı Görüntüle

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
internal class HttpRequestHeaderModel
{
public string appKey { get; set; }
public string appSecret { get; set; }
public string requestId { get; set; }
public string timestamp { get; set; }
public string version { get; set; }
}
}

+ 15
- 0
BPASmartClient.AGV/HttpResponseData.cs Dosyayı Görüntüle

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
internal class HttpResponseData
{
public string code { get; set; }
public bool message { get; set; }
public string robotJobId { get; set; }
}
}

+ 16
- 0
BPASmartClient.AGV/HttpResponseModel.cs Dosyayı Görüntüle

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
internal class HttpResponseModel
{
public string code { get; set; }
public string message { get; set; }
public bool success { get; set; }
public HttpResponseData data { get; set; }
}
}

+ 13
- 0
BPASmartClient.AGV/JobData.cs Dosyayı Görüntüle

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.AGV
{
public interface IJobData
{

}
}

+ 1
- 1
BPASmartClient.Business/BPASmartClient.Business.csproj Dosyayı Görüntüle

@@ -8,7 +8,7 @@

<ItemGroup>
<PackageReference Include="BPA.ApolloClient" Version="1.0.12" />
<PackageReference Include="BPA.Message" Version="1.0.41" />
<PackageReference Include="BPA.Message" Version="1.0.45" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="6.0.1" />
<PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="6.0.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />


+ 10
- 0
BPASmartClient.Business/Plugin/DeviceMgr.cs Dosyayı Görüntüle

@@ -5,6 +5,7 @@ using BPASmartClient.Helper;
using BPASmartClient.Http;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.Model.小炒机;
using BPASmartClient.Peripheral;
using Newtonsoft.Json;
using System;
@@ -128,6 +129,15 @@ namespace BPASmartClient.Business
MessageLog.GetInstance.Show($"物料ID:=[{x.BatchingId}],{x.BatchingLoc}号位置:{x.BatchingCount}");
});
}
else if (PushType == 2)//小炒API流程获取,待定
{
new StirFryGoodsEvent()
{
DeviceId = device.DeviceId,
stirFrymessage = JsonConvert.DeserializeObject<StirFryPushMessage>(result)
}.Publish();
MessageLog.GetInstance.Show("接收到【 API 】获取的小炒流程信息");
}
}
catch (Exception ex)
{


+ 15
- 0
BPASmartClient.Business/Plugin/OrderProxy.cs Dosyayı Görüntüle

@@ -1,11 +1,14 @@
//#define test
using BPA.Message;
using BPA.Message.Enum;
using BPA.Models;
using BPASmartClient.Device;
using BPASmartClient.EventBus;
using BPASmartClient.Helper;
using BPASmartClient.Http;
using BPASmartClient.Message;
using BPASmartClient.Model;
using BPASmartClient.Model.小炒机;
using Newtonsoft.Json;
using System;
using System.Collections.Concurrent;
@@ -99,6 +102,18 @@ namespace BPASmartClient.Business
MessageLog.GetInstance.Show($"物料ID:=[{x.BatchingId}],{x.BatchingLoc}号位置:{x.BatchingCount}");
});
}
//小炒流程信息
else if (message is StirFryPushMessage frybom)
{
IDevice device = deviceMgr.GetDevices().FirstOrDefault(x => x.DeviceId == 28);
new StirFryGoodsEvent() {
DeviceId = device.DeviceId,
stirFrymessage =frybom
}.Publish();
MessageLog.GetInstance.Show("接受到【MQTT】的小炒流程信息");
}
});

EventBus.EventBus.GetInstance().Subscribe<OrderStatusChangedEvent>(0, OrderStatusChangedHandle);


+ 7
- 1
BPASmartClient.CustomResource/BPASmartClient.CustomResource.csproj Dosyayı Görüntüle

@@ -93,6 +93,8 @@
<None Remove="Image\圆角矩形 30 拷贝.png" />
<None Remove="Image\圆角矩形 4.png" />
<None Remove="Image\圆角矩形.png" />
<None Remove="Image\工艺流程.jpg" />
<None Remove="Image\工艺流程.png" />
<None Remove="Image\底部背景.png" />
<None Remove="Image\搜索按钮.png" />
<None Remove="Image\搜索框.png" />
@@ -173,6 +175,7 @@
<None Remove="Image\顶部切图\Top_L.png" />
<None Remove="Image\顶部切图\窗体背景.png" />
<None Remove="Image\顶部切图\窗体背景2.png" />
<None Remove="Image\顶部切图\自动化产线上位机控制系统.png" />
<None Remove="Image\顶部切图\返回按钮1.png" />
<None Remove="Image\顶部切图\返回按钮2.png" />
<None Remove="Image\顶部切图\返回按钮图标.png" />
@@ -203,6 +206,8 @@
<Resource Include="Image\告警\无告警.png" />
<Resource Include="Image\告警\无告警1.png" />
<Resource Include="Image\告警\轻微告警.png" />
<Resource Include="Image\工艺流程.jpg" />
<Resource Include="Image\工艺流程.png" />
<Resource Include="Image\界面2.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Resource>
@@ -221,6 +226,7 @@
<Resource Include="Image\顶部切图\Top_L.png" />
<Resource Include="Image\顶部切图\窗体背景.png" />
<Resource Include="Image\顶部切图\窗体背景2.png" />
<Resource Include="Image\顶部切图\自动化产线上位机控制系统.png" />
<Resource Include="Image\顶部切图\返回按钮1.png" />
<Resource Include="Image\顶部切图\返回按钮2.png" />
<Resource Include="Image\顶部切图\返回按钮图标.png" />
@@ -229,7 +235,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.41" />
<PackageReference Include="BPA.Message" Version="1.0.45" />
</ItemGroup>

<ItemGroup>


+ 48
- 0
BPASmartClient.CustomResource/Converters/StatusConverter.cs Dosyayı Görüntüle

@@ -0,0 +1,48 @@
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 = Brushes.SandyBrown;
if (value != null && value is ushort statusValue)
{
switch (statusValue)
{
case 0:
returnValue = Brushes.SandyBrown;
break;
case 1:
returnValue = Brushes.Green;
break;
case 2:
returnValue = Brushes.Yellow;
break;
case 3:
returnValue = Brushes.Aqua;
break;
case 4:
returnValue = Brushes.Red;
break;
default:
break;
}
}
return returnValue;
}

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}




+ 7
- 4
BPASmartClient.CustomResource/Themes/Generic.xaml Dosyayı Görüntüle

@@ -15,10 +15,6 @@
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<StackPanel HorizontalAlignment="Center" Orientation="Horizontal">
<!--<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>-->
<TextBlock
Name="PART_icoText"
Margin="0,0,10,0"
@@ -37,6 +33,13 @@
Foreground="{TemplateBinding Foreground}" />
</StackPanel>
</Grid>
<!--<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_br" Property="BorderBrush" Value="{TemplateBinding EnableColor}" />
<Setter TargetName="PART_icoText" Property="Foreground" Value="red" />
<Setter TargetName="PART_content" Property="Foreground" Value="red" />
</Trigger>
</ControlTemplate.Triggers>-->
</ControlTemplate>
</Setter.Value>
</Setter>


+ 9
- 1
BPASmartClient.CustomResource/Themes/MyStyle.xaml Dosyayı Görüntüle

@@ -181,6 +181,14 @@
</Style.Setters>
</Style>

<Style x:Key="imagetop_工艺流程" TargetType="Image">
<Style.Setters>
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/工艺流程.png" />
</Style.Setters>
</Style>

<Style x:Key="imagetop_维护" TargetType="Image">
<Style.Setters>
<Setter Property="Width" Value="20" />
@@ -225,7 +233,7 @@
<Setter Property="Width" Value="250" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部切图/黑菠萝智慧餐饮管理系统.png" />
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部切图/自动化产线上位机控制系统.png" />
</Style.Setters>
</Style>



+ 48
- 1
BPASmartClient.CustomResource/UserControls/IcoButton.cs Dosyayı Görüntüle

@@ -72,6 +72,28 @@ namespace BPASmartClient.CustomResource.UserControls
DependencyProperty.Register("Command", typeof(Action), typeof(IcoButton),
new PropertyMetadata(default, new PropertyChangedCallback(OnPropertyChanged)));


public Action<object> CommandObj
{
get { return (Action<object>)GetValue(CommandObjProperty); }
set { SetValue(CommandObjProperty, value); }
}
public static readonly DependencyProperty CommandObjProperty =
DependencyProperty.Register("CommandObj", typeof(Action<object>), typeof(IcoButton),
new PropertyMetadata(default, new PropertyChangedCallback(OnPropertyChanged)));


//public object CommandPar
//{
// get { return (object)GetValue(CommandParProperty); }
// set { SetValue(CommandParProperty, value); }
//}
//public static readonly DependencyProperty CommandParProperty =
// DependencyProperty.Register("CommandPar", typeof(object), typeof(IcoButton),
// new PropertyMetadata(default, new PropertyChangedCallback(OnPropertyChanged)));



public string Content
{
get { return (string)GetValue(ContentProperty); }
@@ -110,13 +132,29 @@ namespace BPASmartClient.CustomResource.UserControls
new PropertyMetadata(Brushes.Gray, new PropertyChangedCallback(OnPropertyChanged)));


public Brush EnableColor
{
get { return (Brush)GetValue(EnableColorProperty); }
set { SetValue(EnableColorProperty, value); }
}
public static readonly DependencyProperty EnableColorProperty =
DependencyProperty.Register("EnableColor", typeof(Brush), typeof(IcoButton),
new PropertyMetadata(Brushes.Gray, new PropertyChangedCallback(OnPropertyChanged)));



public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var icon = base.GetTemplateChild("PART_icoText") as TextBlock;
var content = base.GetTemplateChild("PART_content") as TextBlock;
var gr = base.GetTemplateChild("PART_gr") as Grid;

//if (!this.IsEnabled)
//{
// this.Foreground = EnableColor;
// this.BorderBrush = EnableColor;
//}
//this.IsEnabledChanged += IcoButton_IsEnabledChanged;
if (icon != null)
{
Binding binding = new Binding("IcoText");
@@ -141,6 +179,15 @@ namespace BPASmartClient.CustomResource.UserControls
}
}

private void IcoButton_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
//if (!this.IsEnabled)
//{
// this.Foreground = EnableColor;
// this.BorderBrush = EnableColor;
//}
}

/// <summary>
/// 鼠标离开颜色
/// </summary>


+ 1
- 1
BPASmartClient.Device/BPASmartClient.Device.csproj Dosyayı Görüntüle

@@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.41" />
<PackageReference Include="BPA.Message" Version="1.0.45" />
</ItemGroup>

<ItemGroup>


+ 6
- 6
BPASmartClient.Modbus/ModbusTcp.cs Dosyayı Görüntüle

@@ -21,8 +21,8 @@ namespace BPASmartClient.Modbus
private ModbusFactory modbusFactory;
private IModbusMaster master;
private TcpClient tcpClient;
private string IPAdress;
private int Port;
public string IPAdress;
public int Port;

public Action ConnectOk { get; set; }

@@ -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}】连接成功");
}
@@ -92,7 +92,7 @@ namespace BPASmartClient.Modbus
Thread.Sleep(3000);
}
}
if (ErrorFlag) MessageLog.GetInstance.Show("ModbusTcp 重连成功!");
if (ErrorFlag && IsReconnect) MessageLog.GetInstance.Show("ModbusTcp 重连成功!");
}

/// <summary>


+ 1
- 1
BPASmartClient.Model/BPASmartClient.Model.csproj Dosyayı Görüntüle

@@ -17,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.41" />
<PackageReference Include="BPA.Message" Version="1.0.45" />
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" />
</ItemGroup>



+ 18
- 0
BPASmartClient.Model/小炒机/StirFryGoodsEvent.cs Dosyayı Görüntüle

@@ -0,0 +1,18 @@
using BPA.Message;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.Model.小炒机
{
public class StirFryGoodsEvent : BaseEvent
{

/// <summary>
/// 小炒信息
/// </summary>
public StirFryPushMessage stirFrymessage { get; set; } = new StirFryPushMessage();
}
}

+ 0
- 4
BPASmartClient.MorkF/BPASmartClient.MorkF.csproj Dosyayı Görüntüle

@@ -18,8 +18,4 @@
<ProjectReference Include="..\BPASmartClient.Model\BPASmartClient.Model.csproj" />
</ItemGroup>

<ItemGroup>
<Folder Include="Model\" />
</ItemGroup>

</Project>

+ 228
- 107
BPASmartClient.MorkF/Control_MorkF.cs Dosyayı Görüntüle

@@ -8,18 +8,19 @@ using BPASmartClient.Model;
using BPASmartClient.Model.PLC;
using BPA.Models;
using static BPASmartClient.EventBus.EventBus;

using BPASmartClient.Model.小炒机;
using BPASmartClient.MorkF.Model;

namespace BPASmartClient.MorkF
{
public class Control_MorkF : BaseDevice
{
public override DeviceClientType DeviceType => DeviceClientType.MORKSF;
public override DeviceClientType DeviceType => DeviceClientType.MORKCS;
public AutoResetEvent minorReset = new AutoResetEvent(false);
public AutoResetEvent mainReset = new AutoResetEvent(false);
GVL_MorkF morkF = new GVL_MorkF();//全局对象声明
public StirFryBom stirFryBom = new StirFryBom();//创建获取流程的对象
StirFryGoods stirFryGoods = new StirFryGoods();//创建商品对象
List<StirFryGoods> stirFryGoods = new List<StirFryGoods>();//创建商品对象
List<int> resultorder = new List<int>();//调试变量
/// <summary>
/// 入口
@@ -321,9 +322,9 @@ namespace BPASmartClient.MorkF
{
//队列
string subId = Guid.NewGuid().ToString();
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = 1 });//A料
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = 2 });//B料
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = 3 });//C料
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = new List<int>() { 1 } });//A料
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = new List<int>() { 2 } });//B料
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = subId, MaterialLoc = new List<int>() { 3 } });//C料
morkF.TakePlateQueue.Enqueue(new OrderLocInfo() { SuborderId = subId });
resultorder.AddRange(new int[] { 1, 2, 3 });
morkF.listStirBom.Add(stirFryBom);
@@ -388,6 +389,7 @@ namespace BPASmartClient.MorkF
if (@event is MaterialDeliveryEvent material)
{
orderMaterialDelivery = material.orderMaterialDelivery;

}
});

@@ -401,6 +403,130 @@ namespace BPASmartClient.MorkF
WriteRecipeBoms();
}
});
//小炒流程信息
EventBus.EventBus.GetInstance().Subscribe<StirFryGoodsEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callback)
{
if (@event == null) return;
if (@event is StirFryGoodsEvent stirFry)
{
stirFryGoods = stirFry.stirFrymessage.stirFryGoods;
MessageLog.GetInstance.Show("接收到小炒流程信息");
//流程解析
foreach (var item in stirFryGoods)
{
MessageLog.GetInstance.ShowEx($"执行菜谱{item.GoodsKey}");
// morkF.listStirBom.Add(item.StirFryBomInfo);//添加订单制作流程
foreach (var items in item.StirFryBomInfo.StirFryActions)
{
MessageLog.GetInstance.Show($"执行流程{items.Time}");
foreach (var pro in items.RobotActions)
{
switch (pro)
{
case StirFryRobotAction.等待:
MessageLog.GetInstance.Show($"等待");
break;
case StirFryRobotAction.清洗槽取锅:
MessageLog.GetInstance.Show($"清洗槽取锅");
break;
case StirFryRobotAction.灶放锅:
MessageLog.GetInstance.Show($"灶放锅");
break;
case StirFryRobotAction.清洗槽放锅:
MessageLog.GetInstance.Show($"清洗槽放锅");
break;
case StirFryRobotAction.取A料:
MessageLog.GetInstance.Show($"取A料");
break;
case StirFryRobotAction.取B料:
MessageLog.GetInstance.Show($"取B料");
break;
case StirFryRobotAction.取C料:
MessageLog.GetInstance.Show($"取C料");
break;
case StirFryRobotAction.加入A料:
MessageLog.GetInstance.Show($"加入A料");
break;
case StirFryRobotAction.加入B料:
MessageLog.GetInstance.Show($"加入B料");
break;
case StirFryRobotAction.加入C料:
MessageLog.GetInstance.Show($"加入C料");
break;
case StirFryRobotAction.切换快速:
MessageLog.GetInstance.Show($"切换快速");
break;
case StirFryRobotAction.切换中速:
MessageLog.GetInstance.Show($"切换中速");
break;
case StirFryRobotAction.丢料盒:
MessageLog.GetInstance.Show($"丢料盒");
break;
case StirFryRobotAction.倒菜:
MessageLog.GetInstance.Show($"倒菜");
break;
case StirFryRobotAction.灶取锅:
MessageLog.GetInstance.Show($"灶取锅");
break;
}
}
foreach (var pro in items.PotActions)
{
switch (pro)
{
case StirFryPotAction.NONE:
break;
case StirFryPotAction.加热:
MessageLog.GetInstance.Show($"加热");
break;
case StirFryPotAction.大火t1s:
MessageLog.GetInstance.Show($"大火1s");
break;
case StirFryPotAction.加油:
MessageLog.GetInstance.Show($"加油");
break;
case StirFryPotAction.中火t2s:
MessageLog.GetInstance.Show($"中火2s");
break;
case StirFryPotAction.小火持续:
MessageLog.GetInstance.Show($"小火持续");
break;
case StirFryPotAction.中火持续:
MessageLog.GetInstance.Show($"中火持续");
break;
case StirFryPotAction.大火持续:
MessageLog.GetInstance.Show($"大火持续");
break;
case StirFryPotAction.停止火力:
MessageLog.GetInstance.Show($"停止火力");
break;
case StirFryPotAction.搅拌臂上位:
MessageLog.GetInstance.Show($"搅拌臂上位");
break;
case StirFryPotAction.搅拌臂中位:
MessageLog.GetInstance.Show($"搅拌臂中位");
break;
case StirFryPotAction.搅拌臂下位:
MessageLog.GetInstance.Show($"搅拌臂下位");
break;
case StirFryPotAction.低速旋转:
MessageLog.GetInstance.Show($"低速旋转");
break;
case StirFryPotAction.快速旋转:
MessageLog.GetInstance.Show($"快速旋转");
break;
case StirFryPotAction.停止旋转:
MessageLog.GetInstance.Show($"停止旋转");
break;
}
}
}
}
}
});

}

private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
@@ -423,41 +549,34 @@ namespace BPASmartClient.MorkF
if (order.MorkOrder.GoodBatchings == null) return;
OrderCount++;
DeviceProcessLogShow($"接收到{OrderCount}次订单");
foreach (var item in order.MorkOrder.GoodBatchings)

var res = stirFryGoods?.FirstOrDefault(p => p.GoodsKey == order.MorkOrder.RecipeId);//匹配订单对应制作流程
if (res != null)
{
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId);
if (res != null)
morkF.listStirBom.Add(res.StirFryBomInfo);//添加订单制作流程
if (morkF.TakeMaterialQueue.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
{
if (ushort.TryParse(res.BatchingLoc, out ushort loc))
{

//if (morkF.TakeMaterialQueue.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
//将一个商品的ABC料位置存入队列
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, BatchingId = res.BatchingId, MaterialLoc = ushort.Parse(res.BatchingLoc) });
}

morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, MaterialLoc = res.StirFryBomInfo.ALoc });
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, MaterialLoc = res.StirFryBomInfo.BLoc });
morkF.TakeMaterialQueue.Enqueue(new OrderLocInfo() { SuborderId = order.MorkOrder.SuborderId, MaterialLoc = res.StirFryBomInfo.CLoc });

}

//int index = 0;
//if (recipeBoms != null)
//{
// index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == order.MorkOrder.RecipeId);
// index++;
//}
if (morkF.TakePlateQueue.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
morkF.TakePlateQueue.Enqueue(new OrderLocInfo()
{
SuborderId = order.MorkOrder.SuborderId,
BatchingId = res.BatchingId
//RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0
});

//foreach (var item in order.MorkOrder.GoodBatchings)
//{
if (morkF.TakePlateQueue.FirstOrDefault(p => p.SuborderId == order.MorkOrder.SuborderId) == null)
{
morkF.TakePlateQueue.Enqueue(new OrderLocInfo()
{
SuborderId = order.MorkOrder.SuborderId,

});
}
//}
}
//根据ID 查找对应制作流程,

}

});
}
//}
@@ -572,7 +691,7 @@ namespace BPASmartClient.MorkF
if (morkF.MainProcessWait)
{
if (morkF.MinorHasTakeMaterial)
{
{
}
else
{
@@ -582,7 +701,7 @@ namespace BPASmartClient.MorkF
//阻塞辅流程
minorReset.WaitOne();
}
}
morkF.MinorProessStatus = true;
morkF.MainProcessStatus = false;
@@ -624,13 +743,13 @@ namespace BPASmartClient.MorkF
case StirFryRobotAction.清洗槽取锅:
TakePotTask();//执行取锅操作
break;
case StirFryRobotAction.加入A料:
case StirFryRobotAction.A料:
TakeBurdenATask();//执行取A料操作
break;
case StirFryRobotAction.加入B料:
case StirFryRobotAction.B料:
TakeBurdenATask();//执行取B料操作
break;
case StirFryRobotAction.加入C料:
case StirFryRobotAction.C料:
TakeBurdenCTask();//执行取C料操作
break;
case StirFryRobotAction.灶取锅:
@@ -708,7 +827,7 @@ namespace BPASmartClient.MorkF
//阻塞主流程
mainReset.WaitOne();
}
}
morkF.MinorProessStatus = false;
morkF.MainProcessStatus = true;
@@ -771,27 +890,10 @@ namespace BPASmartClient.MorkF
/// </summary>
private void TurntableControl()
{
//正常轮询
//if (morkF.TakeMaterialQueue.Count > 0 && !morkF.TurnTableLock)
//{
// var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == morkF.TakeMaterialQueue.ElementAt(0).BatchingId).ToList();

// if (result != null)
// {
// if (ushort.TryParse(result[0].BatchingLoc, out ushort loc))
// {
// TurnMaterialStore(loc);
// DeviceProcessLogShow($"转台转到【{loc}】位置");
// morkF.TurnTableLock = true; //取料完成后置false
// }
// }
// elseDeviceProcessLogShow("未找到可用的物料信息");
//}

//调试代码
if (morkF.TakeMaterialQueue.Count > 0 && !morkF.TurnTableLock)
//模拟订单
if (morkF.TakeMaterialQueue.Count > 0 && !morkF.TurnTableLock && General_Config.SimOrderAllow)
{
// var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == morkF.TakeMaterialQueue.ElementAt(0).BatchingId).ToList();

if (resultorder != null)
{

@@ -807,6 +909,25 @@ namespace BPASmartClient.MorkF
}

}
//正式订单
if (morkF.TakeMaterialQueue.Count > 0 && !morkF.TurnTableLock)
{
//var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == morkF.TakeMaterialQueue.ElementAt(0).BatchingId).ToList();
var materialLoc = morkF.TakeMaterialQueue.ElementAt(0).MaterialLoc;
if (materialLoc.Count != 0)
{
TurnMaterialStore(materialLoc[0]);
DeviceProcessLogShow($"转台转到【{materialLoc[0]}】位置");
morkF.TurnTableLock = true; //取料完成后置false

}
else
{
DeviceProcessLogShow("未找到可用的物料信息");
}

}


}

@@ -885,12 +1006,12 @@ namespace BPASmartClient.MorkF
if (morkF.MainProcessStatus)
{
morkF.MainProcessPotLoc = morkF.CurrentPutPotLoc;
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】执行取锅到灶台控制");
}
if (morkF.MinorProessStatus)
{
morkF.MinorProcessPotLoc = morkF.CurrentPutPotLoc;
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】执行取锅到灶台控制");
}
if (morkF.CurrentPutPotLoc == 1)
{
@@ -983,11 +1104,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1016,11 +1137,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1064,11 +1185,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1097,11 +1218,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1174,11 +1295,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1207,11 +1328,11 @@ namespace BPASmartClient.MorkF
}
if (morkF.TakeMaterialQueue.TryDequeue(out OrderLocInfo order))
{
loc = order.MaterialLoc;
TakeBurden(loc);
loc = order.MaterialLoc[0];
TakeBurden();
TurnReset(loc);//转台复位

DeviceProcessLogShow($"订单【{ order.SuborderId}】,执行到转台{loc}位置取料");
DeviceProcessLogShow($"订单【{order.SuborderId}】,执行到转台{loc}位置取料");
}
//等待取料完成
while (!morkF.TakeMaterialComplete)
@@ -1245,9 +1366,9 @@ namespace BPASmartClient.MorkF
RobotOutMeal();
WriteData("M1.2", false);//供盘复位
if (morkF.MainProcessStatus)
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到清洗台控制");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】执行取锅到清洗台控制");
if (morkF.MinorProessStatus)
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到清洗台控制");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】执行取锅到清洗台控制");

}

@@ -1271,7 +1392,7 @@ namespace BPASmartClient.MorkF
{
CleanModuleControl("Start", 2);
}
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行清洗操作");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】执行清洗操作");
morkF.MainProcessFlag = false;
minorReset.Set();
}
@@ -1286,7 +1407,7 @@ namespace BPASmartClient.MorkF
{
CleanModuleControl("Start", 2);
}
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行清洗操作");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】执行清洗操作");
morkF.MinorProcessFlag = false;
mainReset.Set();
}
@@ -1325,9 +1446,9 @@ namespace BPASmartClient.MorkF
/// </summary>
public void TurnDownStatusDetect()
{
int potLoc= TurnMachineOrientControl("Down");
int potLoc = TurnMachineOrientControl("Down");

if (potLoc==1)
if (potLoc == 1)
{
while (!morkF.TurnMachineDownComplete)//等待翻转机下降完成
{
@@ -1335,7 +1456,7 @@ namespace BPASmartClient.MorkF
}
WriteData("M8.3", false);//下降完成复位
}
if (potLoc==2)
if (potLoc == 2)
{
while (!morkF.SecondTurnMachineDownComplete)//等待翻转机下降完成
{
@@ -1354,7 +1475,7 @@ namespace BPASmartClient.MorkF
//}

}
/// <summary>
/// 翻转机上升及状态检测
/// </summary>
@@ -1367,7 +1488,7 @@ namespace BPASmartClient.MorkF
TurnMachineOrientControl("Top");//翻转机上升
if (morkF.MainProcessStatus)
{
if (morkF.MainProcessPotLoc==1)
if (morkF.MainProcessPotLoc == 1)
{
while (!morkF.TurnMachineUpComplete)//等待翻转机上升完成以及取料完成
{
@@ -1392,14 +1513,14 @@ namespace BPASmartClient.MorkF
}
morkF.MainOrderMaterialCom = true;
morkF.MainHasTakeMaterial = false;
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】,配料倒料完成");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】,配料倒料完成");
}
else //辅程准备阻塞
{
morkF.MainProcessWait = true;
}
}
if (morkF.MainProcessPotLoc==2)
if (morkF.MainProcessPotLoc == 2)
{
while (!morkF.SecondTurnMachineUpComplete)//等待翻转机上升完成以及取料完成
{
@@ -1424,12 +1545,12 @@ namespace BPASmartClient.MorkF
}
morkF.MainOrderMaterialCom = true;
morkF.MainHasTakeMaterial = false;
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】,配料倒料完成");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】,配料倒料完成");
}
else //辅流程准备阻塞
{
morkF.MainProcessWait = true;
}
}
}
}
if (morkF.MinorProessStatus)
@@ -1459,14 +1580,14 @@ namespace BPASmartClient.MorkF
}
morkF.MinorOrderMaterialCom = true;
morkF.MinorHasTakeMaterial = false;
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】,配料倒料完成");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】,配料倒料完成");
}
else //主程准备阻塞
{
morkF.MinorProcessWait = true;
}
}
if (morkF.MinorProcessPotLoc==2)
if (morkF.MinorProcessPotLoc == 2)
{
while (!morkF.SecondTurnMachineUpComplete)//等待翻转机上升完成以及取料完成
{
@@ -1491,12 +1612,12 @@ namespace BPASmartClient.MorkF
}
morkF.MinorOrderMaterialCom = true;
morkF.MinorHasTakeMaterial = false;
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】,配料倒料完成");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】,配料倒料完成");
}
else //主流程准备阻塞
{
morkF.MinorProcessWait = true;
}
}
}
}
//if (morkF.MainProcessStatus)//代表主流程执行的操作
@@ -1702,7 +1823,7 @@ namespace BPASmartClient.MorkF
}
FirstPotGears(number);
}
if (morkF.MinorProcessPotLoc==2)
if (morkF.MinorProcessPotLoc == 2)
{
while (!morkF.SecondPotInPlace)
{
@@ -1712,9 +1833,9 @@ namespace BPASmartClient.MorkF
}
}
if (morkF.MainProcessStatus)
DeviceProcessLogShow($"订单【{ morkF.MainCurrentOrderId}】执行取锅到灶台控制");
DeviceProcessLogShow($"订单【{morkF.MainCurrentOrderId}】执行取锅到灶台控制");
if (morkF.MinorProessStatus)
DeviceProcessLogShow($"订单【{ morkF.MinorCurrentOrderId}】执行取锅到灶台控制");
DeviceProcessLogShow($"订单【{morkF.MinorCurrentOrderId}】执行取锅到灶台控制");
}
/// <summary>
/// PLC转台控制
@@ -1818,7 +1939,7 @@ namespace BPASmartClient.MorkF
Task.Delay(5).Wait();
}
}
if (morkF.MainProcessPotLoc==2)
if (morkF.MainProcessPotLoc == 2)
{
while (!morkF.SecondPotInPlace)
{
@@ -1832,7 +1953,7 @@ namespace BPASmartClient.MorkF
Task.Delay(5).Wait();
}
}
}
if (morkF.MinorProessStatus)
{
@@ -1876,8 +1997,8 @@ namespace BPASmartClient.MorkF
{
switch (orientation)
{
case "Top": WriteData("M8.0", true); break;
case "Down": WriteData("M8.2", true); break;
case "Top": WriteData("M8.0", true); break;
case "Down": WriteData("M8.2", true); break;
}
}
public void SecondPotTurnMachine(string orientation)
@@ -1895,7 +2016,7 @@ namespace BPASmartClient.MorkF
/// <param name="orientation"></param>
public int TurnMachineOrientControl(string orientation)
{
int potLoc=0; ;
int potLoc = 0; ;
//switch (orientation)
//{
// case "Top": if (morkF.MainProcessStatus) WriteData("M8.0", true); if (morkF.MinorProessStatus) WriteData("M8.4", true); break;
@@ -1911,7 +2032,7 @@ namespace BPASmartClient.MorkF
if (morkF.MainProcessPotLoc == 2)
{
SecondPotTurnMachine(orientation);
potLoc=2;
potLoc = 2;
}
}
if (morkF.MinorProessStatus)
@@ -1971,7 +2092,7 @@ namespace BPASmartClient.MorkF
//}
if (morkF.MainProcessStatus)
{
if (morkF.MainProcessPotLoc==1)
if (morkF.MainProcessPotLoc == 1)
{
FirstPotTurnMachine(gear);
}
@@ -1982,7 +2103,7 @@ namespace BPASmartClient.MorkF
}
if (morkF.MinorProessStatus)
{
if (morkF.MinorProcessPotLoc==1)
if (morkF.MinorProcessPotLoc == 1)
{
FirstPotTurnMachine(gear);
}
@@ -1996,7 +2117,7 @@ namespace BPASmartClient.MorkF
/// <summary>
/// 取A,B,C料
/// </summary>
public void TakeBurden(int loc)
public void TakeBurden()
{
if (morkF.MainProcessStatus && morkF.PotInPlace)
WriteData("M14.1", true);//机器人倒料至1号锅


+ 1
- 0
BPASmartClient.MorkF/GVL_MorkF.cs Dosyayı Görüntüle

@@ -10,6 +10,7 @@ namespace BPASmartClient.MorkF
{
internal class GVL_MorkF
{
/// <summary>
/// 初始化完成状态
/// </summary>


+ 13
- 0
BPASmartClient.MorkF/Model/General_Config.cs Dosyayı Görüntüle

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BPASmartClient.MorkF.Model
{
internal class General_Config
{
public static bool SimOrderAllow { get; set; }
}
}

+ 1
- 1
BPASmartClient.MorkF/OrderLocInfo.cs Dosyayı Görüntüle

@@ -9,7 +9,7 @@ namespace BPASmartClient.MorkF
internal class OrderLocInfo
{
public string SuborderId { get; set; }
public ushort MaterialLoc { get; set; }//物料位置
public List<int> MaterialLoc { get; set; } = new List<int>();//物料A位置
public ushort RecipeNumber { get; set; }
public int BatchingId { get; set; }
}

+ 1
- 0
BPASmartClient.MorkF/View/DebugView.xaml Dosyayı Görüntüle

@@ -36,6 +36,7 @@
<Button Content="供盘" Command="{Binding OutPlate}" Margin="10,0,10,0"></Button>
<Button Content="清洗模组1启动" Command="{Binding StartQXOne}" Margin="10,0,10,0"></Button>
<Button Content="清洗模组2启动" Command="{Binding StartQXTwo}" Margin="10,10,10,0" Cursor="Hand"></Button>
<CheckBox Name="checkValue" Content="运行模拟订单程序" Margin="10,10,10,0" IsChecked="{Binding SimOrderEnable}"></CheckBox>
</WrapPanel>
</GroupBox>
<GroupBox Header="菜品选择" FontSize="15" Foreground="Aqua" Grid.Row="1" Margin="0,0,0,40" VerticalAlignment="Top" Height="100">


+ 1
- 0
BPASmartClient.MorkF/View/DebugView.xaml.cs Dosyayı Görüntüle

@@ -25,6 +25,7 @@ namespace BPASmartClient.MorkF.View
{
InitializeComponent();
this.DataContext = new DebugViewModel();
}
}
}

+ 4
- 1
BPASmartClient.MorkF/ViewModel/DebugViewModel.cs Dosyayı Görüntüle

@@ -1,4 +1,5 @@
using BPASmartClient.Helper;
using BPASmartClient.MorkF.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using System;
@@ -11,6 +12,7 @@ namespace BPASmartClient.MorkF.ViewModel
{
internal class DebugViewModel : ObservableObject
{
public bool SimOrderEnable { get { return General_Config.SimOrderAllow; } set { General_Config.SimOrderAllow = value; OnPropertyChanged(); } }

public RelayCommand PlcInite { get; set; }
public RelayCommand SimulateOrder { get; set; }
@@ -64,7 +66,8 @@ namespace BPASmartClient.MorkF.ViewModel
public DebugViewModel()
{
PlcInite = new RelayCommand(() => { ActionManage.GetInstance.Send("InitCommand"); });
SimulateOrder = new RelayCommand(() => { ActionManage.GetInstance.Send("SimultaorOrder"); });

SimulateOrder = new RelayCommand(() => {ActionManage.GetInstance.Send("SimultaorOrder"); });
MaterialOne= new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialOne"); });
MaterialTwo = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialTwo"); });
MaterialThree = new RelayCommand(() => { ActionManage.GetInstance.Send("MaterialThree"); });


+ 3
- 1
BPASmartClient.MorkM/Control_MORKM.cs Dosyayı Görüntüle

@@ -15,6 +15,7 @@ using BPASmartClient.MorkM.Model;
using System.Collections.ObjectModel;
using BPASmartClient.Model.PLC;
using BPASmartClient.MorkM.ViewModel;
using BPA.Message;

namespace BPASmartClient.MorkM
{
@@ -800,6 +801,7 @@ namespace BPASmartClient.MorkM
}
});


//配方数据信息
EventBus.EventBus.GetInstance().Subscribe<RecipeBomEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack)
{
@@ -811,7 +813,7 @@ namespace BPASmartClient.MorkM
}
});
}
public override void DoMain()
{
MonitorViewModel.DeviceId = DeviceId;


+ 5
- 1
BPASmartClient.MorkS/Control_Morks.cs Dosyayı Görüntüle

@@ -18,6 +18,8 @@ using BPASmartClient.MorkS.Model;
using System.Collections.ObjectModel;
using BPASmartClient.MorkS.ViewModel;
using BPASmartClient.Business;
using BPASmartClient.Model.小炒机;
using BPA.Models;

namespace BPASmartClient.MorkS
{
@@ -113,8 +115,10 @@ namespace BPASmartClient.MorkS
WriteRecipeBoms();
}
});
}

private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS)
{
var res = mORKS.doOrderEvents.FirstOrDefault(p => p.MorkOrder.SuborderId == subid);


+ 1
- 0
BPASmartClient.MorkS/ViewModel/DebugViewModel.cs Dosyayı Görüntüle

@@ -8,6 +8,7 @@ using BPASmartClient.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using BPASmartClient.EventBus;
using BPASmartClient.MorkS.Model;

namespace BPASmartClient.MorkS.ViewModel
{


+ 4
- 4
BPASmartClient/App.config Dosyayı Görüntüle

@@ -7,14 +7,14 @@
<add key="IsEnableTest" value="false"/>

<!--开发环境-->
<!--<add key="apollouri" value="http://10.2.1.21:28080/"/>
<add key="apollouri" value="http://10.2.1.21:28080/"/>
<add key="AppId" value="dev1_common"/>
<add key ="Namespaces" value="DEV.Config"/>-->
<add key ="Namespaces" value="DEV.Config"/>

<!--正式环境-->
<add key="apollouri" value="http://47.108.65.220:28080/"/>
<!--<add key="apollouri" value="http://47.108.65.220:28080/"/>
<add key="AppId" value="order"/>
<add key ="Namespaces" value="TEST1.Config"/>
<add key ="Namespaces" value="TEST1.Config"/>-->

<!--阿里云上报启动方式:API 或者 LOCAL-->
<!--API :通过客户端ID,调用接口查询“设备连接信息”-->


+ 23
- 0
BPASmartClient/Control/GYLCControl.xaml Dosyayı Görüntüle

@@ -0,0 +1,23 @@
<UserControl x:Class="BPASmartClient.Control.GYLCControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:BPASmartClient.Control"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/GenricStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/MyStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<ScrollViewer>
<Image Style="{DynamicResource imagetop_工艺流程}" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">

</Image>
</ScrollViewer>
</UserControl>

+ 28
- 0
BPASmartClient/Control/GYLCControl.xaml.cs Dosyayı Görüntüle

@@ -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
{
/// <summary>
/// GYLCControl.xaml 的交互逻辑
/// </summary>
public partial class GYLCControl : UserControl
{
public GYLCControl()
{
InitializeComponent();
}
}
}

+ 7
- 1
BPASmartClient/MainWindow.xaml Dosyayı Görüntüle

@@ -116,7 +116,7 @@
<MenuItem
Click="Debug_Click"
FontSize="12"
Header="调试"
Header="AGV控制"
Tag="DebugView" />


@@ -152,6 +152,12 @@
Header="IOT监视"
Tag="IOTView" />
<Separator />
<MenuItem
Click="MenuItem_Click"
FontSize="12"
Header="工艺流程"
Tag="GYLCControl" />
<Separator />
</MenuItem>
<MenuItem Header="综合查询">
<MenuItem


+ 1
- 0
DosingSystem/App.xaml Dosyayı Görüntüle

@@ -23,6 +23,7 @@
<con:ColorConverter x:Key="ColorConverter" />
<con:TextConverter x:Key="TextConverter" />
<con:VisibleTypeConverter x:Key="VisibleTypeConverter" />
<con:StatusConverter x:Key="StatusConverter" />
</ResourceDictionary>

<ResourceDictionary>


+ 1
- 1
DosingSystem/DosingSystem.csproj Dosyayı Görüntüle

@@ -14,7 +14,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="BPA.Message" Version="1.0.39" />
<PackageReference Include="BPA.Message" Version="1.0.45" />
<PackageReference Include="Microsoft.Toolkit.Mvvm" Version="7.1.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>


+ 133
- 32
DosingSystem/Model/DeviceInquire.cs Dosyayı Görüntüle

@@ -1,9 +1,11 @@
using BPASmartClient.Helper;
using BPASmartClient.Message;
using BPASmartClient.Modbus;
using DosingSystem.ViewModel;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
@@ -14,54 +16,68 @@ 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";
int count = 0;
private static readonly object _lock = new object();
ConcurrentDictionary<string, ModbusTcp> modbusTcps = new ConcurrentDictionary<string, ModbusTcp>();
List<string> InvalidIP = new List<string>();
string NameAddress = "VW0";

ConcurrentDictionary<string, DeviceStatus> DeviceLists = new ConcurrentDictionary<string, DeviceStatus>();
List<string> InvalidIP = new List<string>();//无效 IP 集合
List<string> IPLists = new List<string>();//启动 Ping 任务IP集合
ConcurrentQueue<string> IPQueues = new ConcurrentQueue<string>();//pincomplete 完成队列

public void Init()
{
IpAddressLines();
ThreadManage.GetInstance().StartLong(new Action(() =>
{
if (count >= 255) IpAddressLines();
if (IPQueues.Count >= IPLists.Count)
IpAddressLines();
Thread.Sleep(5000);
}), "配料机设备上线监听", true);
}

public ModbusTcp GetModbusTcp(string ip)
public DeviceStatus GetDevice(string ip)
{
if (modbusTcps.ContainsKey(ip)) return modbusTcps[ip];
else return default;
if (ip != null)
{
var res = DeviceLists.Values.FirstOrDefault(p => p.IpAddress == ip);
if (res != null) return res;
}
return new DeviceStatus();
}

private void IpAddressLines()
{
//for (int i = 1; i <= 255; i++)
//{
// if (!InvalidIP.Contains($"{IPSegment}{i}"))
// {
// Ping myPing = new Ping();
// myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
// string pingIP = $"{IPSegment}{i}";
// myPing.SendAsync(pingIP, 1000, null);
// }
//}
//count = 0;

IPLists.Clear();
IPQueues.Clear();
for (int i = 1; i <= 255; i++)
{
if (!InvalidIP.Contains($"{IPSegment}{i}"))
{
Ping myPing;
myPing = new Ping();
myPing.PingCompleted += new PingCompletedEventHandler(_myPing_PingCompleted);
string pingIP = $"{IPSegment}{i}";
myPing.SendAsync(pingIP, 1000, null);
IPLists.Add($"{IPSegment}{i}");
}
}
count = 0;
}

private void CompleteCount()
{
lock (_lock)
count++;
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)
@@ -69,17 +85,20 @@ 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); }));
DeviceStatus DS = new DeviceStatus();
DS.modbusTcp.IsReconnect = false;

modbusTcps[ip].ConnectOk = new Action(() =>
Task.Run(new Action(() => { DS.modbusTcp.ModbusTcpConnect(ip, 508); }));
DS.modbusTcp.ConnectOk = new Action(() =>
{
string DeviceName = modbusTcps[ip].GetString(NameAddress, 10);
string DeviceName = DS.modbusTcp.GetString(NameAddress, 20);
if (DeviceName.Length > 0)
{
DeviceLists.TryAdd(ip, DS);
DeviceLists[ip].Init(DeviceName);
DeviceLists[ip].modbusTcp.IsReconnect = false;
App.Current.Dispatcher.Invoke(new Action(() =>
{
DeviceListViewModel.devices.Add(new Devices()
@@ -87,6 +106,21 @@ namespace DosingSystem.Model
DeviceName = DeviceName,
IpAddress = ip
});

for (int i = 0; i < Json<LocaPar>.Data.Recipes.Count; i++)
{
for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
{
if (Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).DeviceIp == ip)
{
Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.ElementAt(m).RawMaterialName = DeviceName;
}
}
}

if (!NewRecipeViewModel.RawMaterialNames.Contains(DeviceName))
NewRecipeViewModel.RawMaterialNames.Add(DeviceName);

}));
}
else
@@ -95,23 +129,90 @@ namespace DosingSystem.Model
}
});

modbusTcps[ip].ConnectFail = new Action(() =>
DS.modbusTcp.ConnectFail = new Action(() =>
{
if (!InvalidIP.Contains(ip)) InvalidIP.Add(ip);
MessageLog.GetInstance.Show($"{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);
}));
if (DeviceLists.ContainsKey(ip)) DeviceLists[ip].Dispose();
});

}
}
CompleteCount();
IPQueues.Enqueue(e.Reply.Address.ToString());
}
}

public class DeviceStatus
{

#region 对象属性声明
public string DeviceName = String.Empty;
public string IpAddress => modbusTcp.IPAdress;

/// <summary>
/// 设备状态
/// </summary>
public RawMaterialDeviceStatus deviceStatus { get; set; } = new RawMaterialDeviceStatus();

public ModbusTcp modbusTcp = new ModbusTcp();

public bool IsConnected => modbusTcp.Connected;
#endregion

public void Init(string DeviceName)
{
this.DeviceName = DeviceName;
if (modbusTcp.Connected)
{
ThreadManage.GetInstance().StartLong(new Action(() =>
{
var res = this.modbusTcp.Read("VW100");
if (res != null && res is ushort[] ushortValue)
{
if (ushortValue.Length >= 1) deviceStatus.RunStatus = ushortValue[0];
}
Thread.Sleep(100);
}), $"{DeviceName} 开始监听", true);
}
}

public void SetDeviceName(string name)
{
this.modbusTcp.Write("VW0", new ushort[20]);
this.modbusTcp.SetString("VW0", name);
}

public void StatusReset()
{
this.modbusTcp.Write("VW100", (ushort)1);
}

public void Dispose()
{
ThreadManage.GetInstance().StopTask($"{DeviceName} 开始监听");
}

public void Start(float Value)
{
if (modbusTcp.Connected)
{
modbusTcp.SetReal("VW40", Value);//写入配方量
modbusTcp.Write("M0.0", true);//设备启动写入
}
}
}

}

+ 15
- 0
DosingSystem/Model/LocaPar.cs Dosyayı Görüntüle

@@ -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 DosingSystem.ViewModel;

namespace DosingSystem.Model
{
public class LocaPar
{
public ObservableCollection<RecipeModel> Recipes { get; set; } = new ObservableCollection<RecipeModel>();
}
}

+ 45
- 0
DosingSystem/Model/RawMaterialDeviceStatus.cs Dosyayı Görüntüle

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DosingSystem.Model
{
public class RawMaterialDeviceStatus
{

/// <summary>
/// 原料类型 MW18
/// 1:液体
/// 2:膏体
/// 3:粉体
/// </summary>
public ushort RawMaterialType { get; set; }

/// <summary>
/// 料仓重量反馈 MD40
/// </summary>
public float WeightFeedback { get; set; }

/// <summary>
/// 上限反馈
/// </summary>
public bool UpLimitFeedback { get; set; }

/// <summary>
/// 下限反馈
/// </summary>
public bool DownLimitFeedback { get; set; }

/// <summary>
/// 下料重量反馈 MD52
/// </summary>
public float CutWeightFeedback { get; set; }

/// <summary>
/// 设备运行状态
/// </summary>
public ushort RunStatus { get; set; }
}
}

+ 89
- 0
DosingSystem/Model/RawMaterialModel.cs Dosyayı Görüntüle

@@ -0,0 +1,89 @@
using Microsoft.Toolkit.Mvvm.ComponentModel;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DosingSystem.Model
{
/// <summary>
/// 原料模块
/// </summary>
public class RawMaterialModel : ObservableObject
{
/// <summary>
/// 原料名称
/// </summary>
public string RawMaterialName { get { return _mRawMaterialName; } set { _mRawMaterialName = value; OnPropertyChanged(); } }
private string _mRawMaterialName;

/// <summary>
/// 原料设备IP
/// </summary>
public string DeviceIp { get; set; }

/// <summary>
/// 原料重量设置
/// </summary>
public float RawMaterialWeight { get { return _mRawMaterialWeight; } set { _mRawMaterialWeight = value; OnPropertyChanged(); } }
private float _mRawMaterialWeight;

/// <summary>
/// 原料类型 MW18
/// 1:液体
/// 2:膏体
/// 3:粉体
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public ushort RawMaterialType { get { return _mRawMaterialType; } set { _mRawMaterialType = value; OnPropertyChanged(); } }
private ushort _mRawMaterialType;

/// <summary>
/// 料仓重量反馈 MD40
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public float WeightFeedback { get { return _mWeightFeedback; } set { _mWeightFeedback = value; OnPropertyChanged(); } }
private float _mWeightFeedback;

/// <summary>
/// 上限反馈
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public bool UpLimtFeedback { get { return _mUpLimtFeedback; } set { _mUpLimtFeedback = value; OnPropertyChanged(); } }
private bool _mUpLimtFeedback;

/// <summary>
/// 下限反馈
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public bool DownLimtFeedback { get { return _mDownLimtFeedback; } set { _mDownLimtFeedback = value; OnPropertyChanged(); } }
private bool _mDownLimtFeedback;

/// <summary>
/// 下料重量反馈 MD52
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public float UpLimtWeightFeedback { get { return _mUpLimtWeightFeedback; } set { _mUpLimtWeightFeedback = value; OnPropertyChanged(); } }
private float _mUpLimtWeightFeedback;


/// <summary>
/// 原料ID
/// </summary>
public string RawMaterialId { get { return _mRawMaterialId; } set { _mRawMaterialId = value; OnPropertyChanged(); } }
private string _mRawMaterialId;

/// <summary>
/// 原料设备执行状态
/// 1:准备就绪
/// 2:等待接料
/// 3:接料完成
/// 4:设备异常
/// </summary>
[Newtonsoft.Json.JsonIgnore]
public ushort RecipeStatus { get { return _mRecipeStatus; } set { _mRecipeStatus = value; OnPropertyChanged(); } }
private ushort _mRecipeStatus = 1;

}
}

+ 50
- 0
DosingSystem/Model/RecipeModel.cs Dosyayı Görüntüle

@@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using DosingSystem.ViewModel;
using Microsoft.Toolkit.Mvvm.ComponentModel;

namespace DosingSystem.Model
{
/// <summary>
/// 配方模块
/// </summary>
public class RecipeModel : ObservableObject
{
public bool IsEnable { get { return _mIsEnable; } set { _mIsEnable = value; OnPropertyChanged(); } }
private bool _mIsEnable = true;

/// <summary>
/// 序号
/// </summary>
public int SerialNum { get { return _mSerialNum; } set { _mSerialNum = value; OnPropertyChanged(); } }
private int _mSerialNum;

/// <summary>
/// 配方名称
/// </summary>
public string RecipeName { get { return _mRecipeName; } set { _mRecipeName = value; OnPropertyChanged(); } }
private string _mRecipeName;

/// <summary>
/// 配方编码
/// </summary>
public string RecipCode { get { return _mRecipCode; } set { _mRecipCode = value; OnPropertyChanged(); } }
private string _mRecipCode;

[Newtonsoft.Json.JsonIgnore]
public AutoResetEvent Are { get; set; } = new AutoResetEvent(false);

/// <summary>
/// 原料集合
/// </summary>
public ObservableCollection<RawMaterialModel> RawMaterials { get; set; } = new ObservableCollection<RawMaterialModel>();



}
}

+ 122
- 0
DosingSystem/View/ChangeDeviceNameView.xaml Dosyayı Görüntüle

@@ -0,0 +1,122 @@
<Window
x:Class="DosingSystem.View.ChangeDeviceNameView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DosingSystem.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:DosingSystem.ViewModel"
Title="ChangeDeviceNameView"
Width="400"
Height="200"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">

<Window.DataContext>
<vm:ChangeDeviceNameViewModel />
</Window.DataContext>

<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/GenricStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/MyStyle.xaml" />

<ResourceDictionary>
<!--#region ListBox样式-->
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="20" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border" CornerRadius="8">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

<Border
Name="br"
Background="#FF0B2F5F"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="0.5*" />
<RowDefinition />
</Grid.RowDefinitions>

<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock
Margin="10,0,0,0"
Background="Transparent"
FontSize="20"
Foreground="#FF2AB2E7"
Text="请输入新设备名称:" />

<TextBox
Grid.Column="1"
Width="200"
Height="30"
Margin="0,0,7,0"
FontSize="16"
Text="{Binding DeviceName}" />

</StackPanel>

<TextBlock
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="Transparent"
FontSize="16"
Foreground="Red"
Text="{Binding ErrorInfo}" />

<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<Button
Grid.Column="1"
Width="148"
Height="30"
Margin="0,0,7,0"
Command="{Binding ConfirmCommand}"
Content="确认" />

<Button
Name="btClose"
Width="148"
Height="30"
Command="{Binding CancleCommand}"
Content="取消" />

</Grid>

</Grid>
</Border>

</Window>

+ 31
- 0
DosingSystem/View/ChangeDeviceNameView.xaml.cs Dosyayı Görüntüle

@@ -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 DosingSystem.View
{
/// <summary>
/// ChangeDeviceNameView.xaml 的交互逻辑
/// </summary>
public partial class ChangeDeviceNameView : Window
{
public ChangeDeviceNameView()
{
InitializeComponent();
ActionManage.GetInstance.CancelRegister("ChangeDeviceNameViewClose");
ActionManage.GetInstance.Register(new Action(() => { this.Close(); }), "ChangeDeviceNameViewClose");
this.br.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
}
}
}

+ 117
- 47
DosingSystem/View/DeviceListView.xaml Dosyayı Görüntüle

@@ -16,59 +16,129 @@
<vm:DeviceListViewModel />
</UserControl.DataContext>

<UserControl.Resources>
<Style x:Key="UserItemContainerStyle" TargetType="ListBoxItem">
<Style.Resources>
<!-- SelectedItem with focus -->
<SolidColorBrush
x:Key="{x:Static SystemColors.HighlightBrushKey}"
Opacity=".4"
Color="White" />
<!-- SelectedItem without focus -->
<SolidColorBrush
x:Key="{x:Static SystemColors.ControlBrushKey}"
Opacity=".4"
Color="White" />
</Style.Resources>
<!-- 设置触发器 -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>

<Grid>
<ItemsControl
Width="300"
HorizontalAlignment="Left"
ItemsSource="{Binding devices}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border
Margin="0,0,0,15"
BorderBrush="Aqua"
BorderThickness="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid>
<ListView
Grid.Column="1"
Margin="10"
Background="Transparent"
BorderBrush="#00BEFA"
BorderThickness="0"
ItemsSource="{Binding devices}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
HorizontalAlignment="Left"
VerticalAlignment="Top"
Columns="4" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>

<ListView.ItemTemplate>
<DataTemplate>
<Border
Name="ShadowElement"
Height="150"
VerticalAlignment="Top"
BorderBrush="#00BEFA"
BorderThickness="2"
ClipToBounds="True"
CornerRadius="8">
<Border.Effect>
<DropShadowEffect
BlurRadius="18"
ShadowDepth="0"
Color="#00BEFA" />
</Border.Effect>

<Grid Margin="20,0,20,0">

<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Row="0"
Grid.ColumnSpan="2"
VerticalAlignment="Bottom"
FontSize="40"
Foreground="#00BEFA"
Text="{Binding DeviceName}" />


<TextBlock
HorizontalAlignment="Right"
FontSize="16"
Foreground="Aqua"
Text="IP地址:" />
<StackPanel
Grid.Row="1"
Grid.ColumnSpan="2"
Orientation="Horizontal">
<TextBlock
Grid.Row="1"
FontSize="14"
Foreground="Aqua"
Text="设备IP:" />
<TextBlock
Grid.Row="1"
FontSize="14"
Foreground="Aqua"
Text="{Binding IpAddress}" />
</StackPanel>

<TextBlock
Grid.Column="1"
HorizontalAlignment="Left"
FontSize="16"
Foreground="Aqua"
Text="{Binding IpAddress}" />
<Button
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Width="130"
Height="30"
Margin="0,0,0,10"
HorizontalAlignment="Left"
VerticalAlignment="Bottom"
Command="{Binding DataContext.ChangeNameCommand, RelativeSource={RelativeSource AncestorType=ListView, Mode=FindAncestor}}"
CommandParameter="{Binding IpAddress}"
Content="修改设备名称"
IsEnabled="{Binding IsEnable}" />

<TextBlock
Grid.Row="1"
HorizontalAlignment="Right"
FontSize="16"
Foreground="Aqua"
Text="设备名称:" />

<TextBlock
Grid.Row="1"
Grid.Column="1"
FontSize="16"
Foreground="Aqua"
Text="{Binding DeviceName}" />
</Grid>
</Border>
</Grid>
</Border>

</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</UserControl>

+ 1
- 183
DosingSystem/View/MainWindow.xaml Dosyayı Görüntüle

@@ -13,7 +13,7 @@
Height="800"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
Topmost="False"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">
@@ -235,38 +235,6 @@
Foreground="#feffff"
Text="{Binding WindowTitleName}" />

<!--<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button
Grid.Row="0"
Width="70"
Margin="5,0,5,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Command="{Binding Login}"
Content="账号修改"
Cursor="Hand" />
<Button
Name="login"
Grid.Row="0"
Width="45"
Margin="5,0,5,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Command="{Binding Login}"
Content="登录"
Cursor="Hand" />
<Button
Name="logout"
Grid.Row="0"
Width="45"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="Button_LogOut"
Command="{Binding LogoutCommand}"
Content="注销"
Cursor="Hand" />
</StackPanel>-->

</Grid>

<!--#region 底部窗体栏-->
@@ -280,154 +248,4 @@

</Grid>
</Border>

<!--<Grid>
-->
<!--<Grid.Background>
<ImageBrush ImageSource="pack://application:,,,/BPASmartClient.CustomResource;component/Image/界面2.png" />
</Grid.Background>-->
<!--

<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition />
</Grid.RowDefinitions>

-->
<!--#region 标题栏设置-->
<!--<Border
x:Name="MoveBorder"
Height="50"
VerticalAlignment="Top"
BorderBrush="#55ffffff"
BorderThickness="0,0,0,0">

<StackPanel Orientation="Horizontal">
<Image Margin="25 5 0 0" Source="pack://application:,,,/BPASmartClient.CustomResource;component/Image/HBL.png" />
<TextBlock
Name="tbTitle"
Margin="20,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="18"
Foreground="White"
Text="配料控制系统" />
</StackPanel>


</Border>-->
<!--

<Border
x:Name="MoveBorder"
Height="50"
VerticalAlignment="Top"
Background="#0C2349"
BorderBrush="#55ffffff"
BorderThickness="0,0,0,1">

<StackPanel Orientation="Horizontal">
<Image Margin="25,5,0,0" Source="pack://application:,,,/BPASmartClient.CustomResource;component/Image/HBL.png" />
<TextBlock
Name="tbTitle"
Margin="20,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
FontSize="18"
Foreground="White"
Text="配料控制系统" />
</StackPanel>
</Border>

<UniformGrid
Width="150"
Height="50"
HorizontalAlignment="Right"
Columns="3">
<pry:IcoButton
Name="ButMin"
Content="&#xe624;"
Style="{StaticResource IcoTitleBarStyle}" />

<pry:IcoButton
Name="ButMax"
Content="&#xe645;"
Style="{StaticResource IcoTitleBarStyle}" />

<pry:IcoButton
Name="ButClose"
Content="&#xe62f;"
Style="{StaticResource IcoTitleBarStyle}" />

</UniformGrid>
-->
<!--#endregion-->

<!--#region 内容区域-->
<!--
<Grid Grid.Row="1">
-->
<!--<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/WindowImages.png" />
</Grid.Background>-->
<!--

<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.15*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>

<Grid>
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/leftback.png" Opacity="0.8" />
</Grid.Background>

<Grid.RowDefinitions>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition/>
</Grid.RowDefinitions>

<RadioButton Grid.Row="0" Content="配方设置" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Grid.Row="1" Content="设备列表" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Grid.Row="2" Content="硬件状态" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Grid.Row="3" Content="报警记录" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Grid.Row="4" Content="配方控制" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
</Grid>

-->
<!--<StackPanel>
<StackPanel.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/leftback.png" Opacity="0.8" />
</StackPanel.Background>
<RadioButton Content="配方设置" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Content="设备列表" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Content="硬件状态" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Content="报警记录" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
<RadioButton Content="配方控制" Style="{StaticResource RectangleLeftRadioButtonStyle}" />
</StackPanel>-->
<!--

<Grid Grid.Column="1">
<Grid.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/WindowImages.png" />
</Grid.Background>
<TextBlock
Margin="0,10,0,0"
HorizontalAlignment="Center"
FontSize="16"
Foreground="#1A8ADE"
Text="配方设置" />
</Grid>


</Grid>
-->
<!--#endregion-->
<!--

</Grid>-->
</Window>

+ 222
- 0
DosingSystem/View/NewRecipeView.xaml Dosyayı Görüntüle

@@ -0,0 +1,222 @@
<Window
x:Class="DosingSystem.View.NewRecipeView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:DosingSystem.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:DosingSystem.ViewModel"
Title="NewRecipeView"
Width="550"
Height="450"
AllowsTransparency="True"
Background="{x:Null}"
Topmost="True"
WindowStartupLocation="CenterScreen"
WindowStyle="None"
mc:Ignorable="d">

<Window.DataContext>
<vm:NewRecipeViewModel />
</Window.DataContext>

<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/GenricStyle.xaml" />
<ResourceDictionary Source="/BPASmartClient.CustomResource;component/Themes/MyStyle.xaml" />

<ResourceDictionary>
<!--#region ListBox样式-->
<Style x:Key="ListBoxItemStyle1" TargetType="{x:Type ListBoxItem}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="BorderBrush" Value="{x:Null}" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FontSize" Value="20" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="border" CornerRadius="8">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--#endregion-->
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>

<Border Name="br" BorderThickness="1">
<Border.Background>
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/bg.png" />
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="5" />
<RowDefinition />
</Grid.RowDefinitions>

<!--<Button
Name="btClose"
Margin="0,0,5,0"
Padding="10,5"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Background="Transparent"
BorderThickness="0"
Content="X"
FontSize="18"
Foreground="White" />

<Border BorderBrush="#88DDDDDD" BorderThickness="0,0,0,1" />-->

<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
<RowDefinition />
</Grid.RowDefinitions>

<TextBlock
Margin="10,0,0,0"
Background="Transparent"
FontSize="20"
Foreground="#FF2AB2E7"
Text="请输入配方名称:" />

<TextBlock
Margin="0,0,10,0"
HorizontalAlignment="Right"
Background="Transparent"
FontSize="16"
Foreground="Red"
Text="{Binding ErrorInfo}" />

<StackPanel
Grid.Row="1"
Margin="10,0,0,0"
Orientation="Horizontal">

<TextBox
Grid.Column="1"
Width="200"
Height="30"
Margin="0,0,7,0"
FontSize="16"
Text="{Binding RecipeName}" />

<Button
Width="148"
Height="30"
Margin="0,0,7,0"
Command="{Binding AddCommand}"
Content="添加原料" />

<Button
Width="80"
Height="30"
Command="{Binding SaveCommand}"
Content="确认" />

<Button
Name="btClose"
Width="80"
Height="30"
Margin="7,0,0,0"
Content="取消" />

</StackPanel>

<ScrollViewer Grid.Row="2" Margin="5">
<ItemsControl ItemsSource="{Binding RawMaterials}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton GroupName="all">
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">
<Grid Name="gr" Height="40">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>

<ComboBox
Name="cb"
Grid.Column="0"
Margin="3,1"
VerticalAlignment="Center"
BorderBrush="#FF074B92"
BorderThickness="1"
FontFamily="楷体"
FontSize="20"
Foreground="#FF2AB2E7"
IsEditable="False"
ItemsSource="{Binding DataContext.RawMaterialNames, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
SelectedIndex="0"
Style="{StaticResource ComboBoxStyle}"
Text="{Binding RawMaterialName}" />

<!--<TextBox
Name="cb"
Grid.Column="0"
Margin="3,1"
VerticalAlignment="Center"
BorderBrush="#FF074B92"
BorderThickness="1"
FontFamily="楷体"
FontSize="20"
Foreground="#FF2AB2E7"
Text="{Binding RawMaterialName}" />-->
<StackPanel
Grid.Column="1"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBox
Name="tb"
Grid.Column="1"
Width="150"
Height="29"
Margin="3,1"
VerticalAlignment="Center"
FontSize="20"
Text="{Binding RawMaterialWeight}" />

<TextBlock
Grid.Column="1"
Margin="0,0,8,4"
HorizontalAlignment="Right"
VerticalAlignment="Center"
Text="mg" />

</StackPanel>

<Button
Grid.Column="2"
Margin="10,0,10,0"
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RawMaterialId}"
Content="删除" />

</Grid>


</ControlTemplate>
</RadioButton.Template>
</RadioButton>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>

</Grid>

</Grid>
</Border>
</Window>

+ 32
- 0
DosingSystem/View/NewRecipeView.xaml.cs Dosyayı Görüntüle

@@ -0,0 +1,32 @@
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 DosingSystem.View
{
/// <summary>
/// NewRecipeView.xaml 的交互逻辑
/// </summary>
public partial class NewRecipeView : Window
{
public NewRecipeView()
{
InitializeComponent();
this.btClose.Click += (o, e) => { this.Close(); };
this.br.MouseLeftButtonDown += (o, e) => { if (e.LeftButton == MouseButtonState.Pressed) this.DragMove(); };
ActionManage.GetInstance.CancelRegister("CloseNewRecipeView");
ActionManage.GetInstance.Register(new Action(() => { this.Close(); }), "CloseNewRecipeView");
}
}
}

+ 171
- 10
DosingSystem/View/RecipeControlView.xaml Dosyayı Görüntüle

@@ -2,26 +2,187 @@
x:Class="DosingSystem.View.RecipeControlView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:control="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:pry="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:vm="clr-namespace:DosingSystem.ViewModel"
xmlns:local="clr-namespace:DosingSystem.View"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pry="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource"
xmlns:vm="clr-namespace:DosingSystem.ViewModel"
d:DesignHeight="450"
d:DesignWidth="800"
mc:Ignorable="d">

<UserControl.DataContext>
<vm:RecipeControlViewModel/>
<vm:RecipeControlViewModel />
</UserControl.DataContext>

<UserControl.Resources>
<Style x:Key="UserItemContainerStyle" TargetType="ListBoxItem">
<Style.Resources>
<!-- SelectedItem with focus -->
<SolidColorBrush
x:Key="{x:Static SystemColors.HighlightBrushKey}"
Opacity=".4"
Color="White" />
<!-- SelectedItem without focus -->
<SolidColorBrush
x:Key="{x:Static SystemColors.ControlBrushKey}"
Opacity=".4"
Color="White" />
</Style.Resources>
<!-- 设置触发器 -->
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="White" />
</Trigger>
<Trigger Property="IsFocused" Value="true">
<Setter Property="Background" Value="White" />
<Setter Property="Foreground" Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</UserControl.Resources>

<Grid>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="40"
Foreground="Wheat"
Text="配方控制" />

<ScrollViewer>
<ItemsControl ItemsSource="{Binding Recipes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Height="150" VerticalAlignment="Top">
<Border
Name="ShadowElement"
Height="150"
VerticalAlignment="Top"
BorderBrush="#00BEFA"
BorderThickness="2"
ClipToBounds="True"
CornerRadius="8">
<Border.Effect>
<DropShadowEffect
BlurRadius="18"
ShadowDepth="0"
Color="#00BEFA" />
</Border.Effect>
</Border>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>

<Grid Margin="20,0,0,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
FontSize="40"
Foreground="White"
Text="{Binding RecipeName}" />
<Button
Grid.Row="1"
Width="80"
Height="30"
HorizontalAlignment="Left"
Command="{Binding DataContext.StartCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RecipeName}"
Content="配方下发"
IsEnabled="{Binding IsEnable}" />
</Grid>

<ListView
Grid.Column="1"
Margin="10"
Background="Transparent"
BorderBrush="#00BEFA"
BorderThickness="2,0,2,0"
ItemsSource="{Binding RawMaterials}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid
HorizontalAlignment="Left"
VerticalAlignment="Top"
Columns="4" />
</ItemsPanelTemplate>
</ListView.ItemsPanel>

<ListView.ItemTemplate>
<DataTemplate>
<StackPanel
Grid.Column="1"
Height="20"
Margin="20,0,0,0"
VerticalAlignment="Top"
Orientation="Horizontal">
<Ellipse
Width="{Binding ElementName=n, Path=ActualHeight}"
Margin="0,0,5,0"
Fill="{Binding RecipeStatus, Converter={StaticResource StatusConverter}}" />
<TextBlock
Name="n"
FontSize="16"
Foreground="White"
Text="{Binding RawMaterialName}" />

</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

<StackPanel
Grid.Column="2"
Margin="5,0"
VerticalAlignment="Center">
<StackPanel Margin="0,0,0,5" Orientation="Horizontal">
<Ellipse
Width="{Binding ElementName=tb, Path=ActualHeight}"
Margin="0,0,5,0"
Fill="Green" />
<TextBlock
Name="tb"
Foreground="#ddd"
Text="准备就绪" />
</StackPanel>
<StackPanel Margin="0,0,0,5" Orientation="Horizontal">
<Ellipse
Width="{Binding ElementName=tb, Path=ActualHeight}"
Margin="0,0,5,0"
Fill="Yellow" />
<TextBlock
Name="tb1"
Foreground="#ddd"
Text="等待接料" />
</StackPanel>
<StackPanel Margin="0,0,0,5" Orientation="Horizontal">
<Ellipse
Width="{Binding ElementName=tb, Path=ActualHeight}"
Margin="0,0,5,0"
Fill="Aqua" />
<TextBlock
Name="tb2"
Foreground="#ddd"
Text="接料完成" />
</StackPanel>
<StackPanel Margin="0,0,0,5" Orientation="Horizontal">
<Ellipse
Width="{Binding ElementName=tb, Path=ActualHeight}"
Margin="0,0,5,0"
Fill="Red" />
<TextBlock
Name="tb3"
Foreground="#ddd"
Text="设备异常" />
</StackPanel>
</StackPanel>
</Grid>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>

+ 225
- 6
DosingSystem/View/RecipeSettingsView.xaml Dosyayı Görüntüle

@@ -12,16 +12,235 @@
d:DesignWidth="800"
mc:Ignorable="d">

<UserControl.Resources>
<SolidColorBrush x:Key="BorderSolid" Color="#5523CACA" />
<SolidColorBrush x:Key="FontColor" Color="#FF2AB2E7" />
<SolidColorBrush x:Key="TitleFontColor" Color="#ddd" />
<SolidColorBrush x:Key="CursorColor" Color="Aqua" />
<SolidColorBrush x:Key="TitleBorderColor" Color="#FF2AB2E7" />
<SolidColorBrush x:Key="TextBlockForeground" Color="#9934F7F7" />

<Style x:Key="TextBlockStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="楷体" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Background" Value="Transparent" />
<!--<Setter Property="Foreground" Value="{StaticResource FontColor}" />-->
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>

<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="Aqua" />
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="0" />
</Style>

</UserControl.Resources>

<UserControl.DataContext>
<vm:RecipeSettingsViewModel />
</UserControl.DataContext>

<Grid>
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="40"
Foreground="Wheat"
Text="配方设置" />
<Grid.RowDefinitions>
<RowDefinition Height="50" />
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>

<!--#region 操作按钮-->
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<pry:IcoButton
Grid.Column="3"
Width="140"
Margin="10"
HorizontalAlignment="Left"
Command="{Binding NewRecipe}"
Content="新建配方"
FontSize="16"
Foreground="Aqua"
IcoText="&#xe626;"
Style="{StaticResource NewButtonStyle}" />

<pry:IcoButton
Grid.Column="3"
Width="140"
Margin="10"
HorizontalAlignment="Left"
Command="{Binding SaveRecipe}"
Content="保存配方"
EnableColor="#FFB7B7B7"
FontSize="17"
Foreground="Aqua"
IcoText="&#xe936;"
IsEnabled="True"
Style="{StaticResource NewButtonStyle}" />
</StackPanel>
<!--#endregion-->

<!--#region 表格标题栏设置-->
<!--<Grid Grid.Row="1" Background="#dd2AB2E7">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="序号" />

<Grid Grid.Column="1">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="配方名称" />
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="1,0,1,0" />
</Grid>

<TextBlock
Grid.Column="2"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="编码" />

<Grid Grid.Column="3">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="结束时间" />
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="1,0,1,0" />
</Grid>

<Grid Grid.Column="5">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="制作状态" />
<Border BorderBrush="{StaticResource TitleBorderColor}" BorderThickness="0,0,1,0" />
</Grid>

<TextBlock
Grid.Column="6"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="16"
Foreground="{StaticResource TitleFontColor}"
Text="完成时间" />

</Grid>-->
<!--#endregion-->

<!--#region 表格数据显示-->
<ScrollViewer
Grid.Row="2"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Recipes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton Background="Transparent" GroupName="all">
<RadioButton.Template>
<ControlTemplate TargetType="RadioButton">

<Grid Name="gr" Height="30">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0" />
<ColumnDefinition Width="0.7*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>

<TextBlock
Grid.Column="0"
Foreground="#ff00ccff"
Style="{StaticResource TextBlockStyle}"
Text="{Binding SerialNum}" />

<Grid Grid.Column="1">
<TextBlock
Margin="5,0,0,0"
HorizontalAlignment="Left"
Foreground="#ff00ccff"
Style="{StaticResource TextBlockStyle}"
Text="{Binding RecipeName}" />
</Grid>


<TextBlock
Grid.Column="2"
Foreground="#ff00ccff"
Style="{StaticResource TextBlockStyle}"
Text="{Binding RecipCode}" />

<!--<Grid Grid.Column="3">

<Button
Command="{Binding DataContext.EditCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RecipCode}"
Content="编辑"
Style="{StaticResource buttonStyle}" />
</Grid>-->


<Grid Grid.Column="5">
<Button
Command="{Binding DataContext.DetailsCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RecipCode}"
Content="详情"
Style="{StaticResource buttonStyle}" />
</Grid>

<Grid Grid.Column="6">
<Button
Command="{Binding DataContext.RemoveCommand, RelativeSource={RelativeSource AncestorType=ItemsControl, Mode=FindAncestor}}"
CommandParameter="{Binding RecipCode}"
Content="删除"
Style="{StaticResource buttonStyle}" />
</Grid>

</Grid>

<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="gr" Property="Background" Value="#3300ccff" />
</Trigger>

<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="gr" Property="Background" Value="#3300ccff" />
</Trigger>

</ControlTemplate.Triggers>
</ControlTemplate>
</RadioButton.Template>
</RadioButton>


</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<!--#endregion-->
</Grid>
</UserControl>

+ 71
- 0
DosingSystem/ViewModel/ChangeDeviceNameViewModel.cs Dosyayı Görüntüle

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BPASmartClient.Helper;
using DosingSystem.Model;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;

namespace DosingSystem.ViewModel
{
public class ChangeDeviceNameViewModel : ObservableObject
{
public ChangeDeviceNameViewModel()
{
ActionManage.GetInstance.Register(new Action<object>((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<LocaPar>.Data.Recipes.Count; i++)
{
for (int m = 0; m < Json<LocaPar>.Data.Recipes.ElementAt(i).RawMaterials.Count; m++)
{
Json<LocaPar>.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;

}
}

+ 11
- 3
DosingSystem/ViewModel/DeviceListViewModel.cs Dosyayı Görüntüle

@@ -9,6 +9,7 @@ using System.Collections.ObjectModel;
using System.Windows;
using BPASmartClient.Helper;
using Microsoft.Toolkit.Mvvm.Input;
using DosingSystem.View;

namespace DosingSystem.ViewModel
{
@@ -16,12 +17,19 @@ namespace DosingSystem.ViewModel
{
public DeviceListViewModel()
{
for (int i = 0; i < 10; i++)
ChangeNameCommand = new RelayCommand<object>((o) =>
{
devices.Add(new Devices() { IpAddress = $"192.168.1.{i + 10}", DeviceName = $"Device_{i}" });
}
if (o != null && o is string str)
{
ChangeDeviceNameView cdn = new ChangeDeviceNameView();
ActionManage.GetInstance.Send("ChangeDeviceNameViewOpen", str);
cdn.ShowDialog();
}
});
}

public RelayCommand<object> ChangeNameCommand { get; set; }

public static ObservableCollection<Devices> devices { get; set; } = new ObservableCollection<Devices>();
}



+ 3
- 1
DosingSystem/ViewModel/MainViewModel.cs Dosyayı Görüntüle

@@ -38,6 +38,7 @@ namespace DosingSystem.ViewModel

public MainViewModel()
{
Json<LocaPar>.Read();
TogglePag = new RelayCommand<object>(DoNavChanged);
Login = new RelayCommand(() => { DoNavChanged("AdminstratorsView.用户登录"); UserManagement = false; });
PasswordChange = new RelayCommand(() =>
@@ -53,8 +54,9 @@ namespace DosingSystem.ViewModel
Config.GetInstance.Init();
LoginRegister();
MenuInit();
permission = Permission.观察员;
permission = Permission.管理员;
if (Menus.Count > 0) DoNavChanged(Menus.ElementAt(0).CommandParameter);
DeviceInquire.GetInstance.Init();

}



+ 131
- 0
DosingSystem/ViewModel/NewRecipeViewModel.cs Dosyayı Görüntüle

@@ -0,0 +1,131 @@
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 DosingSystem.Model;

namespace DosingSystem.ViewModel
{
public class NewRecipeViewModel : ObservableObject
{
public NewRecipeViewModel()
{
ActionManage.GetInstance.Register(new Action<object>((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<object>((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;
}

if (RecipCode.Length <= 0)
{
var res = Array.FindIndex(Json<LocaPar>.Data.Recipes.ToArray(), p => p.RecipeName == RecipeName);

if (res >= 0 && res < Json<LocaPar>.Data.Recipes.Count)
{
ErrorInfo = "该配方已存在,请重新输入";
}
else
{
AddRecipes();
}
}
else
{
var res = Array.FindIndex(Json<LocaPar>.Data.Recipes.ToArray(), p => p.RecipCode == RecipCode);
if (res >= 0 && res < Json<LocaPar>.Data.Recipes.Count)
{
Json<LocaPar>.Data.Recipes.ElementAt(res).RecipeName = RecipeName;
Json<LocaPar>.Data.Recipes.ElementAt(res).RawMaterials.Clear();
foreach (var item in RawMaterials)
{
Json<LocaPar>.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<LocaPar>.Data.Recipes.Add(new RecipeModel()
{
SerialNum = Json<LocaPar>.Data.Recipes.Count + 1,
RawMaterials = RawMaterials,
RecipCode = sb.ToString(),
RecipeName = RecipeName,
});
}

static NewRecipeViewModel()
{
RawMaterialNames.Clear();
}

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<object> RemoveCommand { get; set; }

public RelayCommand SaveCommand { get; set; }

public ObservableCollection<RawMaterialModel> RawMaterials { get; set; } = new ObservableCollection<RawMaterialModel>();

public static ObservableCollection<string> RawMaterialNames { get; set; } = new ObservableCollection<string>();
}
}

+ 76
- 0
DosingSystem/ViewModel/RecipeControlViewModel.cs Dosyayı Görüntüle

@@ -9,10 +9,86 @@ using System.Collections.ObjectModel;
using System.Windows;
using BPASmartClient.Helper;
using Microsoft.Toolkit.Mvvm.Input;
using DosingSystem.Model;
using System.Threading;

namespace DosingSystem.ViewModel
{
public class RecipeControlViewModel : ObservableObject
{
ConcurrentQueue<string> devices = new ConcurrentQueue<string>();

public RecipeControlViewModel()
{
Recipes = Json<LocaPar>.Data.Recipes;
StartCommand = new RelayCommand<object>((o) =>
{
if (o != null && o is string deviceName)
{
//Task.Run(new Action(() =>
//{
int index = Array.FindIndex(Recipes.ToArray(), p => p.RecipeName == deviceName);
if (index >= 0 && index < Recipes.Count)
{
Recipes.ElementAt(index).IsEnable = false;
//foreach (var item in Recipes.ElementAt(index).RawMaterials)
//{
// DeviceInquire.GetInstance.GetDevice(item.DeviceIp)?.Start(item.RawMaterialWeight);//启动写入
//}
}
//}));
devices.Enqueue(deviceName);
}
});


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).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();
}
Recipes.ElementAt(i).IsEnable = true;
Recipes.ElementAt(i).Are.Set();
}
}
}
Thread.Sleep(100);
}), "RecipeControlViewModelStatusInquire");

}

public RelayCommand<object> StartCommand { get; set; }
public ObservableCollection<RecipeModel> Recipes { get; set; }
}
}

+ 46
- 0
DosingSystem/ViewModel/RecipeSettingsViewModel.cs Dosyayı Görüntüle

@@ -9,9 +9,55 @@ using System.Collections.ObjectModel;
using System.Windows;
using BPASmartClient.Helper;
using Microsoft.Toolkit.Mvvm.Input;
using DosingSystem.Model;
using DosingSystem.View;

namespace DosingSystem.ViewModel
{
public class RecipeSettingsViewModel : ObservableObject
{
public RecipeSettingsViewModel()
{
//Json<LocaPar>.Read();
Recipes = Json<LocaPar>.Data.Recipes;
NewRecipe = new Action(() =>
{
NewRecipeView nrv = new NewRecipeView();
nrv.ShowDialog();
});
SaveRecipe = new Action(() => { Json<LocaPar>.Save(); });
RemoveCommand = new RelayCommand<object>((o) =>
{
if (o is string str)
{
var res = Json<LocaPar>.Data.Recipes.FirstOrDefault(p => p.RecipCode == str);
if (res != null) Json<LocaPar>.Data.Recipes.Remove(res);
}
});

DetailsCommand = new RelayCommand<object>((o) =>
{
if (o != null && o is string str)
{
ActionManage.GetInstance.CancelRegister("Details");
NewRecipeView nrv = new NewRecipeView();
ActionManage.GetInstance.Send("Details", Json<LocaPar>.Data.Recipes.FirstOrDefault(p => p.RecipCode == str));
nrv.ShowDialog();

}
});
}

public Action NewRecipe { get; set; }

public Action SaveRecipe { get; set; }

public RelayCommand<object> EditCommand { get; set; }

public RelayCommand<object> DetailsCommand { get; set; }

public RelayCommand<object> RemoveCommand { get; set; }

public ObservableCollection<RecipeModel> Recipes { get; set; }
}
}

+ 24
- 1
SmartClient.sln Dosyayı Görüntüle

@@ -96,7 +96,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkT_HQ", "
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DosingSystem", "DosingSystem\DosingSystem.csproj", "{4E0B01AD-CFD0-4BD5-BBE6-AD2A4183B4DB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.MorkTJuicer", "BPASmartClient.MorkTJuicer\BPASmartClient.MorkTJuicer.csproj", "{724087A3-E7E7-4494-B844-414FF5CD1D40}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BPASmartClient.MorkTJuicer", "BPASmartClient.MorkTJuicer\BPASmartClient.MorkTJuicer.csproj", "{724087A3-E7E7-4494-B844-414FF5CD1D40}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BPASmartClient.AGV", "BPASmartClient.AGV\BPASmartClient.AGV.csproj", "{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -892,6 +894,26 @@ Global
{724087A3-E7E7-4494-B844-414FF5CD1D40}.Release|x64.Build.0 = Release|Any CPU
{724087A3-E7E7-4494-B844-414FF5CD1D40}.Release|x86.ActiveCfg = Release|Any CPU
{724087A3-E7E7-4494-B844-414FF5CD1D40}.Release|x86.Build.0 = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|ARM.ActiveCfg = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|ARM.Build.0 = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|ARM64.Build.0 = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|x64.ActiveCfg = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|x64.Build.0 = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|x86.ActiveCfg = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Debug|x86.Build.0 = Debug|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|Any CPU.Build.0 = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|ARM.ActiveCfg = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|ARM.Build.0 = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|ARM64.ActiveCfg = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|ARM64.Build.0 = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|x64.ActiveCfg = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|x64.Build.0 = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|x86.ActiveCfg = Release|Any CPU
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -936,6 +958,7 @@ Global
{00C17D87-A323-4A97-BC21-7039E55614DE} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F}
{4E0B01AD-CFD0-4BD5-BBE6-AD2A4183B4DB} = {8712125E-14CD-4E1B-A1CE-4BDE03805942}
{724087A3-E7E7-4494-B844-414FF5CD1D40} = {9FB27073-61A0-4FE3-94DB-5FDDE062332F}
{507A30E2-246E-4AC9-82F4-BE8FBBC1C5B8} = {3D1D0E04-03FD-480A-8CF8-6E01A2E28625}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9AEC9B81-0222-4DE9-B642-D915C29222AC}


Yükleniyor…
İptal
Kaydet