Compare commits

..

2 Commits

Author SHA1 Message Date
Miguel 81643249b9 Mejorada la implementacion de rotacion y redimensionado. 2024-06-28 19:47:08 +02:00
Miguel b3f5ebc53a Mejorado UserControl 2024-06-23 00:07:41 +02:00
5 changed files with 169 additions and 90 deletions

BIN
Icons/connect.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

BIN
Icons/reset.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View File

@ -7,8 +7,14 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<None Remove="Icons\connect.png" />
<None Remove="Icons\reset.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.2.2" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.6.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup>
@ -18,4 +24,9 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\connect.png" />
<Resource Include="Icons\reset.png" />
</ItemGroup>
</Project>

View File

@ -1,44 +1,50 @@
<UserControl x:Class="LibS7Adv.PLCControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibS7Adv">
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:LibS7Adv"
xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" >
<UserControl.DataContext>
<local:PLCViewModel />
</UserControl.DataContext>
<UserControl.Resources>
<!-- Style for Connect/Disconnect Button -->
<Style x:Key="ConnectDisconnectButtonStyle" TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding IsConnected}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Label Content="IP:" Grid.Row="0" Grid.Column="0" Margin="1" VerticalAlignment="Center" />
<TextBox Text="{Binding IP}" Grid.Row="0" Grid.Column="1" Margin="1"
VerticalAlignment="Center" />
<Label Content="Name:" Grid.Row="1" Grid.Column="0" Margin="1" VerticalAlignment="Center" />
<TextBox Text="{Binding Name}" Grid.Row="1" Grid.Column="1" Margin="1"
VerticalAlignment="Center" />
<Button Content="Connect" Command="{Binding ConnectCommand}" Grid.Row="2" Grid.Column="0" Margin="1"
VerticalAlignment="Center" />
<Button Content="Disconnect" Command="{Binding DisconnectCommand}" Grid.Row="2" Grid.Column="1" Margin="1"
VerticalAlignment="Center" />
<Label Content="Status:" Grid.Row="3" Grid.Column="0" Margin="1" VerticalAlignment="Center" />
<Label Content="{Binding ConnectionStatus}" Grid.Row="3" Grid.Column="1" Margin="1" VerticalAlignment="Center" />
<Label Grid.Row="4" Grid.Column="0" Margin="1" VerticalAlignment="Center">
Last Error:
</Label>
<Label Grid.Row="4" Grid.Column="1" Margin="1" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding LastError}" TextWrapping="Wrap" Padding="3" />
</Label>
<StackPanel>
<xctk:PropertyGrid MinWidth="300" x:Name="PanelEdicion" AutoGenerateProperties="True"
SelectedObject="{Binding PlcData}" ShowDescriptionByTooltip="True" ShowSearchBox="False"
ShowSortOptions="False" ForceCursor="True" Margin="5,5,5,5" NameColumnWidth="100" />
<ToolBarTray>
<ToolBar>
<Button Command="{Binding ConnectButtonCommand}" ToolTip="Conectar PLC"
Style="{StaticResource ConnectDisconnectButtonStyle}">
<StackPanel>
<Image Source="Icons/connect.png" Width="24" Height="24" />
<TextBlock Text="Conectar" />
</StackPanel>
</Button>
<Button Command="{Binding ResetAlarmButtonCommand}" ToolTip="Reset Alarm"
>
<StackPanel>
<Image Source="Icons/reset.png" Width="24" Height="24" />
<TextBlock Text="Reset" />
</StackPanel>
</Button>
</ToolBar>
</ToolBarTray>
</StackPanel>
</Grid>
</UserControl>

View File

