移植公共库中的IoPSU和IoSCR对象。

PMOperationView中增加加热器电阻阻值显示功能。
This commit is contained in:
SL 2023-07-25 16:46:56 +08:00
parent 9a4c6e1b1a
commit 181898414d
23 changed files with 1230 additions and 342 deletions

1
.gitignore vendored
View File

@ -362,3 +362,4 @@ MigrationBackup/
# Fody - auto-generated XML schema
FodyWeavers.xsd
/.svn
FrameworkLocal/output/

View File

@ -0,0 +1,107 @@
using MECF.Framework.Common.CommonData;
using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Threading.Tasks;
namespace Aitex.Core.Common.DeviceData.IoDevice
{
[Serializable]
[DataContract]
public class IoPsuData : NotifiableItem, IDeviceData
{
[DataMember]
public string Status { get; set; }
[DataMember]
public bool IsBusy { get; set; }
[DataMember]
public bool IsAlarm { get; set; }
/// <summary>
/// 设置或返回PSU实时电压反馈值。
/// </summary>
[DataMember]
public float OutputVoltageFeedback { get; set; }
/// <summary>
/// 设置或返回PSU输出状态。
/// </summary>
[DataMember]
public float OutputArmsFeedBack { get; set; }
/// <summary>
/// 设置或返回加热器电阻计算值。
/// </summary>
[DataMember]
public float Resistance { get; set; }
/// <summary>
/// 设置或返回电阻上限设定值。
/// </summary>
[DataMember]
public float ResistanceLimitMax { get; set; }
/// <summary>
/// 设置或返回电阻值是否超限。
/// </summary>
[DataMember]
public bool IsResistanceOutOfRange { get; set; }
/// <summary>
/// 设置或返回是否电阻值过大。
/// </summary>
[DataMember]
public bool IsResistanceTooHigh { get; set; }
/// <summary>
/// 设置或返回PSU实时功率反馈值。
/// </summary>
[DataMember]
public float OutputPowerFeedBack { get; set; }
/// <summary>
/// 设置货返回PSU输出状态反馈值。
/// </summary>
[DataMember]
public bool OutputStatusFeedBack { get; set; }
/// <summary>
/// 设置或返回Constant设定值。
/// </summary>
[DataMember]
public float ConstantSetPoint { get; set; }
/// <summary>
/// 设置或返回PSU总开关状态。
/// </summary>
/// <remarks>
/// 所有PSU有一个总开关该属性表示该总开关的状态。
/// </remarks>
[DataMember]
public bool AllHeatEnable { get; set; }
public void Update(IDeviceData data)
{
if (data == null)
return;
var targetProps = GetType().GetProperties()
.Where(prop => Attribute.IsDefined((MemberInfo)prop, typeof(DataMemberAttribute)));
var sourceProps = data.GetType().GetProperties()
.Where(prop => Attribute.IsDefined((MemberInfo)prop, typeof(DataMemberAttribute)));
Parallel.ForEach(targetProps, pi =>
{
var srcPi = sourceProps.FirstOrDefault(x => x.Name == pi.Name);
if (srcPi == null)
return;
pi.SetValue(this, srcPi.GetValue(data));
});
}
}
}

View File

@ -23,6 +23,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -32,6 +33,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="FabConnect">
@ -44,14 +46,12 @@
<Reference Include="MECF.Framework.Common">
<HintPath>..\MECF.Framework.Common.dll</HintPath>
</Reference>
<Reference Include="Npgsql">
<HintPath>..\..\..\..\..\..\..\Test\dotnet\TestS7\TestS7\ThirdParty\dlls\Npgsql.dll</HintPath>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Windows" />
<Reference Include="System.Windows.Forms" />
@ -82,6 +82,7 @@
<DependentUpon>PassWordView.xaml</DependentUpon>
</Compile>
<Compile Include="DBProviderEx\WaferDataRecorderEx.cs" />
<Compile Include="DeviceData\IoPsuData.cs" />
<Compile Include="IoProviders\Contecs\CdioCs.cs" />
<Compile Include="IoProviders\Contecs\ContecIoCard.cs" />
<Compile Include="IoProviders\Mitsubishis\MCProtocolPlc.cs" />

View File

@ -21,7 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.2</LangVersion>
<LangVersion>latest</LangVersion>
<DocumentationFile>
</DocumentationFile>
<NoWarn>67,168,169,414</NoWarn>
@ -34,7 +34,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>7.2</LangVersion>
<LangVersion>latest</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -29,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
@ -555,7 +557,7 @@
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<ProjectExtensions>
<VisualStudio>
<UserProperties vce_4brooksvce_4iosimulatoritems_1json__JsonSchema="http://json.schemastore.org/apibuilder.json" robots_4hiratar4_4iosimulatoritems_1json__JsonSchema="https://jenkins-x.io/schemas/jx-schema.json" />
<UserProperties robots_4hiratar4_4iosimulatoritems_1json__JsonSchema="https://jenkins-x.io/schemas/jx-schema.json" vce_4brooksvce_4iosimulatoritems_1json__JsonSchema="http://json.schemastore.org/apibuilder.json" />
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -0,0 +1,73 @@
<UserControl x:Class="MECF.Framework.UI.Client.Ctrlib.Controls.HeaterResPresenter"
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:MECF.Framework.UI.Client.Ctrlib.Controls"
xmlns:deviceControl="clr-namespace:Aitex.Core.UI.DeviceControl;assembly=MECF.Framework.UI.Core"
xmlns:ioDevice="clr-namespace:Aitex.Core.Common.DeviceData.IoDevice;assembly=MECF.Framework.RT.Core"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance Type=ioDevice:IoPsuData, IsDesignTimeCreatable=False}">
<UserControl.Resources>
<local:IoPsuResistanceSummaryConverter x:Key="resSummaryConverter" />
</UserControl.Resources>
<Grid Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0" />
<ColumnDefinition />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="70" />
</Grid.ColumnDefinitions>
<Border
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="2"
Padding="5,1"
Background="{DynamicResource Table_BG_Title_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="1,0,1,1">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
Text="{Binding Caption,
RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"
TextWrapping="Wrap" />
</Border>
<Border
Grid.Row="0"
Grid.Column="2"
Padding="5,1"
Background="{DynamicResource Table_BG_Content_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="0,0,1,1">
<deviceControl:AITSensor
HorizontalAlignment="Center"
VerticalAlignment="Center"
CustomColorOff="Lime"
CustomColorOn="Red"
IsCustomRender="True"
LightOnValue="{Binding IsResistanceOutOfRange}" />
</Border>
<Border
Grid.Row="0"
Grid.Column="3"
Padding="5,1"
Background="{DynamicResource Table_BG_Content_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="0,0,1,1">
<TextBlock
HorizontalAlignment="Center"
Text="{Binding Resistance, StringFormat={}{0:F1}}"
ToolTip="{Binding Converter={StaticResource resSummaryConverter}}" />
</Border>
</Grid>
</UserControl>

View File

