diff --git a/src/ax.axopen.hwlibrary/ctrl/apax.yml b/src/ax.axopen.hwlibrary/ctrl/apax.yml index ae5098bd6..3c0063791 100644 --- a/src/ax.axopen.hwlibrary/ctrl/apax.yml +++ b/src/ax.axopen.hwlibrary/ctrl/apax.yml @@ -6,7 +6,7 @@ files: devDependencies: "@ix-ax/ax-sdk": '0.0.0-dev.0' catalogs: - "@ax/simatic-ax": ^2405.2.0 + "@ax/simatic-ax": 2405.2.0 dependencies: "@ix-ax/ax.axopen.min": '0.0.0-dev.0' "@ax/simatic-1500-distributedio": 7.0.1 diff --git a/src/data/app/SystemConstants/plc_line_HwIdentifiers.st b/src/data/app/SystemConstants/plc_line_HwIdentifiers.st new file mode 100644 index 000000000..5631dc14d --- /dev/null +++ b/src/data/app/SystemConstants/plc_line_HwIdentifiers.st @@ -0,0 +1,19 @@ +CONFIGURATION HardwareIDs + VAR_GLOBAL CONSTANT + plc_line_HwID : UINT := UINT#32; + plc_line_Rail_0_HwID : UINT := UINT#257; + plc_line_plc_line_HwID : UINT := UINT#48; + plc_line_plc_line_CPU_display_1_HwID : UINT := UINT#54; + plc_line_plc_line_Card_reader_writer_1_HwID : UINT := UINT#51; + plc_line_plc_line_DP_interface_1_HwID : UINT := UINT#60; + plc_line_plc_line_OPC_UA_1_HwID : UINT := UINT#117; + plc_line_plc_line_profinet_x1_HwID : UINT := UINT#64; + plc_line_plc_line_profinet_x1_Port_1_HwID : UINT := UINT#65; + plc_line_plc_line_profinet_x1_Port_2_HwID : UINT := UINT#66; + plc_line_plc_line_profinet_x2_HwID : UINT := UINT#72; + plc_line_plc_line_profinet_x2_Port_3_HwID : UINT := UINT#73; + plc_line_plc_line_virtual_communication_interface_HwID : UINT := UINT#135; + profinet_plc_line_HwID : UINT := UINT#256; + + END_VAR +END_CONFIGURATION diff --git a/src/data/app/SystemConstants/plc_line_IoAddresses.st b/src/data/app/SystemConstants/plc_line_IoAddresses.st new file mode 100644 index 000000000..1f46b8a7a --- /dev/null +++ b/src/data/app/SystemConstants/plc_line_IoAddresses.st @@ -0,0 +1,5 @@ +CONFIGURATION IoAddresses + VAR_GLOBAL + + END_VAR +END_CONFIGURATION diff --git a/src/data/app/apax.yml b/src/data/app/apax.yml index 2d8ab579d..da7603ced 100644 --- a/src/data/app/apax.yml +++ b/src/data/app/apax.yml @@ -14,7 +14,11 @@ dependencies: "@ix-ax/axopen.data": '0.0.0-dev.0' "@ix-ax/ax.axopen.app": '0.0.0-dev.0' "@ix-ax/axopen.simatic1500": '0.0.0-dev.0' -installStrategy: strict + # this is just temporary to test new features + # upto the moment of releasing new catalog + # installStrategy: strict + "@ix-ax/ax.latest.packages": '0.0.0-dev.0' +installStrategy: overridable apaxVersion: 3.3.1 scripts: # For proper execution of these scripts, the following variables need to be defined as environment variables or local variables. diff --git a/src/data/app/certs/plc_line/plc_line.cer b/src/data/app/certs/plc_line/plc_line.cer new file mode 100644 index 000000000..02a0fb0c6 --- /dev/null +++ b/src/data/app/certs/plc_line/plc_line.cer @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUWIyy2tceYfRUs4uPo6KZXlgGQY8wDQYJKoZIhvcNAQELBQAwgYYxCzAJ +BgNVBAYTAlhYMRIwEAYDVQQIDAlTdGF0ZU5hbWUxETAPBgNVBAcMCENpdHlOYW1lMRQwEgYDVQQK +DAtDb21wYW55TmFtZTEbMBkGA1UECwwSQ29tcGFueVNlY3Rpb25OYW1lMR0wGwYDVQQDDBRDb21t +b25OYW1lT3JIb3N0bmFtZTAeFw0yNDEyMTAxMDI3MTFaFw0yNTEyMTAxMDI3MTFaMIGGMQswCQYD +VQQGEwJYWDESMBAGA1UECAwJU3RhdGVOYW1lMREwDwYDVQQHDAhDaXR5TmFtZTEUMBIGA1UECgwL +Q29tcGFueU5hbWUxGzAZBgNVBAsMEkNvbXBhbnlTZWN0aW9uTmFtZTEdMBsGA1UEAwwUQ29tbW9u +TmFtZU9ySG9zdG5hbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmr6liRyZbj0WO +0rxgaGmbR+RB/petCLZXE7zWjVbctSnVHSZOHpRR0MGcdl1Py9LmD4OCBLr227dZBn94E4xZLxFc +LiuIxfxoTLgRdt3mmdaZTdQ1cyhB/vMoYbPlwt1UXXKhZWpJl0k7kyrBE1eilGoBj5QzE/740cVJ +MWZ2TwGOSpzdTDGzCTKwUHiEUdgldslHzf+On5kwPVuYPxyvLF2AtJ3sJOg3Me3W6l39nDXkT2SQ +CcnGiELF0k06UNOS2q+r8mg8uOltNVBkdjnEoTWzMCRx+XHNfiliJPqK3hO6QHuZEP2UZA+6HRrk +jkhopEaaLOE528aVCXqgg+itAgMBAAGjDTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEB +AHzLOYXsUK0aTHtY2VZEg03MgvHrxI3lfCWQNo0/lhkedhxBkHF8/I9IHlZxaSTCElfKVnEsb9JW +JI6zK8UNLei2Sy6qwpHnePQZPkl9usaRn/AmgybEDUZk8vZ/RhAPgTvi8zGZTLU+oIvZ9gL46PUa +/b+YYgGtu2ax+OSz7ZUVqyGeL9mF7mNjGRP+i01qF6DeemhO1YCXw4zdK12z5t3qc/wKJkAdGTun +BF06KgzJIY6Q2jrrC6mtIQou7UdmPSkpWegLLYfk3gPMVbw5Na8puIM1EDE28fFNJb9VABs3prtp +gRfWVdYDCg9/agYD1kR4ZbJZeu6/+I5GUod5DUE= +-----END CERTIFICATE----- diff --git a/src/data/app/hwc/plc_line.hwl.json b/src/data/app/hwc/plc_line.hwl.json deleted file mode 100644 index 0b329ea0f..000000000 --- a/src/data/app/hwc/plc_line.hwl.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "Devices": [ - { - "Name": "plc_line", - "Modules": [ - { - "Apply": { - "TemplateName": "PLC_1516_v3_1", - "Arguments": { - "PLCName": "plc_line", - "IpAddress": "10.10.10.120/24" - } - } - } - ] - } - ], - "IoSystems": [ - { - "Name": "profinet_plc_line", - "ControllerInterfaces": [ - { "Ref": "plc_line/plc_line/profinet_x1" } - ], - "DeviceInterfaces": [ - - ] - } - ] -} diff --git a/src/data/app/hwc/plc_line.hwl.yml b/src/data/app/hwc/plc_line.hwl.yml new file mode 100644 index 000000000..924b490a6 --- /dev/null +++ b/src/data/app/hwc/plc_line.hwl.yml @@ -0,0 +1,14 @@ +Devices: +- Name: plc_line + Modules: + - Apply: + TemplateName: 6ES7516-3AP03-0AB0_v3_1 + Arguments: + PLCName: plc_line + IpAddress_X1: 10.10.10.120/24 + ProfinetDeviceName_X1: plc_line_x1 +IoSystems: +- Name: profinet_plc_line + ControllerInterfaces: + - Ref: plc_line/plc_line/profinet_x1 + \ No newline at end of file diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/App.razor b/src/data/app/ix-blazor/librarytemplate.blazor/App.razor index a68a7fa18..105786ece 100644 --- a/src/data/app/ix-blazor/librarytemplate.blazor/App.razor +++ b/src/data/app/ix-blazor/librarytemplate.blazor/App.razor @@ -1,13 +1,19 @@ -@using librarytemplate.blazor.hmi.Shared; - - - - - - - Not found - -

