Commit 6bea58e7 authored by 潘栩锋's avatar 潘栩锋 🚴

1. 添加 称重服务器,添加生成V3 的 plcgroups.json, 以后不需要再手动放入V3

parent b37ca779
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="PLCGroup.cs" />
<Compile Include="WdSetup.xaml.cs"> <Compile Include="WdSetup.xaml.cs">
<DependentUpon>WdSetup.xaml</DependentUpon> <DependentUpon>WdSetup.xaml</DependentUpon>
</Compile> </Compile>
...@@ -152,10 +153,16 @@ ...@@ -152,10 +153,16 @@
<PackageReference Include="NLog"> <PackageReference Include="NLog">
<Version>4.6.8</Version> <Version>4.6.8</Version>
</PackageReference> </PackageReference>
<PackageReference Include="PropertyChanged.Fody">
<Version>3.3.1</Version>
</PackageReference>
<PackageReference Include="System.Data.SQLite"> <PackageReference Include="System.Data.SQLite">
<Version>1.0.112</Version> <Version>1.0.112</Version>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Resource Include="FodyWeavers.xml" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets. Other similar extension points exist, see Microsoft.Common.targets.
......
<?xml version="1.0" encoding="utf-8"?> <Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> <PropertyChanged />
<Costura /> <Costura />
</Weavers> </Weavers>
\ No newline at end of file
...@@ -4,6 +4,55 @@ ...@@ -4,6 +4,55 @@
<xs:element name="Weavers"> <xs:element name="Weavers">
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventInvokerNames" type="xs:string">
<xs:annotation>
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEquality" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressWarnings" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="Costura" minOccurs="0" maxOccurs="1"> <xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType> <xs:complexType>
<xs:all> <xs:all>
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FLY.Weight.UI.Server
{
public class PLCGroup
{
public class PLCDevice
{
public string EP;
}
public class PLCVariable
{
/// <summary>
/// 设备序号
/// </summary>
public int DeviceIndex;
/// <summary>
/// 0,1,3,4
/// </summary>
public string Mode;
/// <summary>
/// 地址
/// </summary>
public int Addr;
/// <summary>
/// 类型 只有 bool 才对应 bool, 其它数值类型 都转为 float
/// </summary>
public string Type;
/// <summary>
/// 放大倍数
/// </summary>
public double Scale;
/// <summary>
/// 属性拥有者名称
/// </summary>
public string OwnerName;
/// <summary>
/// 属性名称
/// </summary>
public string PropertyName;
}
public List<PLCDevice> Devices = new List<PLCDevice>();
public List<PLCVariable> Variables = new List<PLCVariable>();
}
}
...@@ -6,19 +6,41 @@ ...@@ -6,19 +6,41 @@
xmlns:local="clr-namespace:FLY.Weight.UI.Server" xmlns:local="clr-namespace:FLY.Weight.UI.Server"
mc:Ignorable="d" mc:Ignorable="d"
Title="WdSetup" SizeToContent="WidthAndHeight" > Title="WdSetup" SizeToContent="WidthAndHeight" >
<Window.Resources>
<ResourceDictionary>
<local:BinCntsConverter x:Key="binCntsConv"/>
</ResourceDictionary>
</Window.Resources>
<Grid> <Grid>
<StackPanel Orientation="Horizontal"> <StackPanel>
<StackPanel Margin="5"> <GroupBox Header="配置文件">
<TextBlock Text="plcgroup配置文件" Margin="2"/> <StackPanel Orientation="Horizontal">
<ComboBox MinWidth="200" Margin="2" x:Name="comboBox" > <StackPanel Margin="5">
<ComboBox.ItemTemplate> <TextBlock Text="plcgroup配置文件" Margin="2"/>
<DataTemplate> <ComboBox MinWidth="200" Margin="2" ItemsSource="{Binding PlcGroupItems}" SelectedItem="{Binding SelectedItem}">
<TextBlock Text="{Binding Name}"/> <ComboBox.ItemTemplate>
</DataTemplate> <DataTemplate>
</ComboBox.ItemTemplate> <TextBlock Text="{Binding Name}"/>
</ComboBox> </DataTemplate>
</StackPanel> </ComboBox.ItemTemplate>
<Button Content="确定" Padding="20,5" Margin="5" Click="btnOkClick"/> </ComboBox>
</StackPanel>
<Button Content="确定" Padding="20,5" Margin="5" Click="btnOkClick"/>
</StackPanel>
</GroupBox>
<GroupBox Header="生成V3配置文件">
<StackPanel Orientation="Horizontal">
<StackPanel Margin="5">
<TextBlock Margin="2"
Text="输入每层仓数(最多7层, 例如:64446)" />
<TextBox Margin="2"
Text="{Binding BinCnts,Converter={StaticResource binCntsConv}}"/>
</StackPanel>
<Button Content="生成" Padding="20,5" Margin="5" Click="btnGenClick"/>
</StackPanel>
</GroupBox>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Window> </Window>
using FLY.OBJComponents.Common; using FLY.OBJComponents.Common;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
...@@ -26,17 +29,46 @@ namespace FLY.Weight.UI.Server ...@@ -26,17 +29,46 @@ namespace FLY.Weight.UI.Server
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
WdSetupVm viewModel;
public WdSetup() public WdSetup()
{ {
InitializeComponent(); InitializeComponent();
Init(); viewModel = new WdSetupVm();
viewModel.Init();
this.DataContext = viewModel;
}
private void btnOkClick(object sender, RoutedEventArgs e)
{
viewModel.Ok();
}
private void btnGenClick(object sender, RoutedEventArgs e)
{
viewModel.GenV3();
}
}
public class WdSetupVm : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[PropertyChanged.DoNotCheckEquality]
public int[] BinCnts { get; set; }
public ObservableCollection<PlcGroupItem> PlcGroupItems { get; } = new ObservableCollection<PlcGroupItem>();
public PlcGroupItem SelectedItem { get; set; }
public WdSetupVm() {
}
public void Init() {
Init_PlcGroupItems();
} }
private void Init() private void Init_PlcGroupItems()
{ {
var items = new List<PlcGroupItem>(); PlcGroupItems.Clear();
//查找 脚本/称重 下的全部 设备连接变量表_xxx 的文件夹 //查找 脚本/称重 下的全部 设备连接变量表_xxx 的文件夹
DirectoryInfo directoryInfo = new DirectoryInfo(@"plcgroups"); DirectoryInfo directoryInfo = new DirectoryInfo(@"plcgroups");
...@@ -54,25 +86,26 @@ namespace FLY.Weight.UI.Server ...@@ -54,25 +86,26 @@ namespace FLY.Weight.UI.Server
PlcGroupItem item = new PlcGroupItem(); PlcGroupItem item = new PlcGroupItem();
item.Name = dir.Name.Substring("设备连接变量表_".Length); item.Name = dir.Name.Substring("设备连接变量表_".Length);
item.Path = System.IO.Path.Combine(dir.FullName, "Generated", "plcgroup.json"); //System.IO.Path.Combine(dir.FullName, "Generated", "plcgroup.json");
items.Add(item); item.Path = $@"plcgroups\{dir.Name}\Generated\plcgroup.json";
PlcGroupItems.Add(item);
} }
} }
comboBox.ItemsSource = items; SelectedItem = null;
foreach (var item in items) foreach (var item in PlcGroupItems)
{ {
if (IsSameContent(item.Path, "plcgroup.json")) if (IsSameContent(item.Path, "plcgroup.json"))
{ {
//找到了 //找到了
comboBox.SelectedItem = item; SelectedItem = item;
break; break;
} }
} }
} }
public static bool IsSameContent(string filePath1, string filePath2) static bool IsSameContent(string filePath1, string filePath2)
{ {
//创建一个哈希算法对象 //创建一个哈希算法对象
using (HashAlgorithm hash = HashAlgorithm.Create()) using (HashAlgorithm hash = HashAlgorithm.Create())
...@@ -89,19 +122,128 @@ namespace FLY.Weight.UI.Server ...@@ -89,19 +122,128 @@ namespace FLY.Weight.UI.Server
} }
} }
} }
private void btnOkClick(object sender, RoutedEventArgs e) public void Ok()
{ {
var item = comboBox.SelectedItem as PlcGroupItem; var item = SelectedItem;
if (item == null) { if (item == null)
{
MessageBox.Show("请选择型号!!!"); MessageBox.Show("请选择型号!!!");
return; return;
} }
if (MessageBox.Show("需要重启,才能生效", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK) { if (MessageBox.Show("需要重启,才能生效", "提示", MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{
File.Copy(item.Path, "plcgroup.json", true); File.Copy(item.Path, "plcgroup.json", true);
//System.Windows.Forms.Application.Restart(); //System.Windows.Forms.Application.Restart();
Application.Current.Shutdown(); Application.Current.Shutdown();
} }
} }
public bool GenV3()
{
if (BinCnts == null || BinCnts.Count() == 0) {
MessageBox.Show("输入格式出错", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
if (BinCnts.Count() > 7) {
MessageBox.Show($"输入层数={BinCnts.Count()} 大于7层", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
for (int i = 0; i < BinCnts.Count(); i++) {
if (BinCnts[i] > 6) {
MessageBox.Show($"输入第{i+1}层仓数={BinCnts[i]}>6", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
else if (BinCnts[i] < 2)
{
MessageBox.Show($"输入第{i + 1}层仓数={BinCnts[i]}<2", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}
BinCntsConverter converter = new BinCntsConverter();
string binCnts_str = (string)converter.Convert(BinCnts, typeof(string), null, null);
//检测是否已经存在
string plcGroupName = $"{binCnts_str}_v3";
string targetPath = $@"plcgroups\设备连接变量表_{plcGroupName}\Generated\plcgroup.json";
string targetDir = System.IO.Path.GetDirectoryName(targetPath);
try
{
SelectedItem = PlcGroupItems.First(i => i.Name == plcGroupName);
MessageBox.Show($"{targetPath} 已经存在, 可以在列表选择使用", "通知", MessageBoxButton.OK, MessageBoxImage.Information);
return true;
}
catch {
//不存在!!!
}
//格式正常了
//检测 plcgroups/设备连接变量表_6443236_v3/Generated/plcgroup.json
string filePath = @"plcgroups\设备连接变量表_6666666_v3\Generated\plcgroup.json";
if (!File.Exists(filePath)) {
MessageBox.Show($"{filePath} 不存在,无法生成", "异常", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
string json = File.ReadAllText(filePath);
var plcgroup = Newtonsoft.Json.JsonConvert.DeserializeObject<PLCGroup>(json);
//删除多余的设备
plcgroup.Devices.RemoveRange(BinCnts.Count(), plcgroup.Devices.Count() - BinCnts.Count());
plcgroup.Variables.RemoveAll(var => var.DeviceIndex >= plcgroup.Devices.Count());
Regex r = new Regex(@"Items\[([0-9])\]");
Regex r2 = new Regex(@"(?:\w+)_([1-9])");
//删除每层的仓
plcgroup.Variables.RemoveAll(var =>
{
Match m = r.Match(var.OwnerName);
if (m.Success)
{
int weighter_idx = int.Parse(m.Groups[1].Value);
if (weighter_idx >= BinCnts.Count())
{
//这个层不应该有,删除
return true;
}
Match m2 = r2.Match(var.PropertyName);
if (m2.Success)
{
int bincnt = int.Parse(m2.Groups[1].Value);
if (bincnt > BinCnts[weighter_idx])
{
//这个仓也不应该有,删除
return true;
}
}
}
return false;
});
//输出文件
json = Newtonsoft.Json.JsonConvert.SerializeObject(plcgroup, Newtonsoft.Json.Formatting.Indented);
//创建文件夹
if(!Directory.Exists(targetDir))
Directory.CreateDirectory(targetDir);
File.WriteAllText(targetPath, json);
//把这个添加到 PlcGroupItems
PlcGroupItem item = new PlcGroupItem()
{
Name = plcGroupName,
Path = targetPath
};
PlcGroupItems.Add(item);
SelectedItem = item;
MessageBox.Show($"{targetPath} 添加成功, 可以在列表选择使用", "通知", MessageBoxButton.OK, MessageBoxImage.Information);
return true;
}
} }
public class PlcGroupItem public class PlcGroupItem
{ {
...@@ -114,4 +256,37 @@ namespace FLY.Weight.UI.Server ...@@ -114,4 +256,37 @@ namespace FLY.Weight.UI.Server
/// </summary> /// </summary>
public string Path { get; set; } public string Path { get; set; }
} }
public class BinCntsConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
int[] binCnts = value as int[];
if (binCnts == null || binCnts.Count() == 0)
return null;
string str = "";
for (int i = 0; i < binCnts.Count(); i++) {
str += binCnts[i];
}
return str;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
string str = value as string;
if(string.IsNullOrEmpty(str))
return null;
List<int> binCnts = new List<int>();
str = str.Trim();
for (int i = 0; i < str.Length; i++) {
if (int.TryParse(str[i].ToString(), out int binCnt)) {
binCnts.Add(binCnt);
}
}
return binCnts.ToArray();
}
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment