@@ -129,12 +129,28 @@ | |||
<None Remove="Image\边框效果2.png" /> | |||
<None Remove="Image\退出.png" /> | |||
<None Remove="Image\退出按钮.png" /> | |||
<None Remove="Image\顶部.png" /> | |||
<None Remove="Image\顶部切图\Button_No.png" /> | |||
<None Remove="Image\顶部切图\Button_Select.png" /> | |||
<None Remove="Image\顶部切图\Top_L.png" /> | |||
<None Remove="Image\顶部切图\窗体背景.png" /> | |||
<None Remove="Image\顶部切图\顶部矩形.png" /> | |||
<None Remove="Image\顶部切图\黑菠萝智慧餐饮管理系统.png" /> | |||
<None Remove="Image\顶部矩形.png" /> | |||
<None Remove="Image\顶部线条.png" /> | |||
<None Remove="Image\顶部背景.png" /> | |||
<None Remove="Image\黑菠萝科技.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Resource Include="Image\顶部切图\Button_No.png" /> | |||
<Resource Include="Image\顶部切图\Button_Select.png" /> | |||
<Resource Include="Image\顶部切图\Top_L.png" /> | |||
<Resource Include="Image\顶部切图\窗体背景.png" /> | |||
<Resource Include="Image\顶部切图\顶部矩形.png" /> | |||
<Resource Include="Image\顶部切图\黑菠萝智慧餐饮管理系统.png" /> | |||
</ItemGroup> | |||
<ItemGroup> | |||
<Folder Include="Themes\" /> | |||
</ItemGroup> | |||
@@ -264,6 +280,7 @@ | |||
<Resource Include="Image\边框效果2.png" /> | |||
<Resource Include="Image\退出.png" /> | |||
<Resource Include="Image\退出按钮.png" /> | |||
<Resource Include="Image\顶部.png" /> | |||
<Resource Include="Image\顶部矩形.png" /> | |||
<Resource Include="Image\顶部线条.png" /> | |||
<Resource Include="Image\顶部背景.png" /> | |||
@@ -451,7 +451,7 @@ | |||
<Style TargetType="{x:Type DataGridColumnHeader}"> | |||
<Setter Property="HorizontalContentAlignment" Value="Center"/> | |||
<Setter Property="VerticalContentAlignment" Value="Center"/> | |||
<Setter Property="Height" Value="40"/> | |||
<Setter Property="Height" Value="30"/> | |||
<Setter Property="Background" > | |||
<Setter.Value> | |||
<ImageBrush Opacity="0.2" ImageSource="/BPASmartClient.CustomResource;component/Image/表格标题背景2.png"></ImageBrush> | |||
@@ -459,7 +459,7 @@ | |||
</Setter> | |||
<Setter Property="BorderThickness" Value="0"></Setter> | |||
<Setter Property="Foreground" Value="#00c2f4"></Setter> | |||
<Setter Property="FontSize" Value="20"></Setter> | |||
<Setter Property="FontSize" Value="14"></Setter> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}"> | |||
@@ -892,10 +892,11 @@ | |||
<Setter Property="Padding" Value="6,1,6,1"/> | |||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/> | |||
<Setter Property="VerticalContentAlignment" Value="Stretch"/> | |||
<Setter Property="Cursor" Value="Hand"></Setter> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type TabItem}"> | |||
<Border x:Name="Bd" BorderThickness="1" Padding="{TemplateBinding Padding}" Height="24" Margin="2" CornerRadius="2"> | |||
<Border x:Name="Bd" BorderThickness="1" Padding="{TemplateBinding Padding}" Height="35" Margin="5" CornerRadius="2"> | |||
<ContentPresenter x:Name="Content" Cursor="Hand" ContentSource="Header" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> | |||
</Border> | |||
<ControlTemplate.Triggers> | |||
@@ -908,13 +909,21 @@ | |||
</Setter> | |||
</Trigger> | |||
<Trigger Property="IsSelected" Value="False"> | |||
<Setter Property="Foreground" Value="#134278"/> | |||
<Setter Property="Foreground" Value="White"/> | |||
<Setter Property="Background" TargetName="Bd"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/窗体样式/Tab/Tab4_No.png" /> | |||
</Setter.Value> | |||
</Setter> | |||
</Trigger> | |||
<Trigger Property="IsMouseOver" Value="True"> | |||
<Setter Property="Foreground" Value="#8f723c"/> | |||
<Setter Property="Background" TargetName="Bd"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/窗体样式/Tab/Tab4_Select.png" /> | |||
</Setter.Value> | |||
</Setter> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
@@ -1697,7 +1706,7 @@ | |||
<Setter.Value> | |||
<ControlTemplate TargetType="{x:Type CheckBox}"> | |||
<StackPanel Background="Transparent" SnapsToDevicePixels="True" Orientation="Horizontal"> | |||
<Image x:Name="image1" Source="Image/Cb_HalfChecked.png" Width="12" Height="14"></Image> | |||
<Image x:Name="image1" Source="/BPASmartClient.CustomResource;component/Image/Cb_HalfChecked.png" Width="12" Height="14"></Image> | |||
<ContentPresenter Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> | |||
</StackPanel> | |||
@@ -1722,10 +1731,10 @@ | |||
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> | |||
</Trigger> | |||
<Trigger Property="IsChecked" Value="true"> | |||
<Setter TargetName="image1" Property="Source" Value="Image/Cb_Checked.png"/> | |||
<Setter TargetName="image1" Property="Source" Value="/BPASmartClient.CustomResource;component/Image/Cb_Checked.png"/> | |||
</Trigger> | |||
<Trigger Property="IsChecked" Value="{x:Null}"> | |||
<Setter TargetName="image1" Property="Source" Value="Image/Cb_HalfChecked.png"/> | |||
<Setter TargetName="image1" Property="Source" Value="/BPASmartClient.CustomResource;component/Image/Cb_HalfChecked.png"/> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
@@ -4,24 +4,10 @@ | |||
> | |||
<Style x:Key="bordertopTitle" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Height" Value="100"></Setter> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/topTitle.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="imagetop" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/topTitle.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<ImageBrush x:Key="imageBJ" ImageSource="/BPASmartClient.CustomResource;component/Image/图层1.png"/> | |||
<ImageBrush x:Key="image1" ImageSource="/BPASmartClient.CustomResource;component/Image/shape.png"/> | |||
@@ -46,7 +32,7 @@ | |||
<Border x:Name="bd1" Visibility="Collapsed" Width="25" Height="13" HorizontalAlignment="Right" Panel.ZIndex="100" VerticalAlignment="Top" Margin="0,-5,-5,0" CornerRadius="3" Background="#33FF0000" > | |||
<TextBlock Text="{Binding ListNum}" Foreground="#FF2AA7D3" HorizontalAlignment="Center"></TextBlock> | |||
</Border> | |||
<Image x:Name="image1" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Source="Image/告警.png" Panel.ZIndex="0" Stretch="UniformToFill" ></Image> | |||
<Image x:Name="image1" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}" Source="/BPASmartClient.CustomResource;component/Image/告警.png" Panel.ZIndex="0" Stretch="UniformToFill" ></Image> | |||
</Grid> | |||
<ControlTemplate.Triggers> | |||
<Trigger Property="IsChecked" Value="true"> | |||
@@ -71,6 +57,47 @@ | |||
<!--#endregion--> | |||
<!--#region Image --> | |||
<Style x:Key="imagetop_L" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="Height" Value="80"></Setter> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="HorizontalAlignment" Value="Left"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部切图/Top_L.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="imagetop_Title" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="Width" Value="250"></Setter> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="HorizontalAlignment" Value="Left"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部切图/黑菠萝智慧餐饮管理系统.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="imagetop_矩形" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="HorizontalAlignment" Value="Left"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部切图/顶部矩形.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="imagetop" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/topTitle.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="imagetop1" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="Source" Value="/BPASmartClient.CustomResource;component/Image/顶部.png"/> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="image营销额" TargetType="Image"> | |||
<Style.Setters> | |||
<Setter Property="VerticalAlignment" Value="Bottom"></Setter> | |||
@@ -167,7 +194,76 @@ | |||
<!--#endregion--> | |||
<!--#region Border--> | |||
<Style x:Key="FromBJ" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部切图/窗体背景.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="button_no" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部切图/Button_No.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="button_select" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部切图/Button_Select.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="bordertopL" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Height" Value="80"></Setter> | |||
<Setter Property="Width" Value="300"></Setter> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="HorizontalAlignment" Value="Left"></Setter> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部切图/Top_L.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="bordertop矩形" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Height" Value="50"></Setter> | |||
<Setter Property="VerticalAlignment" Value="Top"></Setter> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部切图/顶部矩形.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="bordertopTitle" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Height" Value="100"></Setter> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/topTitle.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="border窗体背景1" TargetType="Border"> | |||
<Style.Setters> | |||
@@ -209,7 +305,6 @@ | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="border窗体背景5" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Background"> | |||
@@ -309,6 +404,16 @@ | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="border顶部标题背景" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/顶部.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style x:Key="border竖线" TargetType="Border"> | |||
<Style.Setters> | |||
<Setter Property="Width" Value="1"></Setter> | |||
@@ -573,7 +678,7 @@ | |||
</Style.Setters> | |||
</Style> | |||
<Style TargetType="Button"> | |||
<Style x:Key="CommonBtn_1" TargetType="Button"> | |||
<Style.Setters> | |||
<Setter Property="VerticalContentAlignment" Value="Center"></Setter> | |||
<Setter Property="Cursor" Value="Hand"></Setter> | |||
@@ -610,6 +715,61 @@ | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<Style TargetType="Button"> | |||
<Style.Setters> | |||
<Setter Property="VerticalContentAlignment" Value="Center"></Setter> | |||
<Setter Property="Cursor" Value="Hand"></Setter> | |||
<Setter Property="Foreground" Value="{DynamicResource foreground}"></Setter> | |||
<Setter Property="Width" Value="69"></Setter> | |||
<Setter Property="Height" Value="25"></Setter> | |||
<Setter Property="Template"> | |||
<Setter.Value> | |||
<ControlTemplate TargetType="Button"> | |||
<!--<ControlTemplate.Resources> | |||
<Storyboard x:Key="OnMouseEnter1"> | |||
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)" Storyboard.TargetName="BD"> | |||
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="#FF139DDB"/> | |||
</ColorAnimationUsingKeyFrames> | |||
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)" Storyboard.TargetName="BD"> | |||
<EasingColorKeyFrame KeyTime="0:0:0.1" Value="#FF135EC2"/> | |||
</ColorAnimationUsingKeyFrames> | |||
</Storyboard> | |||
</ControlTemplate.Resources>--> | |||
<Border x:Name="BD"> | |||
<TextBlock x:Name="textBlock" FontSize="12" Text="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Foreground="{DynamicResource foreground}" /> | |||
</Border> | |||
<ControlTemplate.Triggers> | |||
<Trigger Property="IsMouseOver" Value="true"> | |||
<Setter TargetName="BD" Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/buttonOn.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
<Setter TargetName="textBlock" Property="Foreground" Value="White" /> | |||
</Trigger> | |||
<Trigger Property="IsMouseOver" Value="False"> | |||
<Setter TargetName="BD" Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/buttonOff.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
<Setter TargetName="textBlock" Property="Foreground" Value="#FFD7DCE0" /> | |||
</Trigger> | |||
<Trigger Property="IsEnabled" Value="False"> | |||
<Setter TargetName="BD" Property="Background"> | |||
<Setter.Value> | |||
<ImageBrush ImageSource="/BPASmartClient.CustomResource;component/Image/buttonOn.png"/> | |||
</Setter.Value> | |||
</Setter> | |||
<Setter TargetName="textBlock" Property="Foreground" Value="#3afdff" /> | |||
</Trigger> | |||
</ControlTemplate.Triggers> | |||
</ControlTemplate> | |||
</Setter.Value> | |||
</Setter> | |||
</Style.Setters> | |||
</Style> | |||
<!--#endregion--> | |||
<!--#region TextBox--> | |||
@@ -11,31 +11,34 @@ namespace BPASmartClient.MORKSM.BK.PLC | |||
{ | |||
public class MorksMachine : BasePeripheral | |||
{ | |||
ModbusTcp modbusTcp => modbusTcp ?? new ModbusTcp(); | |||
ModbusTcp modbusTcp = new ModbusTcp(); | |||
public string IpAddress { get; set; } | |||
public int Port { get; set; } | |||
public override void Init() | |||
{ | |||
//读取布尔数据 | |||
//读取数据 | |||
EventBus.EventBus.GetInstance().Subscribe<ReadModel>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) | |||
{ | |||
if (@event == null) return; | |||
var par = @event as ReadModel; | |||
ushort address = (ushort)modbusTcp.GetAddress(par?.Address); | |||
object readData = new object(); | |||
if (par.Address.ToUpper().Contains("M")) | |||
{ | |||
modbusTcp.Read(address, CommandType.Coils, par.Length); | |||
//modbusTcp.Read(address, CommandType.Coils, par.Length); | |||
modbusTcp.Readbool(address, par.Length, new Action<bool[]>((s) => { readData = s; })); | |||
} | |||
else if (par.Address.ToUpper().Contains("VW")) | |||
{ | |||
modbusTcp.Read(address, CommandType.HoldingRegisters, par.Length); | |||
readData = modbusTcp.Read(address, CommandType.HoldingRegisters, par.Length); | |||
} | |||
callBack?.Invoke(readData); | |||
//callBack = new EventCallBackHandle(readData); | |||
}); | |||
//写入布尔数据 | |||
//写入数据 | |||
EventBus.EventBus.GetInstance().Subscribe<WriteModel>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) | |||
{ | |||
if (@event == null) return; | |||
@@ -51,12 +54,16 @@ namespace BPASmartClient.MORKSM.BK.PLC | |||
} | |||
}); | |||
modbusTcp.ModbusTcpConnect(IpAddress, Port); | |||
////批量读取数据 | |||
//EventBus.EventBus.GetInstance().Subscribe<>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) | |||
//{ | |||
//}); | |||
} | |||
public override void Start() | |||
{ | |||
modbusTcp.ModbusTcpConnect(IpAddress, Port); | |||
} | |||
public override void Stop() | |||
@@ -6,35 +6,605 @@ using BPASmartClient.EventBus; | |||
using BPASmartClient.Model; | |||
using BPASmartClient.Peripheral; | |||
using static BPASmartClient.EventBus.EventBus; | |||
using BPASmartClient.Helper; | |||
using System.Threading; | |||
using BPASmartClient.Message; | |||
using BPA.Message; | |||
using System.Linq; | |||
using BPASmartClient.Model.PLC; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.MorkS | |||
{ | |||
public class Control : IDevice | |||
public class Control : BaseDevice | |||
{ | |||
public string DeviceId { get; set; } | |||
public string Name { get; set; } | |||
public override DeviceClientType DeviceType => DeviceClientType.MORKS; | |||
GVL_MORKS mORKS = new GVL_MORKS(); | |||
/// <summary> | |||
/// 订单物料信息 | |||
/// </summary> | |||
public OrderMaterialDelivery orderMaterialDelivery { get; set; } = new OrderMaterialDelivery(); | |||
/// <summary> | |||
/// 配方数据信息 | |||
/// </summary> | |||
public RecipeBoms recipeBoms { get; set; } = new RecipeBoms(); | |||
int OrderCount; | |||
bool Initing; | |||
public override void StartMain() | |||
{ | |||
} | |||
public override void Stop() | |||
{ | |||
} | |||
private void OrderChange(string subid, ORDER_STATUS oRDER_STATUS) | |||
{ | |||
//EventBus.EventBus.GetInstance().Publish(new); | |||
} | |||
private void ReadData(string address, ushort len = 1, Action<bool[]> action = null) | |||
{ | |||
EventBus.EventBus.GetInstance().Publish(new ReadModel() { Address = address, Length = len }, (o) => | |||
{ | |||
if (o != null && o.Length > 0 && o[0] is bool[] bools) | |||
{ | |||
action(bools); | |||
} | |||
}); | |||
} | |||
private void ReadData() | |||
{ | |||
ThreadManage.GetInstance().StartLong(new Action(() => | |||
{ | |||
ReadData("M0.3", 3, new Action<bool[]>((bools) => | |||
{ | |||
mORKS.RobotTakeNoodle = bools[0]; | |||
mORKS.RobotOutMeal = bools[1]; | |||
mORKS.MoveTurntable = bools[2]; | |||
})); | |||
ReadData("M100.0", 16, new Action<bool[]>((bools) => | |||
{ | |||
mORKS.InitComplete = bools[0]; | |||
mORKS.TakeBowlIdle = bools[1]; | |||
mORKS.TemperatureReached = bools[2]; | |||
mORKS.AllowFallNoodle = bools[3]; | |||
mORKS.RbTakeNoodleComplete = bools[4]; | |||
mORKS.RbFallNoodleComplete = bools[5]; | |||
mORKS.RbOutMealComplete = bools[6]; | |||
mORKS.RobotIdle = bools[7]; | |||
mORKS.TakeMealDetect = bools[8]; | |||
mORKS.MissingBowl = bools[9]; | |||
Initing = bools[10]; | |||
mORKS.TurntableLowerLimit = bools[11]; | |||
mORKS.MissingBowlSignal2 = bools[12]; | |||
mORKS.TurntableUpLimit = bools[13]; | |||
mORKS.FeedComplete = bools[14]; | |||
mORKS.TurntableMoveInPlace = bools[15]; | |||
})); | |||
ReadData("M235.0", 1, new Action<bool[]>((bools) => { mORKS.Error = bools[0]; })); | |||
//var errorStatus = ModbusTcpHelper.GetInstance.Read((ushort)ModbusTcpHelper.GetInstance.GetBoolAddress("M235.0"), ReadType.Coils, 1); | |||
//if (errorStatus != null && errorStatus is bool error) mORKS.Error = error; | |||
ReadData("M102.0", 7, new Action<bool[]>((bools) => | |||
{ | |||
for (int i = 0; i < 6; i++) | |||
{ | |||
mORKS.NoodleCookerStatus[i] = bools[i]; | |||
} | |||
mORKS.Feeding = bools[6]; | |||
})); | |||
ReadData("M103.0", 6, new Action<bool[]>((bools) => | |||
{ | |||
for (int i = 0; i < 6; i++) | |||
{ | |||
mORKS.CookNoodlesComplete[i] = bools[i]; | |||
} | |||
})); | |||
ReadData("M550.0", 20, new Action<bool[]>((bools) => | |||
{ | |||
//alarm.MachineLeftLowTemperature = bools[0]; | |||
//alarm.MachineRightLowTemperature = bools[1]; | |||
//alarm.Supply1_LossBowl = bools[2]; | |||
//alarm.Supply2_LossBowl = bools[3]; | |||
//alarm.Supply1_ErrorOutBowl = bools[4]; | |||
//alarm.Supply2_ErrorOutBowl = bools[5]; | |||
//alarm.PushBowlCylinderError = bools[6]; | |||
//alarm.NoodleMacCommunicateError = bools[7]; | |||
//alarm.DosingMacCommunicateError = bools[8]; | |||
//alarm.RobotMacCommunicateError = bools[9]; | |||
//alarm.RobotInitError = bools[11]; | |||
//alarm.RobotUrgentStop = bools[12]; | |||
//alarm.RobotNotInRemoteMode = bools[13]; | |||
//alarm.RobotNotInReady = bools[14]; | |||
//alarm.RobotSelfInException = bools[15]; | |||
})); | |||
EventBus.EventBus.GetInstance().Publish(new ReadModel() { Address = "VW372", Length = 1 }, (o) => | |||
{ | |||
if (o != null && o.Length > 0 && o[0] is ushort value) | |||
{ | |||
mORKS.TurntableFeedbackloc = value; | |||
} | |||
}); | |||
//var ResLoc = ModbusTcpHelper.GetInstance.Read(286, ReadType.HoldingRegisters); | |||
//if (ResLoc != null) | |||
//{ | |||
// if (ResLoc is ushort loc) | |||
// { | |||
// mORKS.TurntableFeedbackloc = loc; | |||
// } | |||
//} | |||
Thread.Sleep(500); | |||
}), "ReadPLCData"); | |||
} | |||
/// <summary> | |||
/// 数据解析 | |||
/// </summary> | |||
public void DataParse<T>(T order) | |||
{ | |||
OrderCount++; | |||
MessageLog.GetInstance.Show($"接收到{OrderCount}次订单"); | |||
if (order is MorkOrderPush morkOrderPush) | |||
{ | |||
foreach (var item in morkOrderPush.GoodBatchings) | |||
{ | |||
//var res = Json<BatchingInfoPar>.Data.orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); | |||
var res = orderMaterialDelivery?.BatchingInfo?.FirstOrDefault(p => p.BatchingId == item.BatchingId); | |||
if (res != null) | |||
{ | |||
if (ushort.TryParse(res.BatchingLoc, out ushort loc)) | |||
{ | |||
if (loc >= 1 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.FirstOrDefault(p => p.SuborderId == morkOrderPush.SuborderId) == null) | |||
mORKS.RBTakeNoodleTask.Enqueue(new OrderLocInfo() { Loc = ushort.Parse(res.BatchingLoc), SuborderId = morkOrderPush.SuborderId, BatchingId = res.BatchingId }); | |||
} | |||
else if (loc >= 10 && loc <= 11) | |||
{ | |||
int index = 0; | |||
if (recipeBoms != null) | |||
{ | |||
index = Array.FindIndex(recipeBoms.RecipeIds?.ToArray(), p => p.RecipeId == morkOrderPush.RecipeId); | |||
index++; | |||
} | |||
if (mORKS.TakeBowlTask.FirstOrDefault(p => p.SuborderId == morkOrderPush.SuborderId) == null) | |||
mORKS.TakeBowlTask.Enqueue(new OrderLocInfo() | |||
{ | |||
Loc = ushort.Parse(res.BatchingLoc), | |||
SuborderId = morkOrderPush.SuborderId, | |||
RecipeNumber = (index >= 1 && index <= 10) ? (ushort)index : (ushort)0 | |||
}); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
public void Main() | |||
{ | |||
ThreadManage.GetInstance().StartLong(new Action(() => | |||
{ | |||
mORKS.AllowRun = mORKS.InitComplete; | |||
//GeneralConfig.Healthy = mORKS.Error && mORKS.InitComplete && !GeneralConfig.EnableLocalSimOrder; | |||
TakeBowlTask(); | |||
TakeNoodleTask(); | |||
OutNoodleTask(); | |||
SingleDetect(); | |||
TurntableControl(); | |||
Thread.Sleep(100); | |||
}), "MainTask"); | |||
} | |||
public DeviceClientType DeviceType { get; } | |||
public DeviceStatus Status { get; set; } | |||
/// <summary> | |||
/// 取碗控制 | |||
/// </summary> | |||
private void TakeBowlTask() | |||
{ | |||
if (mORKS.AllowRun && mORKS.TakeBowlTask.Count > 0 && !mORKS.TakeBowlIdle && !mORKS.TakeBowlInterlock) | |||
{ | |||
if (mORKS.TakeBowlTask.TryDequeue(out OrderLocInfo orderLocInfo)) | |||
{ | |||
mORKS.TakeBowlId = orderLocInfo.SuborderId; | |||
TakeBowlControl(orderLocInfo.Loc); | |||
SetRecipeNumber(orderLocInfo.RecipeNumber); | |||
OrderChange(mORKS.TakeBowlId, ORDER_STATUS.COOKING); | |||
MessageLog.GetInstance.Show($"订单【{ mORKS.TakeBowlId}】执行取碗控制,位置:[{orderLocInfo.Loc}]"); | |||
} | |||
mORKS.TakeBowlInterlock = true; | |||
} | |||
} | |||
public void Initliaze(List<IPeripheral> peripherals) | |||
/// <summary> | |||
/// 转台控制 | |||
/// </summary> | |||
private void TurntableControl() | |||
{ | |||
peripherals.ForEach(item => { item.Init(); }); | |||
//EventBus.EventBus.GetInstance().Subscribe<Demo_MakeCoffeeEvent>(DeviceId, delegate (IEvent @event, EventCallBackHandle callBack) | |||
//if (GeneralConfig.EnableLocalSimOrder) | |||
//{ | |||
// //不做轮询,直接取面,模拟订单使用 | |||
// if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0) | |||
// { | |||
// if (mORKS.TurntableLowerLimit) | |||
// { | |||
// TurntableStart(mORKS.RBTakeNoodleTask.ElementAt(0).Loc); | |||
// mORKS.TurntableLocLists.Clear(); | |||
// mORKS.AllowTakeNoodle = true; | |||
// MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.RBTakeNoodleTask.ElementAt(0).Loc}】号位置取面"); | |||
// } | |||
// } | |||
//} | |||
//else | |||
{ | |||
//正常轮询 | |||
if (mORKS.TurntableMoveInPlace && !mORKS.Feeding && mORKS.InitComplete && !mORKS.AllowTakeNoodle && mORKS.RBTakeNoodleTask.Count > 0) | |||
{ | |||
//var result = Json<BatchingInfoPar>.Data.orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList(); | |||
var result = orderMaterialDelivery.BatchingInfo.Where(p => p.BatchingId == mORKS.RBTakeNoodleTask.ElementAt(0).BatchingId).ToList(); | |||
if (result != null) | |||
{ | |||
var res = result.FirstOrDefault(P => P.BatchingLoc == mORKS.TurntableFeedbackloc.ToString()); | |||
if (mORKS.TurntableLowerLimit && res != null) | |||
{ | |||
//if (mORKS.RBTakeNoodleTask.ElementAt(0).Loc != mORKS.TurntableFeedbackloc) | |||
TurntableStart(mORKS.TurntableFeedbackloc); | |||
mORKS.TurntableLocLists.Clear(); | |||
mORKS.AllowTakeNoodle = true; | |||
MessageLog.GetInstance.Show($"控制机器人去转台【{mORKS.TurntableFeedbackloc}】号位置取面"); | |||
} | |||
else | |||
{ | |||
if (!mORKS.TurntableInterlock) | |||
{ | |||
foreach (var item in result) | |||
{ | |||
if (ushort.TryParse(item.BatchingLoc, out ushort loc)) | |||
{ | |||
if (mORKS.TurntableFeedbackloc != loc && !mORKS.TurntableLocLists.Contains(loc)) | |||
{ | |||
TurntableStart(loc); | |||
MessageLog.GetInstance.Show($"没有物料检测的启动转台控制,转台位置:[{loc}]"); | |||
break; | |||
} | |||
else if (mORKS.TurntableFeedbackloc == loc && !mORKS.TurntableLocLists.Contains(loc)) mORKS.TurntableLocLists.Add(loc); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
else MessageLog.GetInstance.Show("未找到可用的物料信息"); | |||
} | |||
} | |||
//转台到位检测 | |||
if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace && mORKS.CurrentLoc == mORKS.TurntableFeedbackloc)) | |||
{ | |||
mORKS.CurrentLoc = 0; | |||
mORKS.TurntableInterlock = false; | |||
MessageLog.GetInstance.Show("转台到位检测"); | |||
} | |||
//补料完成检测 | |||
if (RTrig.GetInstance("FeedComplete").Start(mORKS.FeedComplete)) | |||
{ | |||
if (!mORKS.AllowTakeNoodle && mORKS.TurntableLocLists.Count > 0) | |||
{ | |||
mORKS.TurntableLocLists.Clear(); | |||
mORKS.TurntableInterlock = false; | |||
MessageLog.GetInstance.Show("补料完成检测"); | |||
} | |||
} | |||
//}); | |||
} | |||
public void StartMain() | |||
/// <summary> | |||
/// 取面任务 | |||
/// </summary> | |||
private void TakeNoodleTask() | |||
{ | |||
//取面控制 | |||
if (mORKS.AllowRun && mORKS.RobotIdle && !mORKS.Feeding && !mORKS.RobotTaskInterlock && mORKS.AllowTakeNoodle && mORKS.TurntableMoveInPlace && !mORKS.TakeNoodleInterlock && !mORKS.OutNoodleing && mORKS.RBTakeNoodleTask.Count > 0) | |||
{ | |||
int loc = Array.FindIndex(mORKS.NoodleCookerStatus, p => p == false);//查找煮面炉空闲位置 | |||
if (loc >= 0 && loc <= 5) | |||
{ | |||
if (mORKS.RBTakeNoodleTask.TryDequeue(out OrderLocInfo orderLocInfo)) | |||
{ | |||
mORKS.CookNodelId[loc] = orderLocInfo.SuborderId; | |||
SetFallNoodleLoc((ushort)(loc + 1)); | |||
//机器人开始取面 | |||
RobotTakeNoodle(); | |||
OrderChange(orderLocInfo.SuborderId, ORDER_STATUS.COOKING); | |||
MessageLog.GetInstance.Show($"订单【{orderLocInfo.SuborderId}】,机器人倒面至【{loc + 1}】号煮面栏"); | |||
//写入煮面时间 | |||
//List<ushort> values = new List<ushort>(); | |||
//values.Add(Json<KeepDataBase>.Data.parSets.ElementAt(loc).Minute); | |||
//values.Add(Json<KeepDataBase>.Data.parSets.ElementAt(loc).Second); | |||
//ModbusTcpHelper.GetInstance.Write((ushort)ModbusTcpHelper.GetInstance.GetWordAddress($"VW{116 + (loc * 6)}"), WriteType.HoldingRegisters, values.ToArray()); | |||
mORKS.TakeNoodleInterlock = true; | |||
} | |||
} | |||
} | |||
} | |||
public void Stop() | |||
/// <summary> | |||
/// 出餐控制 | |||
/// </summary> | |||
private void OutNoodleTask() | |||
{ | |||
if (mORKS.AllowFallNoodle && mORKS.RobotTaskInterlock && !mORKS.TakeNoodleInterlock && mORKS.RobotIdle && !mORKS.TakeMealDetect) | |||
{ | |||
int loc = Array.FindIndex(mORKS.CookNodelId, p => p == mORKS.IngredientsCompleteId && p.Length > 0); | |||
if (loc >= 0 && loc <= 5) | |||
{ | |||
if (mORKS.CookNoodlesComplete[loc]) | |||
{ | |||
SetTakeNoodleLoc((ushort)(loc + 1)); | |||
RobotOutMeal(); | |||
CookNoodleStatusReset((ushort)(loc + 1)); | |||
ResetAllowFallNoodle(); | |||
mORKS.OutMealId = mORKS.IngredientsCompleteId; | |||
mORKS.IngredientsCompleteId = string.Empty; | |||
mORKS.CookNodelId[loc] = string.Empty; | |||
MessageLog.GetInstance.Show($"{loc + 1}号位置出餐控制"); | |||
mORKS.OutNoodleing = true; | |||
} | |||
} | |||
} | |||
} | |||
/// <summary> | |||
/// 信号检测 | |||
/// </summary> | |||
private void SingleDetect() | |||
{ | |||
//允许倒面信号检测 | |||
if (RTrig.GetInstance("AllowFallNoodle").Start(mORKS.AllowFallNoodle)) | |||
{ | |||
mORKS.IngredientsCompleteId = mORKS.TakeBowlId; | |||
mORKS.TakeBowlId = string.Empty; | |||
MessageLog.GetInstance.Show($"碗到位,允许到面,{mORKS.IngredientsCompleteId}"); | |||
mORKS.TakeBowlInterlock = false; | |||
} | |||
//出餐完成信号检测 | |||
if (RTrig.GetInstance("CompleteChange").Start(mORKS.RbOutMealComplete)) | |||
{ | |||
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_COOK); | |||
MessageLog.GetInstance.Show($"订单【{mORKS.OutMealId}】制作完成"); | |||
mORKS.OutNoodleing = false; | |||
} | |||
//取餐完成逻辑处理 | |||
if (DelayRTrig.GetInstance("CompleteChange1").Start(mORKS.RbOutMealComplete && !mORKS.TakeMealDetect, 2)) | |||
{ | |||
OrderChange(mORKS.OutMealId, ORDER_STATUS.COMPLETED_TAKE); | |||
MessageLog.GetInstance.Show($"订单【{mORKS.OutMealId}】取餐完成"); | |||
ResetCookComplete(); | |||
mORKS.OutMealId = string.Empty; | |||
} | |||
//机器人取面完成信号检测 | |||
if (RTrig.GetInstance("TakeNoodleComplete").Start(mORKS.RbTakeNoodleComplete)) | |||
{ | |||
mORKS.TakeNoodleInterlock = false; | |||
mORKS.AllowTakeNoodle = false; | |||
mORKS.TurntableInterlock = false; | |||
MessageLog.GetInstance.Show("机器人取面完成信号检测"); | |||
TakeNoodleCompleteReset(); | |||
} | |||
//转台到位检测 | |||
//if (RTrig.GetInstance("TurntableInPlace").Start(mORKS.TurntableMoveInPlace)) | |||
//{ | |||
// mORKS.TurntableInterlock = false; | |||
//} | |||
int OutMealRequstCount = mORKS.CookNoodlesComplete.Where(p => p == true).ToList().Count; | |||
int mlCount = mORKS.NoodleCookerStatus.Where(p => p == true).ToList().Count; | |||
mORKS.RobotTaskInterlock = OutMealRequstCount > 0 && mORKS.AllowFallNoodle && (mlCount >= 2 || mORKS.RBTakeNoodleTask.Count == 0); | |||
} | |||
#region PLC 控制函数 | |||
private void WriteData(string address, object value) | |||
{ | |||
EventBus.EventBus.GetInstance().Publish(new WriteModel() { Address = address, Value = value }); | |||
} | |||
/// <summary> | |||
/// 写入配方数据到 PLC | |||
/// </summary> | |||
private void WriteRecipeBoms() | |||
{ | |||
List<ushort> recipeBoms = new List<ushort>(); | |||
if (this.recipeBoms == null) return; | |||
foreach (var item in this.recipeBoms.RecipeIds) | |||
{ | |||
foreach (var rec in item.Recipes) | |||
{ | |||
recipeBoms.Add((ushort)rec); | |||
} | |||
} | |||
if (recipeBoms.Count > 0) | |||
{ | |||
//配方数据地址范围:VW2000 - VW2278 | |||
WriteData("VW2000", recipeBoms.ToArray()); | |||
} | |||
else { MessageLog.GetInstance.Show("配方数据为空"); } | |||
} | |||
/// <summary> | |||
/// 取面完成复位 | |||
/// </summary> | |||
private void TakeNoodleCompleteReset() | |||
{ | |||
WriteData("M100.4", false); | |||
//ModbusTcpHelper.GetInstance.Write(1124, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 指定煮面口状态复位 | |||
/// </summary> | |||
/// <param name="num"></param> | |||
private void CookNoodleStatusReset(int num) | |||
{ | |||
if (num >= 1 && num <= 6) | |||
{ | |||
//ushort addRess = (ushort)(1136 + num - 1); | |||
WriteData($"102.{num - 1}", false); | |||
//ModbusTcpHelper.GetInstance.Write(addRess, WriteType.Coils, false); | |||
MessageLog.GetInstance.Show($"{num}号煮面口占用复位"); | |||
} | |||
} | |||
/// <summary> | |||
/// 写配方编号 | |||
/// </summary> | |||
/// <param name="num"></param> | |||
private void SetRecipeNumber(ushort num) | |||
{ | |||
WriteData("VW0", num); | |||
//ModbusTcpHelper.GetInstance.Write(100, WriteType.HoldingRegisters, num); | |||
} | |||
/// <summary> | |||
/// 启动转台 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void TurntableStart(ushort loc) | |||
{ | |||
mORKS.CurrentLoc = loc; | |||
mORKS.TurntableInterlock = true; | |||
mORKS.TurntableLocLists.Add(loc); | |||
WriteData("VW0", loc); | |||
WriteData("M0.5", true); | |||
//ModbusTcpHelper.GetInstance.Write(101, WriteType.HoldingRegisters, loc); | |||
//ModbusTcpHelper.GetInstance.Write(325, WriteType.Coils, true); | |||
} | |||
/// <summary> | |||
/// 设置倒面位置 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void SetFallNoodleLoc(ushort loc) | |||
{ | |||
WriteData("VW4", loc); | |||
//ModbusTcpHelper.GetInstance.Write(102, WriteType.HoldingRegisters, loc); | |||
} | |||
/// <summary> | |||
/// 设置取面位置 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void SetTakeNoodleLoc(ushort loc) | |||
{ | |||
WriteData("VW6", loc); | |||
//ModbusTcpHelper.GetInstance.Write(103, WriteType.HoldingRegisters, loc); | |||
} | |||
/// <summary> | |||
/// 取碗控制 | |||
/// </summary> | |||
/// <param name="loc"></param> | |||
private void TakeBowlControl(ushort loc) | |||
{ | |||
if (loc == 10)//小碗 | |||
{ | |||
WriteData("M0.1", true); | |||
//ModbusTcpHelper.GetInstance.Write(321, WriteType.Coils, true); | |||
} | |||
else if (loc == 11)//大碗 | |||
{ | |||
WriteData("M0.2", true); | |||
//ModbusTcpHelper.GetInstance.Write(322, WriteType.Coils, true); | |||
} | |||
} | |||
/// <summary> | |||
/// 机器人取面 | |||
/// </summary> | |||
private void RobotTakeNoodle() | |||
{ | |||
WriteData("M0.3", true); | |||
//ModbusTcpHelper.GetInstance.Write(323, WriteType.Coils, true); | |||
} | |||
/// <summary> | |||
/// 机器人取餐 | |||
/// </summary> | |||
private void RobotOutMeal() | |||
{ | |||
WriteData("M0.4", true); | |||
//ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true); | |||
//var result = ModbusTcpHelper.GetInstance.Read(324, ReadType.Coils); | |||
//if (result is bool res) | |||
// while (!res) | |||
// { | |||
// ModbusTcpHelper.GetInstance.Write(324, WriteType.Coils, true); | |||
// } | |||
} | |||
/// <summary> | |||
/// 制作完成信号复位 | |||
/// </summary> | |||
private void ResetCookComplete() | |||
{ | |||
WriteData("M100.6", false); | |||
//ModbusTcpHelper.GetInstance.Write(1126, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 复位允许取面信号 | |||
/// </summary> | |||
private void ResetAllowFallNoodle() | |||
{ | |||
WriteData("M100.3", false); | |||
//ModbusTcpHelper.GetInstance.Write(1123, WriteType.Coils, false); | |||
} | |||
/// <summary> | |||
/// 设备初始化 | |||
/// </summary> | |||
public async void DeviceInit() | |||
{ | |||
WriteData("M0.0", true); | |||
//ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, true); | |||
await Task.Delay(1000); | |||
//ModbusTcpHelper.GetInstance.Write(320, WriteType.Coils, false); | |||
WriteData("M0.0", false); | |||
} | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,346 @@ | |||
using System; | |||
using System.Collections.Concurrent; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.MorkS | |||
{ | |||
public class GVL_MORKS | |||
{ | |||
/// <summary> | |||
/// 机器人取面 | |||
/// PLC -> M0.3 | |||
/// ModbusTcp -> 323 | |||
/// </summary> | |||
public bool RobotTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人出餐 | |||
/// PLC -> M0.4 | |||
/// ModbusTcp -> 324 | |||
/// </summary> | |||
public bool RobotOutMeal { get; set; } | |||
/// <summary> | |||
/// 移动转台 | |||
/// PLC -> M0.5 | |||
/// ModbusTcp -> 325 | |||
/// </summary> | |||
public bool MoveTurntable { get; set; } | |||
#region 临时变量 | |||
/// <summary> | |||
/// 允许运行 | |||
/// </summary> | |||
//[Circuit(new string[] { "机器人取面", "取碗控制" }, "允许运行")] | |||
//[VariableMonitor("允许运行")] | |||
public bool AllowRun { get; set; } | |||
/// <summary> | |||
/// //机器人任务互锁信号 | |||
/// </summary> | |||
//[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人互锁", new bool[] { true, false })] | |||
//[VariableMonitor("机器人任务互锁信号")] | |||
public bool RobotTaskInterlock { get; set; } | |||
/// <summary> | |||
/// 取碗互锁信号 | |||
/// </summary> | |||
//[Circuit("取碗控制", "取碗互锁", true)] | |||
//[VariableMonitor("取碗互锁信号")] | |||
public bool TakeBowlInterlock { get; set; } | |||
/// <summary> | |||
/// 取面互锁信号 | |||
/// </summary> | |||
//[Circuit(new string[] { "机器人取面", "出面控制" }, "取面互锁信号", new bool[] { true, true })] | |||
//[VariableMonitor("取面互锁信号")] | |||
public bool TakeNoodleInterlock { get; set; } | |||
/// <summary> | |||
/// 出面中 | |||
/// </summary> | |||
//[Circuit("机器人取面", "出面中", true)] | |||
//[VariableMonitor("出面中")] | |||
public bool OutNoodleing { get; set; } | |||
/// <summary> | |||
/// 允许取面 | |||
/// </summary> | |||
//[Circuit(new string[] { "转台控制", "机器人取面" }, "允许取面", new bool[] { true, false })] | |||
//[VariableMonitor("允许取面")] | |||
public bool AllowTakeNoodle { get; set; } | |||
/// <summary> | |||
/// 转台互锁信号 | |||
/// </summary> | |||
//[VariableMonitor("转台互锁信号")] | |||
public bool TurntableInterlock { get; set; } | |||
#endregion | |||
/// <summary> | |||
/// 初始化完成 | |||
/// PLC -> M100.0 | |||
/// ModbusTcp -> 1120 | |||
/// </summary> | |||
//[Circuit(new string[] { "允许运行", "转台控制", "转台控制" }, "初始化完成")] | |||
//[VariableMonitor("初始化完成", "M100.0", "1120")] | |||
public bool InitComplete { get; set; } | |||
/// <summary> | |||
/// 取碗机构空闲,True:忙碌,false:空闲 | |||
/// PLC -> M100.1 | |||
/// ModbusTcp -> 1121 | |||
/// </summary> | |||
//[Circuit("取碗控制", "取碗机构空闲", true)] | |||
//[VariableMonitor("取碗机构空闲", "M100.1", "1121")] | |||
public bool TakeBowlIdle { get; set; } | |||
/// <summary> | |||
/// 温度到达,True:表示到达,false:未到达 | |||
/// PLC -> M100.2 | |||
/// ModbusTcp -> 1122 | |||
/// </summary> | |||
//[Circuit("允许运行", "温度到达")] | |||
//[VariableMonitor("温度到达", "M100.2", "1122")] | |||
public bool TemperatureReached { get; set; } | |||
/// <summary> | |||
/// 允许到面,配料完成 | |||
/// PLC -> M100.3 | |||
/// ModbusTcp -> 1123 | |||
/// </summary> | |||
//[Circuit("出面控制", "允许到面")] | |||
//[VariableMonitor("允许到面", "M100.3", "1123")] | |||
public bool AllowFallNoodle { get; set; } | |||
/// <summary> | |||
/// 机器人取面完成 | |||
/// PLC -> M100.4 | |||
/// ModbusTcp -> 1124 | |||
/// </summary> | |||
//[VariableMonitor("机器人取面完成", "M100.4", "1124")] | |||
public bool RbTakeNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人倒面完成 | |||
/// PLC -> M100.5 | |||
/// ModbusTcp -> 1125 | |||
/// </summary> | |||
//[VariableMonitor("机器人倒面完成", "M100.5", "1125")] | |||
public bool RbFallNoodleComplete { get; set; } | |||
/// <summary> | |||
/// 机器人出餐完成,上报取餐完成 | |||
/// PLC -> M100.6 | |||
/// ModbusTcp -> 1126 | |||
/// </summary> | |||
//[VariableMonitor("机器人出餐完成", "M100.6", "1126")] | |||
public bool RbOutMealComplete { get; set; } | |||
/// <summary> | |||
/// 机器人空闲 | |||
/// PLC -> M100.7 | |||
/// ModbusTcp -> 1127 | |||
/// </summary> | |||
//[Circuit(new string[] { "机器人取面", "出面控制" }, "机器人空闲")] | |||
//[VariableMonitor("机器人空闲", "M100.7", "1127")] | |||
public bool RobotIdle { get; set; } | |||
/// <summary> | |||
/// 取餐口检测 | |||
/// PLC -> M101.0 | |||
/// ModbusTcp -> 1128 | |||
/// </summary> | |||
//[Circuit("出面控制", "取餐口检测", true)] | |||
//[VariableMonitor("取餐口检测", "M101.0", "1128")] | |||
public bool TakeMealDetect { get; set; } | |||
/// <summary> | |||
/// 缺碗信号,false:缺碗,true:有碗 | |||
/// PLC -> M101.1 | |||
/// ModbusTcp -> 1129 | |||
/// </summary> | |||
//[VariableMonitor("缺碗信号", "M101.1", "1129")] | |||
public bool MissingBowl { get; set; } | |||
/// <summary> | |||
/// 设备初始化中,执行中等于1,2秒后复位 | |||
/// PLC -> M101.2 | |||
/// ModbusTcp -> 1130 | |||
/// </summary> | |||
//[VariableMonitor("设备初始化中", "M101.2", "1130")] | |||
public bool DeviceIniting { get; set; } | |||
/// <summary> | |||
/// 转台下限检测 | |||
/// PLC -> M101.3 | |||
/// ModbusTcp -> 1131 | |||
/// </summary> | |||
//[Circuit("转台控制", "转台下限检测有物料")] | |||
//[VariableMonitor("转台下限检测", "M101.3", "1131")] | |||
public bool TurntableLowerLimit { get; set; } | |||
/// <summary> | |||
/// 缺碗信号 2 | |||
/// PLC -> M101.4 | |||
/// ModbusTcp -> 1132 | |||
/// </summary> | |||
//[VariableMonitor("缺碗信号 2", "M101.4", "1132")] | |||
public bool MissingBowlSignal2 { get; set; } | |||
/// <summary> | |||
/// 转台上限检测 | |||
/// PLC -> M101.5 | |||
/// ModbusTcp -> 1133 | |||
/// </summary> | |||
//[VariableMonitor("转台上限检测", "M101.5", "1133")] | |||
public bool TurntableUpLimit { get; set; } | |||
/// <summary> | |||
/// 补料完成 | |||
/// PLC -> M101.6 | |||
/// ModbusTcp -> 1134 | |||
/// </summary> | |||
//[VariableMonitor("补料完成", "M101.6", "1134")] | |||
public bool FeedComplete { get; set; } | |||
/// <summary> | |||
/// 转台移动到位 | |||
/// PLC -> M101.7 | |||
/// ModbusTcp -> 1135 | |||
/// </summary> | |||
//[Circuit(new string[] { "转台控制", "机器人取面" }, "转台移动到位")] | |||
//[VariableMonitor("转台移动到位", "M101.7", "1135")] | |||
public bool TurntableMoveInPlace { get; set; } | |||
/// <summary> | |||
/// 煮面炉状态,True:忙碌,false:空闲 | |||
/// M102.0 - M102.5 | |||
/// 1136 - 1141 | |||
/// </summary> | |||
//[VariableMonitor("煮面炉状态", "M102.0", "1136")] | |||
public bool[] NoodleCookerStatus { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 补料中 | |||
/// M102.6 | |||
/// 1142 | |||
/// </summary> | |||
//[VariableMonitor("补料中", "M102.6", "1142")] | |||
public bool Feeding { get; set; } | |||
/// <summary> | |||
/// 煮面完成,上升后给信号 | |||
/// M103.0 - M103.5 | |||
/// 1144 - 1149 | |||
/// </summary> | |||
//[VariableMonitor("煮面完成", "M103.0", "1144")] | |||
public bool[] CookNoodlesComplete { get; set; } = new bool[6] { false, false, false, false, false, false }; | |||
/// <summary> | |||
/// 硬件设备异常 | |||
/// PLC -> M235.0 | |||
/// True:设备正常,False:设备异常 | |||
/// </summary> | |||
//[VariableMonitor("硬件设备异常", "M235.0", "")] | |||
public bool Error { get; set; } = false; | |||
/// <summary> | |||
/// 配方编号 | |||
/// PLC -> VW0 | |||
/// ModbusTcp -> 100 | |||
/// </summary> | |||
//[VariableMonitor("配方编号", "VW0", "100")] | |||
public ushort RecipeNumber { get; set; } | |||
/// <summary> | |||
/// 转台设置位置 | |||
/// PLC -> VW2 | |||
/// ModbusTcp -> 101 | |||
/// </summary> | |||
//[VariableMonitor("转台设置位置", "VW2", "101")] | |||
public ushort TurntableLoc { get; set; } | |||
/// <summary> | |||
/// 到面至煮面炉位置 | |||
/// PLC -> VW4 | |||
/// ModbusTcp -> 102 | |||
/// </summary> | |||
//[VariableMonitor("到面至煮面炉位置", "VW4", "102")] | |||
public ushort FallNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 取面位置 | |||
/// PLC -> VW6 | |||
/// ModbusTcp -> 103 | |||
/// </summary> | |||
//[VariableMonitor("取面位置", "VW6", "103")] | |||
public ushort TakeNoodleLoc { get; set; } | |||
/// <summary> | |||
/// 转台反馈位置 | |||
/// PLC -> VW372 | |||
/// ModbusTcp -> 286 | |||
/// </summary> | |||
//[VariableMonitor("转台反馈位置", "VW372", "286")] | |||
public ushort TurntableFeedbackloc { get; set; } | |||
/// <summary> | |||
/// 机器人取面位置队列 | |||
/// </summary> | |||
//[Circuit(new string[] { "转台控制", "机器人取面" }, "有机器人取面队列")] | |||
public ConcurrentQueue<OrderLocInfo> RBTakeNoodleTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
/// <summary> | |||
/// 出碗队列 | |||
/// </summary> | |||
//[Circuit("取碗控制", "有取碗队列数量")] | |||
public ConcurrentQueue<OrderLocInfo> TakeBowlTask { get; set; } = new ConcurrentQueue<OrderLocInfo>(); | |||
/// <summary> | |||
/// 是否有面条 | |||
/// </summary> | |||
public bool IsNoodles { get; set; } = true; | |||
#region 订单ID记录 | |||
/// <summary> | |||
/// 取碗订单ID | |||
/// </summary> | |||
public string TakeBowlId = string.Empty; | |||
/// <summary> | |||
/// 配料完成订单ID | |||
/// </summary> | |||
public string IngredientsCompleteId = string.Empty; | |||
/// <summary> | |||
/// 煮面口对应的订单ID | |||
/// </summary> | |||
public string[] CookNodelId = new string[6] { string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, }; | |||
/// <summary> | |||
/// 出餐订单ID | |||
/// </summary> | |||
public string OutMealId = string.Empty; | |||
/// <summary> | |||
/// 转台位置轮询 | |||
/// </summary> | |||
public List<ushort> TurntableLocLists = new List<ushort>(); | |||
/// <summary> | |||
/// 转台当前启动位置 | |||
/// </summary> | |||
//[VariableMonitor("转台当前启动位置")] | |||
public ushort CurrentLoc { get; set; } = 0; | |||
#endregion | |||
} | |||
} |
@@ -0,0 +1,16 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using System.Threading.Tasks; | |||
namespace BPASmartClient.MorkS | |||
{ | |||
public class OrderLocInfo | |||
{ | |||
public string SuborderId { get; set; } | |||
public ushort Loc { get; set; } | |||
public ushort RecipeNumber { get; set; } | |||
public int BatchingId { get; set; } | |||
} | |||
} |
@@ -43,17 +43,6 @@ | |||
</Peripherals> | |||
</Device> | |||
<!--<Device Name="MorkM" Module="BPASmartClient.MorkS.Control" DeviceId="2"> | |||
<Peripherals> | |||
<Peripheral Module="BPASmartClient.MORKSM.BK.PLC.MorksMachine"> | |||
<Parameters> | |||
<IpAddress>127.0.0.1</IpAddress> | |||
<Port>1</Port> | |||
</Parameters> | |||
</Peripheral> | |||
</Peripherals> | |||
</Device>--> | |||
</BPADevices> |
@@ -5,8 +5,8 @@ | |||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |||
xmlns:local="clr-namespace:BPASmartClient" | |||
xmlns:pry="clr-namespace:BPASmartClient.CustomResource.UserControls;assembly=BPASmartClient.CustomResource" | |||
Title="MainWindow" Width="1400" | |||
Height="850" | |||
Title="MainWindow" Width="1600" | |||
Height="900" | |||
AllowsTransparency="True" | |||
Background="{x:Null}" | |||
Topmost="False" | |||
@@ -26,73 +26,100 @@ | |||
<Border Style="{DynamicResource border主窗体背景}" x:Name="br" > | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="0.09*" /> | |||
<RowDefinition Height="0.09*" /> | |||
<RowDefinition /> | |||
<RowDefinition Height="60"/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<Image Grid.RowSpan="2" x:Name="MoveBorder" Style="{DynamicResource imagetop}" /> | |||
<TextBlock | |||
Name="TX" | |||
HorizontalAlignment="Center" | |||
VerticalAlignment="Center" | |||
FontSize="24" | |||
Text="上位机监控系统" /> | |||
<Grid> | |||
<Grid.RowDefinitions> | |||
<RowDefinition /> | |||
<RowDefinition /> | |||
</Grid.RowDefinitions> | |||
<StackPanel | |||
Grid.Row="1" | |||
Margin="10,5,10,0" | |||
HorizontalAlignment="Left" | |||
VerticalAlignment="Center" | |||
Orientation="Horizontal"> | |||
<TextBlock | |||
FontSize="16" | |||
Foreground="#00c2f4" | |||
Text="当前订单量:" /> | |||
<TextBlock | |||
FontSize="16" | |||
Foreground="#00c2f4" | |||
Text="{Binding OrderCount}" /> | |||
<!--标题--> | |||
<Grid Grid.Row="0"> | |||
<Grid.ColumnDefinitions> | |||
<ColumnDefinition Width="300"></ColumnDefinition> | |||
<ColumnDefinition ></ColumnDefinition> | |||
</Grid.ColumnDefinitions> | |||
<Border Grid.ColumnSpan="2" Style="{DynamicResource bordertop矩形}"></Border> | |||
<Border Style="{DynamicResource bordertopL}"></Border> | |||
<Image Margin="10,0,0,0" VerticalAlignment="Center" Style="{DynamicResource imagetop_Title}" ></Image> | |||
<Grid Grid.Column="1"> | |||
<TabControl> | |||
<TabItem Header=" 状态监视 "></TabItem> | |||
<TabItem Header=" 产品制作 "></TabItem> | |||
<TabItem Header=" 综合查询 "></TabItem> | |||
<TabItem Header=" 功能列表 "></TabItem> | |||
<TabItem Header=" 参数配置 "></TabItem> | |||
<TabItem Header=" 系统帮助 "></TabItem> | |||
</TabControl> | |||
</Grid> | |||
<StackPanel Grid.Column="4" Orientation="Horizontal" HorizontalAlignment="Right" Height="50" VerticalAlignment="Top"> | |||
<Border Style="{DynamicResource border竖线}" /> | |||
<ToggleButton VerticalAlignment="Center" ToolTip="告警消息" HorizontalAlignment="Center" Style="{DynamicResource StatusBtnStyle告警}" DataContext="{Binding GaoJingMessage}" Cursor="Hand"/> | |||
<Border Style="{DynamicResource border竖线}" /> | |||
<Grid Margin="10,0,10,0" VerticalAlignment="Center" > | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="30"/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<StackPanel Orientation="Horizontal" Grid.Row="0"> | |||
<TextBlock x:Name="time" FontSize="16" Text="18:00:00"/> | |||
<Image Style="{DynamicResource timeImage}" Margin="10,0,0,0"/> | |||
</StackPanel> | |||
<StackPanel Grid.Row="1" Orientation="Horizontal"> | |||
<TextBlock x:Name="dateRL" FontSize="10" >星期一</TextBlock> | |||
<TextBlock x:Name="date" Margin="10,0,0,0" FontSize="10" >2021-11-13</TextBlock> | |||
</StackPanel> | |||
</Grid> | |||
<Border Style="{DynamicResource border竖线}" /> | |||
<Button x:Name="ButClose" Grid.Column="4" Margin="10,0,20,0" Style="{DynamicResource CommonBtnStyle退出按钮}" VerticalAlignment="Center" ToolTip="退出程序" Cursor="Hand" Content="退出"/> | |||
</StackPanel> | |||
</Grid> | |||
<StackPanel | |||
Grid.Row="1" | |||
Margin="10,5,10,0" | |||
HorizontalAlignment="Right" | |||
VerticalAlignment="Center" | |||
Orientation="Horizontal"> | |||
<TextBlock | |||
Margin="10,0,0,0" | |||
FontSize="16" | |||
Foreground="#00c2f4" | |||
Text="网络状态:" /> | |||
</StackPanel> | |||
<!--底部窗体--> | |||
<Grid Grid.Row="1" Margin="10"> | |||
<Border Style="{DynamicResource border窗体背景1}" Visibility="Collapsed" Width="500" HorizontalAlignment="Left" VerticalAlignment="Stretch"> | |||
<Grid Margin="20"> | |||
<Grid.RowDefinitions> | |||
<RowDefinition Height="40"/> | |||
<RowDefinition/> | |||
</Grid.RowDefinitions> | |||
<TextBlock HorizontalAlignment="Center" Margin="0,10,0,0">相关设备状态</TextBlock> | |||
<UniformGrid HorizontalAlignment="Right" Columns="3"> | |||
<Button | |||
Name="ButMin" | |||
Width="40" | |||
Content="" | |||
Style="{StaticResource TitleBarStyle}" /> | |||
<Button | |||
Name="ButMax" | |||
Content="" | |||
Style="{StaticResource TitleBarStyle}" /> | |||
<Button | |||
Name="ButClose" | |||
Content="" | |||
FontSize="26" | |||
Style="{StaticResource TitleBarStyle}" /> | |||
</UniformGrid> | |||
<DataGrid x:Name="datagrid" Margin="0,50,0,0" ItemsSource="{Binding EquiPment, UpdateSourceTrigger=PropertyChanged}" Grid.Row="1"> | |||
<DataGrid.Columns> | |||
<DataGridTemplateColumn Header=" " Width="24"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<Ellipse Width="12" Height="12" ToolTip="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Fill="{Binding color, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Header="设备名称" Width="4.4*"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock HorizontalAlignment="Center" Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="#00ccff"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Header="设备状态" Width="4.4*"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<TextBlock HorizontalAlignment="Center" Text="{Binding Status, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Foreground="#00ccff"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
<DataGridTemplateColumn Header="维护" Width="4.4*"> | |||
<DataGridTemplateColumn.CellTemplate> | |||
<DataTemplate> | |||
<Image Width="12" Height="12" ToolTip="设备维护" Style="{DynamicResource image个人信息}" Cursor="Hand" x:Name="ShowFromButton"/> | |||
</DataTemplate> | |||
</DataGridTemplateColumn.CellTemplate> | |||
</DataGridTemplateColumn> | |||
</DataGrid.Columns> | |||
</DataGrid> | |||
</Grid> | |||
</Border> | |||
<Button Grid.Row="2" Content="测试" HorizontalAlignment="Center" Margin="153,123,0,0" VerticalAlignment="Top" Click="Button_Click"/> | |||
</Grid> | |||
<Button Content="Button" HorizontalAlignment="Left" Margin="153,123,0,0" VerticalAlignment="Top" Click="Button_Click"/> | |||
</Grid> | |||
</Border> | |||
@@ -28,8 +28,6 @@ namespace BPASmartClient | |||
public MainWindow() | |||
{ | |||
InitializeComponent(); | |||
this.ButMin.Click += (o,e) => { this.WindowState = WindowState.Minimized; }; | |||
this.ButMax.Click += (o,e) => { this.WindowState = this.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; }; | |||
this.ButClose.Click += (o,e) => { this.Close(); }; | |||
this.br.MouseLeftButtonDown += (o,e) => | |||
{ | |||