Sorry, there's nothing at this address.

-
-
-
+@using AxOpen.Security.Service +@using librarytemplate.blazor.hmi.Shared; + + + + + + + + + + Not found + +

Sorry, there's nothing at this address.

+
+
+
+
diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/Pages/UserAdministration.razor b/src/data/app/ix-blazor/librarytemplate.blazor/Pages/UserAdministration.razor new file mode 100644 index 000000000..4f34646c8 --- /dev/null +++ b/src/data/app/ix-blazor/librarytemplate.blazor/Pages/UserAdministration.razor @@ -0,0 +1,4 @@ +@page "/Security/UserAdministration" +
+ +
diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/Program.cs b/src/data/app/ix-blazor/librarytemplate.blazor/Program.cs index a81a2ed24..8fe647554 100644 --- a/src/data/app/ix-blazor/librarytemplate.blazor/Program.cs +++ b/src/data/app/ix-blazor/librarytemplate.blazor/Program.cs @@ -1,22 +1,17 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -using System.Data; -using AXOpen.Core; -using AxOpen.Security.Services; -using AXSharp.Presentation.Blazor.Services; -using AXSharp.Connector; -using AXOpen.Base.Data; -using AxOpen.Security.Entities; -using System.Reflection; using AxOpen.Security; -using Serilog; +using AxOpen.Security.Entities; +using AxOpen.Security.Services; using AXOpen; +using AXOpen.Base.Data; +using AXOpen.Data.Json; +using AXOpen.Data.MongoDb; using AXOpen.Logging; +using AXSharp.Connector; +using AXSharp.Presentation.Blazor.Services; using librarytemplate; -using AXOpen.Data.InMemory; -using AXOpen.Data.MongoDb; -using AXOpen.Data.Json; - +using Serilog; +using System.Data; +using System.Reflection; var builder = WebApplication.CreateBuilder(args); @@ -41,13 +36,13 @@ fileSizeLimitBytes: 100000) .MinimumLevel.Debug() .CreateLogger()); + await Entry.Plc.Connector.IdentityProvider.ConstructIdentitiesAsync(); AxoApplication.CreateBuilder().ConfigureLogger(new SerilogLogger(new LoggerConfiguration() .WriteTo.Console().MinimumLevel.Verbose() .CreateLogger())); - // IRepository persistentRepository; @@ -60,17 +55,14 @@ // *** MONGO REPOSITORY *** - persistentRepository = AXOpen.Data.MongoDb.Repository.Factory(new MongoDbRepositorySettings("mongodb://localhost:27017", "AxOpenData", "PersistentData")); - -Entry.Plc.AxoDataPersistentContext.DataManager.InitializeRemoteDataExchange( - Entry.Plc.AxoDataPersistentContext.PersistentRootObject, +Entry.Plc.AxoDataPersistentContext.DataManager.InitializeRemoteDataExchange( + Entry.Plc.AxoDataPersistentContext.PersistentRootObject, persistentRepository ); // - // IRepository SharedDataHeaderDataRepository; IRepository Station_1_DataRepository; @@ -97,7 +89,6 @@ AxoProcessDataManager.InitializeRemoteDataExchange(); // - // IRepository AxoProcessDataRepository; @@ -111,8 +102,7 @@ // *** MONGO REPOSITORY *** - -AxoProcessDataRepository = AXOpen.Data.MongoDb.Repository.Factory(new MongoDbRepositorySettings("mongodb://localhost:27017", "AxOpenData","AxoDataExchangeExample")); +AxoProcessDataRepository = AXOpen.Data.MongoDb.Repository.Factory(new MongoDbRepositorySettings("mongodb://localhost:27017", "AxOpenData", "AxoDataExchangeExample")); Entry.Plc.AxoDataExchangeContext.DataManager.InitializeRemoteDataExchange(AxoProcessDataRepository); // @@ -143,7 +133,6 @@ app.Run(); - static string CreateJsonRepositoryDirectory(string path = "..\\..\\..\\..\\..\\JSONREPOS\\") { var executingAssemblyFile = new FileInfo(Assembly.GetExecutingAssembly().Location); @@ -157,7 +146,6 @@ static string CreateJsonRepositoryDirectory(string path = "..\\..\\..\\..\\..\\J static (IRepository, IRepository) SetUpJsonSecurityRepository(string repositoryDirectory) { - IRepository userRepo = new JsonRepository(new JsonRepositorySettings(Path.Combine(repositoryDirectory, "Users"))); IRepository groupRepo = new JsonRepository(new JsonRepositorySettings(Path.Combine(repositoryDirectory, "Groups"))); @@ -178,6 +166,16 @@ public static List CreateRoles() new Role(can_skip_steps_in_sequence), }; + //roles.Add(new Role(AXOpen.Data.DataExchangeRoleNames.can_data_item_create)); + // ... + + foreach (var item in typeof(AXOpen.Data.DataExchangeRoleNames). + GetFields(BindingFlags.Public | BindingFlags.Static). + Where(f => f.FieldType == typeof(string))) + { + roles.Add(new Role(item.Name)); + } + return roles; } @@ -187,4 +185,4 @@ public static List CreateRoles() public const string process_settings_access = nameof(process_settings_access); public const string process_traceability_access = nameof(process_traceability_access); public const string can_skip_steps_in_sequence = nameof(can_skip_steps_in_sequence); -} +} \ No newline at end of file diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/Shared/MainLayout.razor b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/MainLayout.razor index 83c2c545d..434fd104e 100644 --- a/src/data/app/ix-blazor/librarytemplate.blazor/Shared/MainLayout.razor +++ b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/MainLayout.razor @@ -1,7 +1,7 @@ @inherits LayoutComponentBase librarytemplate.blazor - +
+ + + +
diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor new file mode 100644 index 000000000..ec5eb5eaa --- /dev/null +++ b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor @@ -0,0 +1,49 @@ +@using System.Globalization +@inject NavigationManager NavigationManager + +
+ + + + + +
+ +
+
+ +
+
+ +@code { + private CultureInfo[] supportedCultures = new[] + { + new CultureInfo("en-US"), + new CultureInfo("sk-SK"), + new CultureInfo("es-ES") + }; + + private CultureInfo Culture + { + get => CultureInfo.CurrentCulture; + set + { + // Prevent unnecessary navigation + if (!Equals(CultureInfo.CurrentCulture, value) && !Equals(CultureInfo.CurrentUICulture, value)) + { + var cultureEscaped = Uri.EscapeDataString(value.Name); + NavigationManager.NavigateTo($"/culture?culture={cultureEscaped}", true); + } + } + } + + protected override void OnInitialized() + { + Culture = CultureInfo.CurrentCulture; + } +} \ No newline at end of file diff --git a/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor.css b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor.css new file mode 100644 index 000000000..de1fae53f --- /dev/null +++ b/src/data/app/ix-blazor/librarytemplate.blazor/Shared/TopRow.razor.css @@ -0,0 +1,13 @@ +.top-row { + background-color: #f7f7f7; + border-bottom: 1px solid #d6d5d5; + height: 3.5rem; + display: flex; + align-items: center; +} + +@media (max-width: 769px) { + .IAmHereIndicator { + display: none; + } +} diff --git a/src/data/app/ix/Entry.cs b/src/data/app/ix/Entry.cs index 0d7959358..64e9c9e65 100644 --- a/src/data/app/ix/Entry.cs +++ b/src/data/app/ix/Entry.cs @@ -5,18 +5,39 @@ using System.Text; using System.Threading.Tasks; using AXSharp.Connector.S71500.WebApi; +using System.Net.Security; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; namespace librarytemplate { + public static class Entry { - private static readonly string TargetIp = Environment.GetEnvironmentVariable("AXTARGET"); // <- replace by your IP - private const string UserName = "Everybody"; //<- replace by user name you have set up in your WebAPI settings - private const string Pass = ""; // <- Pass in the password that you have set up for the user. NOT AS PLAIN TEXT! Use user secrets instead. + public static string TargetIp { get; } = Environment.GetEnvironmentVariable("AXTARGET"); // <- replace by your IP + private static string Pass => Environment.GetEnvironmentVariable("AX_TARGET_PWD"); // <- Pass in the password that you have set up for the user. NOT AS PLAIN TEXT! Use user secrets instead. + private static string UserName = Environment.GetEnvironmentVariable("AX_USERNAME"); //<- replace by user name you have set up in your WebAPI settings private const bool IgnoreSslErrors = true; // <- When you have your certificates in order set this to false. + private static string CertificatePath = "certs\\plc_line\\plc_line.cer"; + + static string GetCertPath() + { + var fp = new FileInfo(Path.Combine(Assembly.GetExecutingAssembly().Location)); + return Path.Combine(fp.DirectoryName, CertificatePath); + } + + static readonly X509Certificate2 Certificate = new X509Certificate2(GetCertPath()); + + private static bool CertificateValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) + { + return certificate.Thumbprint == Certificate.Thumbprint; + } public static axopen_data_appTwinController Plc { get; } = new(ConnectorAdapterBuilder.Build() - .CreateWebApi(TargetIp, UserName, Pass, IgnoreSslErrors)); + .CreateWebApi(TargetIp, UserName, Pass, CertificateValidation, IgnoreSslErrors)); + + } + } \ No newline at end of file diff --git a/src/data/app/ix/axopen_data_app.csproj b/src/data/app/ix/axopen_data_app.csproj index 840a074e4..778a11cb2 100644 --- a/src/data/app/ix/axopen_data_app.csproj +++ b/src/data/app/ix/axopen_data_app.csproj @@ -18,6 +18,13 @@ + + + + + + PreserveNewest + diff --git a/src/data/app/src/IO/HwIdentifiers.st b/src/data/app/src/IO/HwIdentifiers.st new file mode 100644 index 000000000..3ceda4158 --- /dev/null +++ b/src/data/app/src/IO/HwIdentifiers.st @@ -0,0 +1,23 @@ +NAMESPACE AXOpen.Data + TYPE + HwIdentifiers : WORD + ( + plc_line_HwID := WORD#32, + plc_line_Rail_0_HwID := WORD#257, + plc_line_plc_line_HwID := WORD#48, + plc_line_plc_line_CPU_display_1_HwID := WORD#54, + plc_line_plc_line_Card_reader_writer_1_HwID := WORD#51, + plc_line_plc_line_DP_interface_1_HwID := WORD#60, + plc_line_plc_line_OPC_UA_1_HwID := WORD#117, + plc_line_plc_line_profinet_x1_HwID := WORD#64, + plc_line_plc_line_profinet_x1_Port_1_HwID := WORD#65, + plc_line_plc_line_profinet_x1_Port_2_HwID := WORD#66, + plc_line_plc_line_profinet_x2_HwID := WORD#72, + plc_line_plc_line_profinet_x2_Port_3_HwID := WORD#73, + plc_line_plc_line_virtual_communication_interface_HwID := WORD#135, + profinet_plc_line_HwID := WORD#256, + + NONE := WORD#0 + ); + END_TYPE +END_NAMESPACE diff --git a/src/data/app/src/IO/Inputs.st b/src/data/app/src/IO/Inputs.st new file mode 100644 index 000000000..ffad6a760 --- /dev/null +++ b/src/data/app/src/IO/Inputs.st @@ -0,0 +1,9 @@ +NAMESPACE AXOpen.Data + TYPE + {S7.extern=ReadWrite} + {#ix-attr:[Container(Layout.Wrap)]} + Inputs : STRUCT + noInputsFoundInTheHwConfig AT %B0: BYTE; + END_STRUCT; + END_TYPE +END_NAMESPACE diff --git a/src/data/app/src/IO/Outputs.st b/src/data/app/src/IO/Outputs.st new file mode 100644 index 000000000..d70d84cda --- /dev/null +++ b/src/data/app/src/IO/Outputs.st @@ -0,0 +1,9 @@ +NAMESPACE AXOpen.Data + TYPE + {S7.extern=ReadWrite} + {#ix-attr:[Container(Layout.Wrap)]} + Outputs : STRUCT + noOutputsFoundInTheHwConfig AT %B0: BYTE; + END_STRUCT; + END_TYPE +END_NAMESPACE diff --git a/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeRoleNames.cs b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeRoleNames.cs new file mode 100644 index 000000000..03f9fc468 --- /dev/null +++ b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeRoleNames.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AXOpen.Data +{ + public static class DataExchangeRoleNames + { + public const string can_data_item_create = nameof(can_data_item_create); + public const string can_data_item_edit = nameof(can_data_item_edit); + public const string can_data_item_copy = nameof(can_data_item_copy); + public const string can_data_item_delete = nameof(can_data_item_delete); + + public const string can_data_send_to_plc = nameof(can_data_send_to_plc); + public const string can_data_load_from_plc = nameof(can_data_send_to_plc); + + public const string can_data_export = nameof(can_data_export); + public const string can_data_import = nameof(can_data_import); + + } +} \ No newline at end of file diff --git a/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor index 74486369b..700e88810 100644 --- a/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor +++ b/src/data/src/AXOpen.Data.Blazor/AxoDataExchange/DataExchangeView.razor @@ -4,6 +4,7 @@ @using AXSharp.Connector; @using CommunityToolkit.Mvvm.ComponentModel; @using CommunityToolkit.Mvvm.Messaging; +@using Microsoft.AspNetCore.Components.Authorization @using Microsoft.AspNetCore.Components.Forms; @using AXOpen.Data.Interfaces; @using AXOpen.Core; @@ -19,12 +20,34 @@ else
@if (Presentation.Equals("Command")) { - - + + + + + + + + + + + + + + + @if (CanExport) { - - + + + + + + + + + + + } } @@ -155,20 +178,36 @@ else @if (Presentation.Equals("Command")) { - - - + + + + + + + + + + + + + + + + + + + } @@ -245,10 +284,32 @@ else @if (Presentation.Equals("Command")) {
- - - - + + + + + + + + + + + + + + + + + + + + + + + + + +
}
@@ -332,10 +393,40 @@ else @@ -471,6 +564,40 @@ else + + + + +