@ -3,18 +3,55 @@ using CommunityToolkit.Mvvm.Input;
using Siemens.Simatic.Simulation.Runtime;
using Newtonsoft.Json;
using System.Text.RegularExpressions;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Siemens.Simatic.Simulation.Runtime;
using System.ComponentModel;
using Newtonsoft.Json.Linq;
using System.ComponentModel.DataAnnotations;
namespace LibS7Adv
{
[DisplayName("PLC Advanced Setup:")]
public partial class PlcData : ObservableObject
{
[ObservableProperty]
[property: Description("IP of the PLC")]
[property: Category("Connection:")]
string iP = "10.1.30.11";
[ObservableProperty]
[property: Description("Name of the instance at the PLC Advanced")]
[property: Category("Connection:")]
string name = "PLC Name";
[ObservableProperty]
[property: Description("CPU Info")]
[property: Category("Status:")]
[property: ReadOnly(true)]
string cpuTime;
[ObservableProperty]
[property: Display(Name = "Status")]
[property: Description("CPU Status")]
[property: Category("Status:")]
[property: ReadOnly(true)]
string connectionStatus;
[ObservableProperty]
[property: Description("API Error")]
[property: Category("Status:")]
[property: ReadOnly(true)]
string lastError;
}
public partial class PLCViewModel : ObservableObject
{
[JsonIgnore]
private IInstance Instance { get; set; }
private bool IsConfigured { get; set; }
[ObservableProperty]
PlcData plcData = new PlcData();
public PLCViewModel()
{
@ -23,69 +60,69 @@ namespace LibS7Adv
public void ucLoaded()
{
IsConnected = false;
lastError = "";
connectionStatus = "offline";
PlcData.LastError = "";
PlcData.ConnectionStatus = "offline";
}
[ObservableProperty]
string iP = "10.1.30.11";
[ObservableProperty]
string name = "PLC Name";
[ObservableProperty]
string cpuTime;
[ObservableProperty]
string connectionStatus;
[ObservableProperty]
string lastError;
[ObservableProperty]
[property: JsonIgnore]
bool isConnected;
[RelayCommand]
[property: JsonIgnore]
public void ResetAlarmButton()
{
PlcData.LastError = "";
}
[RelayCommand]
[property: JsonIgnore]
public void ConnectButton()
{
if (isConnected)
Disconnect();
else
Connect();
}
public void Connect()
{
if (IsConnected)
return;
try
{
// Implementa la conexión utilizando PLCModel
Instance = SimulationRuntimeManager.CreateInterface(Name);
Instance = SimulationRuntimeManager.CreateInterface(PlcData.Name);
Instance.OnSoftwareConfigurationChanged += Instance_OnSoftwareConfigurationChanged;
//_plcModel.Instance.CommunicationInterface = ECommunicationInterface.Softbus;
if (Instance != null)
{
UpdateTagList();
ConnectionStatus = Instance.OperatingState.ToString();
PlcData.ConnectionStatus = Instance.OperatingState.ToString();
IsConnected = true;
}
}
catch (Exception ex)
{
LastError = ex.Message;
ConnectionStatus = "offline";
PlcData.LastError = ex.Message;
PlcData.ConnectionStatus = "offline";
}
}
public void Disconnect()
{
IsConnected = false;
PlcData.ConnectionStatus = "offline";
Instance = null;
}
private void Instance_OnSoftwareConfigurationChanged(IInstance instance, SOnSoftwareConfigChangedParameter event_param)
{
UpdateTagList();
}
[RelayCommand]
[property: JsonIgnore]
public void Disconnect()
{
IsConnected = false;
ConnectionStatus = "offline";
Instance = null;
}
public void UpdateTagList()
{
IsConfigured = false;
@ -96,7 +133,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = ex.Message;
PlcData.LastError = ex.Message;
}
}
@ -106,7 +143,7 @@ namespace LibS7Adv
{
if (!isConnected)
{
LastError = "Not Connected";
PlcData.LastError = "Not Connected";
return false;
}
if (sTag == null)
@ -128,7 +165,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = sTag + ":" + ex.Message;
PlcData.LastError = sTag + ":" + ex.Message;
return false;
}
}
@ -139,7 +176,7 @@ namespace LibS7Adv
{
if (!isConnected)
{
LastError = "Not Connected";
PlcData.LastError = "Not Connected";
return false;
}
if (sTag == null)
@ -152,7 +189,7 @@ namespace LibS7Adv
else if (tag.tagType == EDataType.Bool)
{
if (tag.areaType == EArea.Input)
Instance?.OutputArea.WriteBit(tag.word_offset, tag.bit, Value);
Instance?.InputArea.WriteBit(tag.word_offset, tag.bit, Value);
if (tag.areaType == EArea.Output)
Instance?.OutputArea.WriteBit(tag.word_offset, tag.bit, Value);
if (tag.areaType == EArea.Marker)
@ -162,19 +199,19 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = sTag + ":" + ex.Message;
PlcData.LastError = sTag + ":" + ex.Message;
return false;
}
}
public string? LeerNumber(string sTag)
public string? LeerNumber(string sTag, bool Signed = false)
{
try
{
if (!isConnected)
{
LastError = "Not Connected";
PlcData.LastError = "Not Connected";
return "";
}
if (sTag == null)
@ -190,26 +227,51 @@ namespace LibS7Adv
{
// Read not Work for ImputArea
if (tag.areaType == EArea.Output)
return Instance?.OutputArea.ReadByte(tag.word_offset).ToString();
{
var val = Instance?.OutputArea.ReadByte(tag.word_offset);
if (Signed)
return val > 127 ? (val - 256).ToString() : val.ToString();
return val.ToString();
}
if (tag.areaType == EArea.Marker)
return Instance?.MarkerArea.ReadByte(tag.word_offset).ToString();
{
var val = Instance?.MarkerArea.ReadByte(tag.word_offset);
if (Signed)
return val > 127 ? (val-256).ToString() : val.ToString();
return val.ToString();
}
}
else if (tag.tagType == EDataType.Word)
{
// Read not Work for ImputArea
if (tag.areaType == EArea.Output)
return Instance?.OutputArea.ReadBytes(tag.word_offset,2).ToString();
{
int value;
byte[] bytes = Instance?.OutputArea.ReadBytes(tag.word_offset, 2);
Array.Reverse(bytes);
if (Signed)
value = BitConverter.ToInt16(bytes, 0);
else
value = BitConverter.ToUInt16(bytes, 0);
return value.ToString();
}
if (tag.areaType == EArea.Marker)
{
int value;
byte[] bytes = Instance?.MarkerArea.ReadBytes(tag.word_offset, 2);
return (bytes[0] + bytes[1]*256).ToString();
Array.Reverse(bytes);
if (Signed)
value = BitConverter.ToInt16(bytes, 0);
else
value = BitConverter.ToUInt16(bytes, 0);
return value.ToString();
}
}
return "";
}
catch (Exception ex)
{
LastError = sTag + ":" + ex.Message;
PlcData.LastError = sTag + ":" + ex.Message;
return "";
}
}
@ -224,7 +286,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = ex.Message;
PlcData.LastError = ex.Message;
return false;
}
}
@ -237,7 +299,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = ex.Message;
PlcData.LastError = ex.Message;
}
}
public void EscribirTag(string pTag, SDataValue Value)
@ -248,7 +310,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
}
}
public SDataValue LeerTag(string pTag)
@ -259,7 +321,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
return new SDataValue();
}
}
@ -271,7 +333,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
}
}
public void EscribirTagInt16(string pTag, int pValue)
@ -282,7 +344,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
}
}
@ -294,7 +356,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
return false;
}
}
@ -307,7 +369,7 @@ namespace LibS7Adv
}
catch (Exception ex)
{
LastError = pTag + ":" + ex.Message;
PlcData.LastError = pTag + ":" + ex.Message;
return 0;
}
}