@ -0,0 +1,56 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using Aitex.Core.Common.DeviceData.IoDevice;
namespace MECF.Framework.UI.Client.Ctrlib.Controls
{
/// <summary>
/// Interaction logic for HeaterResistanceOverview.xaml
/// </summary>
public partial class HeaterResPresenter : UserControl
{
public HeaterResPresenter()
{
InitializeComponent();
}
#region Dps
public static readonly DependencyProperty CaptionProperty = DependencyProperty.Register(
nameof(Caption), typeof(string), typeof(HeaterResPresenter), new PropertyMetadata(default(string)));
public string Caption
{
get => (string)GetValue(CaptionProperty);
set => SetValue(CaptionProperty, value);
}
#endregion
}
internal class IoPsuResistanceSummaryConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IoPsuData data)
{
return $"Realtime: {data.Resistance:F1}Ω" +
$"\r\nLimit High: {data.ResistanceLimitMax:F1}Ω" +
$"\r\nVoltage: {data.OutputVoltageFeedback:F1}V" +
$"\r\nAmps: {data.OutputArmsFeedBack:F1}A";
}
else
{
return "";
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

View File

@ -22,6 +22,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -31,6 +32,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="DocumentFormat.OpenXml, Version=2.10.1.0, Culture=neutral, PublicKeyToken=8fb06cb64d019a17, processorArchitecture=MSIL">
@ -447,6 +449,7 @@
<Compile Include="Ctrlib\Controls\ComboBoxExt.cs" />
<Compile Include="Ctrlib\Controls\ComboTextBlock.cs" />
<Compile Include="Ctrlib\Controls\CarrierContentControl.cs" />
<Compile Include="Ctrlib\Controls\HeaterResPresenter.xaml.cs" />
<Compile Include="Ctrlib\Converter\WaferStatusConverter.cs" />
<Compile Include="Ctrlib\UnitControls\AITMicrowaveSettingDialogView.xaml.cs">
<DependentUpon>AITMicrowaveSettingDialogView.xaml</DependentUpon>
@ -1002,6 +1005,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Ctrlib\Controls\HeaterResPresenter.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Ctrlib\UnitControls\AITMicrowaveSettingDialogView.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -29,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="Autofac">

View File

@ -21,6 +21,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -29,6 +30,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="DePacker">

View File

@ -0,0 +1,446 @@
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.SCCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Event;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
namespace SicPM.Devices
{
/// <summary>
/// 设备类型的基类。
/// </summary>
/// <remarks>
/// 该类描述了系统使用的设备对象。该设备对象为系统中最小控制单元所有模组Module通过此设备对象对实际的硬件设备进行控制。
/// </remarks>
public abstract class BaseDevice : IAlarmHandler
{
#region Variables
/// <summary>
/// 当设备报警状态发生变化时,调用此事件。
/// </summary>
public event Action<string, AlarmEventItem> OnDeviceAlarmStateChanged;
/// <summary>
/// 设备线程锁。
/// </summary>
protected readonly object SyncRoot;
/// <summary>
/// 报警信息字典。
/// </summary>
protected readonly Dictionary<string, AlarmEventItem> DicAlarms;
#endregion
#region Constructors
/// <summary>
/// 创建设备对象的实例。
/// </summary>
protected BaseDevice()
{
SyncRoot = new object();
ScBasePath = ModuleName.System.ToString();
IoBasePath = ModuleName.System.ToString();
DicAlarms = new Dictionary<string, AlarmEventItem>();
IsEnabled = true;
}
/// <summary>
/// 创建设备对象的实例。
/// </summary>
/// <param name="module">设备所属的模组名称。</param>
/// <param name="name">设备名称。</param>
/// <param name="display">设备在用户界面的显示名称。</param>
/// <param name="id">设备编号。</param>
protected BaseDevice(string module, string name, string display, string id) : this()
{
display = (string.IsNullOrEmpty(display) ? name : display);
id = (string.IsNullOrEmpty(id) ? name : id);
Module = module;
Name = name;
Display = display;
DeviceID = id;
UniqueName = module + "." + name;
}
/// <summary>
/// 根据XML的配置描述创建设备对象的实例。
/// </summary>
/// <param name="module">设备所属的模组名称。</param>
/// <param name="node">配置文件描述本设备的Xml节点。</param>
/// <param name="ioModule"></param>
protected BaseDevice(string module, XmlElement node, string ioModule = "") : this()
{
var attrModule = node.GetAttribute("module");
Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
Unit = node.GetAttribute("unit");
Name = node.GetAttribute("id");
Display = node.GetAttribute("display");
DeviceID = node.GetAttribute("schematicId");
UniqueName = module + "." + Name;
var scBasePath = node.GetAttribute("scBasePath");
scBasePath = string.IsNullOrEmpty(scBasePath) ?
$"{Module}.{Name}"
: scBasePath.Replace("{module}", Module);
ScBasePath = scBasePath;
}
#endregion
#region Properties
/// <summary>
/// 设置或返回当前设备是否被使能。
/// </summary>
/// <remarks>
/// 默认情况下当设备被创建时自动使能但如果设备对应的Module被配置为UnInstalled则该设备
/// 会被其所属Module禁用以提高RT性能及避免产生不必要的报警信息。
/// </remarks>
public bool IsEnabled { get; set; }
/// <summary>
/// 设置或返回当前设备在系统中唯一的名称。
/// </summary>
public string UniqueName { get; set; }
/// <summary>
/// 设置或返回当前设备所属的模组名称。
/// </summary>
/// <remarks>
/// 关于系统中有效的模组名称,请参考<see cref="ModuleName"/>。
/// </remarks>
public string Module { get; set; }
/// <summary>
/// 设置或返回当前设备名称。
/// </summary>
public string Name { get; set; }
/// <summary>
/// 设置或返回当前设备向用户显示的名称。
/// </summary>
public string Display { get; set; }
/// <summary>
/// 设置或返回当前设备编号。
/// </summary>
public string DeviceID { get; set; }
/// <summary>
/// 设置或返回当前设备的计量单位。
/// </summary>
public string Unit { get; set; }
/// <summary>
/// 设置或返回当前设备配置信息位于系统配置的节点名称。
/// </summary>
public string ScBasePath { get; set; }
/// <summary>
/// 设置或返回当前设备所使用的IO Provider。
/// </summary>
public string IoBasePath { get; set; }
/// <summary>
/// 设置或返回设备是否产生报警。
/// </summary>
public bool HasAlarm =>
DicAlarms?.Values.FirstOrDefault((AlarmEventItem x) => !x.IsAcknowledged && x.Level == EventLevel.Alarm) !=
null;
#endregion
#region Methods
/// <summary>
/// 加载指定的系统配置。
/// </summary>
/// <param name="scPath">指定的系统配置路径</param>
/// <param name="scPathFallback">当指定的系统配置路径不存在时,使用默认路径</param>
/// <param name="valueFallback">当指定的系统配置值数据类型错误时,使用此默认值</param>
/// <param name="valueHolder">存放系统配置的变量</param>
/// <param name="scValueChangedCallback">监测系统配置是否发生变化,当发生变化时,执行此回调函数</param>
/// <typeparam name="T"></typeparam>
protected void LoadSC<T>(string scPath, string scPathFallback, T valueFallback, ref T valueHolder, Action<T> scValueChangedCallback = null)
{
if (scPath == null) throw new ArgumentNullException(nameof(scPath));
if (scPathFallback == null) throw new ArgumentNullException(nameof(scPathFallback));
if (valueFallback == null) throw new ArgumentNullException(nameof(valueFallback));
if (valueHolder == null) throw new ArgumentNullException(nameof(valueHolder));
// 读取系统配置
var path = scPath;
var scItem = SC.GetConfigItem(path);
if (scItem == null)
{
// 没找到配置,用默认路径找
path = scPathFallback;
scItem = SC.GetConfigItem(path);
}
if (scItem != null)
{
// 找到系统配置,尝试转换并赋值到指定的字段
try
{
var converter = TypeDescriptor.GetConverter(typeof(T));
valueHolder = (T)converter.ConvertFromString(scItem.Value.ToString());
// 当前版本Common库不支持此方法
// 如果指定了该回调,则表明需要监测当前系统配置值
/*if (scValueChangedCallback != null)
{
SC.RegisterValueChangedCallback(path, v =>
{
var val = (T)converter.ConvertFromString(scItem.Value.ToString());
scValueChangedCallback(val);
});
}*/
}
catch (Exception)
{
EV.PostWarningLog(Module,
$"System config {path} type mismatched, set to default value");
valueHolder = valueFallback;
}
}
else
{
// 指定路径和默认路径均找不到配置,使用默认配置
EV.PostWarningLog(Module,
$"System config {path} type mismatched, set to default value");
valueHolder = valueFallback;
}
}
/// <summary>
/// 订阅报警事件。
/// </summary>
/// <param name="name">报警事件名称。</param>
/// <param name="description">报警事件描述。</param>
/// <param name="resetChecker">报警复位检查回调函数。</param>
/// <param name="level">报警等级,请参考<see cref="EventLevel"/></param>
/// <returns></returns>
protected AlarmEventItem SubscribeAlarm(string name, string description, Func<bool> resetChecker, EventLevel level = EventLevel.Alarm)
{
var ae = new AlarmEventItem(Module, name, description, resetChecker, this);
ae.Level = level;
DicAlarms[name] = ae;
EV.Subscribe(ae);
return ae;
}
/// <summary>
/// 清除当前设备的报警信息。
/// </summary>
protected void ResetAlarm()
{
foreach (var alarm in DicAlarms)
alarm.Value.Reset();
}
/// <summary>
/// 当前对象的子类实现的扫描任务。
/// </summary>
protected virtual void HandleMonitor()
{
}
/// <summary>
/// 执行当前设备扫描周期任务。
/// </summary>
public void Monitor()
{
// 如果当前设备被标记为禁用,则不要执行周期性扫描任务。
if (IsEnabled)
HandleMonitor();
}
/// <summary>
/// 通知当前设备的报警信息发生了变化。
/// </summary>
/// <param name="args"></param>
public void AlarmStateChanged(AlarmEventItem args)
{
OnDeviceAlarmStateChanged?.Invoke(UniqueName ?? "", args);
}
/// <summary>
/// 从XML配置描述中解析指定的DO对象。
/// </summary>
/// <remarks>
/// 通过该方法从XML配置中获取指定的DO名称从系统点表中查找并返回指定名称的DO实例。
/// </remarks>
/// <param name="name">XML配置节点中定义DO的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <param name="ioModule">IO Provider名称。</param>
/// <returns>
/// 指定名称的<see cref="DOAccessor"/>对象。
/// <br/>
/// 如果未找到指定名称的DO则返回null。
/// </returns>
public DOAccessor ParseDoNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
return IO.DO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : (ioModule + "." + node.GetAttribute(name).Trim())];
}
return null;
}
/// <summary>
/// 从XML配置描述中解析指定的DI对象。
/// </summary>
/// <remarks>
/// 通过该方法从XML配置中获取指定的DI名称从系统点表中查找并返回指定名称的DI实例。
/// </remarks>
/// <param name="name">XML配置节点中定义DI的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <param name="ioModule">IO Provider名称。</param>
/// <returns>
/// 指定名称的<see cref="DIAccessor"/>对象。
/// <br/>
/// 如果未找到指定名称的DI则返回null。
/// </returns>
public DIAccessor ParseDiNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
return IO.DI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : (ioModule + "." + node.GetAttribute(name).Trim())];
}
return null;
}
/// <summary>
/// 从XML配置描述中解析指定的AO对象。
/// </summary>
/// <remarks>
/// 通过该方法从XML配置中获取指定的AO名称从系统点表中查找并返回指定名称的AO实例。
/// </remarks>
/// <param name="name">XML配置节点中定义AO的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <param name="ioModule">IO Provider名称。</param>
/// <returns>
/// 指定名称的<see cref="AOAccessor"/>对象。
/// <br/>
/// 如果未找到指定名称的AO则返回null。
/// </returns>
public AOAccessor ParseAoNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
return IO.AO[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : (ioModule + "." + node.GetAttribute(name).Trim())];
}
return null;
}
/// <summary>
/// 从XML配置描述中解析指定的AI对象。
/// </summary>
/// <remarks>
/// 通过该方法从XML配置中获取指定的AI名称从系统点表中查找并返回指定名称的AI实例。
/// </remarks>
/// <param name="name">XML配置节点中定义AI的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <param name="ioModule">IO Provider名称。</param>
/// <returns>
/// 指定名称的<see cref="AIAccessor"/>对象。
/// <br/>
/// 如果未找到指定名称的AI则返回null。
/// </returns>
public AIAccessor ParseAiNode(string name, XmlElement node, string ioModule = "")
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
return IO.AI[string.IsNullOrEmpty(ioModule) ? node.GetAttribute(name).Trim() : (ioModule + "." + node.GetAttribute(name).Trim())];
}
return null;
}
/// <summary>
/// 从XML配置描述中解析当前设备配置信息位于系统配置中的节点。
/// </summary>
/// <param name="name">XML配置节点中定义系统配置节点的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <param name="ioModule">IO Provider名称。</param>
/// <param name="defaultScPath">如果未找到name指定的系统配置节点则使用此默认系统配置节点。</param>
/// <returns>
/// <see cref="SCConfigItem"/>。
/// </returns>
public SCConfigItem ParseScNode(string name, XmlElement node, string ioModule = "", string defaultScPath = "")
{
SCConfigItem sCConfigItem = null;
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
sCConfigItem = SC.GetConfigItem(node.GetAttribute(name));
}
if (sCConfigItem == null && !string.IsNullOrEmpty(defaultScPath) && SC.ContainsItem(defaultScPath))
{
sCConfigItem = SC.GetConfigItem(defaultScPath);
}
return sCConfigItem;
}
/// <summary>
/// 从XML配置描述中解析设备名称并从系统设备列表中查找该设备。
/// </summary>
/// <typeparam name="T">待查找的设备的类型。</typeparam>
/// <param name="name">XML配置节点中定义设备名称的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <returns>
/// 指定的设备实例。
/// <br/>
/// 如果未找到指定的设备则返回null。
/// </returns>
public static T ParseDeviceNode<T>(string name, XmlElement node) where T : class, IDevice
{
if (!string.IsNullOrEmpty(node.GetAttribute(name).Trim()))
{
return DEVICE.GetDevice<T>(node.GetAttribute(name));
}
LOG.Write($"{node.InnerXml},未定义{name}");
return null;
}
/// <summary>
/// 从XML配置描述中解析设备名称并从系统设备列表中查找该设备。
/// </summary>
/// <typeparam name="T">待查找的设备的类型。</typeparam>
/// <param name="module">设备所属模组。</param>
/// <param name="name">XML配置节点中定义设备名称的属性的名称。</param>
/// <param name="node">XML配置节点。</param>
/// <returns>
/// 指定的设备实例。
/// <br/>
/// 如果未找到指定的设备则返回null。
/// </returns>
public static T ParseDeviceNode<T>(string module, string name, XmlElement node) where T : class, IDevice
{
var attribute = node.GetAttribute(name);
if (!string.IsNullOrEmpty(attribute) && !string.IsNullOrEmpty(attribute.Trim()))
{
return DEVICE.GetDevice<T>(module + "." + attribute);
}
LOG.Write($"{node.InnerXml},未定义{name}");
return null;
}
#endregion
}
}

View File

@ -1,4 +1,5 @@
using Aitex.Core.RT.DataCenter;
using Aitex.Core.Common.DeviceData.IoDevice;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
@ -6,163 +7,65 @@ using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using MECF.Framework.Common.CommonData.DeviceData;
using MECF.Framework.Common.DBCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using Newtonsoft.Json;
namespace SicPM.Devices
{
public class IoPSU : BaseDevice, IDevice
{
#region Variables
public float OutputVoltageFeedBack
{
get
{
return _aiOutputVoltage == null ? 0 : (_isFloatAioType ? _aiOutputVoltage.FloatValue : _aiOutputVoltage.Value);
}
}
private const float DEF_RES_LIMIT_MAX_OHM = 3;
private readonly string _scResLimitMax;
private float _resLimitMax;
public float OutputArmsFeedBack
{
get
{
return _aiOutputArms == null ? 0 : (_isFloatAioType ? _aiOutputArms.FloatValue : _aiOutputArms.Value);
}
}
public float OutputPowerFeedBack
{
get
{
return _aiOutputPower == null ? 0 : (_isFloatAioType ? _aiOutputPower.FloatValue : _aiOutputPower.Value);
}
}
public bool StatusFeedBack
{
get
{
return _diStatus == null ? false : _diStatus.Value;
}
}
public float SimVoltageFeedBack
{
get
{
return _aiSimVoltage == null ? 0 : (_isFloatAioType ? _aiSimVoltage.FloatValue : _aiSimVoltage.Value);
}
}
public float SimArmsFeedBack
{
get
{
return _aiSimArms == null ? 0 : (_isFloatAioType ? _aiSimArms.FloatValue : _aiSimArms.Value);
}
}
public bool AlarmFeedBack
{
get
{
return _diAlarm == null ? false : _diAlarm.Value;
}
}
public float ConstantSetPoint
{
get
{
return _aoConstant == null ? 0 : (_isFloatAioType ? _aoConstant.FloatValue : _aoConstant.Value);
}
set
{
if (_isFloatAioType)
{
_aoConstant.FloatValue = value;
}
else
{
_aoConstant.Value = (short)value;
}
}
}
public bool AllHeatEnable
{
get
{
return _diHeatEnable == null ? false : _diHeatEnable.Value;
}
}
#region DataLog
public float Resistance
{
get
{
return OutputArmsFeedBack == 0 ? 0 : OutputVoltageFeedBack / OutputArmsFeedBack;
}
}
#endregion
private bool _isFloatAioType = false;
private AIAccessor _aiOutputVoltage = null;
private AIAccessor _aiOutputArms = null;
private AIAccessor _aiOutputPower = null;
private AIAccessor _aiSimVoltage = null;
private AIAccessor _aiSimArms = null;
private readonly bool _isFloatAioType;
private readonly AIAccessor _aiOutputVoltage;
private readonly AIAccessor _aiOutputArms;
private readonly AIAccessor _aiOutputPower;
private readonly AIAccessor _aiSimVoltage;
private readonly AIAccessor _aiSimArms;
//private AOAccessor _aoEnable = null;
//private AOAccessor _aoReset = null;
private AOAccessor _aoConstant = null;
private readonly AOAccessor _aoConstant;
private DIAccessor _diStatus = null;
private DIAccessor _diAlarm = null;
private DIAccessor _diHeatEnable = null;
private DIAccessor _diCommunicationError = null;
private readonly DIAccessor _diStatus;
private readonly DIAccessor _diAlarm;
private readonly DIAccessor _diHeatEnable;
private DIAccessor _diCommunicationError;
private DOAccessor _doReset;
private DOAccessor _doStatus;
private DOAccessor _doHeatEnable;
private DOAccessor _doRelatedEnable; //每个Enable同时关联的InnerMiddleOut Enable
private readonly DOAccessor _doReset;
private readonly DOAccessor _doStatus;
private readonly DOAccessor _doHeatEnable;
private readonly DOAccessor _doRelatedEnable; //每个Enable同时关联的InnerMiddleOut Enable
private string _infoText = "";
private string _commInfoText = "";
private R_TRIG _alarmTrig = new R_TRIG();
private R_TRIG _commAlarmTrig = new R_TRIG();
private R_TRIG _enableTrig = new R_TRIG();
private R_TRIG _enableTrig2 = new R_TRIG();
private readonly R_TRIG _alarmTrig = new();
private readonly R_TRIG _commAlarmTrig = new();
private readonly R_TRIG _enableTrig = new();
private readonly R_TRIG _enableTrig2 = new();
private DeviceTimer _timer = new DeviceTimer();
private readonly R_TRIG _trigVoltage = new();
private readonly R_TRIG _trigCurrent = new();
private readonly R_TRIG _trigResOutOfRange = new();
private SCConfigItem _AETempEnable;
private readonly DeviceTimer _timResetPulse = new();
private readonly DeviceTimer _timResCheck = new();
private readonly IoPsuData _deviceData = new();
public Func<bool, bool> FuncCheckInterLock;
#endregion
public IoPSU(string module, XmlElement node, string ioModule = "")
#region Constructors
public IoPSU(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
var attrModule = node.GetAttribute("module");
base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
_aiOutputVoltage = ParseAiNode("aiOutputVoltage", node, ioModule);
_aiOutputArms = ParseAiNode("aiOutputArms", node, ioModule);
_aiOutputPower = ParseAiNode("aiOutputPower", node, ioModule);
@ -176,7 +79,7 @@ namespace SicPM.Devices
_diAlarm = ParseDiNode("diAlarm", node, ioModule);
_doHeatEnable = ParseDoNode("doHeatEnable", node, ioModule);
_diHeatEnable = ParseDiNode("diHeatEnable", node, ioModule);
_doRelatedEnable= ParseDoNode("doRelatedEnable", node, ioModule);
_doRelatedEnable = ParseDoNode("doRelatedEnable", node, ioModule);
_diCommunicationError = ParseDiNode("diCommunicationError", node, ioModule);
_infoText = node.GetAttribute("AlarmText");
@ -184,14 +87,91 @@ namespace SicPM.Devices
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
_AETempEnable = ParseScNode("AETempEnable1", node, ioModule, $"AETemp.EnableDevice");
// 读取电阻上限设定值
_scResLimitMax = node.GetAttribute("scResLimitMax");
}
string reason = string.Empty;
#endregion
#region Properties
public float OutputVoltageFeedBack => _aiOutputVoltage == null ? 0 : (_isFloatAioType ? _aiOutputVoltage.FloatValue : _aiOutputVoltage.Value);
public float OutputArmsFeedBack => _aiOutputArms == null ? 0 : (_isFloatAioType ? _aiOutputArms.FloatValue : _aiOutputArms.Value);
public float ResistanceLimitMax => _resLimitMax;
public float Resistance => OutputArmsFeedBack == 0 ? 0 : OutputVoltageFeedBack / OutputArmsFeedBack;
public bool IsResistanceOutOfRange => IsResistanceTooHigh;
public bool IsResistanceTooHigh
{
get;
private set;
}
public float OutputPowerFeedBack => _aiOutputPower == null ? 0 : (_isFloatAioType ? _aiOutputPower.FloatValue : _aiOutputPower.Value);
public bool StatusFeedBack => _diStatus?.Value ?? false;
public float SimVoltageFeedBack => _aiSimVoltage == null ? 0 : (_isFloatAioType ? _aiSimVoltage.FloatValue : _aiSimVoltage.Value);
public float SimArmsFeedBack => _aiSimArms == null ? 0 : (_isFloatAioType ? _aiSimArms.FloatValue : _aiSimArms.Value);
public bool AlarmFeedBack => _diAlarm?.Value ?? false;
public float ConstantSetPoint
{
get => _aoConstant == null ? 0 : (_isFloatAioType ? _aoConstant.FloatValue : _aoConstant.Value);
set
{
if (_isFloatAioType)
{
_aoConstant.FloatValue = value;
}
else
{
_aoConstant.Value = (short)value;
}
}
}
public bool AllHeatEnable => _diHeatEnable?.Value ?? false;
private string DeviceData
{
get
{
_deviceData.IsAlarm = AlarmFeedBack;
_deviceData.OutputStatusFeedBack = StatusFeedBack;
_deviceData.AllHeatEnable = AllHeatEnable;
_deviceData.ConstantSetPoint = ConstantSetPoint;
_deviceData.OutputArmsFeedBack = OutputArmsFeedBack;
_deviceData.OutputPowerFeedBack = OutputPowerFeedBack;
_deviceData.OutputVoltageFeedback = OutputVoltageFeedBack;
_deviceData.ResistanceLimitMax = ResistanceLimitMax;
_deviceData.Resistance = Resistance;
_deviceData.IsResistanceOutOfRange = IsResistanceOutOfRange;
_deviceData.IsResistanceTooHigh = IsResistanceTooHigh;
return JsonConvert.SerializeObject(_deviceData);
}
}
public Func<bool, bool> FuncCheckInterLock { get; set; }
#endregion
#region Methods
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.OutputVoltageFeedBack", () => OutputVoltageFeedBack);
DATA.Subscribe($"{Module}.{Name}.OutputArmsFeedBack", () => OutputArmsFeedBack);
DATA.Subscribe($"{Module}.{Name}.ResistanceLimitMax", () => ResistanceLimitMax);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.IsResistanceOutOfRange", () => IsResistanceOutOfRange);
DATA.Subscribe($"{Module}.{Name}.IsResistanceTooHigh", () => IsResistanceTooHigh);
DATA.Subscribe($"{Module}.{Name}.OutputPowerFeedBack", () => OutputPowerFeedBack);
DATA.Subscribe($"{Module}.{Name}.StatusFeedBack", () => StatusFeedBack);
DATA.Subscribe($"{Module}.{Name}.SimVoltageFeedBack", () => SimVoltageFeedBack);
@ -199,26 +179,27 @@ namespace SicPM.Devices
DATA.Subscribe($"{Module}.{Name}.ConstantSetPoint", () => ConstantSetPoint);
DATA.Subscribe($"{Module}.{Name}.AlarmFeedBack", () => AlarmFeedBack);
DATA.Subscribe($"{Module}.{Name}.AllHeatEnable", () => AllHeatEnable);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
OP.Subscribe($"{Module}.{Name}.SetHeadHeaterEnable", (function, args) =>
{
bool isTrue = Convert.ToBoolean(args[0]);
SetHeadHeaterEnable(isTrue, out reason);
var isTrue = Convert.ToBoolean(args[0]);
SetHeadHeaterEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetPSUEnable", (function, args) =>
{
bool isTrue = Convert.ToBoolean(args[0]);
SetPSUEnable(isTrue, out reason);
var isTrue = Convert.ToBoolean(args[0]);
SetPSUEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetPSUReset", (function, args) =>
{
bool isTrue = Convert.ToBoolean(args[0]);
SetPSUReset(isTrue, out reason);
var isTrue = Convert.ToBoolean(args[0]);
SetPSUReset(isTrue, out _);
return true;
});
@ -227,8 +208,6 @@ namespace SicPM.Devices
public bool SetPSUEnable(bool setValue, out string reason)
{
reason = "";
if (!_doStatus.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
@ -269,6 +248,7 @@ namespace SicPM.Devices
EV.PostWarningLog(Module, reason);
return false;
}
if (!_doHeatEnable.SetValue(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
@ -280,8 +260,6 @@ namespace SicPM.Devices
public bool SetPSUReset(bool setValue, out string reason)
{
reason = "";
if (!_doReset.Check(setValue, out reason))
{
EV.PostWarningLog(Module, reason);
@ -292,7 +270,8 @@ namespace SicPM.Devices
EV.PostWarningLog(Module, reason);
return false;
}
_timer.Start(1000);
_timResetPulse.Start(1000);
return true;
}
@ -305,22 +284,26 @@ namespace SicPM.Devices
{
}
public void Monitor()
protected override void HandleMonitor()
{
try
{
MonitorEnableTimer();
MonitorAlarm();
if (_timer.IsTimeout())
if (_timResetPulse.IsTimeout())
{
_timer.Stop();
_timResetPulse.Stop();
}
else if (_timer.IsIdle())
else if (_timResetPulse.IsIdle())
{
if (_doReset.Value)
{
_doReset.Value = false;
}
// 电阻检测复位
_trigResOutOfRange.RST = true;
_timResCheck.Stop();
}
}
@ -335,70 +318,75 @@ namespace SicPM.Devices
{
_alarmTrig.RST = true;
_commAlarmTrig.RST = true;
_trigVoltage.RST = true;
_trigCurrent.RST = true;
_trigResOutOfRange.RST = true;
_timResCheck.Stop();
}
private void MonitorAlarm()
{
//_alarmTrig.CLK = _diAlarm != null && _diAlarm.Value && !String.IsNullOrEmpty(_infoText);
//if (_alarmTrig.Q)
//{
// EV.PostAlarmLog(Module, _infoText);
//}
//检查电阻值是否在合理范围
_resLimitMax = (float)SC.GetValue<double>($"PM.{Module}.Heater.{Name}ResistanceMax");
var timeOut = SC.GetValue<int>($"PM.{Module}.Heater.ResistanceCheckTimeOut");
//_commAlarmTrig.CLK = _diCommunicationError != null && _diCommunicationError.Value && !String.IsNullOrEmpty(_commInfoText);
//if (_commAlarmTrig.Q)
//{
// EV.PostWarningLog(Module, _commInfoText);
//}
}
private bool isActiveRecord = false;
private void MonitorEnableTimer()
{
if (base.Name == "PSU2")
if (Resistance > _resLimitMax && _timResCheck.IsIdle())
{
_enableTrig.CLK = AETemp2 < 650 && !_diHeatEnable.Value;
if (_enableTrig.Q)
{
if (isActiveRecord)
{
HeatEnableDataRecorder.StartHeatEnableTime();
}
}
_timResCheck.Start(timeOut * 1000);
}
_enableTrig2.CLK = AETemp2 > 650 || _diHeatEnable.Value;
if (_enableTrig2.Q)
{
isActiveRecord = true;
HeatEnableDataRecorder.ClearHeatEnableTime();
}
if (Resistance <= _resLimitMax)
{
IsResistanceTooHigh = false;
_timResCheck.Stop();
}
_trigResOutOfRange.CLK = _timResCheck.IsTimeout();
if (_trigResOutOfRange.Q)
{
IsResistanceTooHigh = true;
EV.PostWarningLog(Module, $"{Name} Current resistance {Resistance}ohm exceeds the high limit {_resLimitMax}ohm.");
}
}
private void MonitorEnableTimer()
{
if (Name == "PSU2")
{
_enableTrig.CLK = !_diHeatEnable.Value;
if (_enableTrig.Q)
{
SC.SetItemValue($"PM.{Module}.OpenLidCountDownTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
public double AETemp2
_enableTrig2.CLK = _diHeatEnable.Value;
if (_enableTrig2.Q)
{
SC.SetItemValue($"PM.{Module}.OpenLidCountDownTime", "");
}
}
}
public double AETemp
{
get
{
if (_AETempEnable.BoolValue && base.Name== "PSU2")
var temp = new object();
if (SC.GetConfigItem("AETemp.EnableDevice").BoolValue)
{
try
{
object temp1 = DATA.Poll($"{Module}.AETemp.AETemp2");
return temp1 == null ? 0 : (double)temp1;
}
catch (Exception ex)
{
return 0;
}
temp = DATA.Poll($"{Module}.AETemp.Middle");
}
return 0;
}
if (SC.GetConfigItem("AKunTemp.EnableDevice").BoolValue)
{
temp = DATA.Poll($"{Module}.AKunTemp.Middle");
}
return temp == null ? 0 : (double)temp;
}
}
#endregion
}
}

View File

@ -1,117 +1,127 @@
using Aitex.Core.RT.DataCenter;
using Aitex.Core.Common.DeviceData.IoDevice;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.IOCore;
using Aitex.Core.RT.Log;
using Aitex.Core.RT.OperationCenter;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using System;
using System.Xml;
using Newtonsoft.Json;
using Formatting = Newtonsoft.Json.Formatting;
namespace SicPM.Devices
{
public class IoSCR : BaseDevice, IDevice
{
#region Variables
private const float DEF_RES_LIMIT_MAX_OHM = 3;
private readonly string _scResLimitMax;
private float _resLimitMax;
public float VoltageFeedBack
private readonly bool _isFloatAioType = true;
private readonly AIAccessor _aiVoltage;
private readonly AIAccessor _aiArms;
private readonly AIAccessor _aiPower;
private readonly DIAccessor _diStatus;
private DIAccessor _diAlarm;
private readonly DOAccessor _doStatus;
private readonly DOAccessor _doReset;
private readonly DeviceTimer _timResetPulse = new();
private readonly R_TRIG _trigResOutOfRange = new();
private readonly DeviceTimer _timResCheck = new();
private readonly IoPsuData _deviceData = new();
#endregion
#region Constructors
public IoSCR(string module, XmlElement node, string ioModule = "") : base(module, node, ioModule)
{
get
{
return _aiVoltage == null ? 0 : (_isFloatAioType ? _aiVoltage.FloatValue : _aiVoltage.Value);
}
}
public float ArmsFeedBack
{
get
{
return _aiArms == null ? 0 : (_isFloatAioType ? _aiArms.FloatValue : _aiArms.Value);
}
}
public float PowerFeedBack
{
get
{
return _aiPower == null ? 0 : (_isFloatAioType ? _aiPower.FloatValue : _aiPower.Value);
}
}
public bool StatusFeedBack
{
get
{
return _diStatus == null ? false : _diStatus.Value;
}
}
public float Resistance
{
get
{
return ArmsFeedBack == 0 ? 0 : VoltageFeedBack / ArmsFeedBack;
}
}
private bool _isFloatAioType = true;
private AIAccessor _aiVoltage = null;
private AIAccessor _aiArms = null;
private AIAccessor _aiPower = null;
private DIAccessor _diStatus = null;
private DIAccessor _diAlarm = null;
private DOAccessor _doStatus = null;
private DOAccessor _doReset = null;
private DeviceTimer _timer = new DeviceTimer();
private string _infoText = "";
private R_TRIG _alarmTrig = new R_TRIG();
public IoSCR(string module, XmlElement node, string ioModule = "")
{
var attrModule = node.GetAttribute("module");
base.Module = string.IsNullOrEmpty(attrModule) ? module : attrModule;
base.Name = node.GetAttribute("id");
base.Display = node.GetAttribute("display");
base.DeviceID = node.GetAttribute("schematicId");
_aiVoltage = ParseAiNode("aiVoltage", node, ioModule);
_aiArms = ParseAiNode("aiArms", node, ioModule);
_aiPower = ParseAiNode("aiPower", node, ioModule);
_diStatus = ParseDiNode("diStatus", node, ioModule);
_doReset = ParseDoNode("doReset", node, ioModule);
_doStatus = ParseDoNode("doStatus", node, ioModule);
_doStatus = ParseDoNode("doStatus", node, ioModule);
_diAlarm = ParseDiNode("diAlarm", node, ioModule);
_infoText = node.GetAttribute("AlarmText");
_isFloatAioType = !string.IsNullOrEmpty(node.GetAttribute("aioType")) && (node.GetAttribute("aioType") == "float");
// 读取电阻上限设定值
_scResLimitMax = node.GetAttribute("scResLimitMax");
}
string reason = string.Empty;
#endregion
#region Properties
public float VoltageFeedBack => _aiVoltage == null ? 0 : (_isFloatAioType ? _aiVoltage.FloatValue : _aiVoltage.Value);
public float ArmsFeedBack => _aiArms == null ? 0 : (_isFloatAioType ? _aiArms.FloatValue : _aiArms.Value);
public float ResistanceLimitMax => _resLimitMax;
public float Resistance => ArmsFeedBack == 0 ? 0 : VoltageFeedBack / ArmsFeedBack;
public bool IsResistanceOutOfRange => IsResistanceTooHigh;
public bool IsResistanceTooHigh { get; private set; }
public float PowerFeedBack => _aiPower == null ? 0 : (_isFloatAioType ? _aiPower.FloatValue : _aiPower.Value);
public bool StatusFeedBack => _diStatus == null ? false : _diStatus.Value;
private string DeviceData
{
get
{
_deviceData.IsAlarm = false;
_deviceData.OutputStatusFeedBack = StatusFeedBack;
_deviceData.OutputArmsFeedBack = ArmsFeedBack;
_deviceData.OutputPowerFeedBack = PowerFeedBack;
_deviceData.OutputVoltageFeedback = VoltageFeedBack;
_deviceData.ResistanceLimitMax = ResistanceLimitMax;
_deviceData.Resistance = Resistance;
_deviceData.IsResistanceOutOfRange = IsResistanceOutOfRange;
_deviceData.IsResistanceTooHigh = IsResistanceTooHigh;
return JsonConvert.SerializeObject(_deviceData);
}
}
#endregion
#region Methods
public bool Initialize()
{
DATA.Subscribe($"{Module}.{Name}.VoltageFeedBack", () => VoltageFeedBack);
DATA.Subscribe($"{Module}.{Name}.ArmsFeedBack", () => ArmsFeedBack);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.PowerFeedBack", () => PowerFeedBack);
DATA.Subscribe($"{Module}.{Name}.StatusFeedBack", () => StatusFeedBack);
DATA.Subscribe($"{Module}.{Name}.Resistance", () => Resistance);
DATA.Subscribe($"{Module}.{Name}.DeviceData", () => DeviceData);
OP.Subscribe($"{Module}.{Name}.SetEnable", (function, args) =>
{
bool isTrue = Convert.ToBoolean(args[0]);
SetEnable(isTrue, out reason);
var isTrue = Convert.ToBoolean(args[0]);
SetEnable(isTrue, out _);
return true;
});
OP.Subscribe($"{Module}.{Name}.SetReset", (function, args) =>
{
bool isTrue = Convert.ToBoolean(args[0]);
SetReset(isTrue, out reason);
var isTrue = Convert.ToBoolean(args[0]);
SetReset(isTrue, out _);
return true;
});
@ -121,7 +131,6 @@ namespace SicPM.Devices
public bool SetEnable(bool setValue, out string reason)
{
reason = "";
if (!_doStatus.Check(setValue, out reason))
return false;
if (!_doStatus.SetValue(setValue, out reason))
@ -134,8 +143,6 @@ namespace SicPM.Devices
public bool SetReset(bool setValue, out string reason)
{
reason = "";
if (!_doReset.Check(setValue, out reason))
return false;
if (!_doReset.SetValue(setValue, out reason))
@ -143,7 +150,7 @@ namespace SicPM.Devices
return false;
}
_timer.Start(1000);
_timResetPulse.Start(1000);
return true;
}
@ -157,21 +164,25 @@ namespace SicPM.Devices
{
}
public void Monitor()
protected override void HandleMonitor()
{
try
{
MonitorAlarm();
if (_timer.IsTimeout())
if (_timResetPulse.IsTimeout())
{
_timer.Stop();
_timResetPulse.Stop();
}
else if (_timer.IsIdle())
else if (_timResetPulse.IsIdle())
{
if (_doReset.Value)
{
_doReset.Value = false;
}
// 电阻检测复位
_trigResOutOfRange.RST = true;
_timResCheck.Stop();
}
}
@ -184,16 +195,53 @@ namespace SicPM.Devices
public void Reset()
{
_trigResOutOfRange.RST = true;
_timResCheck.Stop();
}
private void MonitorAlarm()
{
//_alarmTrig.CLK = _diAlarm != null && _diAlarm.Value && !String.IsNullOrEmpty(_infoText);
//if (_alarmTrig.Q)
//{
// EV.PostWarningLog(Module, _infoText);
//}
//检查电阻值是否在合理范围
_resLimitMax = (float)SC.GetValue<double>($"PM.{Module}.Heater.{Name}ResistanceMax");
var timeOut = SC.GetValue<int>($"PM.{Module}.Heater.ResistanceCheckTimeOut");
if (Resistance > _resLimitMax && _timResCheck.IsIdle())
{
_timResCheck.Start(timeOut * 1000);
}
if (Resistance <= _resLimitMax)
{
IsResistanceTooHigh = false;
_timResCheck.Stop();
}
_trigResOutOfRange.CLK = _timResCheck.IsTimeout();
if (_trigResOutOfRange.Q)
{
IsResistanceTooHigh = true;
EV.PostWarningLog(Module, $"{Name} Current resistance {Resistance}ohm exceeds the high limit {_resLimitMax}ohm.");
}
}
public double AETemp
{
get
{
var temp = new object();
if (SC.GetConfigItem("AETemp.EnableDevice").BoolValue)
{
temp = DATA.Poll($"{Module}.AETemp.Middle");
}
if (SC.GetConfigItem("AKunTemp.EnableDevice").BoolValue)
{
temp = DATA.Poll($"{Module}.AKunTemp.Middle");
}
return temp == null ? 0 : (double)temp;
}
}
#endregion
}
}

View File

@ -22,6 +22,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@ -30,11 +31,16 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="MECF.Framework.Common">
<HintPath>..\..\FrameworkLocal\MECF.Framework.Common.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\ThirdParty\dlls\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -50,6 +56,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Devices\AdsIoProvider.cs" />
<Compile Include="Devices\DeviceBaseEx.cs" />
<Compile Include="Devices\IoBottomSection.cs" />
<Compile Include="Devices\IoChamberMoveBody.cs" />
<Compile Include="Devices\IoConfinementRing.cs" />

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28729.10
# Visual Studio Version 17
VisualStudioVersion = 17.6.33815.320
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SicRT", "SicRT\SicRT.csproj", "{5EAFA05F-C2C0-40B3-9C8F-46D8559148D0}"
ProjectSection(ProjectDependencies) = postProject
@ -123,7 +123,6 @@ Global
{A40B734C-F2EC-453C-A5FB-70CD46452BF1}.Release|x86.ActiveCfg = Release|Any CPU
{A40B734C-F2EC-453C-A5FB-70CD46452BF1}.Release|x86.Build.0 = Release|Any CPU
{C842F167-DB8E-4827-ACDD-74215AF5100A}.Debug|Any CPU.ActiveCfg = Debug|x86
{C842F167-DB8E-4827-ACDD-74215AF5100A}.Debug|Any CPU.Build.0 = Debug|x86
{C842F167-DB8E-4827-ACDD-74215AF5100A}.Debug|x86.ActiveCfg = Debug|x86
{C842F167-DB8E-4827-ACDD-74215AF5100A}.Debug|x86.Build.0 = Debug|x86
{C842F167-DB8E-4827-ACDD-74215AF5100A}.Release|Any CPU.ActiveCfg = Release|x86

View File

@ -89,8 +89,7 @@
<config default="false" name="IsIsolationRoutine" description="是否Recipe的形式运行Isolation" max="" min="" paramter="" tag="" unit="" type="Bool" />
<config default="false" name="IsLeakCheckRoutine" description="是否Recipe的形式运行LeakCheck" max="" min="" paramter="" tag="" unit="" type="Bool" />
<config default="false" name="IsAbortRoutine" description="是否Recipe的形式运行Abort" max="" min="" paramter="" tag="" unit="" type="Bool" />
<config default="180" name="LidEnableOpenAfterHeatDisbaleMinuts" description="在加热停止多少分钟后才能执行开腔" max="100000" min="1" paramter="" tag="" unit="s" type="Integer" />
<config default="180" name="LidEnableOpenAfterHeatDisbaleTime" description="在加热停止多少分钟后才能执行开腔" max="1000" min="1" paramter="" tag="" unit="Minute" type="Integer" />
<configs name="PM1">
<config default="Sic" name="RecipeChamberType" description="Recipe Chamber Type" max="" min="" paramter="" tag="" unit="" type="String" />
<config default="" name="LastRecipeName" description="last recipe name" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
@ -104,8 +103,8 @@
<config default="0" name="ThrottlePositionDefaultValue" description="蝶阀位置模式默认值" max="100" min="0" paramter="" tag="" unit="s" type="Double" />
<config default="1100" name="ThrottlePressureDefaultValue" description="蝶阀压力模式默认值" max="1500" min="0" paramter="" tag="" unit="s" type="Double" />
<config default="50" name="PT1MinusPT2BigLimit" description="开启EPV1条件,PT1的压力减去PT2的压力小于此数值" max="200" min="0" paramter="" tag="" unit="mbar" type="Integer" />
<config default="-2" name="PT1MinusPT2SmallLimit" description="开启EPV1条件,PT1的压力减去PT2的压力大于此数值" max="0" min="-200" paramter="" tag="" unit="mbar" type="Integer" />
<config default="1000" name="CloseEPV1NeedPT1Limit" description="关闭EPV1条件,PT1的压力大于此数值" max="1200" min="0" paramter="" tag="" unit="mbar" type="Integer" />
<config default="-2" name="PT1MinusPT2SmallLimit" description="开启EPV1条件,PT1的压力减去PT2的压力大于此数值" max="0" min="-200" paramter="" tag="" unit="mbar" type="Integer" />
<config default="1000" name="CloseEPV1NeedPT1Limit" description="关闭EPV1条件,PT1的压力大于此数值" max="1200" min="0" paramter="" tag="" unit="mbar" type="Integer" />
<config default="5" name="EPV2OpenTimeDelayAlterEPV1Open" description="EPV1开启多长时间后才能开启EPV2" max="100" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="9" name="TimeDelayAlterEPV2Open" description="EPV2开启后需要等待多长时间" max="100" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="400" name="ThrottlePositionModeMinPressure" description="蝶阀允许位置模式需要的最大压力值" max="1100" min="0" paramter="" tag="" unit="s" type="Double" />
@ -117,8 +116,8 @@
<config default="0" name="PC7Offset" description="PC7 Offset" max="10000" min="-10000" paramter="" tag="" unit="mbar" type="Double" />
<config default="3000*10,10000*10,15000*10,20000*10,25000*10,30000*10,35000*10,40000*10,45000*10,50000*10" name="MFC28DynamicFlow" description="MFC28 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="1000*10,3000*10,5000*10,6000*10,7000*10,8000*10,9000*10,10000*10,11000*10,12000*10" name="MFC29DynamicFlow" description="MFC29 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="1500*10,5000*10,11000*10,14000*10,17000*10,20000*10,23000*10,26000*10,29000*10,32000*10" name="MFC31DynamicFlow" description="MFC31 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="1500*10,5000*10,11000*10,14000*10,17000*10,20000*10,23000*10,26000*10,29000*10,32000*10" name="MFC40DynamicFlow" description="MFC40 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="1500*10,5000*10,11000*10,14000*10,17000*10,20000*10,23000*10,26000*10,29000*10,32000*10" name="MFC31DynamicFlow" description="MFC31 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="1500*10,5000*10,11000*10,14000*10,17000*10,20000*10,23000*10,26000*10,29000*10,32000*10" name="MFC40DynamicFlow" description="MFC40 动态流量" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="false" name="PreTransferPSUEnable" description="传盘是否开启PSU加热" max="" min="" paramter="" tag="" unit="" type="Bool" />
<config default="false" name="PreTransferSCREnable" description="传盘是否开启SCR加热" max="" min="" paramter="" tag="" unit="" type="Bool" />
<config default="1000" name="ReactorPressRisingRateLimit" description="腔体压力上升速率超速报警" max="1000" min="0" paramter="" tag="" unit="mbar/s" type="Double" />
@ -144,9 +143,9 @@
<config default="Sic\Routine\Isolation" name="IsolationFileName" description="Isolation Routine文件路径" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="Sic\Routine\LeakCheck" name="LeakCheckFileName" description="LeakCheck Routine文件路径" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="Sic\Routine\Abort" name="AbortFileName" description="Abort Routine文件路径" max="" min="" paramter="" tag="" visible="false" unit="" type="String" />
<config default="" name="OpenLidCountDownTime" visible="true" description="临时保存开腔倒计时开始时间" max="" min="" paramter="" tag="" unit="" type="String"/>
<configs name="Heater">
<config default="false" name="PSUOuterAutoEnable" description="PSU Outer是否为Auto控制" max="" min="" paramter="" tag="" unit="" visible="true" type="Bool" />
<config default="false" name="PSUOuterAutoEnable" description="PSU Outer是否为Auto控制" max="" min="" paramter="" tag="" unit="" visible="true" type="Bool" />
<config default="10" name="TempRampRate" description="TC温度每秒调节速率(℃/每秒)" max="100" min="0" paramter="" tag="" unit="℃" type="Double" />
<config default="0.1" name="AmpereRampRate" description="TC1功率每秒调节速率(%/每秒)" max="100" min="0" paramter="" tag="" unit="%" type="Double" />
<config default="0.1" name="KWRampRate" description="TC2功率每秒调节速率(%/每秒)" max="100" min="0" paramter="" tag="" unit="%" type="Double" />
@ -169,7 +168,14 @@
<config default="900" name="SCRUpperTempLowLimit" description="SCR Upper Temp Low Limit(℃)" max="2000" min="0" paramter="" tag="" unit="℃" type="Double" />
<config default="900" name="SCRMiddleTempLowLimit" description="SCR Middle Temp Low Limit(℃)" max="2000" min="0" paramter="" tag="" unit="℃" type="Double" />
<config default="900" name="SCRLowerTempLowLimit" description="SCR Lower Temp Low Limit(℃)" max="2000" min="0" paramter="" tag="" unit="℃" type="Double" />
<config default="1" name="PSU1ResistanceMax" description="Max PSU Inner Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="1" name="PSU2ResistanceMax" description="Max PSU Middle Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="1" name="PSU3ResistanceMax" description="Max PSU Outer Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="1" name="SCR1ResistanceMax" description="Max SCR Upper Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="1" name="SCR2ResistanceMax" description="Max SCR Middle Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="1" name="SCR3ResistanceMax" description="Max SCR Lower Resistance Max Limit" max="1000" min="0" paramter="" tag="" unit="Ω" type="Double" />
<config default="3" name="ResistanceCheckTimeOut" description="Resistance Check kTime Out" max="1000" min="0" paramter="" tag="" unit="s" type="Integer" />
<config default="false" name="AETempRasingFastIsAlarm" description="AETemp温度上升过快报警类型为Alarm" max="" min="" paramter="" tag="" unit="" visible="true" type="Bool" />
<config default="100" name="AETempInnerRasingRate" description="AETemp Inner每秒的上升速率,超过此范围报警" max="2000" min="0" paramter="" tag="" unit="℃" type="Double" />

View File

@ -41,6 +41,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -50,6 +51,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\MyLogoTray.ico</ApplicationIcon>

View File

@ -25,6 +25,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
@ -35,6 +36,7 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<StartupObject />

View File

@ -13,7 +13,7 @@
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<TargetFrameworkProfile />
<DisableOutOfProcTaskHost>true</DisableOutOfProcTaskHost>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
@ -25,6 +25,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -34,6 +35,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Resources\MyLogoPurple.ico</ApplicationIcon>

View File

@ -1,21 +1,12 @@
using Aitex.Core.Common.DeviceData;
using Aitex.Core.RT.Event;
using Aitex.Core.RT.SCCore;
using Aitex.Core.Util;
using Aitex.Core.Util;
using Caliburn.Micro;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.OperationCenter;
using MECF.Framework.UI.Client.ClientBase;
using SicUI.Controls;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace SicUI.Models.PMs
@ -43,7 +34,7 @@ namespace SicUI.Models.PMs
protected override void OnActivate()
{
base.OnActivate();
CheckHeatConditionOK();
CheckHeatConditionOK(out _);
}
protected override void InvokeAfterUpdateProperty(Dictionary<string, object> data)
@ -345,19 +336,20 @@ namespace SicUI.Models.PMs
public void ChamberMoveBodyOpen()
{
if (String.IsNullOrEmpty(SelectedMoveBodyGroup.Trim()))
if (!CheckHeatConditionOK(out var leftTime))
{
return;
}
CheckHeatConditionOK();
//string strTips = $"Are you sure want to open the chamber lid? ";
//if (HeatEnableTips == Visibility.Visible)
//{
// strTips = $"Are you sure want to open the chamber lid? \r\nBe Care full of High Temperature!";
//}
var strTips = $"The temperature is too high to open the Lid. \r\nWait for {leftTime:0.0} minutes before opening it";
if (ShowChoosenDialog(strTips))
{
string strTips = $"Are you sure want to open the chamber lid? ";
if (HeatEnableTips == Visibility.Visible)
{
strTips = $"Are you sure want to open the chamber lid? \r\nBe Carefull of High Temperature!";
}
}
if (ShowChoosenDialog(strTips))
else
{
InvokeClient.Instance.Service.DoOperation($"{SystemName}.ChamberMoveBodyOpen", SelectedMoveBodyGroup, true);
}
@ -370,24 +362,25 @@ namespace SicUI.Models.PMs
}
}
private void CheckHeatConditionOK()
private bool CheckHeatConditionOK(out double minuts)
{
int lidopenAfterHeatDisbaleMinuts = (int)QueryDataClient.Instance.Service.GetConfig("PM.LidEnableOpenAfterHeatDisbaleMinuts");
string sql = string.Format("select * from \"heatenable_data\" where \"start_time\">'{0}' and \"start_time\"<'{1}'",
DateTime.Now.AddDays(-10).ToString("yyyy-MM-dd HH:mm:ss"),
DateTime.Now.AddMinutes(-1 * lidopenAfterHeatDisbaleMinuts).ToString("yyyy-MM-dd HH:mm:ss"));
DataTable dbData = QueryDataClient.Instance.Service.QueryData(sql);
if (dbData == null || dbData.Rows.Count == 0)
minuts = 0;
var lidopenAfterHeatDisbaleMinuts = (int)QueryDataClient.Instance.Service.GetConfig("PM.LidEnableOpenAfterHeatDisbaleTime");
var dateTimeStr = QueryDataClient.Instance.Service.GetConfig($"PM.{SystemName}.OpenLidCountDownTime").ToString();
var dtStartTime = DateTime.Now;
if (DateTime.TryParse(dateTimeStr, out dtStartTime))
{
HeatEnableTips = Visibility.Visible;
}
else
{
HeatEnableTips = Visibility.Collapsed;
minuts = lidopenAfterHeatDisbaleMinuts - (DateTime.Now - dtStartTime).TotalMinutes;
if (dtStartTime.AddMinutes(lidopenAfterHeatDisbaleMinuts) < DateTime.Now)
{
HeatEnableTips = Visibility.Collapsed;
return true;
}
}
HeatEnableTips = Visibility.Visible;
return false;
}
#endregion OP
#region EnableProperties
@ -514,7 +507,5 @@ namespace SicUI.Models.PMs
{
InvokeClient.Instance.Service.DoOperation($"{SystemName}.OmronTemp.SetEnable", !OmronTempEnable);
}
}
}

View File

@ -14,6 +14,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:pm="clr-namespace:SicUI.Models.PMs"
xmlns:system="clr-namespace:System;assembly=mscorlib"
xmlns:controls="clr-namespace:MECF.Framework.UI.Client.Ctrlib.Controls;assembly=MECF.Framework.UI.Client"
d:DesignHeight="780"
d:DesignWidth="1900"
Background="#91b0cd"
@ -2057,6 +2058,94 @@
</TabControl>
</TabItem>
<TabItem Header="Resistance">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Border
Grid.Row="0"
Grid.Column="0"
Background="{DynamicResource Table_BG_Title_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="1 1 1 1">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Arial"
FontSize="14"
Foreground="{DynamicResource FG_Black}"
Text="Name"
TextWrapping="Wrap" />
</Border>
<Border
Grid.Row="0"
Grid.Column="1"
Padding="5,1"
Background="{DynamicResource Table_BG_Title_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="0 1 1 1">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Arial"
FontSize="14"
Foreground="{DynamicResource FG_Black}"
Text="State"
TextWrapping="Wrap" />
</Border>
<Border
Grid.Row="0"
Grid.Column="2"
Padding="5,1"
Background="{DynamicResource Table_BG_Title_Inner}"
BorderBrush="{DynamicResource Table_BD}"
BorderThickness="0 1 1 1">
<TextBlock
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontFamily="Arial"
FontSize="14"
Foreground="{DynamicResource FG_Black}"
Text="R (Ω)"
TextWrapping="Wrap" />
</Border>
<StackPanel Grid.ColumnSpan="3" Grid.Column="0" Grid.Row="1">
<controls:HeaterResPresenter
Caption="PSU1 Resistance(Ω)"
DataContext="{Binding PSU1Data}"/>
<controls:HeaterResPresenter
Caption="PSU2 Resistance(Ω)"
DataContext="{Binding PSU2Data}"/>
<controls:HeaterResPresenter
Caption="PSU3 Resistance(Ω)"
DataContext="{Binding PSU3Data}"/>
<controls:HeaterResPresenter
Caption="SCR1 Resistance(Ω)"
DataContext="{Binding SCR1Data}"/>
<controls:HeaterResPresenter
Caption="SCR2 Resistance(Ω)"
DataContext="{Binding SCR2Data}"/>
<controls:HeaterResPresenter
Caption="SCR3 Resistance(Ω)"
DataContext="{Binding SCR3Data}"/>
</StackPanel>
</Grid>
</TabItem>
</TabControl>
</Border>

View File

@ -15,6 +15,9 @@ using Aitex.Core.UI.MVVM;
using System.Windows;
using SicUI.Controls;
using System.Windows.Media;
using Aitex.Core.Common.DeviceData.IoDevice;
using Newtonsoft.Json;
using SicPM.Devices;
namespace SicUI.Models.PMs
{
@ -755,6 +758,49 @@ namespace SicUI.Models.PMs
#endregion
[Subscription("SCR1.DeviceData")]
public string SCR1DataJson { get; set; }
public IoPsuData SCR1Data => string.IsNullOrEmpty(SCR1DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(SCR1DataJson);
[Subscription("SCR2.DeviceData")]
public string SCR2DataJson { get; set; }
public IoPsuData SCR2Data => string.IsNullOrEmpty(SCR2DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(SCR2DataJson);
[Subscription("SCR3.DeviceData")]
public string SCR3DataJson { get; set; }
public IoPsuData SCR3Data => string.IsNullOrEmpty(SCR3DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(SCR3DataJson);
[Subscription("PSU1.DeviceData")]
public string PSU1DataJson { get; set; }
public IoPsuData PSU1Data => string.IsNullOrEmpty(PSU1DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(PSU1DataJson);
[Subscription("PSU2.DeviceData")]
public string PSU2DataJson { get; set; }
public IoPsuData PSU2Data => string.IsNullOrEmpty(PSU2DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(PSU2DataJson);
[Subscription("PSU3.DeviceData")]
public string PSU3DataJson { get; set; }
public IoPsuData PSU3Data => string.IsNullOrEmpty(PSU3DataJson)
? null
: JsonConvert.DeserializeObject<IoPsuData>(PSU3DataJson);
[Subscription("PSU1.AllHeatEnable")]
public bool AllHeatEnable { get; set; }
@ -1562,6 +1608,11 @@ namespace SicUI.Models.PMs
public ICommand CmdTurnGasValve { get; set; }
public ICommand CmdSetMfcFlow { get; set; }
protected override void Poll()
{
base.Poll();
}
private void PerformCmdTvEnable(object data)
{
var pair = (KeyValuePair<string, string>)data;

View File

@ -35,6 +35,7 @@
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@ -44,6 +45,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Themes\MyLogoNormal.ico</ApplicationIcon>
@ -74,6 +76,10 @@
<HintPath>..\ThirdParty\dlls\Microsoft.Expression.Drawing.dll</HintPath>
</Reference>
<Reference Include="Microsoft.VisualBasic" />
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\ThirdParty\dlls\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework.Aero" />
<Reference Include="presentationframework.aero2" />
<Reference Include="SciChart.Charting, Version=6.0.1.12982, Culture=neutral, PublicKeyToken=b55dd9efe817e823, processorArchitecture=MSIL">