From 3983b431063c9298aa430c29ad7d56c5b9a10acb Mon Sep 17 00:00:00 2001 From: KircMax Date: Wed, 11 Dec 2024 17:14:10 +0100 Subject: [PATCH] Update for Firmware Version V4.0 (#88) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit V4.0 for the S7-1500 is available: [Download](https://support.industry.siemens.com/cs/document/109478459/firmware-update-s7-1500-cpus-incl-displays-and-et-200-cpus-(et-200sp-et-200pro)?dti=0&lc=en-DE) Therefore the according [new Web-Api Methods](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#treeId=7a2b693b7e1b49654c384cde0ede92de) shall also be supported by this library. - [x] ​[​WebServer.ReadResponseHeaders](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] ​[​WebServer.ChangeResponseHeaders](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [Api.GetSessionInfo](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [​WebApp.SetVersion](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [​WebApp.SetUrlRedirectMode](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] Technology.BrowseObjects - [x] Technology.Read - [x] [Plc.ReadCpuType](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [​Plc.ReadStationName](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [​Plc.ReadModuleName](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) Redundancy: - [x] [Redundancy.ReadSystemInformation](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [Redundancy.ReadSystemState](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [Redundancy.RequestChangeSystemState](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) - [x] [​Redundancy.ReadSyncupProgress](https://cache.industry.siemens.com/dl/dl-media/246/109977246/att_1307004/v1/185361597835_en-US/en-US/index.html#) --- README.md | 1 + .../Enums/ApiAlarmAcknowledgementState.cs | 2 +- .../Enums/ApiAlarmsBrowseFilterAttribute.cs | 2 +- .../Enums/ApiAuthenticationMode.cs | 13 +- .../Enums/ApiBrowseFilterMode.cs | 2 +- src/Webserver.API/Enums/ApiDayOfWeek.cs | 2 +- ...iDiagnosticBufferBrowseFilterAttributes.cs | 2 +- src/Webserver.API/Enums/ApiErrorCode.cs | 42 +- .../Enums/ApiFailsafeHardwareType.cs | 2 +- .../Enums/ApiFileResourceState.cs | 2 +- .../Enums/ApiFileResourceType.cs | 2 +- .../Enums/ApiObjectDirectoryStatus.cs | 2 +- .../Enums/ApiPlcDataRepresentation.cs | 25 + src/Webserver.API/Enums/ApiPlcHwId.cs | 2 +- .../Enums/ApiPlcModeSelectorState.cs | 2 +- .../Enums/ApiPlcOperatingMode.cs | 20 +- .../Enums/ApiPlcProgramBlockType.cs | 2 +- .../Enums/ApiPlcProgramBrowseMode.cs | 2 +- .../Enums/ApiPlcProgramDataType.cs | 2 +- src/Webserver.API/Enums/ApiPlcRedundancyId.cs | 2 +- .../Enums/ApiPlcRedundancyPairingState.cs | 53 + .../Enums/ApiPlcRedundancyRole.cs | 32 + .../Enums/ApiPlcRedundancySystemState.cs | 54 + .../Enums/ApiReadLanguagesMode.cs | 20 + .../Enums/ApiRedundancySyncUpPhase.cs | 56 ++ .../Enums/ApiTechnologyObjectType.cs | 84 ++ src/Webserver.API/Enums/ApiTicketProvider.cs | 14 +- src/Webserver.API/Enums/ApiTicketState.cs | 2 +- .../Enums/ApiUserAuthenticationMode.cs | 28 + .../Enums/ApiWebAppRedirectMode.cs | 24 + .../Enums/ApiWebAppResourceVisibility.cs | 2 +- src/Webserver.API/Enums/ApiWebAppState.cs | 2 +- src/Webserver.API/Enums/ApiWebAppType.cs | 8 +- .../ApiAddressDoesNotExistException.cs | 2 +- .../ApiAlreadyAuthenticatedException.cs | 2 +- .../ApiApplicationAlreadyExistsException.cs | 2 +- .../ApiApplicationDoesNotExistException.cs | 2 +- .../ApiApplicationLimitReachedException.cs | 2 +- .../Exceptions/ApiBulkRequestException.cs | 2 +- .../Exceptions/ApiDirectoryParserException.cs | 2 +- .../ApiEntityAlreadyExistsException.cs | 2 +- .../ApiEntityDoesNotExistException.cs | 2 +- .../Exceptions/ApiEntityInUseException.cs | 2 +- src/Webserver.API/Exceptions/ApiException.cs | 2 +- .../ApiHTTPHeaderInvalidException.cs | 38 + .../ApiHTTPHeaderNotAllowedException.cs | 38 + ...elperInvalidPlcProgramDataTypeException.cs | 2 +- .../ApiInconsistentApiWebAppDataException.cs | 2 +- .../ApiInfrastructureErrorException.cs | 37 + .../Exceptions/ApiInternalErrorException.cs | 2 +- .../Exceptions/ApiInvalidAddressException.cs | 2 +- .../Exceptions/ApiInvalidAlarmIdException.cs | 2 +- ...iInvalidAlarmsBrowseParametersException.cs | 2 +- .../ApiInvalidApplicationNameException.cs | 2 +- .../ApiInvalidArrayIndexException.cs | 2 +- .../Exceptions/ApiInvalidETagException.cs | 2 +- .../Exceptions/ApiInvalidHWIDException.cs | 2 +- .../ApiInvalidMediaTypeException.cs | 2 +- .../ApiInvalidModificationTimeException.cs | 2 +- .../ApiInvalidParametersException.cs | 2 +- .../Exceptions/ApiInvalidPatternException.cs | 38 + .../ApiInvalidResourceNameException.cs | 2 +- .../Exceptions/ApiInvalidResponseException.cs | 2 +- .../ApiInvalidTicketIdValueException.cs | 2 +- .../Exceptions/ApiInvalidTimeRuleException.cs | 2 +- .../ApiInvalidTimestampException.cs | 2 +- .../ApiInvalidUTCOffsetException.cs | 2 +- .../ApiInvalidVersionStringException.cs | 39 + .../Exceptions/ApiMethodNotFoundException.cs | 2 +- ...NewPasswordDoesNotFollowPolicyException.cs | 2 +- ...iNewPasswordMatchesOldPasswordException.cs | 2 +- .../Exceptions/ApiNoResourcesException.cs | 2 +- .../ApiNoServiceDataResourcesException.cs | 2 +- .../ApiNotATechnologyObjectException.cs | 38 + .../Exceptions/ApiNotAcceptedException.cs | 37 + .../Exceptions/ApiPLCNotInStopException.cs | 2 +- .../ApiPartnerNotAccessibleException.cs | 2 +- .../Exceptions/ApiPasswordExpiredException.cs | 2 +- .../Exceptions/ApiRequestTooLargeException.cs | 39 + .../ApiResourceAlreadyExistsException.cs | 2 +- ...esourceContentHasBeenCorruptedException.cs | 2 +- .../ApiResourceContentIsNotReadyException.cs | 2 +- .../ApiResourceDeploymentFailedException.cs | 2 +- .../ApiResourceDoesNotExistException.cs | 2 +- .../ApiResourceLimitReachedException.cs | 2 +- ...iResourceVisibilityIsNotPublicException.cs | 2 +- .../Exceptions/ApiSystemIsBusyException.cs | 2 +- .../ApiSystemIsReadOnlyException.cs | 2 +- .../Exceptions/ApiTicketNotFoundException.cs | 2 +- .../ApiTicketNotInCompletedStateException.cs | 2 +- .../ApiTicketingEndpointUploadException.cs | 2 +- .../ApiTimestampOutOfRangeException.cs | 2 +- .../ApiTooManyHTTPHeadersException.cs | 38 + .../ApiUnsupportedAddressException.cs | 2 +- .../ApiVariableIsNotAStructureException.cs | 2 +- .../ApiWebAppConfigParserException.cs | 2 +- .../ApiWebAppConfigurationFailedException.cs | 2 +- .../Exceptions/InvalidHttpRequestException.cs | 2 +- .../ApiPlcRestoreBackupTicketData.cs | 2 +- .../AdditionalTicketData/ApiTicketDataBase.cs | 2 +- .../Models/AlarmsBrowse/ApiAlarms.cs | 2 +- .../Models/AlarmsBrowse/ApiAlarms_Entry.cs | 2 +- .../ApiAlarms_EntryAcknowledgement.cs | 2 +- .../AlarmsBrowse/ApiAlarms_RequestFilters.cs | 2 +- src/Webserver.API/Models/ApiClass.cs | 2 +- .../ApiDiagnosticBuffer.cs | 2 +- .../ApiDiagnosticBuffer_Entry.cs | 2 +- .../ApiDiagnosticBuffer_EntryEvent.cs | 2 +- .../ApiDiagnosticBuffer_RequestFilters.cs | 2 +- src/Webserver.API/Models/ApiError.cs | 2 +- .../Models/ApiFailsafeRuntimeGroup.cs | 2 +- src/Webserver.API/Models/ApiFileResource.cs | 2 +- src/Webserver.API/Models/ApiLanguage.cs | 47 +- .../Models/ApiPasswordExpiration.cs | 12 +- src/Webserver.API/Models/ApiPasswordPolicy.cs | 2 +- .../ApiPlcProgramBrowseCodeBlocksData.cs | 2 +- src/Webserver.API/Models/ApiPlcProgramData.cs | 2 +- .../Models/ApiPlcProgramDataArrayIndexer.cs | 2 +- .../ApiPlcProgramDataTypes/ApiDateAndTime.cs | 2 +- .../ApiPlcProgramDataTypes/ApiS5Time.cs | 2 +- .../Models/ApiQuantityStructure.cs | 2 +- .../Models/ApiRedundancySystemState.cs | 61 ++ src/Webserver.API/Models/ApiSessionInfo.cs | 88 ++ .../Models/ApiSyslog/ApiPlcSyslog.cs | 2 +- .../Models/ApiSyslog/ApiPlcSyslog_Entry.cs | 2 +- src/Webserver.API/Models/ApiTicket.cs | 2 +- src/Webserver.API/Models/ApiWebAppData.cs | 33 +- .../Models/ApiWebAppDataSaveSetting.cs | 2 +- src/Webserver.API/Models/ApiWebAppResource.cs | 2 +- .../FailsafeParameters/FailsafeHardware.cs | 2 +- .../Models/HttpClientAndWebAppCookie.cs | 2 +- .../HttpClientConnectionConfiguration.cs | 2 +- src/Webserver.API/Models/IApiWebAppData.cs | 2 +- .../Models/IApiWebAppDataSaveSetting.cs | 2 +- .../ApiRedundancySyncupProgress.cs | 102 ++ ...RedundancySyncupProgress_CopyMemoryCard.cs | 73 ++ ...RedundancySyncupProgress_CopyWorkMemory.cs | 67 ++ ...edundancySyncupProgress_MinimizingDelay.cs | 71 ++ .../ApiRedundancySystemInfo.cs | 86 ++ .../ApiRedundancySystemInfo_Plc.cs | 81 ++ .../ApiRedundancySystemInfo_Plcs.cs | 67 ++ .../Models/Requests/ApiRequest.cs | 2 +- .../Models/Requests/IApiRequest.cs | 2 +- .../Responses/ApiAlarmsBrowseResponse.cs | 2 +- .../Responses/ApiArrayOfApiClassResponse.cs | 2 +- .../Responses/ApiBrowseFilesResponse.cs | 2 +- .../Responses/ApiBrowseTicketsResponse.cs | 2 +- .../Models/Responses/ApiBulkResponse.cs | 2 +- .../ApiDiagnosticBufferBrowseResponse.cs | 2 +- .../Models/Responses/ApiDoubleResponse.cs | 2 +- .../Models/Responses/ApiErrorModel.cs | 22 +- .../ApiFailsafeReadParametersResponse.cs | 2 +- .../ApiFailsafeReadRuntimeGroupsResponse.cs | 2 +- .../ApiGetAuthenticationModeResponse.cs | 2 +- .../Responses/ApiGetPasswordPolicyResponse.cs | 2 +- .../ApiGetQuantityStructuresResponse.cs | 2 +- .../Models/Responses/ApiLoginResponse.cs | 2 +- .../ApiPlcProgramBrowseCodeBlocksResponse.cs | 2 +- .../Responses/ApiPlcProgramBrowseResponse.cs | 2 +- .../Responses/ApiPlcReadCpuTypeResponse.cs | 13 + .../ApiPlcReadModeSelectorStateResponse.cs | 2 +- .../Responses/ApiPlcReadModuleNameResponse.cs | 14 + .../ApiPlcReadStationNameResponse.cs | 14 + .../Responses/ApiPlcReadSystemTimeResult.cs | 2 +- .../ApiPlcReadTimeSettingsResponse.cs | 2 +- .../Responses/ApiReadLanguagesResponse.cs | 2 +- .../Responses/ApiReadOperatingModeResponse.cs | 2 +- ...ApiRedundancyReadSyncupProgressResponse.cs | 14 + ...RedundancyReadSystemInformationResponse.cs | 14 + .../ApiRedundancyReadSystemStateResponse.cs | 13 + .../Models/Responses/ApiResultResponse.cs | 2 +- .../Responses/ApiSessionInfoResponse.cs | 13 + .../Responses/ApiSingleStringResponse.cs | 2 +- .../Responses/ApiSyslogBrowseResponse.cs | 2 +- .../ApiTechnologyBrowseObjectsResponse.cs | 14 + .../Models/Responses/ApiTicketIdResponse.cs | 2 +- .../Responses/ApiTrueOnSuccessResponse.cs | 2 +- .../Responses/ApiTrueWithResourceResponse.cs | 2 +- .../Responses/ApiTrueWithWebAppResponse.cs | 2 +- .../ApiWebAppBrowseResourcesResponse.cs | 2 +- .../Responses/ApiWebAppBrowseResponse.cs | 2 +- .../ApiWebServerGetReadDefaultPageResponse.cs | 2 +- ...ApiWebServerReadResponseHeadersResponse.cs | 14 + .../Models/Responses/BaseApiResponse.cs | 2 +- .../ResponseResults/ApiBrowseFilesResult.cs | 2 +- .../ResponseResults/ApiBrowseTicketsResult.cs | 2 +- .../ApiFailsafeReadParametersResult.cs | 2 +- .../ApiFailsafeReadRuntimeGroupsResult.cs | 2 +- .../ApiGetAuthenticationModeResult.cs | 2 +- .../ApiGetPasswordPolicyResult.cs | 2 +- .../ApiPlcReadCpuTypeResult.cs | 52 + .../ApiPlcReadModeSelectorStateResult.cs | 2 +- .../ApiPlcReadModuleNameResult.cs | 46 + .../ApiPlcReadStationNameResult.cs | 46 + .../ApiPlcReadSystemTimeResult.cs | 2 +- .../ApiPlcReadTimeSettingsResult.cs | 2 +- .../ResponseResults/ApiReadLanguagesResult.cs | 4 +- .../ApiTechnologyBrowseObjectsResult.cs | 19 + .../ResponseResults/ApiTokenResult.cs | 2 +- .../ApiWebAppBrowseResourcesResult.cs | 2 +- .../ResponseResults/ApiWebAppBrowseResult.cs | 2 +- .../WebServerDefaultPageResult.cs | 2 +- .../Models/Technology/ApiTechnologyObject.cs | 53 + .../TimeSettings/DaylightSavingsRule.cs | 2 +- .../DaylightSavingsTimeConfiguration.cs | 2 +- .../Models/TimeSettings/PlcDate.cs | 2 +- .../TimeSettings/StandardTimeConfiguration.cs | 2 +- .../ApiWebserverResponseHeaders.cs | 23 + .../ApiWebserverResponseHeaders_Allowed.cs | 22 + .../ApiWebserverResponseHeaders_Configured.cs | 23 + .../Services/ApiStandardServiceFactory.cs | 7 +- .../Services/Backup/ApiBackupHandler.cs | 89 +- .../Services/Backup/IApiBackupHandler.cs | 4 +- .../EnabledDisabledConverter.cs | 2 +- .../FailsafeHardwareConverter.cs | 2 +- .../TimeSpanISO8601Converter.cs | 2 +- .../FileHandling/ApiDirectoryBuilder.cs | 2 +- .../ApiDirectoryBuilderConfiguration.cs | 2 +- .../FileHandling/ApiDirectoryHandler.cs | 8 +- .../Services/FileHandling/ApiFileHandler.cs | 6 +- .../FileHandling/ApiFileResourceBuilder.cs | 2 +- .../FileHandling/IApiDirectoryBuilder.cs | 2 +- .../FileHandling/IApiDirectoryHandler.cs | 8 +- .../Services/FileHandling/IApiFileHandler.cs | 6 +- .../FileHandling/IApiFileResourceBuilder.cs | 2 +- .../FileParser/ApiWebAppConfigParser.cs | 6 +- .../Services/HelperHandlers/WaitHandler.cs | 2 +- .../Services/IApiServiceFactory.cs | 3 +- .../IdGenerator/CharSetIdGenerator.cs | 2 +- .../Services/IdGenerator/GUIDGenerator.cs | 2 +- .../Services/IdGenerator/IIdGenerator.cs | 2 +- .../PlcProgram/ApiPlcProgramHandler.cs | 13 +- .../PlcProgram/IApiPlcProgramHandler.cs | 13 +- .../ApiHttpClientRequestHandler.cs | 476 ++++++++- .../RequestHandling/ApiRequestFactory.cs | 330 +++++- .../ApiRequestParameterChecker.cs | 12 +- .../RequestHandling/ApiResponseChecker.cs | 2 +- .../RequestHandling/IApiRequestFactory.cs | 149 ++- .../RequestHandling/IApiRequestHandler.cs | 365 ++++++- .../IApiRequestParameterChecker.cs | 4 +- .../RequestHandling/IApiResponseChecker.cs | 2 +- .../Services/Ticketing/ApiTicketHandler.cs | 4 +- .../Services/Ticketing/IApiTicketHandler.cs | 2 +- .../Services/WebApp/ApiResourceHandler.cs | 5 +- .../Services/WebApp/ApiWebAppDataSaver.cs | 2 +- .../Services/WebApp/ApiWebAppDeployer.cs | 12 +- .../WebApp/ApiWebAppResourceBuilder.cs | 2 +- .../Services/WebApp/IApiResourceHandler.cs | 5 +- .../Services/WebApp/IApiWebAppDeployer.cs | 4 +- .../WebApp/IApiWebAppResourceBuilder.cs | 2 +- .../StaticHelpers/DateTimeFormat.cs | 2 +- tests/Webserver.API.UnitTests/ApiBulkTests.cs | 2 +- .../ApiDirectoryBuilderTests.cs | 2 +- .../ApiRequestTests.cs | 939 +++++++++++++++++- .../ApiWebAppDataSaverTests.cs | 2 +- tests/Webserver.API.UnitTests/Base.cs | 2 +- tests/Webserver.API.UnitTests/EnumTests.cs | 2 +- .../Webserver.API.UnitTests/ExtensionTests.cs | 2 +- .../FileParserTests.cs | 5 +- .../IdGeneratorTests.cs | 2 +- .../Webserver.API.UnitTests/MIMETypeTests.cs | 2 +- tests/Webserver.API.UnitTests/ModelTests.cs | 2 +- .../RequestFactoryTests.cs | 2 +- .../RequestParameterCheckerTests.cs | 20 +- .../ResponseCheckerTest.cs | 2 +- .../ResponseStrings.cs | 50 +- version.json | 2 +- 267 files changed, 4557 insertions(+), 395 deletions(-) create mode 100644 src/Webserver.API/Enums/ApiPlcDataRepresentation.cs create mode 100644 src/Webserver.API/Enums/ApiPlcRedundancyPairingState.cs create mode 100644 src/Webserver.API/Enums/ApiPlcRedundancyRole.cs create mode 100644 src/Webserver.API/Enums/ApiPlcRedundancySystemState.cs create mode 100644 src/Webserver.API/Enums/ApiReadLanguagesMode.cs create mode 100644 src/Webserver.API/Enums/ApiRedundancySyncUpPhase.cs create mode 100644 src/Webserver.API/Enums/ApiTechnologyObjectType.cs create mode 100644 src/Webserver.API/Enums/ApiUserAuthenticationMode.cs create mode 100644 src/Webserver.API/Enums/ApiWebAppRedirectMode.cs create mode 100644 src/Webserver.API/Exceptions/ApiHTTPHeaderInvalidException.cs create mode 100644 src/Webserver.API/Exceptions/ApiHTTPHeaderNotAllowedException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInfrastructureErrorException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidPatternException.cs create mode 100644 src/Webserver.API/Exceptions/ApiInvalidVersionStringException.cs create mode 100644 src/Webserver.API/Exceptions/ApiNotATechnologyObjectException.cs create mode 100644 src/Webserver.API/Exceptions/ApiNotAcceptedException.cs create mode 100644 src/Webserver.API/Exceptions/ApiRequestTooLargeException.cs create mode 100644 src/Webserver.API/Exceptions/ApiTooManyHTTPHeadersException.cs create mode 100644 src/Webserver.API/Models/ApiRedundancySystemState.cs create mode 100644 src/Webserver.API/Models/ApiSessionInfo.cs create mode 100644 src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress.cs create mode 100644 src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyMemoryCard.cs create mode 100644 src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyWorkMemory.cs create mode 100644 src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_MinimizingDelay.cs create mode 100644 src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo.cs create mode 100644 src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plc.cs create mode 100644 src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plcs.cs create mode 100644 src/Webserver.API/Models/Responses/ApiPlcReadCpuTypeResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiPlcReadModuleNameResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiPlcReadStationNameResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiRedundancyReadSyncupProgressResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiRedundancyReadSystemInformationResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiRedundancyReadSystemStateResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiSessionInfoResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiTechnologyBrowseObjectsResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ApiWebServerReadResponseHeadersResponse.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadCpuTypeResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModuleNameResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadStationNameResult.cs create mode 100644 src/Webserver.API/Models/Responses/ResponseResults/ApiTechnologyBrowseObjectsResult.cs create mode 100644 src/Webserver.API/Models/Technology/ApiTechnologyObject.cs create mode 100644 src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders.cs create mode 100644 src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Allowed.cs create mode 100644 src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Configured.cs diff --git a/README.md b/README.md index 4894ba3..32f3dc2 100644 --- a/README.md +++ b/README.md @@ -244,6 +244,7 @@ Plc Version | Client Library Version 2.9.x | 2.0.x 3.0.x | 2.1.x 3.1.x | 2.2.x +4.0.x | 3.0.x ## SIMATIC S7-1200: Plc Version | Client Library Version diff --git a/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs b/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs index 58f92bc..0619848 100644 --- a/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs +++ b/src/Webserver.API/Enums/ApiAlarmAcknowledgementState.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs b/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs index 0017ad8..897522d 100644 --- a/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs +++ b/src/Webserver.API/Enums/ApiAlarmsBrowseFilterAttribute.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiAuthenticationMode.cs b/src/Webserver.API/Enums/ApiAuthenticationMode.cs index bec689e..c78a85b 100644 --- a/src/Webserver.API/Enums/ApiAuthenticationMode.cs +++ b/src/Webserver.API/Enums/ApiAuthenticationMode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -9,12 +9,15 @@ namespace Siemens.Simatic.S7.Webserver.API.Enums { /// /// User Authentication modes of the PLC.
- /// Depends on the configured user management which authentication modes will be supported by the PLC
- /// based on the authentication mode. + /// Depends on the configured user management which authentication modes will be supported by the PLC based on the authentication mode. ///
[JsonConverter(typeof(StringEnumConverter), converterParameters: typeof(SnakeCaseNamingStrategy))] public enum ApiAuthenticationMode { + /// + /// The users are stored on the PLC + /// + Local, /// /// Legacy User Management /// @@ -24,8 +27,8 @@ public enum ApiAuthenticationMode /// Disabled, /// - /// The users are stored on the PLC + /// Central User Management (via remote authentication with Username and Password) /// - Local + Umc, } } diff --git a/src/Webserver.API/Enums/ApiBrowseFilterMode.cs b/src/Webserver.API/Enums/ApiBrowseFilterMode.cs index 331b281..520a4b8 100644 --- a/src/Webserver.API/Enums/ApiBrowseFilterMode.cs +++ b/src/Webserver.API/Enums/ApiBrowseFilterMode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiDayOfWeek.cs b/src/Webserver.API/Enums/ApiDayOfWeek.cs index af1331b..3be6f24 100644 --- a/src/Webserver.API/Enums/ApiDayOfWeek.cs +++ b/src/Webserver.API/Enums/ApiDayOfWeek.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs b/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs index dfa6003..d651e64 100644 --- a/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs +++ b/src/Webserver.API/Enums/ApiDiagnosticBufferBrowseFilterAttributes.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiErrorCode.cs b/src/Webserver.API/Enums/ApiErrorCode.cs index b429af8..6ba81ac 100644 --- a/src/Webserver.API/Enums/ApiErrorCode.cs +++ b/src/Webserver.API/Enums/ApiErrorCode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT @@ -53,9 +53,11 @@ public enum ApiErrorCode /// SystemIsReadOnly = 5, /// - /// The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC.
+ /// Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// The execution of the requested method has not been accepted due to a method-specific restriction. ///
- PasswordChangeNotAccepted = 6, + NotAccepted = 6, /// /// The data of a PLC of an R/H system is not accessible. /// This may happen if the system is in state Syncup or RUN-redundant or if the service data of the partner PLC has been requested. @@ -83,6 +85,10 @@ public enum ApiErrorCode /// NewPasswordMatchesOldPassword = 104, /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + InfrastructureError = 105, + /// /// The requested address does not exist or the webserver cannot access the requested address. /// Die angeforderte Adresse existiert nicht oder der Webserver kann nicht auf die angeforderte Adresse zugreifen. /// @@ -173,6 +179,10 @@ public enum ApiErrorCode /// ResourceLimitReached = 509, /// + /// The version string provided does not meet the criteria of a valid version string. + /// + InvalidVersionString = 510, + /// /// The proposed modification time is inalid. Adjust the proposed modification before calling this method again. /// Die vorgesehene Änderungszeit liegt außerhalb des zulässigen Zeitfensters für die Änderungszeit. Verringern Sie die Änderungszeit entsprechend, bevor Sie diese Methode aufrufen. /// @@ -228,6 +238,32 @@ public enum ApiErrorCode /// InvalidHwId = 1100, /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + InvalidPattern = 1301, + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + HTTPHeaderNotAllowed = 1302, + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + HTTPHeaderInvalid = 1303, + /// + /// Too many HTTP response headers are configured.
+ /// Reduce the number to a supported number of headers. The number is currently capped at 1. + ///
+ TooManyHTTPHeaders = 1304, + /// + /// The overall size of all HTTP headers requested to be configured is too large.
+ /// The user shall either reduce the number of headers or the length of an individual HTTP header. + ///
+ RequestTooLarge = 1305, + /// + /// The accessed variable is not a variable of a technology object and cannot be read. + /// + NotATechnologyObject = 1400, + /// /// The method has not been found by the plc - check the spelling and fw-version (and according methods) of plc /// MethodNotFound = -32601, diff --git a/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs b/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs index ad5f239..931908e 100644 --- a/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs +++ b/src/Webserver.API/Enums/ApiFailsafeHardwareType.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiFileResourceState.cs b/src/Webserver.API/Enums/ApiFileResourceState.cs index 83a4e6c..f86fd73 100644 --- a/src/Webserver.API/Enums/ApiFileResourceState.cs +++ b/src/Webserver.API/Enums/ApiFileResourceState.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiFileResourceType.cs b/src/Webserver.API/Enums/ApiFileResourceType.cs index de25306..c1af22e 100644 --- a/src/Webserver.API/Enums/ApiFileResourceType.cs +++ b/src/Webserver.API/Enums/ApiFileResourceType.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs b/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs index 4e7e720..b82e9f6 100644 --- a/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs +++ b/src/Webserver.API/Enums/ApiObjectDirectoryStatus.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiPlcDataRepresentation.cs b/src/Webserver.API/Enums/ApiPlcDataRepresentation.cs new file mode 100644 index 0000000..f837ecb --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcDataRepresentation.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Determines the response format for various methods that return data from the PLC. + /// + public enum ApiPlcDataRepresentation + { + /// + /// Should never be the case + /// + None = 0, + /// + /// "Simple", comfortable format -- represented in a semi-human-readable format. + /// + Simple = 1, + /// + /// The data is represented in big endian format, formatted as a JSON byte array. + /// + Raw = 2 + } +} diff --git a/src/Webserver.API/Enums/ApiPlcHwId.cs b/src/Webserver.API/Enums/ApiPlcHwId.cs index c0d80c8..9905e2a 100644 --- a/src/Webserver.API/Enums/ApiPlcHwId.cs +++ b/src/Webserver.API/Enums/ApiPlcHwId.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs b/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs index 6bf5098..2174d25 100644 --- a/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs +++ b/src/Webserver.API/Enums/ApiPlcModeSelectorState.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Enums/ApiPlcOperatingMode.cs b/src/Webserver.API/Enums/ApiPlcOperatingMode.cs index 59b44de..8435750 100644 --- a/src/Webserver.API/Enums/ApiPlcOperatingMode.cs +++ b/src/Webserver.API/Enums/ApiPlcOperatingMode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT @@ -36,6 +36,22 @@ public enum ApiPlcOperatingMode /// /// STOP Firmware-Update /// - Stop_fwupdate = 6 + Stop_fwupdate = 6, + /// + /// RH PLCs are in Run-Redundant mode. + /// + Run_redundant = 7, + /// + /// RH PLCs are in syncup state. + /// + Syncup = 8, + /// + /// RH PLCs are synchronizing. + /// + Run_syncup = 9, + /// + /// + /// + Remote_unknown = 10, } } diff --git a/src/Webserver.API/Enums/ApiPlcProgramBlockType.cs b/src/Webserver.API/Enums/ApiPlcProgramBlockType.cs index 5f5d59f..92b8df0 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramBlockType.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramBlockType.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs b/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs index e4d6e91..c6accd0 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramBrowseMode.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiPlcProgramDataType.cs b/src/Webserver.API/Enums/ApiPlcProgramDataType.cs index 9785a98..8a82cec 100644 --- a/src/Webserver.API/Enums/ApiPlcProgramDataType.cs +++ b/src/Webserver.API/Enums/ApiPlcProgramDataType.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes; diff --git a/src/Webserver.API/Enums/ApiPlcRedundancyId.cs b/src/Webserver.API/Enums/ApiPlcRedundancyId.cs index 621b833..120a9b7 100644 --- a/src/Webserver.API/Enums/ApiPlcRedundancyId.cs +++ b/src/Webserver.API/Enums/ApiPlcRedundancyId.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiPlcRedundancyPairingState.cs b/src/Webserver.API/Enums/ApiPlcRedundancyPairingState.cs new file mode 100644 index 0000000..72ca404 --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcRedundancyPairingState.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The pairing status of the R/H system. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiPlcRedundancyPairingState + { + /// + /// Default value if the pairing status could not be retrieved or was 0. + /// + [EnumMember(Value = "unknown")] + Unknown = 0, + /// + /// Redundant connection between both PLCs. + /// + [EnumMember(Value = "paired")] + Paired = 1, + /// + /// Only single pairing via port 1 (or 2) is available. + /// + [EnumMember(Value = "paired_single")] + Paired_single = 2, + /// + /// There are more than 2 R/H PLCs in the network. Cannot determine partner PLC. + /// + [EnumMember(Value = "not_paired_too_many_partners")] + Not_paired_too_many_partners = 3, + /// + /// The partner PLC is not reachable or internal error, represented as unspecified error to the user. + /// + [EnumMember(Value = "not_paired")] + Not_paired = 4, + /// + /// The order IDs of both PLCs of the R/H system do not match. + /// + [EnumMember(Value = "not_paired_order_id_mismatch")] + Not_paired_order_id_mismatch = 5, + /// + /// The firmware versions of both PLCs of the R/H system do not match. + /// + [EnumMember(Value = "not_paired_firmware_mismatch")] + Not_paired_firmware_mismatch = 6, + + } +} diff --git a/src/Webserver.API/Enums/ApiPlcRedundancyRole.cs b/src/Webserver.API/Enums/ApiPlcRedundancyRole.cs new file mode 100644 index 0000000..a404121 --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcRedundancyRole.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The role of the represented PLC in the redundant system. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiPlcRedundancyRole + { + /// + /// For the tree of the partner PLC, the role may be unknown in case that the partner PLC is not properly paired. + /// + [EnumMember(Value = "unknown")] + Unknown = 0, + /// + /// Primary PLC + /// + [EnumMember(Value = "primary")] + Primary = 1, + /// + /// Backup PLC + /// + [EnumMember(Value = "backup")] + Backup = 2 + } +} diff --git a/src/Webserver.API/Enums/ApiPlcRedundancySystemState.cs b/src/Webserver.API/Enums/ApiPlcRedundancySystemState.cs new file mode 100644 index 0000000..f2ddb5e --- /dev/null +++ b/src/Webserver.API/Enums/ApiPlcRedundancySystemState.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using System.Runtime.Serialization; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// The system state describes the overall state of the R/H system. + /// It is determined by the combination of the operating modes of both R/H PLCs. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiPlcRedundancySystemState + { + /// + /// Unknown + /// + [EnumMember(Value = "unknown")] + Unknown = 0, + /// + /// Run_solo + /// + [EnumMember(Value = "run_solo")] + Run_solo = 1, + /// + /// Run_redundant + /// + [EnumMember(Value = "run_redundant")] + Run_redundant = 2, + /// + /// Stop + /// + [EnumMember(Value = "stop")] + Stop = 3, + /// + /// Syncup + /// + [EnumMember(Value = "syncup")] + Syncup = 4, + /// + /// Halt + /// + [EnumMember(Value = "halt")] + Halt = 5, + /// + /// Startup + /// + [EnumMember(Value = "startup")] + Startup = 6, + + } +} diff --git a/src/Webserver.API/Enums/ApiReadLanguagesMode.cs b/src/Webserver.API/Enums/ApiReadLanguagesMode.cs new file mode 100644 index 0000000..a59a433 --- /dev/null +++ b/src/Webserver.API/Enums/ApiReadLanguagesMode.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Enum for all possible ReadLanguages modes + /// + public enum ApiReadLanguagesMode + { + /// + /// All languages are returned. + /// + All, + /// + /// Only the active languages are returned. + /// + Active + } +} diff --git a/src/Webserver.API/Enums/ApiRedundancySyncUpPhase.cs b/src/Webserver.API/Enums/ApiRedundancySyncUpPhase.cs new file mode 100644 index 0000000..7f40a99 --- /dev/null +++ b/src/Webserver.API/Enums/ApiRedundancySyncUpPhase.cs @@ -0,0 +1,56 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Enum containing all possible syncup phases. + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiRedundancySyncupPhase + { + /// + /// All other states that are not used anymore or shall never occur will be mapped to this value. + /// + Unknown = 0, + /// + /// Precondition checks are performed. In this phase, the system checks for IP address duplicates, open ring etc. + /// + Checking_preconditions = 1, + /// + /// Copying memory card content to Backup PLC. + /// + Copying_memory_card = 2, + /// + /// Waiting for restart of the Backup PLC. + /// + Rebooting_backup = 3, + /// + /// Preparing for transfer of work memory. + /// + Preparing_work_memory = 4, + /// + /// Copying work memory to Backup PLC. + /// + Copying_work_memory = 5, + /// + /// The Backup PLC has completely received the snapshot and is now minimizing the delay between this PLC and the Backup PLC (catching up). + /// + Minimizing_delay = 6, + /// + /// Cancellation of the Syncup process is currently ongoing. + /// + Cancelling = 7, + /// + /// The system entered the redundant system state. + /// + Redundant = 8, + /// + /// The system is not synchronized. + /// + Not_redundant = 9, + } +} diff --git a/src/Webserver.API/Enums/ApiTechnologyObjectType.cs b/src/Webserver.API/Enums/ApiTechnologyObjectType.cs new file mode 100644 index 0000000..9ee7c67 --- /dev/null +++ b/src/Webserver.API/Enums/ApiTechnologyObjectType.cs @@ -0,0 +1,84 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; + +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Enum of all possible technology objects + /// + [JsonConverter(typeof(StringEnumConverter))] + public enum ApiTechnologyObjectType + { + /// + /// Technology Object SpeedAxis + /// + To_SpeedAxis, + /// + /// Technology Object PositioningAxis + /// + To_PositioningAxis, + /// + /// Technology Object SynchronousAxis + /// + To_SynchronousAxis, + /// + /// Technology Object ExternalEncoder + /// + To_ExternalEncoder, + /// + /// Technology Object MeasuringInput + /// + To_MeasuringInput, + /// + /// Technology Object OutputCam + /// + To_OutputCam, + /// + /// Technology Object CamTrack + /// + To_CamTrack, + /// + /// Technology Object Cam + /// + To_Cam, + /// + /// Technology Object Kinematics + /// + To_Kinematics, + /// + /// Technology Object LeadingAxisProxy + /// + To_LeadingAxisProxy, + /// + /// Technology Object Cam_10K + /// + To_Cam_10k, + /// + /// Technology Object Interpreter + /// + To_Interpreter, + /// + /// Technology Object InterpreterMapping + /// + To_InterpreterMapping, + /// + /// Technology Object InterpreterProgram + /// + To_InterpreterProgram, + /// + /// Technology Object Cam_600 + /// + To_Cam_600, + /// + /// Technology Object Cam_6k + /// + To_Cam_6k, + /// + /// Unknown + /// + Unknown + } +} \ No newline at end of file diff --git a/src/Webserver.API/Enums/ApiTicketProvider.cs b/src/Webserver.API/Enums/ApiTicketProvider.cs index d39b310..cf005ba 100644 --- a/src/Webserver.API/Enums/ApiTicketProvider.cs +++ b/src/Webserver.API/Enums/ApiTicketProvider.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -51,5 +51,17 @@ public enum ApiTicketProvider [JsonProperty("PlcProgram.DownloadProfilingData")] [EnumMember(Value = "PlcProgram.DownloadProfilingData")] PlcProgram_DownloadProfilingData = 6, + /// + /// For Api: Files.Download + /// + [JsonProperty("Files.Download")] + [EnumMember(Value = "Files.Download")] + Files_Download = 7, + /// + /// For Api: DataLogs.DownloadAndClear + /// + [JsonProperty("DataLogs.DownloadAndClear")] + [EnumMember(Value = "DataLogs.DownloadAndClear")] + DataLogs_DownloadAndClear = 8, } } diff --git a/src/Webserver.API/Enums/ApiTicketState.cs b/src/Webserver.API/Enums/ApiTicketState.cs index 321ca05..346c07f 100644 --- a/src/Webserver.API/Enums/ApiTicketState.cs +++ b/src/Webserver.API/Enums/ApiTicketState.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiUserAuthenticationMode.cs b/src/Webserver.API/Enums/ApiUserAuthenticationMode.cs new file mode 100644 index 0000000..be2b833 --- /dev/null +++ b/src/Webserver.API/Enums/ApiUserAuthenticationMode.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Possible user authentication modes + /// + public enum ApiUserAuthenticationMode + { + /// + /// Anonymous + /// + None = 0, + /// + /// Local User Management + /// + Local = 1, + /// + /// Central User Management (via Username and Password) + /// + Umc = 2, + /// + /// Central User Management (via Single-Sign-On) + /// + Umc_sso = 3, + } +} diff --git a/src/Webserver.API/Enums/ApiWebAppRedirectMode.cs b/src/Webserver.API/Enums/ApiWebAppRedirectMode.cs new file mode 100644 index 0000000..3a489ed --- /dev/null +++ b/src/Webserver.API/Enums/ApiWebAppRedirectMode.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +namespace Siemens.Simatic.S7.Webserver.API.Enums +{ + /// + /// Possible Application Redirect Modes + /// + public enum ApiWebAppRedirectMode + { + /// + /// Should never be the case + /// + None = 0, + /// + /// Redirect mode + /// + Redirect = 1, + /// + /// Forward mode + /// + Forward = 2 + } +} diff --git a/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs b/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs index 3854c56..8291a1d 100644 --- a/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs +++ b/src/Webserver.API/Enums/ApiWebAppResourceVisibility.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiWebAppState.cs b/src/Webserver.API/Enums/ApiWebAppState.cs index c1b7907..c3959b1 100644 --- a/src/Webserver.API/Enums/ApiWebAppState.cs +++ b/src/Webserver.API/Enums/ApiWebAppState.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Enums/ApiWebAppType.cs b/src/Webserver.API/Enums/ApiWebAppType.cs index a6227ee..d75d571 100644 --- a/src/Webserver.API/Enums/ApiWebAppType.cs +++ b/src/Webserver.API/Enums/ApiWebAppType.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT @@ -20,6 +20,10 @@ public enum ApiWebAppType /// /// View-Of-Things Web Application (=>restricted access possible - no download,...) /// - VoT = 2 + VoT = 2, + /// + /// System built in Web Application + /// + system_builtin = 3 } } diff --git a/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs index 7cf83a2..31516b9 100644 --- a/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiAddressDoesNotExistException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs b/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs index ff3446a..3435615 100644 --- a/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs +++ b/src/Webserver.API/Exceptions/ApiAlreadyAuthenticatedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs index 77fe9a3..66d1cd9 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationAlreadyExistsException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs index a001e13..33f07fb 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationDoesNotExistException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs b/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs index a9d0b26..e6cdf50 100644 --- a/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs +++ b/src/Webserver.API/Exceptions/ApiApplicationLimitReachedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiBulkRequestException.cs b/src/Webserver.API/Exceptions/ApiBulkRequestException.cs index d95cee2..88adfb5 100644 --- a/src/Webserver.API/Exceptions/ApiBulkRequestException.cs +++ b/src/Webserver.API/Exceptions/ApiBulkRequestException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses; diff --git a/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs b/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs index ecf4f1b..41a9e61 100644 --- a/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs +++ b/src/Webserver.API/Exceptions/ApiDirectoryParserException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs index b766b46..9008a38 100644 --- a/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityAlreadyExistsException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs index a8fe730..be34da9 100644 --- a/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityDoesNotExistException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiEntityInUseException.cs b/src/Webserver.API/Exceptions/ApiEntityInUseException.cs index aaccb96..0b920fa 100644 --- a/src/Webserver.API/Exceptions/ApiEntityInUseException.cs +++ b/src/Webserver.API/Exceptions/ApiEntityInUseException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiException.cs b/src/Webserver.API/Exceptions/ApiException.cs index e396090..edbcc84 100644 --- a/src/Webserver.API/Exceptions/ApiException.cs +++ b/src/Webserver.API/Exceptions/ApiException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Exceptions/ApiHTTPHeaderInvalidException.cs b/src/Webserver.API/Exceptions/ApiHTTPHeaderInvalidException.cs new file mode 100644 index 0000000..ba4f627 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiHTTPHeaderInvalidException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + public class ApiHTTPHeaderInvalidException : Exception + { + private static string message = "At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required."; + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + public ApiHTTPHeaderInvalidException() : base(message) { } + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiHTTPHeaderInvalidException(Exception innerException) : base(message, innerException) { } + + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiHTTPHeaderInvalidException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// At least one of the provided HTTP headers represents an invalid HTTP header. Verify the provided HTTP header string and correct it as required. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiHTTPHeaderInvalidException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiHTTPHeaderNotAllowedException.cs b/src/Webserver.API/Exceptions/ApiHTTPHeaderNotAllowedException.cs new file mode 100644 index 0000000..4c2be20 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiHTTPHeaderNotAllowedException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + public class ApiHTTPHeaderNotAllowedException : Exception + { + private static string message = "At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set."; + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + public ApiHTTPHeaderNotAllowedException() : base(message) { } + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiHTTPHeaderNotAllowedException(Exception innerException) : base(message, innerException) { } + + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiHTTPHeaderNotAllowedException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// At least one of the provided HTTP headers is not part in the allowed list. Choose a HTTP header that is allowed to be set. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiHTTPHeaderNotAllowedException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs b/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs index 4c787b2..a556b36 100644 --- a/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs +++ b/src/Webserver.API/Exceptions/ApiHelperInvalidPlcProgramDataTypeException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs b/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs index c7a7f3b..151205c 100644 --- a/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs +++ b/src/Webserver.API/Exceptions/ApiInconsistentApiWebAppDataException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInfrastructureErrorException.cs b/src/Webserver.API/Exceptions/ApiInfrastructureErrorException.cs new file mode 100644 index 0000000..5499076 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInfrastructureErrorException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + public class ApiInfrastructureErrorException : Exception + { + private static string message = "Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC."; + /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInfrastructureErrorException(Exception innerException) : base(message, innerException) { } + /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + public ApiInfrastructureErrorException() : base(message) { } + /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInfrastructureErrorException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// Authentication on the UMC server was not successful. This may happen due to various reasons, e.g. the UMC server could not be reached by the PLC. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInfrastructureErrorException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInternalErrorException.cs b/src/Webserver.API/Exceptions/ApiInternalErrorException.cs index 05fe1b4..662d21b 100644 --- a/src/Webserver.API/Exceptions/ApiInternalErrorException.cs +++ b/src/Webserver.API/Exceptions/ApiInternalErrorException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs b/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs index 3878d2d..535f8d4 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidAddressException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs b/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs index d6ead62..8b3da4d 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidAlarmIdException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs b/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs index 1435dac..71a195d 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidAlarmsBrowseParametersException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs b/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs index a748ee1..5a89a26 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidApplicationNameException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs b/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs index d7f5b27..090b3df 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidArrayIndexException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidETagException.cs b/src/Webserver.API/Exceptions/ApiInvalidETagException.cs index 426cb50..c280b9f 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidETagException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidETagException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs b/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs index 7520330..0a11742 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidHWIDException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs b/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs index 6c17768..ccdd41a 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidMediaTypeException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs b/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs index 6d8008e..bf82a6f 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidModificationTimeException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs b/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs index 263f10b..58ca548 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidParametersException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidPatternException.cs b/src/Webserver.API/Exceptions/ApiInvalidPatternException.cs new file mode 100644 index 0000000..9d7d897 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidPatternException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + public class ApiInvalidPatternException : Exception + { + private static string message = "The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured."; + /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + public ApiInvalidPatternException() : base(message) { } + /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidPatternException(Exception innerException) : base(message, innerException) { } + + /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidPatternException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The provided pattern is not in the allowed list. Choose a pattern that is allowed to be configured. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidPatternException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs b/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs index bfb524e..f7771b9 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidResourceNameException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs b/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs index afb3df0..9a3d433 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidResponseException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs b/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs index 1705ab2..f14d871 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidTicketIdValueException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs b/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs index 25fcd4d..8ad495e 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidTimeRuleException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs b/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs index 8e8a209..61a497d 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidTimestampException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs b/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs index 0972257..a3393e3 100644 --- a/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs +++ b/src/Webserver.API/Exceptions/ApiInvalidUTCOffsetException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiInvalidVersionStringException.cs b/src/Webserver.API/Exceptions/ApiInvalidVersionStringException.cs new file mode 100644 index 0000000..fbc1492 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiInvalidVersionStringException.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The version string provided does not meet the criteria of a valid version string. + /// + public class ApiInvalidVersionStringException : Exception + { + private static string message = "The version string provided does not meet the criteria of a valid version string. Valid version string example: V1.2"; + /// + /// The version string provided does not meet the criteria of a valid version string. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidVersionStringException(Exception innerException) : base(message, innerException) { } + /// + /// The version string provided does not meet the criteria of a valid version string. + /// + public ApiInvalidVersionStringException() : base(message) { } + + + /// + /// The version string provided does not meet the criteria of a valid version string. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiInvalidVersionStringException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The version string provided does not meet the criteria of a valid version string. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiInvalidVersionStringException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs b/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs index 69b3194..70f38dd 100644 --- a/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs +++ b/src/Webserver.API/Exceptions/ApiMethodNotFoundException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs b/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs index 046f920..f711a36 100644 --- a/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs +++ b/src/Webserver.API/Exceptions/ApiNewPasswordDoesNotFollowPolicyException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs b/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs index 702c8e5..9088989 100644 --- a/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs +++ b/src/Webserver.API/Exceptions/ApiNewPasswordMatchesOldPasswordException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiNoResourcesException.cs b/src/Webserver.API/Exceptions/ApiNoResourcesException.cs index 562a4b9..102be8e 100644 --- a/src/Webserver.API/Exceptions/ApiNoResourcesException.cs +++ b/src/Webserver.API/Exceptions/ApiNoResourcesException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs b/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs index 52cb20e..d24f4ce 100644 --- a/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs +++ b/src/Webserver.API/Exceptions/ApiNoServiceDataResourcesException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiNotATechnologyObjectException.cs b/src/Webserver.API/Exceptions/ApiNotATechnologyObjectException.cs new file mode 100644 index 0000000..f130486 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiNotATechnologyObjectException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// Exception for Error code 1400 + /// + public class ApiNotATechnologyObjectException : Exception + { + private static string message = "The accessed variable is not a variable of a technology object and cannot be read."; + /// + /// The accessed variable is not a variable of a technology object and cannot be read. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNotATechnologyObjectException(Exception innerException) : base(message, innerException) { } + /// + /// The accessed variable is not a variable of a technology object and cannot be read. + /// + public ApiNotATechnologyObjectException() : base(message) { } + + /// + /// The accessed variable is not a variable of a technology object and cannot be read. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiNotATechnologyObjectException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The accessed variable is not a variable of a technology object and cannot be read. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNotATechnologyObjectException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiNotAcceptedException.cs b/src/Webserver.API/Exceptions/ApiNotAcceptedException.cs new file mode 100644 index 0000000..f86d448 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiNotAcceptedException.cs @@ -0,0 +1,37 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + public class ApiNotAcceptedException : Exception + { + private static string message = "Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported."; + /// + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNotAcceptedException(Exception innerException) : base(message, innerException) { } + /// + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + public ApiNotAcceptedException() : base(message) { } + /// + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiNotAcceptedException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// Not accepted in login: The authentication cannot be performed. This may happen because the requested mode is not supported by the PLC. Not accepted in password change: The password change cannot be performed. This is caused for example if an older PLC project is present where password changes are not supported. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiNotAcceptedException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs b/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs index ba79355..0f3aca5 100644 --- a/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs +++ b/src/Webserver.API/Exceptions/ApiPLCNotInStopException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs b/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs index 30c70f9..24df6fc 100644 --- a/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs +++ b/src/Webserver.API/Exceptions/ApiPartnerNotAccessibleException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs b/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs index 2b334c9..344e6c4 100644 --- a/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs +++ b/src/Webserver.API/Exceptions/ApiPasswordExpiredException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiRequestTooLargeException.cs b/src/Webserver.API/Exceptions/ApiRequestTooLargeException.cs new file mode 100644 index 0000000..94ed00b --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiRequestTooLargeException.cs @@ -0,0 +1,39 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header. + /// + public class ApiRequestTooLargeException : Exception + { + private static string message = "The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header."; + + /// + /// At least one of the provided HTTP headers is not part in the allowed list. The user can choose a HTTP header that is allowed to be set. + /// + public ApiRequestTooLargeException() : base(message) { } + /// + /// The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiRequestTooLargeException(Exception innerException) : base(message, innerException) { } + + /// + /// The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiRequestTooLargeException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiRequestTooLargeException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs b/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs index c5b2306..832df67 100644 --- a/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceAlreadyExistsException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs b/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs index 40ae41f..edd024e 100644 --- a/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceContentHasBeenCorruptedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs b/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs index ef9b5e6..ad96c7b 100644 --- a/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceContentIsNotReadyException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs b/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs index e6d65f7..6afe15b 100644 --- a/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceDeploymentFailedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs b/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs index 152281b..42d3e2a 100644 --- a/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceDoesNotExistException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs b/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs index 1e24003..7a29e02 100644 --- a/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceLimitReachedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs b/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs index 541afa9..ee1cbb3 100644 --- a/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs +++ b/src/Webserver.API/Exceptions/ApiResourceVisibilityIsNotPublicException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs b/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs index 6963528..494f997 100644 --- a/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs +++ b/src/Webserver.API/Exceptions/ApiSystemIsBusyException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs b/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs index fd8042d..9a71a73 100644 --- a/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs +++ b/src/Webserver.API/Exceptions/ApiSystemIsReadOnlyException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs b/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs index f7ec6a5..fab69f5 100644 --- a/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketNotFoundException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs b/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs index c2a0005..c076f34 100644 --- a/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketNotInCompletedStateException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; diff --git a/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs b/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs index 518152a..0e7bce4 100644 --- a/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs +++ b/src/Webserver.API/Exceptions/ApiTicketingEndpointUploadException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs b/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs index 1876ea3..989a23e 100644 --- a/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs +++ b/src/Webserver.API/Exceptions/ApiTimestampOutOfRangeException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiTooManyHTTPHeadersException.cs b/src/Webserver.API/Exceptions/ApiTooManyHTTPHeadersException.cs new file mode 100644 index 0000000..a7685a5 --- /dev/null +++ b/src/Webserver.API/Exceptions/ApiTooManyHTTPHeadersException.cs @@ -0,0 +1,38 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Exceptions +{ + /// + /// Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1. + /// + public class ApiTooManyHTTPHeadersException : Exception + { + private static string message = "Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1."; + /// + /// Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1. + /// + public ApiTooManyHTTPHeadersException() : base(message) { } + /// + /// Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1. + /// + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiTooManyHTTPHeadersException(Exception innerException) : base(message, innerException) { } + + /// + /// Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1. + /// + /// Further information about the error message that explains the reason for the exception. + public ApiTooManyHTTPHeadersException(string userMessage) : base(message + Environment.NewLine + userMessage) { } + /// + /// Too many HTTP response headers are configured -- reduce the number to a supported number of headers. The number is currently capped at 1. + /// + /// Further information about the error message that explains the reason for the exception. + /// The exception that is the cause of the current exception, or a null reference + /// (Nothing in Visual Basic) if no inner exception is specified. + public ApiTooManyHTTPHeadersException(string userMessage, Exception innerException) : base(message + Environment.NewLine + userMessage, innerException) { } + } +} diff --git a/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs b/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs index 8d1c5bd..33bfffb 100644 --- a/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs +++ b/src/Webserver.API/Exceptions/ApiUnsupportedAddressException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs b/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs index 42fa245..684371e 100644 --- a/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs +++ b/src/Webserver.API/Exceptions/ApiVariableIsNotAStructureException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs b/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs index 71eb8f1..c14b7f9 100644 --- a/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs +++ b/src/Webserver.API/Exceptions/ApiWebAppConfigParserException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs b/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs index d59ddfe..c749b02 100644 --- a/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs +++ b/src/Webserver.API/Exceptions/ApiWebAppConfigurationFailedException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs b/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs index 2d1bd8d..22ae5b5 100644 --- a/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs +++ b/src/Webserver.API/Exceptions/InvalidHttpRequestException.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs b/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs index f9375ac..06a018a 100644 --- a/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs +++ b/src/Webserver.API/Models/AdditionalTicketData/ApiPlcRestoreBackupTicketData.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs b/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs index 4e2a1df..44603f4 100644 --- a/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs +++ b/src/Webserver.API/Models/AdditionalTicketData/ApiTicketDataBase.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs index 6a65d41..a4bade8 100644 --- a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs index a7c56fa..7804dee 100644 --- a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_Entry.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs index a9de5a6..2ecae49 100644 --- a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_EntryAcknowledgement.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs index fc8f1f7..26061c0 100644 --- a/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs +++ b/src/Webserver.API/Models/AlarmsBrowse/ApiAlarms_RequestFilters.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/ApiClass.cs b/src/Webserver.API/Models/ApiClass.cs index 7f862c5..f65c1d7 100644 --- a/src/Webserver.API/Models/ApiClass.cs +++ b/src/Webserver.API/Models/ApiClass.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs index 3642e53..553f022 100644 --- a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs index 7a8c169..31b86b4 100644 --- a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_Entry.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs index 1f10334..705012a 100644 --- a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_EntryEvent.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs index c678e5a..e998a14 100644 --- a/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs +++ b/src/Webserver.API/Models/ApiDiagnosticBuffer/ApiDiagnosticBuffer_RequestFilters.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/ApiError.cs b/src/Webserver.API/Models/ApiError.cs index b7ee79b..a46f358 100644 --- a/src/Webserver.API/Models/ApiError.cs +++ b/src/Webserver.API/Models/ApiError.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs b/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs index 2ce4caa..7940aca 100644 --- a/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs +++ b/src/Webserver.API/Models/ApiFailsafeRuntimeGroup.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiFileResource.cs b/src/Webserver.API/Models/ApiFileResource.cs index 2f8ab7b..ddc6926 100644 --- a/src/Webserver.API/Models/ApiFileResource.cs +++ b/src/Webserver.API/Models/ApiFileResource.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiLanguage.cs b/src/Webserver.API/Models/ApiLanguage.cs index b339cef..937c3b4 100644 --- a/src/Webserver.API/Models/ApiLanguage.cs +++ b/src/Webserver.API/Models/ApiLanguage.cs @@ -1,7 +1,9 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT +using System.Collections.Generic; using System.Globalization; +using System.Linq; namespace Siemens.Simatic.S7.Webserver.API.Models { @@ -11,8 +13,49 @@ namespace Siemens.Simatic.S7.Webserver.API.Models public class ApiLanguage { /// - /// Language with built-in CultureInfo class + /// Language of the project /// public CultureInfo Language { get; set; } + /// + /// The state tells if the project language is available for usage by API methods such as Alarms.Browse or not. + /// Only present from V40 and onwards. + /// + public bool? Active { get; set; } + /// + /// Each element of the array represents one user interface language for which the given project language should be applied for as default. + /// A client application may overrule this information. + /// The setting is configured in TIA Portal or through the user program. + /// Only present from V40 and onwards. + /// + public List User_interface_languages { get; set; } + + /// + /// Compares input object to this ApiLanguage + /// + /// Object to compare + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiLanguage language && + language.Language.Equals(Language) && + Active == language.Active && (language.User_interface_languages == null ? User_interface_languages == null : (User_interface_languages == null ? false : language.User_interface_languages.SequenceEqual(User_interface_languages))); + } + + /// + /// Hashcode + /// + /// + public override int GetHashCode() + { + var hash = (Language, Active).GetHashCode(); + if (User_interface_languages != null) + { + for (int i = 0; i < User_interface_languages.Count; i++) + { + hash ^= User_interface_languages[i].GetHashCode(); + } + } + return hash; + } } } diff --git a/src/Webserver.API/Models/ApiPasswordExpiration.cs b/src/Webserver.API/Models/ApiPasswordExpiration.cs index d1844a6..bb3d481 100644 --- a/src/Webserver.API/Models/ApiPasswordExpiration.cs +++ b/src/Webserver.API/Models/ApiPasswordExpiration.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; @@ -40,5 +40,15 @@ public override int GetHashCode() { return (Timestamp, Warning).GetHashCode(); } + + /// + /// ToString for ApiPasswordExpiration + /// + /// + public override string ToString() + { + return $"{nameof(Timestamp)}: {Timestamp} | " + + $"{nameof(Warning)}: {Warning}"; + } } } diff --git a/src/Webserver.API/Models/ApiPasswordPolicy.cs b/src/Webserver.API/Models/ApiPasswordPolicy.cs index c5b0f8e..80987f1 100644 --- a/src/Webserver.API/Models/ApiPasswordPolicy.cs +++ b/src/Webserver.API/Models/ApiPasswordPolicy.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs b/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs index 33d5560..d7aa150 100644 --- a/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs +++ b/src/Webserver.API/Models/ApiPlcProgramBrowseCodeBlocksData.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiPlcProgramData.cs b/src/Webserver.API/Models/ApiPlcProgramData.cs index e022277..f756792 100644 --- a/src/Webserver.API/Models/ApiPlcProgramData.cs +++ b/src/Webserver.API/Models/ApiPlcProgramData.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs b/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs index 8383353..5a3fada 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataArrayIndexer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs index 62033ff..88f3594 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiDateAndTime.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs index 3f2abba..d90297a 100644 --- a/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs +++ b/src/Webserver.API/Models/ApiPlcProgramDataTypes/ApiS5Time.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/ApiQuantityStructure.cs b/src/Webserver.API/Models/ApiQuantityStructure.cs index 786debc..c4e14df 100644 --- a/src/Webserver.API/Models/ApiQuantityStructure.cs +++ b/src/Webserver.API/Models/ApiQuantityStructure.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/ApiRedundancySystemState.cs b/src/Webserver.API/Models/ApiRedundancySystemState.cs new file mode 100644 index 0000000..71277f5 --- /dev/null +++ b/src/Webserver.API/Models/ApiRedundancySystemState.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// System state of the R/H system. + /// + public class ApiRedundancySystemState + { + /// + /// Contains the current system state of the R/H system. + /// + public ApiPlcRedundancySystemState State { get; set; } + /// + /// Check wether properties match + /// + /// ApiRedundancySystemInfo_Plc + /// Returns true if the ApiRedundancySystemInfo_Plc are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySystemState; + if (structure == null) { return false; } + return structure.State == this.State; + } + /// + /// GetHashCode for ApiRedundancySystemInfo_Plc + /// + /// hashcode for the ApiRedundancySystemInfo_Plc + public override int GetHashCode() + { + return (State).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySystemInfo_Plc + /// + /// ApiRedundancySystemInfo_Plc as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySystemInfo_Plc + /// + /// Defines if null values should be ignored + /// ApiRedundancySystemInfo_Plc as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiSessionInfo.cs b/src/Webserver.API/Models/ApiSessionInfo.cs new file mode 100644 index 0000000..53a118f --- /dev/null +++ b/src/Webserver.API/Models/ApiSessionInfo.cs @@ -0,0 +1,88 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models +{ + /// + /// Information of the user session, including the authentication mode, username, password expiration and timeout + /// + public class ApiSessionInfo + { + /// + /// Authentication mode that was used to create this user session. + /// + public ApiUserAuthenticationMode Authentication_Mode { get; set; } + + /// + /// Username of the requested session. + /// + public string Username { get; set; } + + /// + /// Password expiration information. Used only when the authentication mode local or umc is used, and the password expiration functionality is enabled on the PLC. + /// + public ApiPasswordExpiration Password_Expiration { get; set; } + + /// + /// The inactivity timespan after which a client application may perform a log out using API method Api.Logout. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan? Runtime_Timeout { get; set; } + + /// + /// Check whether properties match + /// + /// Object to check + /// Returns true if the ApiQuantityStructures are the same + public override bool Equals(object obj) + { + var structure = obj as ApiSessionInfo; + if (structure == null) { return false; } + if ((structure.Password_Expiration == null) != (this.Password_Expiration == null)) + { + return false; + } + if ((structure.Runtime_Timeout == null) != (this.Runtime_Timeout == null)) + { + return false; + } + if (structure.Password_Expiration != null) + { + if (!structure.Password_Expiration.Equals(this.Password_Expiration)) { return false; } + } + if (structure.Runtime_Timeout != null) + { + if (structure.Runtime_Timeout != this.Runtime_Timeout) { return false; } + } + return structure.Authentication_Mode == this.Authentication_Mode && + structure.Username == this.Username; + } + + /// + /// GetHashCode for SequenceEqual etc. + /// + /// hashcode for the ApiQuantityStructures + public override int GetHashCode() + { + return (Authentication_Mode, Username, Password_Expiration, Runtime_Timeout).GetHashCode(); + } + + /// + /// ToString for ApiSessionInfo + /// + /// Formatted string + public override string ToString() + { + string result = $"{nameof(Authentication_Mode)}: {Authentication_Mode} | " + + $"{nameof(Username)}: {Username}"; + if (Password_Expiration != null) { result += $" | {nameof(Password_Expiration)}: ({Password_Expiration.ToString()})"; } + if (Runtime_Timeout != null) { result += $" | {nameof(Runtime_Timeout)}: {Runtime_Timeout}"; } + return result; + } + } +} diff --git a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs index 26f46d0..a8db42a 100644 --- a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs +++ b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs index 29a5895..5e25ff6 100644 --- a/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs +++ b/src/Webserver.API/Models/ApiSyslog/ApiPlcSyslog_Entry.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/ApiTicket.cs b/src/Webserver.API/Models/ApiTicket.cs index 06a1915..561133a 100644 --- a/src/Webserver.API/Models/ApiTicket.cs +++ b/src/Webserver.API/Models/ApiTicket.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/ApiWebAppData.cs b/src/Webserver.API/Models/ApiWebAppData.cs index 0d943a1..6bbacf0 100644 --- a/src/Webserver.API/Models/ApiWebAppData.cs +++ b/src/Webserver.API/Models/ApiWebAppData.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -74,6 +74,32 @@ public ApiWebAppType Type } } + /// + /// The version of the application. + /// + public string Version { get; set; } + + private ApiWebAppRedirectMode redirect_mode; + + /// + /// The URL redirect mode of the application. + /// + public ApiWebAppRedirectMode Redirect_mode + { + get + { + return redirect_mode; + } + set + { + if (value == ApiWebAppRedirectMode.None) + { + throw new ApiInvalidResponseException($"Returned from api was:{value.ToString()} - which is not valid! contact Siemens"); + } + redirect_mode = value; + } + } + /// /// WebApps DefaultPage: The Page a user should be forwarded to in case he accesses the WebApp (https://plcIPOrDNSName/)~WebAppName or (https://plcIPOrDNSName/)~WebAppName/ /// If this page is not present the user will be forwarded to the Not_found_page if that one is configured @@ -137,8 +163,7 @@ public bool Equals(ApiWebAppData other) { if (other is null) return false; - - return this.Name == other.Name && this.State == other.State && this.Type == other.Type + return this.Name == other.Name && this.State == other.State && this.Type == other.Type && this.Version == other.Version && this.Redirect_mode == other.Redirect_mode && this.Default_page == other.Default_page && this.Not_found_page == other.Not_found_page && this.Not_authorized_page == other.Not_authorized_page; } /// @@ -151,6 +176,6 @@ public bool Equals(ApiWebAppData other) /// GetHashCode => (Name, State, Type, Default_page, Not_found_page, Not_authorized_page).GetHashCode() /// /// - public override int GetHashCode() => (Name, State, Type, Default_page, Not_found_page, Not_authorized_page).GetHashCode(); + public override int GetHashCode() => (Name, State, Type, Version, Redirect_mode, Default_page, Not_found_page, Not_authorized_page).GetHashCode(); } } diff --git a/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs b/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs index bf726af..4918bf2 100644 --- a/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs +++ b/src/Webserver.API/Models/ApiWebAppDataSaveSetting.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/ApiWebAppResource.cs b/src/Webserver.API/Models/ApiWebAppResource.cs index b597147..f7a746f 100644 --- a/src/Webserver.API/Models/ApiWebAppResource.cs +++ b/src/Webserver.API/Models/ApiWebAppResource.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs b/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs index 1bc6ebe..0bcab2c 100644 --- a/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs +++ b/src/Webserver.API/Models/FailsafeParameters/FailsafeHardware.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs b/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs index fe7bf9e..44b6fdf 100644 --- a/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs +++ b/src/Webserver.API/Models/HttpClientAndWebAppCookie.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs b/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs index acafe6a..67cbd48 100644 --- a/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs +++ b/src/Webserver.API/Models/HttpClientConnectionConfiguration.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/IApiWebAppData.cs b/src/Webserver.API/Models/IApiWebAppData.cs index 09e87ae..3e2446a 100644 --- a/src/Webserver.API/Models/IApiWebAppData.cs +++ b/src/Webserver.API/Models/IApiWebAppData.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/IApiWebAppDataSaveSetting.cs b/src/Webserver.API/Models/IApiWebAppDataSaveSetting.cs index 7708223..276ec50 100644 --- a/src/Webserver.API/Models/IApiWebAppDataSaveSetting.cs +++ b/src/Webserver.API/Models/IApiWebAppDataSaveSetting.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress.cs b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress.cs new file mode 100644 index 0000000..05bab5c --- /dev/null +++ b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress.cs @@ -0,0 +1,102 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySyncupProgress +{ + /// + /// Information of an ongoing Syncup phase of the R/H system. + /// + public class ApiRedundancySyncupProgress + { + /// + /// The currently active Syncup phase. + /// + public ApiRedundancySyncupPhase Syncup_phase { get; set; } + + /// + /// If the attribute syncup_phase is in state copying_work_memory, and both its attributes are valid, + /// this object will be present in the response, otherwise it will not. + /// + public ApiRedundancySyncupProgress_CopyWorkMemory Copying_work_memory { get; set; } + + /// + /// If the attribute syncup_phase is in state copying_memory_card, and both its attributes are valid, + /// this object will be present in the response, otherwise it will not. + /// + public ApiRedundancySyncupProgress_CopyMemoryCard Copying_memory_card { get; set; } + + /// + /// If the attribute syncup_phase is in state minimizing_delay, and both its attributes are valid, + /// this object will be present in the response, otherwise it will not. + /// + public ApiRedundancySyncupProgress_MinimizingDelay Minimizing_delay { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySyncupProgress + /// Returns true if the ApiRedundancySyncupProgress are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySyncupProgress; + if (structure == null) { return false; } + if (((structure.Copying_memory_card == null) != (this.Copying_memory_card == null)) || + ((structure.Copying_work_memory == null) != (this.Copying_work_memory == null)) || + ((structure.Minimizing_delay == null) != (this.Minimizing_delay == null))) + { + return false; + } + return structure.Syncup_phase == this.Syncup_phase && + structure.Copying_memory_card == this.Copying_memory_card && + structure.Copying_work_memory == this.Copying_work_memory && + structure.Minimizing_delay == this.Minimizing_delay; + } + /// + /// GetHashCode for ApiRedundancySyncupProgress + /// + /// hashcode for the ApiRedundancySyncupProgress + public override int GetHashCode() + { + int hash = 1; + if (Copying_memory_card != null) + { + hash *= Copying_memory_card.GetHashCode(); + } + if (Copying_work_memory != null) + { + hash *= Copying_work_memory.GetHashCode(); + } + if (Minimizing_delay != null) + { + hash *= Minimizing_delay.GetHashCode(); + } + return (Syncup_phase, hash).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySyncupProgress + /// + /// ApiRedundancySyncupProgress as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySyncupProgress + /// + /// Defines if null values should be ignored + /// ApiRedundancySyncupProgress as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyMemoryCard.cs b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyMemoryCard.cs new file mode 100644 index 0000000..8fe9bb7 --- /dev/null +++ b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyMemoryCard.cs @@ -0,0 +1,73 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySyncupProgress +{ + /// + /// This object provides information about syncup state 'copying_memory_card'. + /// + public class ApiRedundancySyncupProgress_CopyMemoryCard + { + /// + /// The file name of the file that is currently transferred to the Backup PLC. + /// + public string Current_filename { get; set; } + + /// + /// The number of bytes of the copy work memory that have been transferred so far to the Backup PLC. + /// + public int Current { get; set; } + + /// + /// The total number of bytes of the copy work memory to be processed. + /// + public int Total { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySyncupProgress_CopyMemoryCard + /// Returns true if the ApiRedundancySyncupProgress_CopyMemoryCard are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySyncupProgress_CopyMemoryCard; + if (structure == null) { return false; } + return structure.Current_filename == this.Current_filename && + structure.Current == this.Current && + structure.Total == this.Total; + } + /// + /// GetHashCode for ApiRedundancySyncupProgress_CopyMemoryCard + /// + /// hashcode for the ApiRedundancySyncupProgress_CopyMemoryCard + public override int GetHashCode() + { + return (Current_filename, Current, Total).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySyncupProgress_CopyMemoryCard + /// + /// ApiRedundancySyncupProgress_CopyMemoryCard as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySyncupProgress_CopyMemoryCard + /// + /// Defines if null values should be ignored + /// ApiRedundancySyncupProgress_CopyMemoryCard as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyWorkMemory.cs b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyWorkMemory.cs new file mode 100644 index 0000000..9087b79 --- /dev/null +++ b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_CopyWorkMemory.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySyncupProgress +{ + /// + /// This object provides information about syncup state 'copying_work_memory'. + /// + public class ApiRedundancySyncupProgress_CopyWorkMemory + { + /// + /// The number of bytes of the copy work memory that have been transferred so far to the Backup PLC. + /// + public int Current { get; set; } + + /// + /// The total number of bytes of the copy work memory to be processed. + /// + public int Total { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySyncupProgress_CopyWorkMemory + /// Returns true if the ApiRedundancySyncupProgress_CopyWorkMemory are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySyncupProgress_CopyWorkMemory; + if (structure == null) { return false; } + return structure.Current == this.Current && + structure.Total == this.Total; + } + /// + /// GetHashCode for ApiRedundancySyncupProgress_CopyWorkMemory + /// + /// hashcode for the ApiRedundancySyncupProgress_CopyWorkMemory + public override int GetHashCode() + { + return (Current, Total).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySyncupProgress_CopyWorkMemory + /// + /// ApiRedundancySyncupProgress_CopyWorkMemory as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySyncupProgress_CopyWorkMemory + /// + /// Defines if null values should be ignored + /// ApiRedundancySyncupProgress_CopyWorkMemory as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_MinimizingDelay.cs b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_MinimizingDelay.cs new file mode 100644 index 0000000..978671b --- /dev/null +++ b/src/Webserver.API/Models/RedundancySyncupProgress/ApiRedundancySyncupProgress_MinimizingDelay.cs @@ -0,0 +1,71 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Services.Converters.JsonConverters; +using System; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySyncupProgress +{ + /// + /// This object provides information about syncup state 'minimizing_delay'. + /// + public class ApiRedundancySyncupProgress_MinimizingDelay + { + /// + /// The hypothetical cycle time with millisecond resolution. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Hypothetical_cycle_time { get; set; } + + /// + /// The tolerable cycle time with millisecond resolution. + /// + [JsonConverter(typeof(TimeSpanISO8601Converter))] + public TimeSpan Tolerable_cycle_time { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySyncupProgress_MinimizingDelay + /// Returns true if the ApiRedundancySyncupProgress_MinimizingDelay are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySyncupProgress_MinimizingDelay; + if (structure == null) { return false; } + return structure.Hypothetical_cycle_time == this.Hypothetical_cycle_time && + structure.Tolerable_cycle_time == this.Tolerable_cycle_time; + } + /// + /// GetHashCode for ApiRedundancySyncupProgress_MinimizingDelay + /// + /// hashcode for the ApiRedundancySyncupProgress_MinimizingDelay + public override int GetHashCode() + { + return (Hypothetical_cycle_time, Tolerable_cycle_time).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySyncupProgress_MinimizingDelay + /// + /// ApiRedundancySyncupProgress_MinimizingDelay as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySyncupProgress_MinimizingDelay + /// + /// Defines if null values should be ignored + /// ApiRedundancySyncupProgress_MinimizingDelay as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo.cs b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo.cs new file mode 100644 index 0000000..f7e31da --- /dev/null +++ b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo.cs @@ -0,0 +1,86 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySystemInformation +{ + /// + /// Basic information and the pairing status of the R/H system. + /// + public class ApiRedundancySystemInfo + { + /// + /// The pairing status of the R/H system. + /// + public ApiPlcRedundancyPairingState Pairing_state { get; set; } + + /// + /// Describes if the Syncup lock has been enabled via the user program. + /// If the Syncup lock is enabled, the user will not be able to switch the system to Syncup state. + /// + public bool Syncup_lock { get; set; } + + /// + /// Provides the redundancy ID of the PLC through which the HTTP connection has been established to. + /// + public ApiPlcRedundancyId Connected_redundancy_id { get; set; } + + /// + /// Describes if the PLC is running in standalone operation or not. + /// + public bool Standalone_operation { get; set; } + + /// + /// This object represents the R/H system and its both PLCs. + /// + public ApiRedundancySystemInfo_Plcs Plcs { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySystemInfo + /// Returns true if the ApiRedundancySystemInfo are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySystemInfo; + if (structure == null) { return false; } + return structure.Pairing_state == this.Pairing_state && + structure.Syncup_lock == this.Syncup_lock && + structure.Standalone_operation == this.Standalone_operation && + structure.Connected_redundancy_id == this.Connected_redundancy_id && + structure.Plcs.Equals(this.Plcs); + } + /// + /// GetHashCode for ApiRedundancySystemInfo + /// + /// hashcode for the ApiRedundancySystemInfo + public override int GetHashCode() + { + return (Pairing_state, Syncup_lock, Standalone_operation, Connected_redundancy_id, Plcs.GetHashCode()).GetHashCode(); + } + /// + /// ToString for ApiRedundancySystemInfo + /// + /// ApiRedundancySystemInfo as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySystemInfo + /// + /// Defines if null values should be ignored + /// ApiRedundancySystemInfo as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plc.cs b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plc.cs new file mode 100644 index 0000000..b602d79 --- /dev/null +++ b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plc.cs @@ -0,0 +1,81 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySystemInformation +{ + /// + /// This object represents one of the PLC in the redundant system + /// + public class ApiRedundancySystemInfo_Plc + { + /// + /// The Redundancy ID of the represented PLC. + /// For object plc_1 this attribute always contains value 1. + /// For object plc_2 this attribute always contains value 2. + /// + public ApiPlcRedundancyId Redundancy_id { get; set; } + + /// + /// The role of the represented PLC. + /// For the local PLC, it must always contain a valid value, either containing role primary or backup. + /// For the tree of the partner PLC, the role may be unknown in case that the partner PLC is not properly paired. + /// + public ApiPlcRedundancyRole Role { get; set; } + + /// + /// The hardware identifier of the represented PLC. + /// This can contain either value 65149 or 65349. + /// For object plc_1 this attribute always contains value 65149. + /// For object plc_2 this attribute always contains value 65349. + /// + public int Hwid { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySystemInfo_Plc + /// Returns true if the ApiRedundancySystemInfo_Plc are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySystemInfo_Plc; + if (structure == null) { return false; } + return structure.Redundancy_id == this.Redundancy_id && + structure.Role == this.Role && + structure.Hwid == this.Hwid; + } + /// + /// GetHashCode for ApiRedundancySystemInfo_Plc + /// + /// hashcode for the ApiRedundancySystemInfo_Plc + public override int GetHashCode() + { + return (Redundancy_id, Role, Hwid).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySystemInfo_Plc + /// + /// ApiRedundancySystemInfo_Plc as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySystemInfo_Plc + /// + /// Defines if null values should be ignored + /// ApiRedundancySystemInfo_Plc as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plcs.cs b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plcs.cs new file mode 100644 index 0000000..ca0d1e7 --- /dev/null +++ b/src/Webserver.API/Models/RedundancySystemInformation/ApiRedundancySystemInfo_Plcs.cs @@ -0,0 +1,67 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Newtonsoft.Json; + +namespace Siemens.Simatic.S7.Webserver.API.Models.RedundancySystemInformation +{ + /// + /// This object represents the R/H system and its both PLCs. + /// + public class ApiRedundancySystemInfo_Plcs + { + /// + /// This object represents the PLC with Redundancy ID 1. + /// + public ApiRedundancySystemInfo_Plc Plc_1 { get; set; } + + /// + /// This object represents the PLC with Redundancy ID 2. + /// + public ApiRedundancySystemInfo_Plc Plc_2 { get; set; } + + /// + /// Check wether properties match + /// + /// ApiRedundancySystemInfo_Plcs + /// Returns true if the ApiRedundancySystemInfo_Plcs are the same + public override bool Equals(object obj) + { + var structure = obj as ApiRedundancySystemInfo_Plcs; + if (structure == null) { return false; } + return structure.Plc_1.Equals(this.Plc_1) && + structure.Plc_2.Equals(this.Plc_2); + } + /// + /// GetHashCode for ApiRedundancySystemInfo_Plcs + /// + /// hashcode for the ApiRedundancySystemInfo_Plcs + public override int GetHashCode() + { + return (Plc_1.GetHashCode(), Plc_2.GetHashCode()).GetHashCode(); + } + + /// + /// ToString for ApiRedundancySystemInfo_Plcs + /// + /// ApiRedundancySystemInfo_Plcs as a multiline string + public override string ToString() + { + return ToString(NullValueHandling.Ignore); + } + /// + /// ToString for ApiRedundancySystemInfo_Plcs + /// + /// Defines if null values should be ignored + /// ApiRedundancySystemInfo_Plcs as a multiline string + public string ToString(NullValueHandling nullValueHandling) + { + JsonSerializerSettings options = new JsonSerializerSettings() + { + NullValueHandling = nullValueHandling, + }; + string result = JsonConvert.SerializeObject(this, Formatting.Indented, options); + return result; + } + } +} diff --git a/src/Webserver.API/Models/Requests/ApiRequest.cs b/src/Webserver.API/Models/Requests/ApiRequest.cs index e317950..d83ecaf 100644 --- a/src/Webserver.API/Models/Requests/ApiRequest.cs +++ b/src/Webserver.API/Models/Requests/ApiRequest.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/Requests/IApiRequest.cs b/src/Webserver.API/Models/Requests/IApiRequest.cs index c61b391..86fc714 100644 --- a/src/Webserver.API/Models/Requests/IApiRequest.cs +++ b/src/Webserver.API/Models/Requests/IApiRequest.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs index b327177..64d690b 100644 --- a/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiAlarmsBrowseResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.AlarmsBrowse; diff --git a/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs b/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs index 8502848..87b0c74 100644 --- a/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiArrayOfApiClassResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs b/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs index fb971fc..fbdb798 100644 --- a/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBrowseFilesResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs b/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs index f630e2e..b52266d 100644 --- a/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBrowseTicketsResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiBulkResponse.cs b/src/Webserver.API/Models/Responses/ApiBulkResponse.cs index d85fbdf..ca9cff7 100644 --- a/src/Webserver.API/Models/Responses/ApiBulkResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiBulkResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs index aca3a3b..eb8b71b 100644 --- a/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiDiagnosticBufferBrowseResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs b/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs index a4eaac9..03606d5 100644 --- a/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiDoubleResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiErrorModel.cs b/src/Webserver.API/Models/Responses/ApiErrorModel.cs index 9d0f9aa..1584e25 100644 --- a/src/Webserver.API/Models/Responses/ApiErrorModel.cs +++ b/src/Webserver.API/Models/Responses/ApiErrorModel.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -102,8 +102,8 @@ public void ThrowAccordingException(string apiRequestString, string responseStri throw new ApiInvalidParametersException(new ApiException(this, apiRequestString)); case ApiErrorCode.PasswordExpired: throw new ApiPasswordExpiredException(new ApiException(this, apiRequestString)); - case ApiErrorCode.PasswordChangeNotAccepted: - throw new ApiPasswordChangeNotAcceptedException(new ApiException(this, apiRequestString)); + case ApiErrorCode.NotAccepted: + throw new ApiNotAcceptedException(new ApiException(this, apiRequestString)); case ApiErrorCode.NewPasswordDoesNotFollowPolicy: throw new ApiNewPasswordDoesNotFollowPolicyException(new ApiException(this, apiRequestString)); case ApiErrorCode.NewPasswordMatchesOldPassword: @@ -122,6 +122,22 @@ public void ThrowAccordingException(string apiRequestString, string responseStri throw new ApiInvalidTimeRuleException(new ApiException(this, apiRequestString)); case ApiErrorCode.InvalidUTCOffset: throw new ApiInvalidUTCOffsetException(new ApiException(this, apiRequestString)); + case ApiErrorCode.NotATechnologyObject: + throw new ApiNotATechnologyObjectException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InfrastructureError: + throw new ApiInfrastructureErrorException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidPattern: + throw new ApiInvalidPatternException(new ApiException(this, apiRequestString)); + case ApiErrorCode.HTTPHeaderNotAllowed: + throw new ApiHTTPHeaderNotAllowedException(new ApiException(this, apiRequestString)); + case ApiErrorCode.HTTPHeaderInvalid: + throw new ApiHTTPHeaderInvalidException(new ApiException(this, apiRequestString)); + case ApiErrorCode.TooManyHTTPHeaders: + throw new ApiTooManyHTTPHeadersException(new ApiException(this, apiRequestString)); + case ApiErrorCode.RequestTooLarge: + throw new ApiRequestTooLargeException(new ApiException(this, apiRequestString)); + case ApiErrorCode.InvalidVersionString: + throw new ApiInvalidVersionStringException(new ApiException(this, apiRequestString)); default: throw new ApiException(this, apiRequestString); diff --git a/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs b/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs index 4dae3bf..7ed3a23 100644 --- a/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiFailsafeReadParametersResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs b/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs index 21844cd..9531da0 100644 --- a/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiFailsafeReadRuntimeGroupsResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs b/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs index 64a6f5d..bfc3fbf 100644 --- a/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiGetAuthenticationModeResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs b/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs index 7e42b42..baffc6b 100644 --- a/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiGetPasswordPolicyResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs b/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs index 738bc1e..3b1ff16 100644 --- a/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiGetQuantityStructuresResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT namespace Siemens.Simatic.S7.Webserver.API.Models.Responses diff --git a/src/Webserver.API/Models/Responses/ApiLoginResponse.cs b/src/Webserver.API/Models/Responses/ApiLoginResponse.cs index 1716de8..75287d6 100644 --- a/src/Webserver.API/Models/Responses/ApiLoginResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiLoginResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs index da58dbf..1d4da0e 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseCodeBlocksResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs index e95f304..33a5804 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcProgramBrowseResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadCpuTypeResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadCpuTypeResponse.cs new file mode 100644 index 0000000..7cf200d --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiPlcReadCpuTypeResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with an ApiPlcCpuType + /// + public class ApiPlcReadCpuTypeResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs index 2ef0fbf..983a9ba 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcReadModeSelectorStateResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadModuleNameResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadModuleNameResponse.cs new file mode 100644 index 0000000..38f2173 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiPlcReadModuleNameResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with a ApiPlcReadModuleNameResult + /// + public class ApiPlcReadModuleNameResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadStationNameResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadStationNameResponse.cs new file mode 100644 index 0000000..4d198a8 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiPlcReadStationNameResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with a ApiPlcReadStationNameResult + /// + public class ApiPlcReadStationNameResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs b/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs index 56d8e14..bdb0d38 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcReadSystemTimeResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs b/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs index f5fc4c4..62a0b11 100644 --- a/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiPlcReadTimeSettingsResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs b/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs index 94d92da..f376a37 100644 --- a/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiReadLanguagesResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs b/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs index 78b3ed9..5e5595f 100644 --- a/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiReadOperatingModeResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/Responses/ApiRedundancyReadSyncupProgressResponse.cs b/src/Webserver.API/Models/Responses/ApiRedundancyReadSyncupProgressResponse.cs new file mode 100644 index 0000000..d01f632 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiRedundancyReadSyncupProgressResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.RedundancySyncupProgress; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response to an Redundancy.ReadSyncupProgress request + /// + public class ApiRedundancyReadSyncupProgressResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemInformationResponse.cs b/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemInformationResponse.cs new file mode 100644 index 0000000..cabbf39 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemInformationResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.RedundancySystemInformation; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response to an Redundancy.ReadSystemInformation request + /// + public class ApiRedundancyReadSystemInformationResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemStateResponse.cs b/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemStateResponse.cs new file mode 100644 index 0000000..7f01de4 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiRedundancyReadSystemStateResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of Redundancy.ReadSystemState + /// + public class ApiRedundancyReadSystemStateResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiResultResponse.cs b/src/Webserver.API/Models/Responses/ApiResultResponse.cs index f710e02..3e27a73 100644 --- a/src/Webserver.API/Models/Responses/ApiResultResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiResultResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiSessionInfoResponse.cs b/src/Webserver.API/Models/Responses/ApiSessionInfoResponse.cs new file mode 100644 index 0000000..d466818 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiSessionInfoResponse.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// ApiResponse (Jsonrpc,id) with an ApiSessionInfo + /// + public class ApiSessionInfoResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs b/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs index 18b097c..ad54b4c 100644 --- a/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiSingleStringResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs index cad83d7..01e59c6 100644 --- a/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiSyslogBrowseResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiTechnologyBrowseObjectsResponse.cs b/src/Webserver.API/Models/Responses/ApiTechnologyBrowseObjectsResponse.cs new file mode 100644 index 0000000..2fa5b72 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiTechnologyBrowseObjectsResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of Technology.BrowseObjects + /// + public class ApiTechnologyBrowseObjectsResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs b/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs index 8cab8d3..58eecb7 100644 --- a/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTicketIdResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs index 919cd4f..cde3466 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueOnSuccessResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Exceptions; diff --git a/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs index 13c34a1..26bd508 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueWithResourceResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs b/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs index 53bb8a7..b0a639b 100644 --- a/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiTrueWithWebAppResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs index f96759e..d838f28 100644 --- a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResourcesResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs index 97ef3b9..c940a2a 100644 --- a/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiWebAppBrowseResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs b/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs index 84c30c8..1dd1d43 100644 --- a/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs +++ b/src/Webserver.API/Models/Responses/ApiWebServerGetReadDefaultPageResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults; diff --git a/src/Webserver.API/Models/Responses/ApiWebServerReadResponseHeadersResponse.cs b/src/Webserver.API/Models/Responses/ApiWebServerReadResponseHeadersResponse.cs new file mode 100644 index 0000000..d496384 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ApiWebServerReadResponseHeadersResponse.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.WebserverResponseHeaders; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses +{ + /// + /// Response of WebServer.ReadCustomHttpHeaders + /// + public class ApiWebServerReadResponseHeadersResponse : ApiResultResponse + { + } +} diff --git a/src/Webserver.API/Models/Responses/BaseApiResponse.cs b/src/Webserver.API/Models/Responses/BaseApiResponse.cs index d208de0..cc03b6a 100644 --- a/src/Webserver.API/Models/Responses/BaseApiResponse.cs +++ b/src/Webserver.API/Models/Responses/BaseApiResponse.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseFilesResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseFilesResult.cs index 0458a02..e38eb98 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseFilesResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseFilesResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseTicketsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseTicketsResult.cs index 1ed9a2d..cd5564e 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseTicketsResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiBrowseTicketsResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs index c765e4e..cf99ea3 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadParametersResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs index d6e89bd..3f003bb 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiFailsafeReadRuntimeGroupsResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs index b5f0683..3e06f71 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetAuthenticationModeResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs index f531c32..3046652 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiGetPasswordPolicyResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadCpuTypeResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadCpuTypeResult.cs new file mode 100644 index 0000000..334d92c --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadCpuTypeResult.cs @@ -0,0 +1,52 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Public product information such as the PLC product name and order number. + /// + public class ApiPlcReadCpuTypeResult + { + /// + /// The product name of the PLC or R/H system on which the request is executed. + /// + public string Product_Name { get; set; } + /// + /// The order number of the PLC or R/H system on which the request is executed. + /// + public string Order_Number { get; set; } + + /// + /// Compares this to input object + /// + /// Object to compare to + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiPlcReadCpuTypeResult cpuType && + Product_Name == cpuType.Product_Name && + Order_Number == cpuType.Order_Number; + } + + /// + /// Get Hash Code of PasswordExpiraton object + /// + /// Hash Code + public override int GetHashCode() + { + return (Product_Name, Product_Name).GetHashCode(); + } + + /// + /// ToString for ApiPlcCpuType + /// + /// + public override string ToString() + { + return $"{nameof(Product_Name)}: {Product_Name} | " + + $"{nameof(Product_Name)}: {Product_Name}"; + } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs index dfe1b02..4a47094 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModeSelectorStateResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModuleNameResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModuleNameResult.cs new file mode 100644 index 0000000..9dfa804 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadModuleNameResult.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// + /// + public class ApiPlcReadModuleNameResult + { + /// + /// The module name of the PLC on which the request is executed. + /// + public string Module_name { get; set; } + + /// + /// Compares this to input object + /// + /// Object to compare to + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiPlcReadModuleNameResult moduleName && + Module_name == moduleName.Module_name; + } + + /// + /// Get Hash Code of PasswordExpiraton object + /// + /// Hash Code + public override int GetHashCode() + { + return Module_name.GetHashCode(); + } + + /// + /// ToString for ApiPlcCpuType + /// + /// + public override string ToString() + { + return $"{nameof(Module_name)}: {Module_name}"; + } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadStationNameResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadStationNameResult.cs new file mode 100644 index 0000000..e6441f6 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadStationNameResult.cs @@ -0,0 +1,46 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Contains the station name of the PLC on which the request was executed. + /// + public class ApiPlcReadStationNameResult + { + /// + /// The station name of the PLC on which the request was executed. + /// + public string Station_Name { get; set; } + + /// + /// Compares this to input object + /// + /// Object to compare to + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiPlcReadStationNameResult stationName && + Station_Name == stationName.Station_Name; + } + + /// + /// Get Hash Code of PasswordExpiraton object + /// + /// Hash Code + public override int GetHashCode() + { + return Station_Name.GetHashCode(); + } + + /// + /// ToString for ApiPlcCpuType + /// + /// + public override string ToString() + { + return $"{nameof(Station_Name)}: {Station_Name}"; + } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs index 844a47d..fa35204 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadSystemTimeResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs index ec6d3f7..c0e5ec3 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiPlcReadTimeSettingsResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs index 9de4053..cf6b647 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiReadLanguagesResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; @@ -6,7 +6,7 @@ namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults { /// - /// Read Langzages result containing a List of ApiLanguageResults + /// Read Languages result containing a List of ApiLanguageResults /// public class ApiReadLanguagesResult { diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiTechnologyBrowseObjectsResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiTechnologyBrowseObjectsResult.cs new file mode 100644 index 0000000..343dc76 --- /dev/null +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiTechnologyBrowseObjectsResult.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Models.Technology; +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Responses.ResponseResults +{ + /// + /// Technlogy.BrowseObjects results + /// + public class ApiTechnologyBrowseObjectsResult + { + /// + /// List containing Technology Objects + /// + public List Objects { get; set; } + } +} diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs index 0b867df..f90ca02 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiTokenResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs index b4f6e3c..e82e684 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResourcesResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs index e5bc505..6f91472 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/ApiWebAppBrowseResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs b/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs index d936446..34e9ead 100644 --- a/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs +++ b/src/Webserver.API/Models/Responses/ResponseResults/WebServerDefaultPageResult.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/Technology/ApiTechnologyObject.cs b/src/Webserver.API/Models/Technology/ApiTechnologyObject.cs new file mode 100644 index 0000000..ce3e679 --- /dev/null +++ b/src/Webserver.API/Models/Technology/ApiTechnologyObject.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using Siemens.Simatic.S7.Webserver.API.Enums; + +namespace Siemens.Simatic.S7.Webserver.API.Models.Technology +{ + /// + /// A Technology Object + /// + public class ApiTechnologyObject + { + /// + /// The block number of the technology object + /// + public uint Number { get; set; } + /// + /// The name of the technology object + /// + public string Name { get; set; } + /// + /// The type of the technology object + /// + public ApiTechnologyObjectType Type { get; set; } + /// + /// The major version of the technology object + /// + public float Version { get; set; } + + /// + /// Compares input object to this TechnologyObject + /// + /// + /// True if objects are the same + public override bool Equals(object obj) + { + return obj is ApiTechnologyObject @object && + Number == @object.Number && + Name == @object.Name && + Type == @object.Type && + Version == @object.Version; + } + + /// + /// HashCode + /// + /// + public override int GetHashCode() + { + return (Number, Name, Type, Version).GetHashCode(); + } + } +} diff --git a/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs b/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs index 4c94026..ff8c850 100644 --- a/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs +++ b/src/Webserver.API/Models/TimeSettings/DaylightSavingsRule.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs b/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs index cba4a25..aaf516c 100644 --- a/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs +++ b/src/Webserver.API/Models/TimeSettings/DaylightSavingsTimeConfiguration.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Models/TimeSettings/PlcDate.cs b/src/Webserver.API/Models/TimeSettings/PlcDate.cs index bb10a2c..61c1aa4 100644 --- a/src/Webserver.API/Models/TimeSettings/PlcDate.cs +++ b/src/Webserver.API/Models/TimeSettings/PlcDate.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs b/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs index e85d3bf..17e9184 100644 --- a/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs +++ b/src/Webserver.API/Models/TimeSettings/StandardTimeConfiguration.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders.cs b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders.cs new file mode 100644 index 0000000..0ca5aef --- /dev/null +++ b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT +using System.Collections.Generic; + +namespace Siemens.Simatic.S7.Webserver.API.Models.WebserverResponseHeaders +{ + /// + /// The user-configured HTTP response headers, as well as a list of HTTP response headers that are configurable. + /// + public class ApiWebserverResponseHeaders + { + /// + /// Holds an array of objects where each object represents a HTTP header that is currently configured on the PLC. + /// + public List Configured_headers { get; set; } + + /// + /// Holds an array of objects where each object represents an entry of a HTTP header that the user is allowed to configure on the PLC. + /// + public List Allowed_headers { get; set; } + } +} diff --git a/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Allowed.cs b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Allowed.cs new file mode 100644 index 0000000..06abcfc --- /dev/null +++ b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Allowed.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.WebserverResponseHeaders +{ + /// + /// Represents an entry of a HTTP header that is allowed to be configured on the PLC. + /// + public class ApiWebserverResponseHeaders_Allowed + { + /// + /// The pattern for which the header may be applied for. + /// + public string Pattern { get; set; } + + /// + /// The HTTP response header key. + /// + public string Key { get; set; } + } +} diff --git a/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Configured.cs b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Configured.cs new file mode 100644 index 0000000..429b162 --- /dev/null +++ b/src/Webserver.API/Models/WebserverResponseHeaders/ApiWebserverResponseHeaders_Configured.cs @@ -0,0 +1,23 @@ +// Copyright (c) 2024, Siemens AG +// +// SPDX-License-Identifier: MIT + +namespace Siemens.Simatic.S7.Webserver.API.Models.WebserverResponseHeaders +{ + /// + /// Represents a HTTP header that is currently configured on the PLC. + /// + public class ApiWebserverResponseHeaders_Configured + { + /// + /// The pattern defines for which webserver endpoint this HTTP header must be returned for.
+ /// For now, this value is always /~**/*. + ///
+ public string Pattern { get; set; } + + /// + /// The HTTP response header. + /// + public string Header { get; set; } + } +} diff --git a/src/Webserver.API/Services/ApiStandardServiceFactory.cs b/src/Webserver.API/Services/ApiStandardServiceFactory.cs index 3cdc444..acfa50e 100644 --- a/src/Webserver.API/Services/ApiStandardServiceFactory.cs +++ b/src/Webserver.API/Services/ApiStandardServiceFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -149,7 +149,7 @@ public HttpClientAndWebAppCookie GetHttpClient(string baseAddress, string userna httpClient.DefaultRequestHeaders.ConnectionClose = connectionConfiguration.ConnectionClose; httpClient.BaseAddress = new Uri("https://" + connectionConfiguration.BaseAddress); httpClient.Timeout = connectionConfiguration.TimeOut; - var apiLoginRequest = _apiRequestFactory.GetApiLoginRequest(connectionConfiguration.Username, connectionConfiguration.Password, include_web_application_cookie); + var apiLoginRequest = _apiRequestFactory.GetApiLoginRequest(Enums.ApiAuthenticationMode.Local, connectionConfiguration.Username, connectionConfiguration.Password, include_web_application_cookie); if (apiLoginRequest.Params != null) { apiLoginRequest.Params = apiLoginRequest.Params @@ -225,7 +225,7 @@ public HttpClientAndWebAppCookie GetHttpClient(HttpClientConnectionConfiguration httpClient.DefaultRequestHeaders.ConnectionClose = connectionConfiguration.ConnectionClose; httpClient.BaseAddress = new Uri("https://" + connectionConfiguration.BaseAddress); httpClient.Timeout = connectionConfiguration.TimeOut; - var apiLoginRequest = _apiRequestFactory.GetApiLoginRequest(connectionConfiguration.Username, connectionConfiguration.Password); + var apiLoginRequest = _apiRequestFactory.GetApiLoginRequest(Enums.ApiAuthenticationMode.Local, connectionConfiguration.Username, connectionConfiguration.Password); if (apiLoginRequest.Params != null) { apiLoginRequest.Params = apiLoginRequest.Params @@ -279,6 +279,7 @@ public HttpClient GetHttpClient(HttpClientConnectionConfiguration connectionConf /// ip address or dns name of your plc /// username to login with /// password to login with + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// A usable and authenticated public async Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)) { diff --git a/src/Webserver.API/Services/Backup/ApiBackupHandler.cs b/src/Webserver.API/Services/Backup/ApiBackupHandler.cs index ebbcd55..cd74b45 100644 --- a/src/Webserver.API/Services/Backup/ApiBackupHandler.cs +++ b/src/Webserver.API/Services/Backup/ApiBackupHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Exceptions; @@ -6,8 +6,9 @@ using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; using Siemens.Simatic.S7.Webserver.API.Services.Ticketing; using System; +using System.Diagnostics; using System.IO; -using System.Net.Http; +using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -38,6 +39,7 @@ public ApiBackupHandler(IApiRequestHandler apiRequestHandler, IApiTicketHandler /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// will default to the backup name suggested by the plc /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo /// public async Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) @@ -62,15 +64,26 @@ public FileInfo DownloadBackup(string pathToDownloadDirectory = null, string bac => DownloadBackupAsync(pathToDownloadDirectory, backupName).GetAwaiter().GetResult(); /// - /// Will send a DownloadbackupName, Downloadticket and Closeticket request to the API + /// Restores the PLC from a backup file /// + /// + /// Works only if the PLC is in STOP!
+ /// Checks if the restore file can be found at the restoreFilePath.
+ /// Sends a PlcRestoreBackup then starts to upload the backup file with the response ticket.
+ /// If the PLC validated the restorebackup file header, the upload is cancelled and the PLC will reboot in 3 seconds.
+ /// After the reboot completed, sends a Login, then a PlcRestoreBackup request.
+ /// Uploads again the backup file with the response ticket.
+ /// When the upload finished, the PLC will reboot again. After that sends a final login request. + ///
/// Username for re-login /// Password for re-login /// path to the file to be restored /// timeout for the waithandler => plc to be up again after reboot, etc. - defaults to 3 minutes + /// Optional token to cancel the async method /// Task /// File at restorefilepath has not been found - public async Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null, CancellationToken cancellationToken = default(CancellationToken)) + /// Restore is not possible + public async Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null, CancellationToken externalCancellationToken = default(CancellationToken)) { var timeToWait = timeOut ?? TimeSpan.FromMinutes(3); if (restoreFilePath == null) @@ -81,34 +94,66 @@ public FileInfo DownloadBackup(string pathToDownloadDirectory = null, string bac { throw new FileNotFoundException($"the given file at {Environment.NewLine}{restoreFilePath}{Environment.NewLine} has not been found!"); } - string ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password, cancellationToken)).Result; - try - { - await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath, cancellationToken); - } - // HttpRequestException is okay since during the upload the plc will power cycle and not "successfully answer" the request - catch (ApiTicketingEndpointUploadException e) + + var browseResult = (await ApiRequestHandler.ApiBrowseAsync(externalCancellationToken)).Result; + bool restoreMode = !browseResult.Any(x => x.Name == "Plc.CreateBackup"); + string uploadTicket; + var waitHandler = new WaitHandler(timeToWait); + + if (!restoreMode) { - if (e.InnerException != null || !(e.InnerException is HttpRequestException)) - throw; + uploadTicket = (await ApiRequestHandler.PlcRestoreBackupAsync(password, externalCancellationToken)).Result; + CancellationTokenSource internalCancellationTokenSource = new CancellationTokenSource(); + try + { + Task uploadTask = ApiTicketHandler.HandleUploadAsync(uploadTicket, restoreFilePath, internalCancellationTokenSource.Token); + Stopwatch sw = Stopwatch.StartNew(); + while (sw.ElapsedMilliseconds < 60_000 || uploadTask.IsCompleted || uploadTask.IsFaulted) + { + var brTicketsResp = ApiRequestHandler.ApiBrowseTickets(uploadTicket); + string apiTicketData = brTicketsResp.Result.Tickets.First().Data.ToString(); + if (apiTicketData.Contains("\"restore_state\": \"rebooting_format\"") || externalCancellationToken.IsCancellationRequested) + { + internalCancellationTokenSource.Cancel(); + break; + } + } + sw.Stop(); + await uploadTask; + } + catch (ApiTicketingEndpointUploadException e) when (e.InnerException is TaskCanceledException) { } + finally + { + internalCancellationTokenSource.Dispose(); + externalCancellationToken.ThrowIfCancellationRequested(); + } + WaitForPlcReboot(waitHandler); + await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: externalCancellationToken); } - var waitHandler = new WaitHandler(timeToWait); - WaitForPlcReboot(waitHandler); - await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: cancellationToken); - ticketResponse = (await ApiRequestHandler.PlcRestoreBackupAsync(password, cancellationToken)).Result; - await ApiTicketHandler.HandleUploadAsync(ticketResponse, restoreFilePath, cancellationToken); + uploadTicket = (await ApiRequestHandler.PlcRestoreBackupAsync(password, externalCancellationToken)).Result; + await ApiTicketHandler.HandleUploadAsync(uploadTicket, restoreFilePath, externalCancellationToken); WaitForPlcReboot(waitHandler); - await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: cancellationToken); + await ApiRequestHandler.ReLoginAsync(userName, password, cancellationToken: externalCancellationToken); } /// - /// Will send a DownloadbackupName, Downloadticket and Closeticket request to the API + /// Restores the PLC from a backup file /// + /// + /// Works only if the PLC is in STOP!
+ /// Checks if the restore file can be found at the restoreFilePath.
+ /// Sends a PlcRestoreBackup then starts to upload the backup file with the response ticket.
+ /// If the PLC validated the restorebackup file header, the upload is cancelled and the PLC will reboot in 3 seconds.
+ /// After the reboot completed, sends a Login, then a PlcRestoreBackup request.
+ /// Uploads again the backup file with the response ticket.
+ /// When the upload finished, the PLC will reboot again. After that sends a final login request. + ///
/// Username for re-login /// Password for re-login /// path to the file to be restored - /// timeout for the waithandler => plc to be up again after reboot, etc. - /// Task/void + /// timeout for the waithandler => plc to be up again after reboot, etc. - defaults to 3 minutes + /// Task + /// File at restorefilepath has not been found public void RestoreBackup(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null) => RestoreBackupAsync(restoreFilePath, userName, password, timeOut).GetAwaiter().GetResult(); diff --git a/src/Webserver.API/Services/Backup/IApiBackupHandler.cs b/src/Webserver.API/Services/Backup/IApiBackupHandler.cs index 5354109..aa5a20a 100644 --- a/src/Webserver.API/Services/Backup/IApiBackupHandler.cs +++ b/src/Webserver.API/Services/Backup/IApiBackupHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; @@ -27,6 +27,7 @@ public interface IApiBackupHandler /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// will default to the backup name suggested by the plc /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo Task DownloadBackupAsync(string pathToDownloadDirectory = null, string backupName = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -45,6 +46,7 @@ public interface IApiBackupHandler /// Password for re-login /// path to the file to be restored /// timeout for the waithandler => plc to be up again after reboot, etc. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void Task RestoreBackupAsync(string restoreFilePath, string userName, string password, TimeSpan? timeOut = null, CancellationToken cancellationToken = default(CancellationToken)); } diff --git a/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs b/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs index 0e6d106..8251eae 100644 --- a/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs +++ b/src/Webserver.API/Services/Converters/JsonConverters/EnabledDisabledConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs b/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs index 311439e..ebfcc96 100644 --- a/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs +++ b/src/Webserver.API/Services/Converters/JsonConverters/FailsafeHardwareConverter.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs b/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs index dbcca76..e752761 100644 --- a/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs +++ b/src/Webserver.API/Services/Converters/JsonConverters/TimeSpanISO8601Converter.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs index 98479e7..e12a363 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MITusing Newtonsoft.Json; using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs index 8f501f4..56b008a 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryBuilderConfiguration.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Collections.Generic; diff --git a/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs b/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs index 9d68d21..ecc44c8 100644 --- a/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs +++ b/src/Webserver.API/Services/FileHandling/ApiDirectoryHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -41,6 +41,7 @@ public ApiDirectoryHandler(IApiRequestHandler apiRequestHandler, IApiFileHandler /// the function will only upload the resource and its direct sub-resources /// /// - e.g. from parsed directory + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task DeployAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { if (resource.Type == Enums.ApiFileResourceType.File) @@ -71,6 +72,7 @@ public ApiDirectoryHandler(IApiRequestHandler apiRequestHandler, IApiFileHandler /// Delete the given resource (and all its sub-resources) ///
/// the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task for deletion public async Task DeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -117,6 +119,7 @@ public void Delete(ApiFileResource resource) /// Get all Resources underneath the given resource /// /// resouce to be browsed + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// A resource containing everything that is present underneath public async Task BrowseAndBuildResourceAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -160,6 +163,7 @@ public ApiFileResource BrowseAndBuildResource(ApiFileResource resource) /// /// the resource to be updated /// the resource returned by browsing the plc - make sure the sub-Nodes are present (!) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task to update the resource public async Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -204,6 +208,7 @@ public void UpdateResource(ApiFileResource resource, ApiFileResource browsedReso /// /// the file to be updated /// the file returned by browsing the plc + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task to update the File public async Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -244,6 +249,7 @@ public void UpdateFileResource(ApiFileResource resource, ApiFileResource browsed /// optional parameter: /// used to determine wether the DirectoryHandler should retry a upload and compare of the resources found or give up right away (default) /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)) { if (amountOfTriesForResourceDeployment < 1) diff --git a/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs b/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs index 201f24a..535c507 100644 --- a/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs +++ b/src/Webserver.API/Services/FileHandling/ApiFileHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; @@ -45,6 +45,7 @@ public ApiFileHandler(IApiRequestHandler apiRequestHandler, IApiTicketHandler ap /// Path of the file relative to the memory card root. /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo public async Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) { @@ -73,6 +74,7 @@ public FileInfo DownloadFile(string resource, string pathToDownloadDirectory = n /// Resource name of data log to retrieve, including the path. /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo /// public async Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overwriteExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)) @@ -101,6 +103,7 @@ public FileInfo DataLogs_DownloadAndClear(string resource, string pathToDownload /// /// resource name on the PLC File API endpoint /// path to the local file to upload + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task to upload the file public async Task DeployFileAsync(string resource, string filePath, CancellationToken cancellationToken = default(CancellationToken)) { @@ -119,6 +122,7 @@ public void DeployFile(string resource, string filePath) /// Upload a resource to the File API /// /// resource to upload - filepath built via the ResourcePathResolver, name on PLC File Api built via GetVarNameForMethods() + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task DeployFileAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { var varNameForMethods = resource.GetVarNameForMethods(); diff --git a/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs b/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs index 2f77a62..76b6d50 100644 --- a/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/ApiFileResourceBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; diff --git a/src/Webserver.API/Services/FileHandling/IApiDirectoryBuilder.cs b/src/Webserver.API/Services/FileHandling/IApiDirectoryBuilder.cs index 70656b5..8cabe6a 100644 --- a/src/Webserver.API/Services/FileHandling/IApiDirectoryBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/IApiDirectoryBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MITusing Newtonsoft.Json; using Siemens.Simatic.S7.Webserver.API.Models; diff --git a/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs b/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs index 6eef028..b021faf 100644 --- a/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs +++ b/src/Webserver.API/Services/FileHandling/IApiDirectoryHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; @@ -22,6 +22,7 @@ public interface IApiDirectoryHandler /// Get all Resources underneath the given resource /// /// resouce to be browsed + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// A resource containing everything that is present underneath Task BrowseAndBuildResourceAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -33,6 +34,7 @@ public interface IApiDirectoryHandler /// Delete the given resource (and all its sub-resources) /// /// the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task for deletion Task DeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -52,6 +54,7 @@ public interface IApiDirectoryHandler /// the function will only upload the resource and its direct sub-resources /// /// - e.g. from parsed directory + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task DeployAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// /// make very sure the given resource contains all the data: @@ -80,12 +83,14 @@ public interface IApiDirectoryHandler /// optional parameter: /// used to determine wether the DirectoryHandler should retry a upload and compare of the resources found or give up right away (default) /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task DeployOrUpdateAsync(ApiFileResource resource, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)); /// /// Update the given File Resource when necessary /// /// the file to be updated /// the file returned by browsing the plc + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task to update the File Task UpdateFileResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -100,6 +105,7 @@ public interface IApiDirectoryHandler /// /// the resource to be updated /// the resource returned by browsing the plc - make sure the sub-Nodes are present (!) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task to update the resource Task UpdateResourceAsync(ApiFileResource resource, ApiFileResource browsedResource, CancellationToken cancellationToken = default(CancellationToken)); /// diff --git a/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs b/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs index 5e1c433..adf64f1 100644 --- a/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs +++ b/src/Webserver.API/Services/FileHandling/IApiFileHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; @@ -19,6 +19,7 @@ public interface IApiFileHandler /// Path of the file relative to the memory card root. /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo Task DownloadFileAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); @@ -36,6 +37,7 @@ public interface IApiFileHandler /// /// Path of the file relative to the memory card root. /// Path of the file to upload + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task Task DeployFileAsync(string resource, string filePath, CancellationToken cancellationToken = default(CancellationToken)); @@ -51,6 +53,7 @@ public interface IApiFileHandler /// Creates a file on the PLC : creates a file ticket which the client can use to transfer a file to the PLC. This is referred to as "uploading" a file to the PLC. /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task Task DeployFileAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -68,6 +71,7 @@ public interface IApiFileHandler /// Resource name of data log to retrieve, including the path. /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// FileInfo Task DataLogs_DownloadAndClearAsync(string resource, string pathToDownloadDirectory = null, bool overrideExistingFile = false, CancellationToken cancellationToken = default(CancellationToken)); diff --git a/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs b/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs index 586a1cb..67661a8 100644 --- a/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs +++ b/src/Webserver.API/Services/FileHandling/IApiFileResourceBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; diff --git a/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs b/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs index ef0df38..3d1bce3 100644 --- a/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs +++ b/src/Webserver.API/Services/FileParser/ApiWebAppConfigParser.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -87,6 +87,10 @@ public ApiWebAppData Parse() { webApp.ProtectedResources = new List(); } + if (webApp.Redirect_mode == ApiWebAppRedirectMode.None) //config has no redirect mode or has "none" + { + webApp.Redirect_mode = ApiWebAppRedirectMode.Redirect; //set to default + } // get resources in Directory webApp.ApplicationResources = RecursiveGetResources(PathToWebAppDirectory, webApp); return webApp; diff --git a/src/Webserver.API/Services/HelperHandlers/WaitHandler.cs b/src/Webserver.API/Services/HelperHandlers/WaitHandler.cs index e369e39..1cabe96 100644 --- a/src/Webserver.API/Services/HelperHandlers/WaitHandler.cs +++ b/src/Webserver.API/Services/HelperHandlers/WaitHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Services/IApiServiceFactory.cs b/src/Webserver.API/Services/IApiServiceFactory.cs index e85fcdc..e37cf6a 100644 --- a/src/Webserver.API/Services/IApiServiceFactory.cs +++ b/src/Webserver.API/Services/IApiServiceFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Models; @@ -59,6 +59,7 @@ public interface IApiServiceFactory /// ip address or dns name of your plc /// username to login with /// password to login with + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// A usable and authenticated Task GetApiHttpClientRequestHandlerAsync(string baseAddress, string username, string password, CancellationToken cancellationToken = default(CancellationToken)); /// diff --git a/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs b/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs index a73d7d9..8225e73 100644 --- a/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/CharSetIdGenerator.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs b/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs index 3c02013..aeb9fc6 100644 --- a/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/GUIDGenerator.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System; diff --git a/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs b/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs index f69dd41..cc96c3e 100644 --- a/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs +++ b/src/Webserver.API/Services/IdGenerator/IIdGenerator.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs b/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs index 79e2c32..7f252bf 100644 --- a/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs +++ b/src/Webserver.API/Services/PlcProgram/ApiPlcProgramHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -39,6 +39,7 @@ public ApiPlcProgramHandler(IApiRequestHandler asyncRequestHandler, IApiRequestF /// /// Mode for PlcProgramBrowse function /// the db/structure of which the children should be browsed + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiResultResponse of List of ApiPlcProgramData containing the children of the given var public async Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)) { @@ -84,8 +85,9 @@ public ApiPlcProgramBrowseResponse PlcProgramBrowseSetChildrenAndParents(ApiPlcP /// /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// The Struct containing the Children with their according Values - public async Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple + public async Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcDataRepresentation childrenReadMode = ApiPlcDataRepresentation.Simple , CancellationToken cancellationToken = default(CancellationToken)) { var toReturn = structToRead.ShallowCopy(); @@ -151,7 +153,7 @@ public async Task PlcProgramReadStructByChildValuesAsync(ApiP /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - public ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple) + public ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData structToRead, ApiPlcDataRepresentation childrenReadMode = ApiPlcDataRepresentation.Simple) => PlcProgramReadStructByChildValuesAsync(structToRead, childrenReadMode).GetAwaiter().GetResult(); /// @@ -159,8 +161,9 @@ public ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData str /// /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// The Struct containing the Children with their according Values - public async Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcDataRepresentation childrenWriteMode = ApiPlcDataRepresentation.Simple, CancellationToken cancellationToken = default(CancellationToken)) { var toReturn = structToWrite.ShallowCopy(); if (toReturn.Children == null || toReturn.Children.Count == 0) @@ -182,7 +185,7 @@ public ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData str /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - public ApiBulkResponse PlcProgramWriteStructByChildValues(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple) + public ApiBulkResponse PlcProgramWriteStructByChildValues(ApiPlcProgramData structToWrite, ApiPlcDataRepresentation childrenWriteMode = ApiPlcDataRepresentation.Simple) => PlcProgramWriteStructByChildValuesAsync(structToWrite, childrenWriteMode).GetAwaiter().GetResult(); } } diff --git a/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs b/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs index 8ad2626..2d97c44 100644 --- a/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs +++ b/src/Webserver.API/Services/PlcProgram/IApiPlcProgramHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -28,6 +28,7 @@ public interface IApiPlcProgramHandler /// /// Mode for PlcProgramBrowse function /// the db/structure of which the children should be browsed + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiResultResponse of List of ApiPlcProgramData containing the children of the given var Task PlcProgramBrowseSetChildrenAndParentsAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -36,27 +37,29 @@ public interface IApiPlcProgramHandler /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple); + ApiPlcProgramData PlcProgramReadStructByChildValues(ApiPlcProgramData structToRead, ApiPlcDataRepresentation childrenReadMode = ApiPlcDataRepresentation.Simple); /// /// Method to comfortably read all Children of a struct using a Bulk Request /// /// Struct of which the Children should be Read by Bulk Request /// Mode in which the child values should be read - defaults to simple (easy user handling) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// The Struct containing the Children with their according Values - Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcProgramReadOrWriteMode childrenReadMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcProgramReadStructByChildValuesAsync(ApiPlcProgramData structToRead, ApiPlcDataRepresentation childrenReadMode = ApiPlcDataRepresentation.Simple, CancellationToken cancellationToken = default(CancellationToken)); /// /// Method to comfortably write all Children of a struct using a Bulk Request /// /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) /// The Struct containing the Children with their according Values - ApiBulkResponse PlcProgramWriteStructByChildValues(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple); + ApiBulkResponse PlcProgramWriteStructByChildValues(ApiPlcProgramData structToWrite, ApiPlcDataRepresentation childrenWriteMode = ApiPlcDataRepresentation.Simple); /// /// Method to comfortably write all Children of a struct using a Bulk Request /// /// Struct of which the Children should be written by Bulk Request /// Mode in which the child values should be written - defaults to simple (easy user handling) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// The Struct containing the Children with their according Values - Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcProgramReadOrWriteMode childrenWriteMode = ApiPlcProgramReadOrWriteMode.Simple, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcProgramWriteStructByChildValuesAsync(ApiPlcProgramData structToWrite, ApiPlcDataRepresentation childrenWriteMode = ApiPlcDataRepresentation.Simple, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs b/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs index 7aec347..cbce01f 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiHttpClientRequestHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -157,6 +157,7 @@ public ApiHttpClientRequestHandler(HttpClient httpClient, IApiRequestFactory api /// will remove those Params that have the value Null and send the request using the HttpClient. /// /// further information about the Api requeest the user tried to send (or was trying to send) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// string: response from thePLC public async Task> SendPostRequestAsyncFileName(string apiRequestString, CancellationToken cancellationToken = default(CancellationToken)) { @@ -288,10 +289,12 @@ public ApiHttpClientRequestHandler(HttpClient httpClient, IApiRequestFactory api /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if changing password for the user was successful - public async Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, CancellationToken cancellationToken = default(CancellationToken)) + public async Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiChangePasswordRequest(username, currentPassword, newPassword); + var req = _apiRequestFactory.GetApiChangePasswordRequest(username, currentPassword, newPassword, mode); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; @@ -302,9 +305,10 @@ public ApiHttpClientRequestHandler(HttpClient httpClient, IApiRequestFactory api /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. /// True if changing password for the user was successful - public ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword) => - ApiChangePasswordAsync(username, currentPassword, newPassword).GetAwaiter().GetResult(); + public ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null) => + ApiChangePasswordAsync(username, currentPassword, newPassword, mode).GetAwaiter().GetResult(); /// /// Send an Api.GetCertificateUrl Request using the Request from the ApiRequestFactory /// @@ -414,6 +418,7 @@ public ApiTrueOnSuccessResponse ApiChangePassword(string username, string curren /// Perform a service data download on the corresponding module with hwid /// /// The HWID of a node (module) for which a service data file can be downloaded + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket to use for downloading the service data public async Task ModulesDownloadServiceDataAsync(ApiPlcHwId hwid, CancellationToken cancellationToken = default(CancellationToken)) { @@ -433,10 +438,12 @@ public ApiTicketIdResponse ModulesDownloadServiceData(ApiPlcHwId hwid) => /// /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// The current Plc OperatingMode - public async Task PlcReadOperatingModeAsync(CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcReadOperatingModeAsync(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiPlcReadOperatingModeRequest(); + var req = _apiRequestFactory.GetApiPlcReadOperatingModeRequest(rhid); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; @@ -444,18 +451,22 @@ public ApiTicketIdResponse ModulesDownloadServiceData(ApiPlcHwId hwid) => /// /// Send a Plc.ReadOperatingMode Request using the Request from the ApiRequestFactory /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// The current Plc OperatingMode - public ApiReadOperatingModeResponse PlcReadOperatingMode() => PlcReadOperatingModeAsync().GetAwaiter().GetResult(); + public ApiReadOperatingModeResponse PlcReadOperatingMode(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC) => PlcReadOperatingModeAsync(rhid).GetAwaiter().GetResult(); /// /// Send a Plc.RequestChangeOperatingMode Request using the Request from the ApiRequestFactory /// Method to change the plc operating mode /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// Plc Operating mode wanted /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - public async Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiPlcRequestChangeOperatingModeRequest(plcOperatingMode); + var req = _apiRequestFactory.GetApiPlcRequestChangeOperatingModeRequest(plcOperatingMode, rhid); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; @@ -465,9 +476,11 @@ public ApiTicketIdResponse ModulesDownloadServiceData(ApiPlcHwId hwid) => /// Method to change the plc operating mode /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Plc Operating mode wanted /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode) - => PlcRequestChangeOperatingModeAsync(plcOperatingMode).GetAwaiter().GetResult(); + public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC) + => PlcRequestChangeOperatingModeAsync(plcOperatingMode, rhid).GetAwaiter().GetResult(); /// /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory @@ -484,6 +497,7 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// sucht nach der Variable, um die Metadaten der Variable zu finden. /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -527,6 +541,7 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// sucht nach der Variable, um die Metadaten der Variable zu finden. /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData public async Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)) @@ -607,8 +622,9 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - public async Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) + public async Task> PlcProgramReadAsync(string var, ApiPlcDataRepresentation? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiPlcProgramReadRequest(var, plcProgramReadMode); string response = await SendPostRequestAsync(req, cancellationToken); @@ -632,7 +648,7 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - public ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); + public ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcDataRepresentation? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); /// /// Send a PlcProgram.Browse Request using the Request from the ApiRequestFactory @@ -651,9 +667,10 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiPlcProgramReadResponse: object with the value for the variables value to be read /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) + public async Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcDataRepresentation? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)) { //RequestParameterChecker.CheckPlcProgramReadOrWriteDataType(var.Datatype, true); string varName = var.GetVarNameForMethods(); @@ -678,7 +695,7 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiResultResponse PlcProgramRead(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); + public ApiResultResponse PlcProgramRead(string var, ApiPlcDataRepresentation? plcProgramReadMode = null) => PlcProgramReadAsync(var, plcProgramReadMode).GetAwaiter().GetResult(); /// /// Send a PlcProgram.Write Request using the Request from the ApiRequestFactory @@ -688,10 +705,11 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// Name of the variable to be read /// Name der zu lesenden Variable /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// true to indicate success /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) { string varName = var.GetVarNameForMethods(); // ApiRequestFactory.CheckPlcProgramReadOrWriteDataType(var.Datatype); will also be called by GetApiPlcProgramWriteValueToBeSet! @@ -709,7 +727,7 @@ public ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMod /// /// true to indicate success /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) + public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null) => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); /// @@ -719,10 +737,11 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object va /// Name of the variable to be read /// Name der zu lesenden Variable /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// true to indicate success /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public async Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiPlcProgramWriteRequest(var, valueToBeSet, plcProgramWriteMode); string response = await SendPostRequestAsync(req, cancellationToken); @@ -739,13 +758,14 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object va /// /// true to indicate success /// will be thrown if a ApiPlcProgramDatathat is an array will be given without an index - public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null) + public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null) => PlcProgramWriteAsync(var, valueToBeSet, plcProgramWriteMode).GetAwaiter().GetResult(); /// /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory /// /// webappdata that should be requested + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested public async Task WebAppBrowseAsync(ApiWebAppData webAppData, CancellationToken cancellationToken = default(CancellationToken)) @@ -764,6 +784,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// Send a WebApp.Browse Request using the Request from the ApiRequestFactory /// /// webapp name in case only one is requested + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, /// Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested public async Task WebAppBrowseAsync(string webAppName = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -789,6 +810,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// /// WebApp name to browse resources of /// If given only that resource will be inside the array (in case it exists) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, /// Resources:Array of ApiWebAppResource (only 1 if one is requested) public async Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -818,6 +840,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// /// WebApp.Name to browse resources of /// If given only that resource will be inside the array (in case it exists) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, /// Resources:Array of ApiWebAppResource (only 1 if one is requested) public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -843,6 +866,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// /// WebApp Name to browse resources of /// resource.Name to browse for + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, /// Resources:Array of ApiWebAppResource (only 1 if one is requested) public async Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) @@ -869,6 +893,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// /// webApp.Name to browse resources of /// resource.Name to browse for + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint, /// Resources:Array of ApiWebAppResource (only 1 if one is requested) public async Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) @@ -892,6 +917,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// /// webapp name for the app to be created /// optional parameter: state the webapp should be in + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -912,6 +938,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// Send a WebApp.Create Request using the Request from the ApiRequestFactory /// /// containing information about name and state for the app to be created + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppCreateAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) { @@ -934,6 +961,7 @@ public ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, /// Be sure to provide the RFC3339 format! /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on public async Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -966,6 +994,7 @@ public ApiTicketIdResponse WebAppCreateResource(string webAppName, string resour /// Be sure to provide the RFC3339 format! /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)) @@ -994,6 +1023,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// Last_modified: Be sure to provide the RFC3339 format! /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on public async Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1023,6 +1053,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// Last_modified: Be sure to provide the RFC3339 format! /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on public async Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1046,6 +1077,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory /// /// Name of the webapp to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteAsync(string webAppName, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1065,6 +1097,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// Send a WebApp.Delete Request using the Request from the ApiRequestFactory /// /// webApp.Name of the webapp to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1082,6 +1115,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// Name of the webapp that contains the resource /// Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1103,6 +1137,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// webapp.Name of the webapp that contains the resource /// Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1128,6 +1163,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1146,6 +1182,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// Name of the webapp that contains the resource /// resource.Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success public async Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1157,6 +1194,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// Name of the webapp that contains the resource /// Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on public async Task WebAppDownloadResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1178,6 +1216,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// webApp.Name of the webapp that contains the resource /// Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1196,6 +1235,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on public async Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1214,6 +1254,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// Name of the webapp that contains the resource /// resource.Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on public async Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1232,6 +1273,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// Name of the webapp that should be renamed /// New name for the WebApp + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: /// name which equals the newname public async Task WebAppRenameAsync(string webAppName, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)) @@ -1260,6 +1302,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// /// webApp.Name of the webapp that should be renamed /// New name for the WebApp + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: /// name which equals the newname public async Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)) @@ -1284,6 +1327,7 @@ public ApiTicketIdResponse WebAppCreateResource(ApiWebAppData webApp, string res /// Name of the webapp that contains the resource /// Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname public async Task WebAppRenameResourceAsync(string webAppName, string resourceName, @@ -1316,6 +1360,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, strin /// webApp.Name of the webapp that contains the resource /// Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, @@ -1340,6 +1385,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, st /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname public async Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, @@ -1367,6 +1413,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(ApiWebAppData webApp, Ap /// Name of the webapp that contains the resource /// resource.Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname public async Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, @@ -1393,6 +1440,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the default page should be set for /// Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Default_Page: which equals the resourceName @@ -1425,6 +1473,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the default page should be set for /// Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resourceName /// @@ -1450,6 +1499,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the default page should be set for /// resource.Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resource.Name /// @@ -1475,6 +1525,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the default page should be set for /// resource.Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Default_Page: which equals the resourceName @@ -1499,6 +1550,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the not authorized page should be set for /// Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals webAppName /// Not_authorized_page: which equals the resourceName @@ -1530,6 +1582,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the not authorized page should be set for /// Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// @@ -1554,6 +1607,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the not authorized page should be set for /// resource.Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// @@ -1579,6 +1633,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the not authorized page should be set for /// resource.Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals webAppName /// Not_authorized_page: which equals the resource.Name @@ -1603,6 +1658,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the not found page should be set for /// Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Not_found_page: which equals the resourceName @@ -1635,6 +1691,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the not found page should be set for /// Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resourceName /// @@ -1660,6 +1717,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// webApp.Name of the webapp that the not found page should be set for /// resource.Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resource.Name /// @@ -1685,6 +1743,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the not found page should be set for /// resource.Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Not_found_page: which equals the resource.Name @@ -1709,6 +1768,7 @@ public ApiTrueWithResourceResponse WebAppRenameResource(string webAppName, ApiWe /// /// Name of the webapp that the state should be set for /// State the WebApp should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// State: which equals the state @@ -1742,6 +1802,7 @@ public ApiTrueWithWebAppResponse WebAppSetState(string webAppName, ApiWebAppStat /// Send a WebServer.SetDefaultPage Request using the Request from the ApiRequestFactory /// /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse public async Task WebServerSetDefaultPageAsync(string defaultPage, CancellationToken cancellationToken = default(CancellationToken)) { @@ -1783,6 +1844,7 @@ public ApiWebServerGetReadDefaultPageResponse WebServerGetReadDefaultPage() /// /// webApp.Name of the webapp that state should be set for /// State the WebApp should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// State: which equals the state /// @@ -1812,6 +1874,7 @@ public ApiTrueWithWebAppResponse WebAppSetState(ApiWebAppData webApp, ApiWebAppS /// resourceName of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Etag: which equals the newEtagValue @@ -1850,6 +1913,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, stri /// resourceName of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Etag: which equals the newEtagValue @@ -1880,6 +1944,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, s /// resource.Name of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// @@ -1912,6 +1977,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceETag(ApiWebAppData webApp, A /// resource.Name of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// @@ -1942,6 +2008,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceETag(string webAppName, ApiW /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// MediaType: which equals the newMediaType @@ -1979,6 +2046,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// MediaType: which equals the newMediaType @@ -2007,6 +2075,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webA /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// @@ -2036,6 +2105,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceMediaType(ApiWebAppData webA /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// @@ -2065,6 +2135,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceMediaType(string webAppName, /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -2099,6 +2170,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webA /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -2127,6 +2199,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppDa /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -2157,6 +2230,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppDa /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -2186,6 +2260,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webA /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -2215,6 +2290,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppDa /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -2246,6 +2322,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(ApiWebAppDa /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -2277,6 +2354,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webA /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -2307,6 +2385,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceModificationTime(string webA /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Visibility: which equals the newVisibility @@ -2343,6 +2422,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceVisibility(string webAppName /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Visibility: which equals the newResourceVisibility @@ -2371,6 +2451,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData web /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// @@ -2400,6 +2481,7 @@ public ApiTrueWithResourceResponse WebAppSetResourceVisibility(ApiWebAppData web /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// @@ -2504,6 +2586,7 @@ public HttpResponseMessage DownloadTicketAndGetResponse(ApiTicket ticket) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(string ticketId, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2533,6 +2616,7 @@ public HttpResponseMessage DownloadTicketAndGetResponse(ApiTicket ticket) /// /// The Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(ApiTicket ticket, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)) => await UploadTicketAsync(ticket.Id, data, cancellationToken); @@ -2553,6 +2637,7 @@ public void UploadTicket(ApiTicket ticket, ByteArrayContent data) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(string ticketId, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2578,6 +2663,7 @@ public void UploadTicket(ApiTicket ticket, ByteArrayContent data) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(string ticketId, FileInfo pathToFile, CancellationToken cancellationToken = default(CancellationToken)) => await UploadTicketAsync(ticketId, pathToFile.FullName, cancellationToken); @@ -2597,6 +2683,7 @@ public void UploadTicket(string ticketId, FileInfo pathToFile) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(ApiTicket ticket, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)) => await UploadTicketAsync(ticket.Id, pathToFile, cancellationToken); @@ -2616,6 +2703,7 @@ public void UploadTicket(string ticketId, FileInfo pathToFile) /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void public async Task UploadTicketAsync(ApiTicket ticket, FileInfo pathToFile, CancellationToken cancellationToken = default(CancellationToken)) => await UploadTicketAsync(ticket, pathToFile.FullName, cancellationToken); @@ -2635,10 +2723,11 @@ public void UploadTicket(ApiTicket ticket, FileInfo pathToFile) /// Username to login with /// Password for the user to login with /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie public async Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiLoginRequest(userName, password, includeWebApplicationCookie); + var req = _apiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, userName, password, includeWebApplicationCookie); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = new ApiLoginResponse(); responseObj = JsonConvert.DeserializeObject(response); @@ -2661,10 +2750,47 @@ public void UploadTicket(ApiTicket ticket, FileInfo pathToFile) /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie public ApiLoginResponse ApiLogin(string userName, string password, bool? includeWebApplicationCookie = null) => ApiLoginAsync(userName, password, includeWebApplicationCookie).GetAwaiter().GetResult(); + /// + /// Send a Api.Login Request + /// + /// The mode defines where the login shall be performed. All available modes supported by API method Api.GetAuthenticationMode can be passed. + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + public async Task ApiLoginAsync(ApiAuthenticationMode mode, string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiLoginRequest(mode, userName, password, includeWebApplicationCookie); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = new ApiLoginResponse(); + responseObj = JsonConvert.DeserializeObject(response); + if (!string.IsNullOrEmpty(responseObj.Result.Token)) + { + if (_httpClient.DefaultRequestHeaders.Any(x => x.Key.Contains("X-Auth-Token"))) + { + _httpClient.DefaultRequestHeaders.Remove("X-Auth-Token"); + } + _httpClient.DefaultRequestHeaders.Add("X-Auth-Token", responseObj.Result.Token); + } + return responseObj; + } + + /// + /// Send a Api.Login Request + /// + /// The mode defines where the login shall be performed. All available modes supported by API method Api.GetAuthenticationMode can be passed. + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + public ApiLoginResponse ApiLogin(ApiAuthenticationMode mode, string userName, string password, bool? includeWebApplicationCookie = null) => ApiLoginAsync(mode, userName, password, includeWebApplicationCookie).GetAwaiter().GetResult(); + /// /// Send an Api Bulk Request /// /// Api Requests to be sent as Bulk + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// List of ApiResultResponses with Result as object - not "directly" casted to the expected Result type public async Task ApiBulkAsync(IEnumerable apiRequests, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2731,6 +2857,7 @@ public void UploadTicket(ApiTicket ticket, FileInfo pathToFile) /// Send an Plc.SetSystemTime Request /// /// The timestamp of the system time to be set + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if time was set successfully public async Task PlcSetSystemTimeAsync(DateTime timestamp, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2770,6 +2897,7 @@ public ApiTrueOnSuccessResponse PlcSetSystemTime(DateTime timestamp) => /// /// The time zone offset from the UTC time in hours /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the settings are applied successfully public async Task PlcSetTimeSettingsAsync(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2792,6 +2920,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// /// Path of the directory or file relative to the memory card root to fetch the entry list. /// The resource name must start with a "/". The parameter may be omitted.In that case, it will default to "/". + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Browsed resources (files/dir/...) public async Task FilesBrowseAsync(string resource = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2813,6 +2942,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.Browse Request /// /// resource to browse: file/dir/... + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Browsed resources (files/dir/...) public async Task FilesBrowseAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) => await FilesBrowseAsync(resource.GetVarNameForMethods(), cancellationToken); @@ -2829,6 +2959,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.Download Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID. public async Task FilesDownloadAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2850,6 +2981,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.Create request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID. public async Task FilesCreateAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2871,6 +3003,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.Create request /// /// FileInfo for informations about the file to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID. public async Task FilesCreateAsync(FileInfo resource, CancellationToken cancellationToken = default(CancellationToken)) => await FilesCreateAsync(resource.FullName, cancellationToken); @@ -2887,6 +3020,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// /// Current path of file/folder /// New path of file/folder + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file or folder is renamed successfully public async Task FilesRenameAsync(string resource, string new_resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2908,6 +3042,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.Delete Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file is deleted successfully public async Task FilesDeleteAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2928,6 +3063,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.CreateDirectory Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully public async Task FilesCreateDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2949,6 +3085,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.CreateDirectory Request /// /// DirectoryInfo for informations about the file to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully public async Task FilesCreateDirectoryAsync(DirectoryInfo resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2969,6 +3106,7 @@ public ApiTrueOnSuccessResponse PlcSetTimeSettings(TimeSpan utcOffset, DaylightS /// Send a Files.CreateDirectory Request /// /// The resource to create + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully public async Task FilesCreateDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -2989,6 +3127,7 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// Send a Files.DeleteDirectory Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is deleted successfully public async Task FilesDeleteDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3009,6 +3148,7 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// Send a DataLogs.DownloadAndClear Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID. public async Task DatalogsDownloadAndClearAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3047,6 +3187,7 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// Send a Plc.RestoreBackup Request /// /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// public async Task PlcRestoreBackupAsync(string password = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3069,6 +3210,7 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// /// /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// public async Task ReLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3089,6 +3231,7 @@ public ApiTrueOnSuccessResponse FilesCreateDirectory(ApiFileResource resource) /// Send a Files.Delete Request /// /// the resource that shall be deleted. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file is deleted successfully public async Task FilesDeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3109,6 +3252,7 @@ public ApiTrueOnSuccessResponse FilesDelete(ApiFileResource resource) /// Send a Files.DeleteDirectory Request /// /// the directory to delete. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is deleted successfully public async Task FilesDeleteDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3128,6 +3272,7 @@ public ApiTrueOnSuccessResponse FilesDeleteDirectory(ApiFileResource resource) /// Send a Failsafe.ReadParameters request /// /// The hardware identifier from which the parameters shall be read + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Response with Failsafe parameters public async Task FailsafeReadParametersAsync(uint hwid, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3167,9 +3312,9 @@ public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => /// Send an Api.GetPasswordPolicy request /// /// ApiGetPasswordPolicy response - public async Task ApiGetPasswordPolicyAsync(CancellationToken cancellationToken = default(CancellationToken)) + public async Task ApiGetPasswordPolicyAsync(ApiAuthenticationMode mode = ApiAuthenticationMode.Local, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiGetPasswordPolicyRequest(); + var req = _apiRequestFactory.GetApiGetPasswordPolicyRequest(mode); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; @@ -3179,7 +3324,7 @@ public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => /// Send an Api.GetPasswordPolicy request /// /// ApiGetPasswordPolicy response - public ApiGetPasswordPolicyResponse ApiGetPasswordPolicy() => ApiGetPasswordPolicyAsync().GetAwaiter().GetResult(); + public ApiGetPasswordPolicyResponse ApiGetPasswordPolicy(ApiAuthenticationMode mode = ApiAuthenticationMode.Local) => ApiGetPasswordPolicyAsync(mode).GetAwaiter().GetResult(); /// /// Send an Api.GetAuthenticationMode request @@ -3202,10 +3347,12 @@ public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => /// /// Send a Project.ReadLanguages Request /// + /// Determines whether all or only active languages should be returned. Default is 'active'. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Languages Response containing a list of languages - public async Task ProjectReadLanguagesAsync(CancellationToken cancellationToken = default(CancellationToken)) + public async Task ProjectReadLanguagesAsync(ApiReadLanguagesMode? mode = null, CancellationToken cancellationToken = default(CancellationToken)) { - var req = _apiRequestFactory.GetApiProjectReadLanguagesRequest(); + var req = _apiRequestFactory.GetApiProjectReadLanguagesRequest(mode); string response = await SendPostRequestAsync(req, cancellationToken); var responseObj = JsonConvert.DeserializeObject(response); return responseObj; @@ -3214,15 +3361,17 @@ public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => /// /// Send a Project.ReadLanguages Request /// + /// Determines whether all or only active languages should be returned. Default is 'active'. /// Languages Response containing a list of languages - public ApiReadLanguagesResponse ProjectReadLanguages() => ProjectReadLanguagesAsync().GetAwaiter().GetResult(); + public ApiReadLanguagesResponse ProjectReadLanguages(ApiReadLanguagesMode? mode = null) => ProjectReadLanguagesAsync(mode).GetAwaiter().GetResult(); /// /// Send a Plc.ReadModeSelectorState request /// /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Mode Selector state - public async Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid, CancellationToken cancellationToken = default(CancellationToken)) + public async Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiPlcReadModeSelectorStateRequest(rhid); string response = await SendPostRequestAsync(req, cancellationToken); @@ -3234,7 +3383,7 @@ public ApiFailsafeReadParametersResponse FailsafeReadParameters(uint hwid) => /// /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Mode Selector state - public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid) => + public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC) => PlcReadModeSelectorStateAsync(rhid).GetAwaiter().GetResult(); /// @@ -3246,6 +3395,7 @@ public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedund /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
/// This allows the user to traverse through the syslog buffer using multiple API calls. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiSyslogBrowseResponse public async Task ApiSyslogBrowseAsync(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3271,6 +3421,7 @@ public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedund ///
/// The Acknowledgement ID of the alarm which shall be acknowledged.
/// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiTrueOnSuccessResponse public async Task AlarmsAcknowledgeAsync(string id, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3302,6 +3453,7 @@ public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedund /// /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no count parameter can be provided as filter. /// (optional) Optional object that contains parameters to filter the response. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task ApiAlarmsBrowseAsync(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)) { var req = _apiRequestFactory.GetApiAlarmsBrowseRequest(language, count, alarm_id, filters); @@ -3332,6 +3484,7 @@ public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedund /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiDiagnosticBufferBrowseResponse public async Task ApiDiagnosticBufferBrowseAsync(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -3348,6 +3501,271 @@ public ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedund /// ApiDiagnosticBufferBrowseResponse public ApiDiagnosticBufferBrowseResponse ApiDiagnosticBufferBrowse(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null) => ApiDiagnosticBufferBrowseAsync(language, count, filters).GetAwaiter().GetResult(); + /// + /// Send a Techology.Read Request + /// + /// Name of the technology object to be read + /// Determines the response format for this method. See the param for more details + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// A generic ApiResultResponse: object with the value for the variables value to be read + public async Task> TechnologyReadAsync(string var, ApiPlcDataRepresentation? mode = null, CancellationToken cancellationToken = default) + { + var req = _apiRequestFactory.GetTechnologyReadRequest(var, mode); + string response = await SendPostRequestAsync(req, cancellationToken); + var responseObj = JsonConvert.DeserializeObject>(response); + return responseObj; + } + + /// + /// Send a Techology.Read Request + /// + /// Name of the technology object to be read + /// Determines the response format for this method. See the param for more details + /// A generic ApiResultResponse: object with the value for the variables value to be read + public ApiResultResponse TechnologyRead(string var, ApiPlcDataRepresentation? mode = null) => TechnologyReadAsync(var, mode).GetAwaiter().GetResult(); + + /// + /// Send a WebServer.ReadResponseHeaders request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiWebServerReadCustomHttpHeadersResponse + public async Task ApiWebServerReadResponseHeadersAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebServerReadResponseHeadersRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a WebServer.ReadResponseHeaders request + /// + /// ApiWebServerReadCustomHttpHeadersResponse + public ApiWebServerReadResponseHeadersResponse ApiWebServerReadResponseHeaders() => ApiWebServerReadResponseHeadersAsync().GetAwaiter().GetResult(); + + /// + /// Send a WebServer.ChangeResponseHeaders request + /// + /// + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + public async Task ApiWebServerChangeResponseHeadersAsync(string header = null, string pattern = "~**/*", CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebServerChangeResponseHeadersRequest(header, pattern); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a WebServer.ChangeResponseHeaders request + /// + public ApiTrueOnSuccessResponse ApiWebServerChangeResponseHeaders(string header = null, string pattern = "~**/*") => ApiWebServerChangeResponseHeadersAsync(header, pattern).GetAwaiter().GetResult(); + + /// + /// Send a Redundancy.ReadSyncupProgress request + /// + /// ApiRedundancyReadSyncupProgressResponse + public async Task ApiRedundancyReadSyncupProgressAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiRedundancyReadSyncupProgressRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + Console.WriteLine(response); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a Redundancy.ReadSyncupProgress request + /// + /// ApiRedundancyReadSyncupProgressResponse + public ApiRedundancyReadSyncupProgressResponse ApiRedundancyReadSyncupProgress() => ApiRedundancyReadSyncupProgressAsync().GetAwaiter().GetResult(); + + /// + /// This method returns a complete list of all technology objects that are configured on the PLC. + /// + /// ApiTechnologyBrowseObjectsResponse + public async Task TechnologyBrowseObjectsAsync(CancellationToken cancellationToken = default) + { + var req = _apiRequestFactory.GetTechnologyBrowseObjectsRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// This method returns a complete list of all technology objects that are configured on the PLC. + /// + /// ApiTechnologyBrowseObjectsResponse + public ApiTechnologyBrowseObjectsResponse TechnologyBrowseObjects() => TechnologyBrowseObjectsAsync().GetAwaiter().GetResult(); + + /// + /// Send a Redundancy.ReadSystemInformation request + /// + /// ApiRedundancyReadSystemInformationResponse + public async Task ApiRedundancyReadSystemInformationAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiRedundancyReadSystemInformationRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a Redundancy.ReadSystemInformation request + /// + /// ApiRedundancyReadSystemInformationResponse + public ApiRedundancyReadSystemInformationResponse ApiRedundancyReadSystemInformation() => ApiRedundancyReadSystemInformationAsync().GetAwaiter().GetResult(); + + /// + /// Send a Redundancy.ReadSystemState request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiDiagnosticBufferBrowseResponse + public async Task ApiRedundancyReadSystemStateAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiRedundancyReadSystemStateRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a Redundancy.ReadSystemState request + /// + /// ApiDiagnosticBufferBrowseResponse + public ApiRedundancyReadSystemStateResponse ApiRedundancyReadSystemState() => ApiRedundancyReadSystemStateAsync().GetAwaiter().GetResult(); + + /// + /// Send a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiTrueOnSuccessResponse + public async Task ApiRedundancyRequestChangeSystemStateAsync(ApiPlcRedundancySystemState state, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiRedundancyRequestChangeSystemStateRequest(state); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// ApiTrueOnSuccessResponse + public ApiTrueOnSuccessResponse ApiRedundancyRequestChangeSystemState(ApiPlcRedundancySystemState state) => ApiRedundancyRequestChangeSystemStateAsync(state).GetAwaiter().GetResult(); + + /// + /// Send a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + public async Task ApiWebAppSetVersionAsync(string webAppName, string version, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetVersionRequest(webAppName, version); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// + public ApiTrueOnSuccessResponse ApiWebAppSetVersion(string webAppName, string version) => ApiWebAppSetVersionAsync(webAppName, version).GetAwaiter().GetResult(); + + + /// + /// Send a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + public async Task ApiWebAppSetUrlRedirectModeAsync(string webAppName, ApiWebAppRedirectMode redirect_mode, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiWebAppSetUrlRedirectModeRequest(webAppName, redirect_mode); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// + public ApiTrueOnSuccessResponse ApiWebAppSetUrlRedirectMode(string webAppName, ApiWebAppRedirectMode redirect_mode) => ApiWebAppSetUrlRedirectModeAsync(webAppName, redirect_mode).GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadCpuType request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + public async Task ApiGetPlcCpuTypeAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadCpuTypeRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + /// + /// Send a Plc.ReadCpuType request + /// + /// + public ApiPlcReadCpuTypeResponse ApiGetPlcCpuType() => ApiGetPlcCpuTypeAsync().GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadStationName request + /// + /// + public async Task ApiGetPlcStationNameAsync(CancellationToken cancellationToken = default) + { + var req = _apiRequestFactory.GetApiPlcReadStationNameRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a Plc.ReadStationName request + /// + /// + public ApiPlcReadStationNameResponse ApiGetPlcStationName() => ApiGetPlcStationNameAsync().GetAwaiter().GetResult(); + + /// + /// Send a Plc.ReadModuleName request + /// + /// + /// The Redundancy ID parameter must be present when the request is executed on an R/H PLC. It must either have a value of 1 or 2.
+ /// On non-R/H PLCs, the parameter must not be part of the request. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + public async Task ApiGetPlcModuleNameAsync(uint? redundancy_id = null, CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiPlcReadModuleNameRequest(redundancy_id); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a Plc.ReadModuleName request + /// + /// + /// The Redundancy ID parameter must be present when the request is executed on an R/H PLC. It must either have a value of 1 or 2.
+ /// On non-R/H PLCs, the parameter must not be part of the request. + /// + public ApiPlcReadModuleNameResponse ApiGetPlcModuleName(uint? redundancy_id = null) => ApiGetPlcModuleNameAsync(redundancy_id).GetAwaiter().GetResult(); + + /// + /// Send a GetSessionInfo request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + public async Task ApiGetSessionInfoAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + var req = _apiRequestFactory.GetApiGetSessionInfoRequest(); + string response = await SendPostRequestAsync(req, cancellationToken); + return JsonConvert.DeserializeObject(response); + } + + /// + /// Send a GetSessionInfo request + /// + /// + public ApiSessionInfoResponse ApiGetSessionInfo() => ApiGetSessionInfoAsync().GetAwaiter().GetResult(); + /// /// Cancel the outstanding requests of the HttpClient /// diff --git a/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs b/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs index b55ffaf..d6699c7 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiRequestFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -99,33 +99,48 @@ public virtual IApiRequest GetApiCloseTicketRequest(string ticketId, string json /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. /// Request Id /// JsonRpc to be used /// an Api.ChangePassword request - public IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, string jsonRpc = null, string id = null) + public IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null, string jsonRpc = null, string id = null) { RequestParameterChecker.CheckUsername(username, PerformCheck); RequestParameterChecker.CheckPasswords(currentPassword, newPassword, PerformCheck); string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.ChangePassword", jsonRpcReq, idReq, new Dictionary() + Dictionary requestParams = new Dictionary() { { "username", username }, { "password", currentPassword }, { "new_password", newPassword } - }); + }; + if (mode != null) + { + requestParams.Add("mode", mode.ToString().ToLower()); + } + return new ApiRequest("Api.ChangePassword", jsonRpcReq, idReq, requestParams); } /// /// Get an Api.GetPasswordPolicy request /// + /// The authentication mode that defines where the password policy shall be read from. /// Request Id /// JsonRpc to be used /// An Api.GetPasswordPolicy request - public IApiRequest GetApiGetPasswordPolicyRequest(string jsonRpc = null, string id = null) + public IApiRequest GetApiGetPasswordPolicyRequest(ApiAuthenticationMode mode = ApiAuthenticationMode.Local, string jsonRpc = null, string id = null) { string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Api.GetPasswordPolicy", jsonRpcReq, idReq); + if (mode != ApiAuthenticationMode.Local) + { + return new ApiRequest("Api.GetPasswordPolicy", jsonRpcReq, idReq, + new Dictionary() { { "mode", mode.ToString().ToLower() } }); + } + else + { + return new ApiRequest("Api.GetPasswordPolicy", jsonRpcReq, idReq); + } } /// @@ -153,23 +168,36 @@ public virtual IApiRequest GetApiGetCertificateUrlRequest(string jsonRpc = null, string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("Api.GetCertificateUrl", jsonRpcReq, idReq); } + /// - /// get an Api.Login Request with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) + /// get an Api.Login Request with the given "mode":mode, "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) /// - /// - /// + /// The mode defines where the login shall be performed. + /// All available modes supported by API method Api.GetAuthenticationMode can be passed, except for umc_sso. + /// username for login + /// password for login /// bool used to determine if the response should include a valid application cookie value for protected pages access /// ApiLoginRequest with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) - /// Request Id, defaults to RequestIdGenerator.Generate() - /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiLoginRequest(string userName, string password, bool? include_web_application_cookie = null, string jsonRpc = null, string id = null) + /// Request Id + /// JsonRpc to be used + public virtual IApiRequest GetApiLoginRequest(ApiAuthenticationMode mode, string userName, string password, bool? include_web_application_cookie = null, + string jsonRpc = null, string id = null) { string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - // wenn bspw. username leer ist: request kann nicht gebaut werden -> parameter abprüfen und exceptions schmeißen - return new ApiRequest("Api.Login", jsonRpcReq, idReq, new Dictionary() { { "user", userName }, { "password", password }, - { "include_web_application_cookie", include_web_application_cookie } }); + Dictionary requestParams = new Dictionary() + { + { "mode", mode.ToString().ToLower() }, + { "user", userName }, + { "password", password } + }; + if (include_web_application_cookie == true) + { + requestParams.Add("include_web_application_cookie", include_web_application_cookie); + } + return new ApiRequest("Api.Login", jsonRpcReq, idReq, requestParams); } + /// /// get an Api.Logout Request without parameters /// @@ -272,9 +300,9 @@ public virtual IApiRequest GetApiPlcProgramDownloadProfilingDataRequest(string j /// PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" /// Request Id, defaults to RequestIdGenerator.Generate() /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null) + public virtual IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcDataRepresentation? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null) { - RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramReadMode, PerformCheck); + RequestParameterChecker.CheckPlcDataRepresentationMode(apiPlcProgramReadMode, PerformCheck); string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("PlcProgram.Read", jsonRpcReq, idReq, new Dictionary() { { "var", var }, @@ -289,9 +317,9 @@ public virtual IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcProgram /// PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - defaults to "simple" /// Request Id, defaults to RequestIdGenerator.Generate() /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null) + public virtual IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcDataRepresentation? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null) { - RequestParameterChecker.CheckPlcProgramReadOrWriteMode(apiPlcProgramWriteMode, PerformCheck); + RequestParameterChecker.CheckPlcDataRepresentationMode(apiPlcProgramWriteMode, PerformCheck); string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); return new ApiRequest("PlcProgram.Write", jsonRpcReq, idReq, new Dictionary() { { "var", var }, @@ -320,28 +348,38 @@ public virtual object GetApiPlcProgramWriteValueToBeSet(ApiPlcProgramDataType ap /// get an Plc.ReadOperatingMode Request without parameters /// /// Plc.ReadOperatingMode Request without parameters + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Request Id, defaults to RequestIdGenerator.Generate() /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcReadOperatingModeRequest(string jsonRpc = null, string id = null) + public virtual IApiRequest GetApiPlcReadOperatingModeRequest(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null) { string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.ReadOperatingMode", jsonRpcReq, idReq); + return new ApiRequest("Plc.ReadOperatingMode", jsonRpcReq, idReq, + rhid == ApiPlcRedundancyId.StandardPLC ? null : new Dictionary() + { + { "redundancy_id", (int)rhid } + }); } /// /// get an Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode /// + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Plc Operating mode wanted /// Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode /// Request Id, defaults to RequestIdGenerator.Generate() /// JsonRpc to be used - defaults to JsonRpcVersion - public virtual IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, string jsonRpc = null, string id = null) + public virtual IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null) { RequestParameterChecker.CheckPlcRequestChangeOperatingMode(apiPlcOperatingMode, PerformCheck); string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Plc.RequestChangeOperatingMode", jsonRpcReq, idReq, new Dictionary() { - { "mode", apiPlcOperatingMode.ToString().ToLower() } }); + var dict = new Dictionary() { { "mode", apiPlcOperatingMode.ToString().ToLower() } }; + if (rhid != ApiPlcRedundancyId.StandardPLC) + { + dict.Add("redundancy_id", (int)rhid); + } + return new ApiRequest("Plc.RequestChangeOperatingMode", jsonRpcReq, idReq, dict); } /// /// Get a Plc.ReadModeSelectorState Request with redundancy id parameter @@ -350,7 +388,7 @@ public virtual IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOper /// Request Id /// JsonRpc to be used /// Plc.ReadModeSelectorState request with redundancy id parameter - public IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid, string jsonRpc = null, string id = null) + public IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null) { string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); @@ -984,14 +1022,15 @@ public IApiRequest GetFailsafeReadRuntimeGroupsRequest(string jsonRpc = null, st /// /// Get a Project.ReadLanguages request without parameters /// + /// Determines whether all or only active languages should be returned. Default is 'active'. /// Request Id /// JsonRpc to be used /// Project.ReadLanguages request without parameters - public IApiRequest GetApiProjectReadLanguagesRequest(string jsonRpc = null, string id = null) + public IApiRequest GetApiProjectReadLanguagesRequest(ApiReadLanguagesMode? mode = null, string jsonRpc = null, string id = null) { string jsonRpcReq = jsonRpc ?? JsonRpcVersion; string idReq = id ?? RequestIdGenerator.Generate(); - return new ApiRequest("Project.ReadLanguages", jsonRpcReq, idReq); + return new ApiRequest("Project.ReadLanguages", jsonRpcReq, idReq, mode == null ? null : new Dictionary() { { "mode", mode } }); } /// @@ -1153,5 +1192,242 @@ public virtual IApiRequest GetApiDiagnosticBufferBrowseRequest(CultureInfo langu } return new ApiRequest("DiagnosticBuffer.Browse", jsonRpcReq, idReq, requestParams); } + + /// + /// Get a Technology.Read request + /// + /// Name of the variable to read. The name must not be empty. + /// Enumeration that determines the response format + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Technology.Read request + public IApiRequest GetTechnologyReadRequest(string var, ApiPlcDataRepresentation? mode = null, string jsonRpc = null, string id = null) + { + RequestParameterChecker.CheckPlcDataRepresentationMode(mode, PerformCheck); + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() { { "var", var } }; + if (mode != null) + { + requestParams.Add("mode", mode); + } + return new ApiRequest("Technology.Read", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a WebServer.ReadResponseHeaders request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiWebServerReadResponseHeadersRequest + public virtual IApiRequest GetApiWebServerReadResponseHeadersRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebServer.ReadResponseHeaders", jsonRpcReq, idReq); + } + + /// + /// Get a WebServer.ChangeResponseHeaders request + /// + /// The HTTP response header to be returned when accessing URLs that match the given pattern. + /// The URL pattern for which the header must be returned. For now, this must always be set to /~**/*. Other values are not allowed. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiWebServerChangeResponseHeadersRequest + public virtual IApiRequest GetApiWebServerChangeResponseHeadersRequest(string header = null, string pattern = "/~**/*", string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams; + if (header != null) + { + requestParams = new Dictionary() + { + {"headers", + new List>() + { + new Dictionary() + { + {"pattern", pattern }, + {"header", header } + } + } + }, + }; + } + else + { + requestParams = new Dictionary() + { + {"headers", new List>()} + }; + } + return new ApiRequest("WebServer.ChangeResponseHeaders", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a Redundancy.ReadSyncupProgress request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiRedundancyReadSyncupProgressRequest + public virtual IApiRequest GetApiRedundancyReadSyncupProgressRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Redundancy.ReadSyncupProgress", jsonRpcReq, idReq); + } + + /// + /// Get a Technology.BrowseObjects request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Technology.BrowseObjects request + public IApiRequest GetTechnologyBrowseObjectsRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Technology.BrowseObjects", jsonRpcReq, idReq); + } + + /// + /// Get a Redundancy.ReadSystemInformation request + /// + public virtual IApiRequest GetApiRedundancyReadSystemInformationRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Redundancy.ReadSystemInformation", jsonRpcReq, idReq); + } + + /// + /// Get a Redundancy.ReadSystemState request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiDiagnosticBufferBrowseRequest + public virtual IApiRequest GetApiRedundancyReadSystemStateRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Redundancy.ReadSystemState", jsonRpcReq, idReq); + } + + /// + /// Get a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiRedundancyRequestChangeSystemStateRequest + public virtual IApiRequest GetApiRedundancyRequestChangeSystemStateRequest(ApiPlcRedundancySystemState state, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() { { "state", state.ToString().ToLower() } }; + return new ApiRequest("Redundancy.RequestChangeSystemState", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// + /// + /// + public IApiRequest GetApiWebAppSetVersionRequest(string webAppName, string version, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + Dictionary requestParams = new Dictionary() + { + { "name", webAppName }, + { "version", version } + }; + return new ApiRequest("WebApp.SetVersion", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// + /// + /// + public IApiRequest GetApiWebAppSetUrlRedirectModeRequest(string webAppName, ApiWebAppRedirectMode redirect_mode, string jsonRpc = null, string id = null) + { + Dictionary requestParams = new Dictionary() + { + { "name", webAppName }, + { "redirect_mode", redirect_mode.ToString().ToLower() } + }; + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("WebApp.SetUrlRedirectMode", jsonRpcReq, idReq, requestParams); + } + + /// + /// Get a Plc.ReadCpuType request + /// + /// + /// + /// + public virtual IApiRequest GetApiPlcReadCpuTypeRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadCpuType", jsonRpcReq, idReq); + } + + /// + /// Get a Plc.ReadStationName request + /// + /// + /// + /// + public IApiRequest GetApiPlcReadStationNameRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Plc.ReadStationName", jsonRpcReq, idReq); + } + + /// + /// Get a Plc.ReadModuleName request + /// + /// + /// The Redundancy ID parameter must be present when the request is executed on an R/H PLC. It must either have a value of 1 or 2.
+ /// On non-R/H PLCs, the parameter must not be part of the request. + /// + /// + /// + public IApiRequest GetApiPlcReadModuleNameRequest(uint? redundancy_id = null, string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + if (redundancy_id != null) + { + Dictionary requestParams = new Dictionary() { { "redundancy_id", redundancy_id } }; + return new ApiRequest("Plc.ReadModuleName", jsonRpcReq, idReq, requestParams); + } + return new ApiRequest("Plc.ReadModuleName", jsonRpcReq, idReq); + } + + /// + /// Get a GetSessionInfo request + /// + /// + /// + /// + public virtual IApiRequest GetApiGetSessionInfoRequest(string jsonRpc = null, string id = null) + { + string jsonRpcReq = jsonRpc ?? JsonRpcVersion; + string idReq = id ?? RequestIdGenerator.Generate(); + return new ApiRequest("Api.GetSessionInfo", jsonRpcReq, idReq); + } } } diff --git a/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs b/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs index d61d69f..8eedab8 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiRequestParameterChecker.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -148,15 +148,15 @@ public void CheckPlcProgramBrowseMode(ApiPlcProgramBrowseMode plcProgramBrowseMo /// /// None isnt valid! /// - /// PlcProgramReadMode that should be checked for being valid + /// Determines the response format for various methods that return data from the PLC /// Bool to determine wether to really perform the check or not - public void CheckPlcProgramReadOrWriteMode(ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode, bool performCheck) + public void CheckPlcDataRepresentationMode(ApiPlcDataRepresentation? apiPlcProgramReadMode, bool performCheck) { if (performCheck) { if (apiPlcProgramReadMode != null) { - if (apiPlcProgramReadMode == ApiPlcProgramReadOrWriteMode.None) + if (apiPlcProgramReadMode == ApiPlcDataRepresentation.None) { throw new ApiInvalidParametersException($"PlcProgram.Read or Write shall not be called with {Environment.NewLine + apiPlcProgramReadMode.ToString().ToLower()}" + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.InvalidParams, Message = "Invalid Params" } })); @@ -313,8 +313,8 @@ public void CheckUsername(string username, bool performCheck) } if (username == "Anonymous") { - throw new ApiPasswordChangeNotAcceptedException($"Password can not be changed for the Anonymous user! {Environment.NewLine}" + - $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.PasswordChangeNotAccepted, Message = "The password change cannot be performed" } })); + throw new ApiNotAcceptedException($"Password can not be changed for the Anonymous user! {Environment.NewLine}" + + $"{Environment.NewLine}Probably Api would send: ", new ApiException(new ApiErrorModel() { Error = new ApiError() { Code = ApiErrorCode.NotAccepted, Message = "The password change cannot be performed" } })); } } } diff --git a/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs b/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs index b937fea..942babd 100644 --- a/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/ApiResponseChecker.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs index 3828e68..d2d1af1 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestFactory.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -56,17 +56,19 @@ public interface IApiRequestFactory /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. /// Request Id /// JsonRpc to be used /// an Api.ChangePassword request - IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, string jsonRpc = null, string id = null); + IApiRequest GetApiChangePasswordRequest(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null, string jsonRpc = null, string id = null); /// /// Get an Api.GetPasswordPolicy request /// + /// The authentication mode that defines where the password policy shall be read from. /// Request Id /// JsonRpc to be used /// An Api.GetPasswordPolicy request - IApiRequest GetApiGetPasswordPolicyRequest(string jsonRpc = null, string id = null); + IApiRequest GetApiGetPasswordPolicyRequest(ApiAuthenticationMode mode = ApiAuthenticationMode.Local, string jsonRpc = null, string id = null); /// /// Get an Api.GetAuthenticationMode request /// @@ -82,17 +84,18 @@ public interface IApiRequestFactory /// JsonRpc to be used IApiRequest GetApiGetCertificateUrlRequest(string jsonRpc = null, string id = null); /// - /// get an Api.Login Request with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) + /// get an Api.Login Request with the given "mode":mode, "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) /// + /// The mode defines where the login shall be performed. + /// All available modes supported by API method Api.GetAuthenticationMode can be passed, except for umc_sso. /// username for login /// password for login /// bool used to determine if the response should include a valid application cookie value for protected pages access /// ApiLoginRequest with the given "user":userName, "password": password, "include_web_application_cookie" : include_web_application_cookie (might be null) /// Request Id /// JsonRpc to be used - IApiRequest GetApiLoginRequest(string userName, string password, bool? include_web_application_cookie = null, + IApiRequest GetApiLoginRequest(ApiAuthenticationMode mode, string userName, string password, bool? include_web_application_cookie = null, string jsonRpc = null, string id = null); - /// /// get an Api.Logout Request without parameters /// @@ -124,10 +127,11 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// /// Get a Project.ReadLanguages request without parameters /// + /// Determines whether all or only active languages should be returned. Default is 'active'. /// Request Id /// JsonRpc to be used /// Project.ReadLanguages request without parameters - IApiRequest GetApiProjectReadLanguagesRequest(string jsonRpc = null, string id = null); + IApiRequest GetApiProjectReadLanguagesRequest(ApiReadLanguagesMode? mode = null, string jsonRpc = null, string id = null); /// /// get an PlcProgram.Browse Request with parameter "mode": apiPlcProgramBrowseMode, "var" : var (might be null) /// @@ -162,7 +166,7 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// PlcProgram.Read Request with parameter "var" : var, "mode": apiPlcProgramReadMode (might be null) - /// Request Id /// JsonRpc to be used - IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null); + IApiRequest GetApiPlcProgramReadRequest(string var, ApiPlcDataRepresentation? apiPlcProgramReadMode = null, string jsonRpc = null, string id = null); /// /// get an PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - /// @@ -172,7 +176,7 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// PlcProgram.Write Request with parameter "var" : var, "value":valueToBeSet, "mode": apiPlcProgramReadMode (might be null) - /// Request Id /// JsonRpc to be used - IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null); + IApiRequest GetApiPlcProgramWriteRequest(string var, object valueToBeSet, ApiPlcDataRepresentation? apiPlcProgramWriteMode = null, string jsonRpc = null, string id = null); /// /// "Comfort" function to get the according Type object for a value the user Wants depending on the apiPlcProgramData /// @@ -186,17 +190,19 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// get an Plc.ReadOperatingMode Request without parameters ///
/// Plc.ReadOperatingMode Request without parameters + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Request Id /// JsonRpc to be used - IApiRequest GetApiPlcReadOperatingModeRequest(string jsonRpc = null, string id = null); + IApiRequest GetApiPlcReadOperatingModeRequest(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null); /// /// get an Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode /// /// Plc Operating mode wanted + /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Plc.CheckPlcRequestChangeOperatingMode Request with parameter "mode": apiPlcOperatingMode /// Request Id /// JsonRpc to be used - IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, string jsonRpc = null, string id = null); + IApiRequest GetApiPlcRequestChangeOperatingModeRequest(ApiPlcOperatingMode apiPlcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null); /// /// Get a Plc.ReadModeSelectorState Request with redundancy id parameter /// @@ -204,7 +210,7 @@ IApiRequest GetApiLoginRequest(string userName, string password, bool? include_w /// Request Id /// JsonRpc to be used /// Plc.ReadModeSelectorState request with redundancy id parameter - IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid, string jsonRpc = null, string id = null); + IApiRequest GetApiPlcReadModeSelectorStateRequest(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, string jsonRpc = null, string id = null); /// /// check new Etag value /// get an WebApp.SetResourceETag Request with parameter "app_name" : webAppName,"name": resourceName, "etag" : newETagValue @@ -617,6 +623,125 @@ IApiRequest GetApiDiagnosticBufferBrowseRequest(CultureInfo language, ApiDiagnosticBuffer_RequestFilters filters = null, string jsonRpc = null, string id = null); + /// + /// Get a Technology.Read request + /// + /// Name of the variable to read. The name must not be empty. + /// Enumeration that determines the response format + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Technology.Read request + IApiRequest GetTechnologyReadRequest(string var, ApiPlcDataRepresentation? mode = null, string jsonRpc = null, string id = null); + /// + /// Get a WebServer.ReadResponseHeaders request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiWebServerReadResponseHeadersRequest + IApiRequest GetApiWebServerReadResponseHeadersRequest(string jsonRpc = null, string id = null); + + /// + /// Get a WebServer.ChangeResponseHeaders request + /// + /// The HTTP response header to be returned when accessing URLs that match the given pattern. + /// The URL pattern for which the header must be returned. For now, this must always be set to /~**/*. Other values are not allowed. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiWebServerChangeResponseHeadersRequest + IApiRequest GetApiWebServerChangeResponseHeadersRequest(string header = null, string pattern = "~**/*", string jsonRpc = null, string id = null); + + /// + /// Get a Redundancy.ReadSyncupProgress request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiRedundancyReadSyncupProgressRequest + IApiRequest GetApiRedundancyReadSyncupProgressRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Technology.BrowseObjects request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// Technology.BrowseObjects request + IApiRequest GetTechnologyBrowseObjectsRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Redundancy.ReadSystemInformation request + /// + IApiRequest GetApiRedundancyReadSystemInformationRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Redundancy.RequestChangeSystemState request + /// + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiDiagnosticBufferBrowseRequest + IApiRequest GetApiRedundancyReadSystemStateRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// Request Id, defaults to RequestIdGenerator.Generate() + /// JsonRpc to be used - defaults to JsonRpcVersion + /// ApiRedundancyRequestChangeSystemStateRequest + IApiRequest GetApiRedundancyRequestChangeSystemStateRequest(ApiPlcRedundancySystemState state, string jsonRpc = null, string id = null); + + /// + /// Get a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// + /// + /// + IApiRequest GetApiWebAppSetVersionRequest(string webAppName, string version, string jsonRpc = null, string id = null); + + /// + /// Get a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// + /// + /// + IApiRequest GetApiWebAppSetUrlRedirectModeRequest(string webAppName, ApiWebAppRedirectMode redirect_mode, string jsonRpc = null, string id = null); + + /// + /// Get a Plc.ReadCpuType request + /// + /// + /// + /// + IApiRequest GetApiPlcReadCpuTypeRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Plc.ReadStationName request + /// + /// + /// + /// + IApiRequest GetApiPlcReadStationNameRequest(string jsonRpc = null, string id = null); + + /// + /// Get a Plc.ReadModuleName request + /// + /// + /// The Redundancy ID parameter must be present when the request is executed on an R/H PLC. It must either have a value of 1 or 2.
+ /// On non-R/H PLCs, the parameter must not be part of the request. + /// + /// + /// + IApiRequest GetApiPlcReadModuleNameRequest(uint? redundancy_id = null, string jsonRpc = null, string id = null); + + /// + /// Get a GetSessionInfo request + /// + /// + /// + /// + IApiRequest GetApiGetSessionInfoRequest(string jsonRpc = null, string id = null); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs index 52534ae..63c4de8 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -42,6 +42,7 @@ public interface IApiRequestHandler ///
/// an array of ApiResponses /// api Requests to send + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task ApiBulkAsync(IEnumerable apiRequests, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Browse Request @@ -100,16 +101,19 @@ public interface IApiRequestHandler /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if changing password for the user was successful - Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, CancellationToken cancellationToken = default(CancellationToken)); + Task ApiChangePasswordAsync(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.ChangePassword request /// /// The user account for which the password shall be changed /// The current password for the user /// The new password for the user + /// The mode defines where the password change shall be performed on. If null, the PLC will treat it as local. /// True if changing password for the user was successful - ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword); + ApiTrueOnSuccessResponse ApiChangePassword(string username, string currentPassword, string newPassword, ApiAuthenticationMode? mode = null); /// /// Send an Api.GetCertificateUrl Request /// @@ -137,8 +141,20 @@ public interface IApiRequestHandler /// Username to login with /// Password for the user to login with /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie Task ApiLoginAsync(string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Api.Login Request + /// + /// The mode defines where the login shall be performed. All available modes supported by API method Api.GetAuthenticationMode can be passed. + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + Task ApiLoginAsync(ApiAuthenticationMode mode, string userName, string password, bool? includeWebApplicationCookie = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.Logout Request /// @@ -184,6 +200,7 @@ public interface IApiRequestHandler /// sucht nach der Variable, um die Metadaten der Variable zu finden. /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, string var = null, CancellationToken cancellationToken = default(CancellationToken)); @@ -202,6 +219,7 @@ public interface IApiRequestHandler /// sucht nach der Variable, um die Metadaten der Variable zu finden. /// • Wenn "mode" = "children", ist dieses Attribut optional. Die Browse-Methode /// sucht die Variable und liefert eine Liste an Kind-Variablen und Metadaten. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// PlcProgramBrowseResponse: An Array of ApiPlcProgramData Task PlcProgramBrowseAsync(ApiPlcProgramBrowseMode plcProgramBrowseMode, ApiPlcProgramData var, CancellationToken cancellationToken = default(CancellationToken)); @@ -220,8 +238,9 @@ public interface IApiRequestHandler /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); + Task> PlcProgramReadAsync(ApiPlcProgramData var, ApiPlcDataRepresentation? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Read Request /// @@ -236,8 +255,9 @@ public interface IApiRequestHandler /// "simple" in Kapitel "Unterstützte Datentypen (Seite 162)" /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - Task> PlcProgramReadAsync(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); + Task> PlcProgramReadAsync(string var, ApiPlcDataRepresentation? plcProgramReadMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Write Request /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite @@ -246,9 +266,10 @@ public interface IApiRequestHandler /// Name of the variable to be read /// Name der zu lesenden Variable /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// true to indicate success - Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcProgramWriteAsync(ApiPlcProgramData var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a PlcProgram.Write Request /// @@ -256,21 +277,22 @@ public interface IApiRequestHandler /// Name of the variable to be read /// Name der zu lesenden Variable /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// /// true to indicate success - Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcProgramWriteAsync(string var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.ReadOperatingMode Request /// /// The current Plc OperatingMode - Task PlcReadOperatingModeAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task PlcReadOperatingModeAsync(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.RequestChangeOperatingMode Request /// Method to change the plc operating mode /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. /// /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode plcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)); /// /// only use this function if you know how to build up apiRequests on your own! /// @@ -319,6 +341,7 @@ public interface IApiRequestHandler /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// ByteArray that should be sent to the plc Ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void Task UploadTicketAsync(string ticketId, ByteArrayContent data, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -327,18 +350,21 @@ public interface IApiRequestHandler /// /// Id of the Ticket - will be used to send the request to the endpoint /api/ticket?id=ticketId /// File Bytes will be Read and saved into ByteArrayContent - then sent to the ticketing Endpoint + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task/void Task UploadTicketAsync(string ticketId, string pathToFile, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Browse Request /// /// webapp name in case only one is requested + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, Applications: Array of ApiWebAppdata Task WebAppBrowseAsync(string webAppName = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Browse Request /// /// webappdata that should be requested + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResponse: Containing WebAppBrowseResult: Max_Applications:uint, Applications: Array of ApiWebAppdata containing one element: the webappdata that has been requested Task WebAppBrowseAsync(ApiWebAppData webAppData, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -348,6 +374,7 @@ public interface IApiRequestHandler /// /// WebApp.Name to browse resources of /// If given only that resource will be inside the array (in case it exists) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -357,6 +384,7 @@ public interface IApiRequestHandler /// /// WebApp Name to browse resources of /// resource.Name to browse for + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources Task WebAppBrowseResourcesAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -366,6 +394,7 @@ public interface IApiRequestHandler /// /// webApp.Name to browse resources of /// resource.Name to browse for + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources:Array of ApiWebAppResource (only 1 if one is requested) Task WebAppBrowseResourcesAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -375,12 +404,14 @@ public interface IApiRequestHandler /// /// WebApp name to browse resources of /// If given only that resource will be inside the array (in case it exists) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiWebAppBrowseResourcesResponse:containing ApiWebAppBrowseResourcesResult: Max_Resources:uint,Resources Task WebAppBrowseResourcesAsync(string webAppName, string resourceName = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Create Request /// /// containing information about name and state for the app to be created + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppCreateAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -388,6 +419,7 @@ public interface IApiRequestHandler /// /// webapp name for the app to be created /// optional parameter: state the webapp should be in + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppCreateAsync(string webAppName, ApiWebAppState? apiWebAppState = null, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -400,6 +432,7 @@ public interface IApiRequestHandler /// Last_modified: Be sure to provide the RFC3339 format! /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on Task WebAppCreateResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -412,6 +445,7 @@ public interface IApiRequestHandler /// Last_modified: Be sure to provide the RFC3339 format! /// Visibility: resource visibility (protect your confidential data) /// Etag: you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on Task WebAppCreateResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -423,6 +457,7 @@ public interface IApiRequestHandler /// Be sure to provide the RFC3339 format! /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on Task WebAppCreateResourceAsync(ApiWebAppData webApp, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -434,18 +469,21 @@ public interface IApiRequestHandler /// Be sure to provide the RFC3339 format! /// resource visibility (protect your confidential data) /// you can provide an etag as identification,... for your resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// TicketId for the Ticketing Endpoint to perform the Upload on Task WebAppCreateResourceAsync(string webAppName, string resourceName, string media_type, string last_modified, ApiWebAppResourceVisibility? apiWebAppResourceVisibility = null, string etag = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Delete Request /// /// webApp.Name of the webapp to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a WebApp.Delete Request /// /// Name of the webapp to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteAsync(string webAppName, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -453,6 +491,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -460,6 +499,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that contains the resource /// resource.Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -467,6 +507,7 @@ public interface IApiRequestHandler /// /// webapp.Name of the webapp that contains the resource /// Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -474,6 +515,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that contains the resource /// Name of the resource to delete + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// true to indicate success Task WebAppDeleteResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -481,6 +523,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on Task WebAppDownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -488,6 +531,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that contains the resource /// resource.Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on Task WebAppDownloadResourceAsync(string webAppName, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -495,6 +539,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that contains the resource /// Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on Task WebAppDownloadResourceAsync(ApiWebAppData webApp, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -502,6 +547,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that contains the resource /// Name of the resource to download + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket id for Ticketing Endpoint to trigger the download on Task WebAppDownloadResourceAsync(string webAppName, string resourceName, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -509,6 +555,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that should be renamed /// New name for the WebApp + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the given WebApp that has the change: /// name which equals the newname Task WebAppRenameAsync(ApiWebAppData webApp, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)); @@ -517,6 +564,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that should be renamed /// New name for the WebApp + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a WebApp that only has the information: /// name which equals the newname Task WebAppRenameAsync(string webAppName, string newWebAppName, CancellationToken cancellationToken = default(CancellationToken)); @@ -526,6 +574,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname Task WebAppRenameResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); @@ -535,6 +584,7 @@ public interface IApiRequestHandler /// Name of the webapp that contains the resource /// resource.Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the Resource given that has the following change: /// name which equals the newname Task WebAppRenameResourceAsync(string webAppName, ApiWebAppResource resource, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); @@ -544,6 +594,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname Task WebAppRenameResourceAsync(ApiWebAppData webApp, string resourceName, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); @@ -553,6 +604,7 @@ public interface IApiRequestHandler /// Name of the webapp that contains the resource /// Name of the resource that should be renamed /// New name for the resource + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a Resource that only has the information: /// name which equals the newname Task WebAppRenameResourceAsync(string webAppName, string resourceName, string newResourceName, CancellationToken cancellationToken = default(CancellationToken)); @@ -561,6 +613,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that the default page should be set for /// resource.Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resource.Name /// @@ -570,6 +623,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the default page should be set for /// resource.Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Default_Page: which equals the resourceName @@ -580,6 +634,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that the default page should be set for /// Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Default_Page: which equals the resourceName /// @@ -589,6 +644,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the default page should be set for /// Name of the resource that should be the webapps default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Default_Page: which equals the resourceName @@ -599,6 +655,7 @@ public interface IApiRequestHandler ///
/// webApp.Name of the webapp that the not authorized page should be set for /// resource.Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// @@ -608,6 +665,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the not authorized page should be set for /// resource.Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals webAppName /// Not_authorized_page: which equals the resource.Name @@ -618,6 +676,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that the not authorized page should be set for /// Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_authorized_page: which equals the resourceName /// @@ -627,6 +686,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the not authorized page should be set for /// Name of the resource that should be the webapps not authorized page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals webAppName /// Not_authorized_page: which equals the resourceName @@ -637,6 +697,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that the not found page should be set for /// resource.Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resource.Name /// @@ -646,6 +707,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the not found page should be set for /// resource.Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Not_found_page: which equals the resource.Name @@ -656,6 +718,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that the not found page should be set for /// Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// Not_found_page: which equals the resourceName /// @@ -665,6 +728,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the not found page should be set for /// Name of the resource that should be the webapps not found page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// Not_found_page: which equals the resourceName @@ -677,6 +741,7 @@ public interface IApiRequestHandler /// resource.Name of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// @@ -688,6 +753,7 @@ public interface IApiRequestHandler /// resource.Name of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Etag: which equals the newEtagValue /// @@ -699,6 +765,7 @@ public interface IApiRequestHandler /// resourceName of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Etag: which equals the newEtagValue @@ -711,6 +778,7 @@ public interface IApiRequestHandler /// resourceName of the resource that the etag should be set for /// Etag value the resource should have /// new value for the resource etag - "" for "null"/"no etag", also null can be given for null! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Etag: which equals the newEtagValue @@ -722,6 +790,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// @@ -732,6 +801,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// MediaType: which equals the newMediaType /// @@ -742,6 +812,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// MediaType: which equals the newMediaType @@ -753,6 +824,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Media_type should be set for /// MediaType value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// MediaType: which equals the newMediaType @@ -764,6 +836,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -774,6 +847,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -784,6 +858,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -795,6 +870,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -806,6 +882,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -817,6 +894,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -827,6 +905,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Last_Modified: which equals the newModificationTime @@ -838,6 +917,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Last_modified should be set for /// ModificationTime - Last_modified value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Last_Modified: which equals the newModificationTime /// @@ -848,6 +928,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resource.Name of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// @@ -858,6 +939,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resource.Name of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the resource given containing only the change: /// Visibility: which equals the newResourceVisibility /// @@ -868,6 +950,7 @@ public interface IApiRequestHandler /// webApp.Name of the webapp that contains the resource /// resourceName of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Visibility: which equals the newResourceVisibility @@ -879,6 +962,7 @@ public interface IApiRequestHandler /// webAppName of the webapp that contains the resource /// resourceName of the resource that the Visibility should be set for /// Visibility value the resource should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a a resource containing only the information: /// Name: which equals the resourceName /// Visibility: which equals the newVisibility @@ -889,6 +973,7 @@ public interface IApiRequestHandler /// /// webApp.Name of the webapp that state should be set for /// State the WebApp should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and a copy of the webapp given containing only the change: /// State: which equals the state /// @@ -899,6 +984,7 @@ public interface IApiRequestHandler /// /// Name of the webapp that the state should be set for /// State the WebApp should have + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// This function will return the TrueOnSuccessResponse and webapp containing only the information: /// Name: which equals the webAppName /// State: which equals the state @@ -921,6 +1007,7 @@ public interface IApiRequestHandler /// Send a WebServer.SetDefaultPage request /// /// Name of the default page + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Returns a TrueOnSuccessResponse Task WebServerSetDefaultPageAsync(string defaultPage, CancellationToken cancellationToken = default(CancellationToken)); @@ -973,6 +1060,16 @@ public interface IApiRequestHandler /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie ApiLoginResponse ApiLogin(string userName, string password, bool? includeWebApplicationCookie = null); + + /// + /// Send a Api.Login Request + /// + /// The mode defines where the login shall be performed. All available modes supported by API method Api.GetAuthenticationMode can be passed. + /// Username to login with + /// Password for the user to login with + /// Used to determine wether or not a WebApplicationCookie should be included in the Response (Result) + /// ApiLoginResponse: contains ApiTokenResult: Token(auth token string) and if requested Web_application_cookie + ApiLoginResponse ApiLogin(ApiAuthenticationMode mode, string userName, string password, bool? includeWebApplicationCookie = null); /// /// Send an Api.Logout Request /// @@ -997,17 +1094,21 @@ public interface IApiRequestHandler /// /// Send a Project.ReadLanguages Request /// + /// Determines whether all or only active languages should be returned. Default is 'active'. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Languages Response containing a list of languages - Task ProjectReadLanguagesAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task ProjectReadLanguagesAsync(ApiReadLanguagesMode? mode = null, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Project.ReadLanguages Request /// + /// Determines whether all or only active languages should be returned. Default is 'active'. /// Languages Response containing a list of languages - ApiReadLanguagesResponse ProjectReadLanguages(); + ApiReadLanguagesResponse ProjectReadLanguages(ApiReadLanguagesMode? mode = null); /// /// Perform a service data download on the corresponding module with hwid /// /// The HWID of a node (module) for which a service data file can be downloaded + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket to use for downloading the service data Task ModulesDownloadServiceDataAsync(ApiPlcHwId hwid, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1095,7 +1196,7 @@ public interface IApiRequestHandler /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null); + ApiResultResponse PlcProgramRead(ApiPlcProgramData var, ApiPlcDataRepresentation? plcProgramReadMode = null); /// /// Send a PlcProgram.Read Request /// @@ -1112,7 +1213,7 @@ public interface IApiRequestHandler /// • "raw": liefert Variablenwerte gemäß der Darstellung "raw" /// in Kapitel "Unterstützte Datentypen" /// ApiPlcProgramReadResponse: object with the value for the variables value to be read - ApiResultResponse PlcProgramRead(string var, ApiPlcProgramReadOrWriteMode? plcProgramReadMode = null); + ApiResultResponse PlcProgramRead(string var, ApiPlcDataRepresentation? plcProgramReadMode = null); /// /// Send a PlcProgram.Write Request /// This function will build up the name with quotes from the parents given with the ApiPlcProgramDataand call PlcProgramWrite @@ -1123,7 +1224,7 @@ public interface IApiRequestHandler /// /// /// true to indicate success - ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null); + ApiTrueOnSuccessResponse PlcProgramWrite(ApiPlcProgramData var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null); /// /// Send a PlcProgram.Write Request /// @@ -1133,31 +1234,32 @@ public interface IApiRequestHandler /// /// /// true to indicate success - ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcProgramReadOrWriteMode? plcProgramWriteMode = null); + ApiTrueOnSuccessResponse PlcProgramWrite(string var, object valueToBeSet, ApiPlcDataRepresentation? plcProgramWriteMode = null); /// /// Send a Plc.ReadOperatingMode Request /// /// The current Plc OperatingMode - ApiReadOperatingModeResponse PlcReadOperatingMode(); + ApiReadOperatingModeResponse PlcReadOperatingMode(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC); /// /// Send a Plc.RequestChangeOperatingMode Request /// Method to change the plc operating mode /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. /// /// valid plcOperatingModes are: "run", "stop" - others will lead to an invalid params exception. - ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode); + ApiTrueOnSuccessResponse PlcRequestChangeOperatingMode(ApiPlcOperatingMode plcOperatingMode, ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC); /// /// Send a Plc.ReadModeSelectorState request /// /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Mode Selector state - Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid, CancellationToken cancellationToken = default(CancellationToken)); + Task PlcReadModeSelectorStateAsync(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send a Plc.ReadModeSelectorState request /// /// In an R/H system, a PLC with ID 1 (primary) or 2 (backup). For standard PLCs, enum value 0 (StandardPLC) is required. /// Mode Selector state - ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid); + ApiPlcReadModeSelectorStateResponse PlcReadModeSelectorState(ApiPlcRedundancyId rhid = ApiPlcRedundancyId.StandardPLC); /// /// Function to send the ByteArrayContent for a Ticket (e.g. CreateResource) /// MediaTypeHeaderValue: application/octet-stream @@ -1765,6 +1867,7 @@ public interface IApiRequestHandler /// Send an Plc.SetSystemTime Request /// /// The timestamp of the system time to be set + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if time was set successfully Task PlcSetSystemTimeAsync(DateTime timestamp, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1790,6 +1893,7 @@ public interface IApiRequestHandler /// /// The time zone offset from the UTC time in hours /// (Optional) Represents the settings for daylight-savings. If there is no daylight-savings rule configured, the utcOffset is applied to calculate the local time + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the settings are applied successfully Task PlcSetTimeSettingsAsync(TimeSpan utcOffset, DaylightSavingsRule daylightSavings = null, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -1804,6 +1908,7 @@ public interface IApiRequestHandler /// /// Path of the directory or file relative to the memory card root to fetch the entry list. /// The resource name must start with a "/". The parameter may be omitted.In that case, it will default to "/". + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Browsed resources (files/dir/...) Task FilesBrowseAsync(string resource = null, CancellationToken cancellationToken = default(CancellationToken)); @@ -1819,6 +1924,7 @@ public interface IApiRequestHandler /// Send a Files.Browse Request /// /// resource to browse. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Browsed resources (files/dir/...) Task FilesBrowseAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1833,6 +1939,7 @@ public interface IApiRequestHandler /// Send a Files.Download Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID Task FilesDownloadAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1848,6 +1955,7 @@ public interface IApiRequestHandler /// Send a Files.Create Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID Task FilesCreateAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1863,6 +1971,7 @@ public interface IApiRequestHandler /// Send a Files.Create Request /// /// FileInfo for informations about the file to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Ticket ID Task FilesCreateAsync(FileInfo resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1878,6 +1987,7 @@ public interface IApiRequestHandler /// /// Current path of file/folder /// New path of file/folder + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file or folder is renamed successfully Task FilesRenameAsync(string resource, string new_resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1894,6 +2004,7 @@ public interface IApiRequestHandler /// Send a Files.Delete Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file is deleted successfully Task FilesDeleteAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1908,6 +2019,7 @@ public interface IApiRequestHandler /// Send a Files.Delete Request /// /// the resource that shall be deleted. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the file is deleted successfully Task FilesDeleteAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1922,6 +2034,7 @@ public interface IApiRequestHandler /// Send a Files.CreateDirectory Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully Task FilesCreateDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1938,6 +2051,7 @@ public interface IApiRequestHandler /// Send a Files.CreateDirectory Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully Task FilesCreateDirectoryAsync(DirectoryInfo resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1953,6 +2067,7 @@ public interface IApiRequestHandler /// Send a Files.CreateDirectory Request /// /// The resource to create + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is created successfully Task FilesCreateDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1968,6 +2083,7 @@ public interface IApiRequestHandler /// Send a Files.DeleteDirectory Request /// /// Path of the file relative to the memory card root. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is deleted successfully Task FilesDeleteDirectoryAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1982,6 +2098,7 @@ public interface IApiRequestHandler /// Send a Files.DeleteDirectory Request /// /// the directory to delete. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the directory is deleted successfully Task FilesDeleteDirectoryAsync(ApiFileResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -1996,6 +2113,7 @@ public interface IApiRequestHandler /// Send a Datalogs.DownloadAndClear Request /// /// Resource name of data log to retrieve, including the path. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// True if the resource is downloaded and deleted successfully Task DatalogsDownloadAndClearAsync(string resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -2046,6 +2164,7 @@ public interface IApiRequestHandler /// Send a Failsafe.ReadParameters request /// /// The hardware identifier from which the parameters shall be read + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Response with Failsafe parameters Task FailsafeReadParametersAsync(uint hwid, CancellationToken cancellationToken = default(CancellationToken)); @@ -2070,14 +2189,16 @@ public interface IApiRequestHandler /// /// Send an Api.GetPasswordPolicy request /// + /// The authentication mode that defines where the password policy shall be read from. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiGetPasswordPolicy response - Task ApiGetPasswordPolicyAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task ApiGetPasswordPolicyAsync(ApiAuthenticationMode mode = ApiAuthenticationMode.Local, CancellationToken cancellationToken = default(CancellationToken)); /// /// Send an Api.GetPasswordPolicy request /// /// ApiGetPasswordPolicy response - ApiGetPasswordPolicyResponse ApiGetPasswordPolicy(); + ApiGetPasswordPolicyResponse ApiGetPasswordPolicy(ApiAuthenticationMode mode = ApiAuthenticationMode.Local); /// /// Send an Api.GetAuthenticationMode request @@ -2100,6 +2221,7 @@ public interface IApiRequestHandler /// A count of 0 will omit any syslog entries from the response and only return the attributes last_modified, count_total and count_lost. /// Optionally allows the user to provide the id of an entry as a starting point for the returned entries array.
/// This allows the user to traverse through the syslog buffer using multiple API calls. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiSyslogBrowseResponse Task ApiSyslogBrowseAsync(ApiPlcRedundancyId? redundancy_id = null, uint? count = null, uint? first = null, CancellationToken cancellationToken = default(CancellationToken)); @@ -2121,6 +2243,7 @@ public interface IApiRequestHandler ///
/// The Acknowledgement ID of the alarm which shall be acknowledged.
/// The acknowledgement ID can be found in the alarm object that was returned by method Alarms.Browse. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiTrueOnSuccessResponse Task AlarmsAcknowledgeAsync(string id, CancellationToken cancellationToken = default(CancellationToken)); @@ -2146,6 +2269,7 @@ public interface IApiRequestHandler /// /// (optional) The CPU alarm ID for which the user wants to return the data. If this is provided, no other parameters can be provided as filter. /// (optional) Optional object that contains parameters to filter the response. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task ApiAlarmsBrowseAsync(CultureInfo language, int? count = null, string alarm_id = null, ApiAlarms_RequestFilters filters = null, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -2169,6 +2293,7 @@ public interface IApiRequestHandler /// The language in which the texts should be returned. If the language is valid, then the response must contain the texts in the requested language.An empty string shall be treated the same as an invalid language string. /// (optional) The maximum number of diagnostic buffer entries to be requested. Default value: 50. A count of 0 will omit any diagnostic buffer entries from the response /// (optional) ApiDiagnosticBufferBrowse_RequestFilters representing various filtering possibilities. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// ApiDiagnosticBufferBrowseResponse Task ApiDiagnosticBufferBrowseAsync(CultureInfo language, uint? count = null, @@ -2183,6 +2308,204 @@ Task ApiDiagnosticBufferBrowseAsync(CultureIn /// ApiDiagnosticBufferBrowseResponse ApiDiagnosticBufferBrowseResponse ApiDiagnosticBufferBrowse(CultureInfo language, uint? count = null, ApiDiagnosticBuffer_RequestFilters filters = null); + /// + /// Send a Techology.Read Request + /// + /// Name of the technology object to be read + /// Determines the response format for this method. See the param for more details + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// A generic ApiResultResponse: object with the value for the variables value to be read + Task> TechnologyReadAsync(string var, ApiPlcDataRepresentation? mode = null, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Techology.Read Request + /// + /// Name of the technology object to be read + /// Determines the response format for this method. See the param for more details + /// A generic ApiResultResponse: object with the value for the variables value to be read + ApiResultResponse TechnologyRead(string var, ApiPlcDataRepresentation? mode = null); + + /// + /// Send a WebServer.ReadResponseHeaders request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiWebServerReadResponseHeadersResponse + Task ApiWebServerReadResponseHeadersAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a WebServer.ReadResponseHeaders request + /// + /// ApiWebServerReadResponseHeadersResponse + ApiWebServerReadResponseHeadersResponse ApiWebServerReadResponseHeaders(); + + /// + /// Send a WebServer.ChangeResponseHeaders request + /// + /// The HTTP response header to be returned when accessing URLs that match the given pattern. + /// The URL pattern for which the header must be returned. + /// For now, this must always be set to /~**/*. Other values are not allowed. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + Task ApiWebServerChangeResponseHeadersAsync(string header = null, string pattern = "~**/*", CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebServer.ChangeResponseHeaders request + /// + /// /// The HTTP response header to be returned when accessing URLs that match the given pattern. + /// The URL pattern for which the header must be returned. + /// For now, this must always be set to /~**/*. Other values are not allowed. + ApiTrueOnSuccessResponse ApiWebServerChangeResponseHeaders(string header = null, string pattern = "~**/*"); + + /// + /// Send a Redundancy.ReadSyncupProgress request + /// + /// ApiRedundancyReadSyncupProgressResponse + Task ApiRedundancyReadSyncupProgressAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Redundancy.ReadSyncupProgress request + /// + /// ApiRedundancyReadSyncupProgressResponse + ApiRedundancyReadSyncupProgressResponse ApiRedundancyReadSyncupProgress(); + + /// + /// This method returns a complete list of all technology objects that are configured on the PLC. + /// + /// ApiTechnologyBrowseObjectsResponse + Task TechnologyBrowseObjectsAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// This method returns a complete list of all technology objects that are configured on the PLC. + /// + /// ApiTechnologyBrowseObjectsResponse + ApiTechnologyBrowseObjectsResponse TechnologyBrowseObjects(); + + /// + /// Send a Redundancy.ReadSystemInformation request + /// + /// ApiRedundancyReadSystemInformationResponse + Task ApiRedundancyReadSystemInformationAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Redundancy.ReadSystemInformation request + /// + /// ApiRedundancyReadSystemInformationResponse + ApiRedundancyReadSystemInformationResponse ApiRedundancyReadSystemInformation(); + + /// + /// Send a Redundancy.ReadSystemState request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiRedundancyReadSystemStateResponse + Task ApiRedundancyReadSystemStateAsync(CancellationToken cancellationToken = default(CancellationToken)); + /// + /// Send a Redundancy.ReadSystemState request + /// + /// ApiRedundancyReadSystemStateResponse + ApiRedundancyReadSystemStateResponse ApiRedundancyReadSystemState(); + + /// + /// Send a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// ApiTrueOnSuccessResponse + Task ApiRedundancyRequestChangeSystemStateAsync(ApiPlcRedundancySystemState state, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Redundancy.RequestChangeSystemState request + /// + /// The requested system state for the R/H system. + /// ApiTrueOnSuccessResponse + ApiTrueOnSuccessResponse ApiRedundancyRequestChangeSystemState(ApiPlcRedundancySystemState state); + + /// + /// Send a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiWebAppSetVersionAsync(string webAppName, string version, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebApp.SetVersion request + /// + /// The application in which the resource is located. + /// The version of the application. The string may be empty to reset the version string. + /// + ApiTrueOnSuccessResponse ApiWebAppSetVersion(string webAppName, string version); + + /// + /// Send a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiWebAppSetUrlRedirectModeAsync(string app_name, ApiWebAppRedirectMode redirect_mode, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a WebApp.SetUrlRedirectMode request + /// + /// The application for which the redirect mode shall be changed. + /// The redirect mode of the application. + /// + ApiTrueOnSuccessResponse ApiWebAppSetUrlRedirectMode(string app_name, ApiWebAppRedirectMode redirect_mode); + + /// + /// Send a Plc.ReadCpuType request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiGetPlcCpuTypeAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Plc.ReadCpuType request + /// + /// + ApiPlcReadCpuTypeResponse ApiGetPlcCpuType(); + + /// + /// Send a Plc.ReadStationName request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiGetPlcStationNameAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Plc.ReadStationName request + /// + /// + ApiPlcReadStationNameResponse ApiGetPlcStationName(); + + /// + /// Send a Plc.ReadModuleName request + /// + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiGetPlcModuleNameAsync(uint? redundancy_id = null, CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a Plc.ReadModuleName request + /// + /// + /// The Redundancy ID parameter must be present when the request is executed on an R/H PLC. It must either have a value of 1 or 2.
+ /// On non-R/H PLCs, the parameter must not be part of the request. + /// + ApiPlcReadModuleNameResponse ApiGetPlcModuleName(uint? redundancy_id = null); + + /// + /// Send a GetSessionInfo request + /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. + /// + Task ApiGetSessionInfoAsync(CancellationToken cancellationToken = default(CancellationToken)); + + /// + /// Send a GetSessionInfo request + /// + /// + ApiSessionInfoResponse ApiGetSessionInfo(); + + /// /// Cancel the outstanding Requests /// diff --git a/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs b/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs index f8e76ab..9a9e07b 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiRequestParameterChecker.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -41,7 +41,7 @@ public interface IApiRequestParameterChecker ///
/// PlcProgramReadMode that should be checked for being valid /// Bool to determine wether to really perform the check or not - void CheckPlcProgramReadOrWriteMode(ApiPlcProgramReadOrWriteMode? apiPlcProgramReadMode, bool performCheck); + void CheckPlcDataRepresentationMode(ApiPlcDataRepresentation? apiPlcProgramReadMode, bool performCheck); /// /// None isnt valid (unsupported type = -1) /// diff --git a/src/Webserver.API/Services/RequestHandling/IApiResponseChecker.cs b/src/Webserver.API/Services/RequestHandling/IApiResponseChecker.cs index b32a73b..c32649b 100644 --- a/src/Webserver.API/Services/RequestHandling/IApiResponseChecker.cs +++ b/src/Webserver.API/Services/RequestHandling/IApiResponseChecker.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using System.Net.Http; diff --git a/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs b/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs index 51f6214..38f40c9 100644 --- a/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs +++ b/src/Webserver.API/Services/Ticketing/ApiTicketHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT @@ -494,7 +494,7 @@ public ApiTicket HandleDownload(ApiTicket ticket, DirectoryInfo pathToDownloadDi { try { - await ApiRequestHandler.UploadTicketAsync(ticketId, filePath); + await ApiRequestHandler.UploadTicketAsync(ticketId, filePath, cancellationToken); return await CheckTicketAsync(ticketId, CheckAfterUpload, cancellationToken); } finally diff --git a/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs b/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs index 19a4052..8a49141 100644 --- a/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs +++ b/src/Webserver.API/Services/Ticketing/IApiTicketHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs b/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs index ba4660a..aa907dd 100644 --- a/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs +++ b/src/Webserver.API/Services/WebApp/ApiResourceHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -45,6 +45,7 @@ public ApiResourceHandler(IApiRequestHandler apiRequestHandler, IApiWebAppResour /// /// /// optionally: + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// , /// Task public async Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)) @@ -77,6 +78,7 @@ public void DeployResource(ApiWebAppData webApp, ApiWebAppResource resource) /// make sure to set the before calling this method! /// filepath to the resource that should be deployed! /// Visibility for the resource that shall be set! defaults to public + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// public async Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public, CancellationToken cancellationToken = default(CancellationToken)) { @@ -102,6 +104,7 @@ public void DeployResource(ApiWebAppData webApp, string pathToResource, ApiWebAp /// will default to Downloads but will determine path from -DESKTOP-, replaced "Desktop" by "Downloads" /// will default to "resource.name" /// in case you want to set a specific fileExtension (normally included in filename) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// Task/void public async Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, CancellationToken cancellationToken = default(CancellationToken)) diff --git a/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs b/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs index a103016..8add2ca 100644 --- a/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs +++ b/src/Webserver.API/Services/WebApp/ApiWebAppDataSaver.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs b/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs index b79e8bc..c381c97 100644 --- a/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs +++ b/src/Webserver.API/Services/WebApp/ApiWebAppDeployer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -48,6 +48,7 @@ public ApiWebAppDeployer(IApiRequestHandler apiRequestHandler, IApiResourceHandl /// PathToWebAppDirectory /// /// - e.g. from parsed webappdirectory + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task DeployAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)) { var res = await ApiRequestHandler.WebAppCreateAsync(webApp, cancellationToken); @@ -101,6 +102,7 @@ public ApiWebAppDeployer(IApiRequestHandler apiRequestHandler, IApiResourceHandl /// optional parameter: /// used to determine wether the deployer should retry a upload and compare of the resources found or give up right away (default) /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. public async Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)) { var webApps = await ApiRequestHandler.WebAppBrowseAsync(cancellationToken: cancellationToken); @@ -192,6 +194,14 @@ public ApiWebAppDeployer(IApiRequestHandler apiRequestHandler, IApiResourceHandl { await ApiRequestHandler.WebAppSetStateAsync(webApp.Name, webApp.State, cancellationToken); } + if (browsedWebApp.Redirect_mode != webApp.Redirect_mode) + { + if (webApp.Redirect_mode == Enums.ApiWebAppRedirectMode.None) + { + throw new ApiInvalidParametersException("Redirect mode should never be none!"); + } + await ApiRequestHandler.ApiWebAppSetUrlRedirectModeAsync(webApp.Name, webApp.Redirect_mode, cancellationToken); + } browsedWebAppResp = await ApiRequestHandler.WebAppBrowseAsync(webApp, cancellationToken); browsedWebApp = browsedWebAppResp.Result.Applications.First(); if (!browsedWebApp.Equals(webApp)) diff --git a/src/Webserver.API/Services/WebApp/ApiWebAppResourceBuilder.cs b/src/Webserver.API/Services/WebApp/ApiWebAppResourceBuilder.cs index da22b23..c0467fe 100644 --- a/src/Webserver.API/Services/WebApp/ApiWebAppResourceBuilder.cs +++ b/src/Webserver.API/Services/WebApp/ApiWebAppResourceBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs b/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs index d41d797..b984e81 100644 --- a/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs +++ b/src/Webserver.API/Services/WebApp/IApiResourceHandler.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; @@ -46,6 +46,7 @@ public interface IApiResourceHandler /// Media_type /// Last_modified /// optionally: + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// etag, visibility /// Task DeployResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, CancellationToken cancellationToken = default(CancellationToken)); @@ -56,6 +57,7 @@ public interface IApiResourceHandler /// make sure to set the webapp PathToWebAppDirectory before calling this method! /// filepath to the resource that should be deployed! /// Visibility for the resource that shall be set! + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// Task DeployResourceAsync(ApiWebAppData webApp, string pathToResource, ApiWebAppResourceVisibility visibility = ApiWebAppResourceVisibility.Public, CancellationToken cancellationToken = default(CancellationToken)); /// @@ -77,6 +79,7 @@ public interface IApiResourceHandler /// Directory the file should be stored in /// name for the downloaded file /// in case you want to set a specific fileExtension (normally included in filename) + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. /// choose wether you want to replace an existing file or add another file with that name to you download directory in case one already exists /// task/void Task DownloadResourceAsync(ApiWebAppData webApp, ApiWebAppResource resource, bool overrideExistingFile = false, string pathToDownloadDirectory = null, string fileName = null, string fileExtension = null, CancellationToken cancellationToken = default(CancellationToken)); diff --git a/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs b/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs index 75be4ad..7a9b6bc 100644 --- a/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs +++ b/src/Webserver.API/Services/WebApp/IApiWebAppDeployer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MITusing System.Threading.Tasks; using Siemens.Simatic.S7.Webserver.API.Models; @@ -27,6 +27,7 @@ public interface IApiWebAppDeployer /// PathToWebAppDirectory /// /// - e.g. from parsed webappdirectory + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task DeployAsync(ApiWebAppData webApp, CancellationToken cancellationToken = default(CancellationToken)); /// /// make very sure the given webapp contains all the data: @@ -59,6 +60,7 @@ public interface IApiWebAppDeployer /// optional parameter: /// used to determine wether the deployer should retry a upload and compare of the resources found or give up right away /// + /// Enables the method to terminate its operation if a cancellation is requested from it's CancellationTokenSource. Task DeployOrUpdateAsync(ApiWebAppData webApp, int amountOfTriesForResourceDeployment = 1, CancellationToken cancellationToken = default(CancellationToken)); } } \ No newline at end of file diff --git a/src/Webserver.API/Services/WebApp/IApiWebAppResourceBuilder.cs b/src/Webserver.API/Services/WebApp/IApiWebAppResourceBuilder.cs index 16951e9..494fda1 100644 --- a/src/Webserver.API/Services/WebApp/IApiWebAppResourceBuilder.cs +++ b/src/Webserver.API/Services/WebApp/IApiWebAppResourceBuilder.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Enums; diff --git a/src/Webserver.API/StaticHelpers/DateTimeFormat.cs b/src/Webserver.API/StaticHelpers/DateTimeFormat.cs index fadfeec..9371925 100644 --- a/src/Webserver.API/StaticHelpers/DateTimeFormat.cs +++ b/src/Webserver.API/StaticHelpers/DateTimeFormat.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT diff --git a/tests/Webserver.API.UnitTests/ApiBulkTests.cs b/tests/Webserver.API.UnitTests/ApiBulkTests.cs index 6d59044..22662e4 100644 --- a/tests/Webserver.API.UnitTests/ApiBulkTests.cs +++ b/tests/Webserver.API.UnitTests/ApiBulkTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs b/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs index 6fdc525..3d10c4f 100644 --- a/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs +++ b/tests/Webserver.API.UnitTests/ApiDirectoryBuilderTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/ApiRequestTests.cs b/tests/Webserver.API.UnitTests/ApiRequestTests.cs index 7fb2805..23c2e46 100644 --- a/tests/Webserver.API.UnitTests/ApiRequestTests.cs +++ b/tests/Webserver.API.UnitTests/ApiRequestTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -11,6 +11,7 @@ using Siemens.Simatic.S7.Webserver.API.Models.FailsafeParameters; using Siemens.Simatic.S7.Webserver.API.Models.Requests; using Siemens.Simatic.S7.Webserver.API.Models.Responses; +using Siemens.Simatic.S7.Webserver.API.Models.Technology; using Siemens.Simatic.S7.Webserver.API.Models.TimeSettings; using Siemens.Simatic.S7.Webserver.API.Services.PlcProgram; using Siemens.Simatic.S7.Webserver.API.Services.RequestHandling; @@ -467,7 +468,7 @@ public void T007_01_ApiLogin_InvalidLogin_UnauthorizedExc() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Everybody", "wrong"); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Everybody", "wrong"); Assert.ThrowsAsync(async () => await TestHandler.SendPostRequestAsync(req)); } @@ -486,7 +487,7 @@ public void T007_02_ApiLogin_AlreadyLoggedIn_UnauthorizedExc() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Everybody", ""); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Everybody", ""); Assert.ThrowsAsync(async () => await TestHandler.SendPostRequestAsync(req)); } @@ -505,7 +506,7 @@ public void T007_03_ApiLogin_NoResources_NoResourcesExc() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Everybody", ""); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Everybody", ""); Assert.ThrowsAsync(async () => await TestHandler.SendPostRequestAsync(req)); } @@ -524,7 +525,7 @@ public async Task T007_04_ApiLogin_ValidToken_TokenReturnedNoCookie() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Everybody", ""); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Everybody", ""); var res = JsonConvert.DeserializeObject(await TestHandler.SendPostRequestAsync(req)); if (string.IsNullOrEmpty(res.Result.Token)) Assert.Fail("token is empty or null altough server returned with!"); @@ -547,7 +548,7 @@ public async Task T007_05_ApiLogin_ValidToken_TokenReturnedAndCookie() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Everybody", "", true); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Everybody", "", true); var res = JsonConvert.DeserializeObject(await TestHandler.SendPostRequestAsync(req)); if (string.IsNullOrEmpty(res.Result.Token)) Assert.Fail("token is empty or null altough server returned with!"); @@ -570,7 +571,7 @@ public async Task T007_06_ApiLogin_ValidToken_WithEverything() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var req = ApiRequestFactory.GetApiLoginRequest("Anonymous", "", true); + var req = ApiRequestFactory.GetApiLoginRequest(ApiAuthenticationMode.Local, "Anonymous", "", true); var res = JsonConvert.DeserializeObject(await TestHandler.SendPostRequestAsync(req)); if (string.IsNullOrEmpty(res.Result.Token)) Assert.Fail("token is empty or null altough server returned with!"); @@ -585,6 +586,43 @@ public async Task T007_06_ApiLogin_ValidToken_WithEverything() Assert.That(!res.Result.Password_expiration.Warning); } + /// + /// Unit test for Api.Login that returns every possible value + /// + /// + [Test] + public async Task T007_07_ApiLogin_ValidToken_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.LoginWorked); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiLoginAsync(ApiAuthenticationMode.Local, "Admin", "Siemens_1")).Result; + Assert.That(result.Token, Is.EqualTo("G8ejtdxTZ6fz8AIuwDG.tWf+6Cou")); + } + + /// + /// Unit test for Api.Login that returns every possible value + /// + /// + [Test] + public void T007_08_ApiLogin_ValidToken_InfrastructureErrorExc() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.LoginFailedInfrastructureError); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiLoginAsync(ApiAuthenticationMode.Umc, "Admin", "Siemens_1")); + } + /// /// /// @@ -779,6 +817,86 @@ public void T011_07_ApiPlcReadOperatingMode_None_ThrowsExc() Assert.ThrowsAsync(async () => await TestHandler.PlcReadOperatingModeAsync()); } + /// + /// + /// + /// + [Test] + public async Task T011_08_ApiPlcReadOperatingMode_runRedundant_RH_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadOpModeRunRedundant); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadOperatingModeAsync(ApiPlcRedundancyId.RedundancyId_1); + if (res.Result != ApiPlcOperatingMode.Run_redundant) + Assert.Fail("unexpected response:" + res.Result.ToString()); + } + + /// + /// + /// + /// + [Test] + public async Task T011_09_ApiPlcReadOperatingMode_syncup_RH_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadOpModeSyncup); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadOperatingModeAsync(ApiPlcRedundancyId.RedundancyId_2); + if (res.Result != ApiPlcOperatingMode.Syncup) + Assert.Fail("unexpected response:" + res.Result.ToString()); + } + + /// + /// + /// + /// + [Test] + public async Task T011_10_ApiPlcReadOperatingMode_runsyncup_RH_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadOpModeRunSyncup); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadOperatingModeAsync(ApiPlcRedundancyId.RedundancyId_2); + if (res.Result != ApiPlcOperatingMode.Run_syncup) + Assert.Fail("unexpected response:" + res.Result.ToString()); + } + + /// + /// + /// + /// + [Test] + public async Task T011_11_ApiPlcReadOperatingMode_remoteunknown_RH_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcReadOpModeRemoteUnknown); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var res = await TestHandler.PlcReadOperatingModeAsync(ApiPlcRedundancyId.RedundancyId_2); + if (res.Result != ApiPlcOperatingMode.Remote_unknown) + Assert.Fail("unexpected response:" + res.Result.ToString()); + } + /// /// /// @@ -903,6 +1021,24 @@ public async Task T012_07_ApiRequestChangeOperatingMode_run_works() await TestHandler.PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode.Stop); } + /// + /// + /// + /// + [Test] + public async Task T012_08_ApiRequestChangeOperatingMode_run_RH_works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + await TestHandler.PlcRequestChangeOperatingModeAsync(ApiPlcOperatingMode.Stop, ApiPlcRedundancyId.RedundancyId_1); + } + /// /// /// @@ -1414,7 +1550,7 @@ public void T016_06_ApiPlcProgramRead_InvalidMode_ThrowsExc() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - Assert.ThrowsAsync(async () => await TestHandler.PlcProgramReadAsync("\"DataTypes\".\"Struct1L\"", ApiPlcProgramReadOrWriteMode.None)); + Assert.ThrowsAsync(async () => await TestHandler.PlcProgramReadAsync("\"DataTypes\".\"Struct1L\"", ApiPlcDataRepresentation.None)); } /// @@ -1432,7 +1568,7 @@ public void T017_01_ApiPlcProgramWrite_InvalidMode_ThrowsExc() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - Assert.ThrowsAsync(async () => await TestHandler.PlcProgramWriteAsync("\"DataTypes\".\"bool\"", true, ApiPlcProgramReadOrWriteMode.None)); + Assert.ThrowsAsync(async () => await TestHandler.PlcProgramWriteAsync("\"DataTypes\".\"bool\"", true, ApiPlcDataRepresentation.None)); } /// @@ -1450,7 +1586,7 @@ public async Task T017_02_ApiPlcProgramWrite_Valid_works() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var res = await TestHandler.PlcProgramWriteAsync("\"DataTypes\".Bool", true, ApiPlcProgramReadOrWriteMode.Simple); + var res = await TestHandler.PlcProgramWriteAsync("\"DataTypes\".Bool", true, ApiPlcDataRepresentation.Simple); } /// @@ -1468,7 +1604,7 @@ public async Task T017_03_ApiPlcProgramWrite_ValidRaw_works() var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); - var res = await TestHandler.PlcProgramWriteAsync("\"DataTypes\".Bool", new int[1] { 1 }, ApiPlcProgramReadOrWriteMode.Raw); + var res = await TestHandler.PlcProgramWriteAsync("\"DataTypes\".Bool", new int[1] { 1 }, ApiPlcDataRepresentation.Raw); } /// @@ -1492,7 +1628,7 @@ public async Task T018_01_ApiWebAppBrowse_Valid_works() } /// - /// + /// TestCase for WebApp.Browse method /// /// [Test] @@ -1509,9 +1645,39 @@ public void T018_02_ApiWebAppBrowse_ApplDoesNotExist_throwsExc() Assert.ThrowsAsync(async () => await TestHandler.WebAppBrowseAsync("anotherWebAp")); } + /// + /// TestCase for WebApp.Browse method + /// + /// + [Test] + public async Task T018_03_ApiWebAppBrowse_CheckAllValues() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.WebAppBrowse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.WebAppBrowseAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Max_Applications, Is.EqualTo(4), "Max_Applications"); + var app1 = result.Applications.First(); + Assert.That(app1.Name, Is.EqualTo("customerExampleManualAdjusted"), "app1.Name"); + Assert.That(app1.State, Is.EqualTo(ApiWebAppState.Enabled), "app1.State"); + Assert.That(app1.Type, Is.EqualTo(ApiWebAppType.User), "app1.Type"); + Assert.That(app1.Version, Is.EqualTo("V1.2"), "app1.Version"); + Assert.That(app1.Redirect_mode, Is.EqualTo(ApiWebAppRedirectMode.Redirect), "app1.Redirect_mode"); + Assert.That(app1.Default_page, Is.EqualTo("index.html"), "app1.Default_page"); + Assert.That(app1.Not_found_page, Is.EqualTo("index2.html"), "app1.Name"); + Assert.That(app1.Not_authorized_page, Is.EqualTo("login.html"), "app1.Name"); + }); + } /// - /// + /// TestCase for WebApp.Browse method /// /// [Test] @@ -2573,8 +2739,8 @@ public async Task T038_01_PlcReadTimeSettings_Rule_Works() var dst = new DaylightSavingsTimeConfiguration(new PlcDate(3, 5, ApiDayOfWeek.Sun, 1, 0), new TimeSpan(0, 60, 0)); var sdt = new StandardTimeConfiguration(new PlcDate(10, 5, ApiDayOfWeek.Sun, 2, 0)); var expectedRule = new DaylightSavingsRule(sdt, dst); - Assert.That(result.Current_offset, Is.EqualTo(TimeSpan.Zero), "Current offset is not equal to expected value!"); - Assert.That(result.Rule, Is.EqualTo(expectedRule), "Time setting rule doesn't match!"); + Assert.That(result.Current_offset, Is.EqualTo(TimeSpan.Zero)); + Assert.That(result.Rule, Is.EqualTo(expectedRule)); } /// @@ -2720,7 +2886,7 @@ public async Task T043_01_ApiFilesCreate_Works() TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var result = await TestHandler.FilesCreateAsync("/"); var expectedResult = "dlBvEAfpgSVBfwlU7Py5TsVbmRTq"; - Assert.That(result.Result, Is.EqualTo(expectedResult), "Tickets for FilesCreate!"); + Assert.That(result.Result, Is.EqualTo(expectedResult)); } /// @@ -2903,7 +3069,7 @@ public async Task T052_ApiSyslogBrowse_Works() Assert.That(result.Count_Lost, Is.EqualTo(1)); Assert.That(result.Entries.Count, Is.EqualTo(2)); Assert.That(result.Entries[0].Raw, Is.EqualTo("I am a syslog, no need to question it!")); - Assert.That(result.Entries[1].Raw, Is.EqualTo("I am a syslog, too. But the previous syslog is an impostor!"), "Tickets for FilesCreate!"); + Assert.That(result.Entries[1].Raw, Is.EqualTo("I am a syslog, too. But the previous syslog is an impostor!")); }); } /// @@ -2998,7 +3164,7 @@ public async Task T054_ApiFailsafeReadRuntimeGroups_Works() /// /// [Test] - public async Task T055_ApiChangePassword_Works() + public async Task T055_1_ApiChangePassword_Works() { var mockHttp = new MockHttpMessageHandler(); // Setup a respond for the user api (including a wildcard in the URL) @@ -3012,12 +3178,31 @@ public async Task T055_ApiChangePassword_Works() Assert.That(result.Result, "Changing passwords not possible!"); } + /// + /// TestCase for Api.ChangePassword + /// + /// + [Test] + public async Task T055_2_ApiChangePassword_RequestParam() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiChangePasswordAsync("Admin", "adminpw", "newadminpw", ApiAuthenticationMode.Umc); + Assert.That(result.Result, "Changing passwords not possible!"); + } + /// /// TestCase for Api.GetPasswordPolicy /// /// [Test] - public async Task T056_ApiGetPasswordPolicy_Works() + public async Task T056_1_ApiGetPasswordPolicy_Works() { var mockHttp = new MockHttpMessageHandler(); // Setup a respond for the user api (including a wildcard in the URL) @@ -3035,7 +3220,33 @@ public async Task T056_ApiGetPasswordPolicy_Works() expectedResult.Max_password_length = 120; expectedResult.Min_digits = 1; expectedResult.Min_special_characters = 0; - Assert.That(result.Result.Password_policy, Is.EqualTo(expectedResult), "Tickets for FilesCreate!"); + Assert.That(result.Result.Password_policy, Is.EqualTo(expectedResult)); + } + + /// + /// TestCase for Api.GetPasswordPolicy + /// + /// + [Test] + public async Task T056_2_ApiGetPasswordPolicy_RequestParam() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiGetPasswordPolicy); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ApiGetPasswordPolicyAsync(ApiAuthenticationMode.Umc); + var expectedResult = new ApiPasswordPolicy(); + expectedResult.Requires_lowercase_characters = true; + expectedResult.Requires_uppercase_characters = true; + expectedResult.Min_password_length = 8; + expectedResult.Max_password_length = 120; + expectedResult.Min_digits = 1; + expectedResult.Min_special_characters = 0; + Assert.That(result.Result.Password_policy, Is.EqualTo(expectedResult)); } /// @@ -3058,6 +3269,7 @@ public async Task T057_ApiGetAuthenticationMode_Works() expectedResult.Add(ApiAuthenticationMode.Local); expectedResult.Add(ApiAuthenticationMode.Static); expectedResult.Add(ApiAuthenticationMode.Disabled); + expectedResult.Add(ApiAuthenticationMode.Umc); Assert.That(result.Result.Authentication_modes.Count, Is.EqualTo(expectedResult.Count)); Assert.That(expectedResult.SequenceEqual(result.Result.Authentication_modes), "Order of authetication modes is different!"); } @@ -3067,12 +3279,12 @@ public async Task T057_ApiGetAuthenticationMode_Works() /// /// [Test] - public async Task T058_ProjectReadLanguages_Works() + public async Task T058_ProjectReadLanguages_Works_V31() { var mockHttp = new MockHttpMessageHandler(); // Setup a respond for the user api (including a wildcard in the URL) mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") - .Respond("application/json", ResponseStrings.ProjectReadLanguagesMany); // Respond with JSON + .Respond("application/json", ResponseStrings.ProjectReadLanguagesMany_V31); // Respond with JSON // Inject the handler or client into your application code var client = new HttpClient(mockHttp); client.BaseAddress = new Uri($"https://{Ip.ToString()}"); @@ -3087,6 +3299,47 @@ public async Task T058_ProjectReadLanguages_Works() Assert.That(expectedResult.SequenceEqual(result.Result.Languages.Select(x => x.Language)), "The order of languages are different, or they don't contain the same languages."); } + /// + /// TestCase for Project.ReadLanguages with 4 languages + /// + /// + [Test] + public async Task T058_ProjectReadLanguages_Works_V40() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ProjectReadLanguagesMany_V40); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = await TestHandler.ProjectReadLanguagesAsync(); + + var expectedResult1 = new ApiLanguage(); + expectedResult1.Active = true; + expectedResult1.Language = new CultureInfo("en-US"); + expectedResult1.User_interface_languages = new List(); + expectedResult1.User_interface_languages.Add(new CultureInfo("de-DE")); + expectedResult1.User_interface_languages.Add(new CultureInfo("en-US")); + expectedResult1.User_interface_languages.Add(new CultureInfo("fr-FR")); + + var expectedResult2 = new ApiLanguage(); + expectedResult2.Active = false; + expectedResult2.Language = new CultureInfo("ja-JP"); + expectedResult2.User_interface_languages = new List(); + + var exp = new List(); + exp.Add(expectedResult1); + exp.Add(expectedResult2); + + Assert.That(exp.Count, Is.EqualTo(result.Result.Languages.Count)); + for (int i = 0; i < 2; i++) + { + Assert.That(result.Result.Languages[i].Equals(exp[i])); + } + } + /// /// TestCase for Plc.ReadModeSelectorState with Standard PLC /// @@ -3161,7 +3414,7 @@ public async Task T061_ApiAlarmsAcknowledge_Works() client.BaseAddress = new Uri($"https://{Ip.ToString()}"); TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); var result = await TestHandler.AlarmsAcknowledgeAsync("/"); - Assert.That(result.Result); + Assert.That(result.Result, Is.EqualTo(true)); } /// /// TestCase for Plc.SetSystemTime @@ -3355,5 +3608,645 @@ public async Task T068_ApiDiagnosticBufferBrowse_Works() Assert.That(result.Language, Is.EqualTo("en-US")); }); } + + /// + /// TestCase for ApiGetSessionInfo method + /// + /// + [Test] + public void T069_ApiSessionInfo_FullResponseWorks() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiSessionInfoFullResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + + var result = TestHandler.ApiGetSessionInfo().Result; + Console.WriteLine(result.ToString()); + Assert.Multiple(() => + { + Assert.That(result.Username, Is.EqualTo("MyUser")); + Assert.That(result.Authentication_Mode, Is.EqualTo(ApiUserAuthenticationMode.Local)); + Assert.That(result.Runtime_Timeout, Is.EqualTo(new TimeSpan(0, 30, 0))); + Assert.That(result.Password_Expiration.Timestamp, Is.EqualTo(new DateTime(2012, 4, 23, 18, 25, 43))); + Assert.That(result.Password_Expiration.Warning, Is.EqualTo(true)); + }); + } + + /// + /// TestCase for ApiGetSessionInfo method + /// + /// + [Test] + public void T070_ApiSessionInfo_MinimumResponseWorks() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiSessionInfoMinimumResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + + var result = TestHandler.ApiGetSessionInfo().Result; + Assert.Multiple(() => + { + Assert.That(result.Username, Is.EqualTo("Anonymous")); + Assert.That(result.Authentication_Mode, Is.EqualTo(ApiUserAuthenticationMode.None)); + Assert.That(result.Password_Expiration, Is.Null); + Assert.That(result.Runtime_Timeout, Is.Null); + }); + } + + /// + /// TestCase for WebApp.SetVersion method + /// + /// + [Test] + public async Task T071_1_ApiWebAppSetVersion_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiWebAppSetVersionAsync("testApp", "V1.2")).Result; + Assert.That(result, Is.True); + } + + /// + /// TestCase for WebApp.SetVersion method + /// + /// + [Test] + public void T071_2_ApiWebAppSetVersion_ApplDoesNotExist_throwsExc() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.WebAppDoesNotExist); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebAppSetVersionAsync("apple", "V1.2")); + } + + /// + /// TestCase for WebApp.SetVersion method + /// + /// + [Test] + public void T071_3_ApiWebAppSetVersion_InvalidVersionString_throwsExc() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.InvalidVersionString); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebAppSetVersionAsync("testApp", "xy")); + } + + /// + /// TestCase for WebApp.SetUrlRedirectMode method + /// + /// + [Test] + public async Task T072_1_ApiWebAppSetUrlRedirectMode_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiWebAppSetUrlRedirectModeAsync("testApp", ApiWebAppRedirectMode.Redirect)).Result; + Assert.That(result, Is.True); + } + + /// + /// TestCase for WebApp.SetUrlRedirectMode method + /// + /// + [Test] + public void T072_2_ApiWebAppSetUrlRedirectMode_ApplDoesNotExist_throwsExc() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.WebAppDoesNotExist); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebAppSetUrlRedirectModeAsync("testApp", ApiWebAppRedirectMode.Redirect)); + } + + /// + /// TestCase for ApiPlcReadCpuType method + /// + /// + [Test] + public void T073_ApiPlcReadCpuType_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiPlcReadCpuTypeResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = TestHandler.ApiGetPlcCpuType().Result; + Assert.Multiple(() => + { + Assert.That(result.Product_Name, Is.EqualTo("CPU 1513F-1 PN")); + Assert.That(result.Order_Number, Is.EqualTo("6ES7 513-1FM03-0AB0")); + }); + } + + /// + /// TestCase for ApiPlcReadStationName method + /// + /// + [Test] + public void T074_ApiPlcReadStationName_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiPlcReadStationNameResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = TestHandler.ApiGetPlcStationName().Result; + Assert.That(result.Station_Name, Is.EqualTo("1513F")); + } + + /// + /// TestCase for ApiPlcReadModuleName method + /// + /// + [Test] + public void T075_ApiPlcReadModuleName_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.ApiPlcReadModuleNameResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = TestHandler.ApiGetPlcModuleName().Result; + Assert.That(result.Module_name, Is.EqualTo("1513F")); + } + + /// + /// TestCase for Redundancy.ReadSystemState method + /// + /// + [Test] + public async Task T076_1_ApiRedundancyReadSystemState_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RedundancyReadSystemStateResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyReadSystemStateAsync()).Result; + Assert.That(result.State, Is.EqualTo(ApiPlcRedundancySystemState.Run_redundant)); + } + + /// + /// TestCase for Redundancy.ReadSystemState method + /// + /// + [Test] + public void T076_2_ApiRedundancyReadSystemState_PermissionDenied() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PermissionDenied); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiRedundancyReadSystemStateAsync()); + } + + /// + /// TestCase for Redundancy.RequestChangeSystemState method + /// + /// + [Test] + public async Task T077_1_ApiRedundancyReadSystemState_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyRequestChangeSystemStateAsync(ApiPlcRedundancySystemState.Stop)).Result; + Assert.That(result, Is.True); + } + + /// + /// TestCase for Redundancy.RequestChangeSystemState method + /// + /// + [Test] + public void T077_2_ApiRedundancyReadSystemState_PermissionDenied() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PermissionDenied); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiRedundancyRequestChangeSystemStateAsync(ApiPlcRedundancySystemState.Stop)); + } + + /// + /// + /// + /// + [Test] + public async Task T078_01_TechnologyRead_BoolIsFalse_works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcProgramReadFalseBool); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var resp = await TestHandler.TechnologyReadAsync("\"DataTypes\".\"Bool\""); + if ((bool)resp.Result != false) + Assert.Fail("not casted to \"false\" bool!"); + } + + /// + /// + /// + /// + [Test] + public async Task T078_02_TechnologyRead_Array_works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PlcProgramReadRawFalseBool); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var resp = await TestHandler.TechnologyReadAsync("\"DataTypes\".\"Bool\""); + if (resp.Result is JArray) + { + var jarr = (JArray)resp.Result; + var respRes = jarr.ToObject>(); + if (respRes[0] != false) + Assert.Fail("not casted to \"false\" bool!"); + } + else + Assert.Fail("raw mode returned sth else than jarray: " + resp.Result.GetType().ToString()); + } + + /// + /// TestCase for Redundancy.ReadSystemInformation method + /// + [Test] + public async Task T079_1_ApiRedundancyReadSystemInformation_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RedundancyReadSystemInformationResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyReadSystemInformationAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Pairing_state, Is.EqualTo(ApiPlcRedundancyPairingState.Paired_single)); + Assert.That(result.Syncup_lock, Is.EqualTo(false)); + Assert.That((int)result.Connected_redundancy_id, Is.EqualTo(1)); + Assert.That(result.Standalone_operation, Is.EqualTo(false)); + + var plc_1 = result.Plcs.Plc_1; + Assert.That((int)plc_1.Redundancy_id, Is.EqualTo(1)); + Assert.That(plc_1.Role, Is.EqualTo(ApiPlcRedundancyRole.Backup)); + Assert.That(plc_1.Hwid, Is.EqualTo(65149)); + + var plc_2 = result.Plcs.Plc_2; + Assert.That((int)plc_2.Redundancy_id, Is.EqualTo(2)); + Assert.That(plc_2.Role, Is.EqualTo(ApiPlcRedundancyRole.Primary)); + Assert.That(plc_2.Hwid, Is.EqualTo(65349)); + }); + } + + /// + /// TestCase for Redundancy.ReadSystemInformation method + /// + [Test] + public void T079_2_ApiRedundancyReadSystemInformation_PermissionDenied() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.PermissionDenied); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiRedundancyReadSystemInformationAsync()); + } + + /// + /// + /// + /// + [Test] + public async Task T080_01_TechnologyBrowseObjects() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TechnologyBrowseObjectsResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var resp = await TestHandler.TechnologyBrowseObjectsAsync(); + var t1 = new ApiTechnologyObject() { Name = "Kinematics_1", Number = 2, Type = ApiTechnologyObjectType.To_Kinematics, Version = 6 }; + var t2 = new ApiTechnologyObject() { Name = "Int_1", Number = 3, Type = ApiTechnologyObjectType.To_Interpreter, Version = 5 }; + var exp = new List(); + exp.Add(t1); + exp.Add(t2); + + Assert.That(resp.Result.Objects.SequenceEqual(exp)); + + for (int i = 0; i < 2; i++) + { + Assert.That(resp.Result.Objects[i].Equals(exp[i])); + } + } + + /// + /// + /// + /// + [Test] + public async Task T080_02_TechnologyBrowseObjects_Empty() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TechnologyBrowseObjectsResponseEmpty); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var resp = await TestHandler.TechnologyBrowseObjectsAsync(); + Assert.That(!resp.Result.Objects.Any()); + } + + /// + /// TestCase for Redundancy.ReadSyncupProgress method + /// + /// + [Test] + public async Task T081_1_ApiRedundancyReadSyncupProgress_copying_work_memory() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RedundancyReadSyncupProgress_CopyingWorkMemoryResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyReadSyncupProgressAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Syncup_phase, Is.EqualTo(ApiRedundancySyncupPhase.Copying_work_memory)); + Assert.That(result.Copying_work_memory.Current, Is.EqualTo(1000)); + Assert.That(result.Copying_work_memory.Total, Is.EqualTo(100000)); + Assert.That(result.Copying_memory_card, Is.Null, "result.Copying_memory_card"); + Assert.That(result.Minimizing_delay, Is.Null, "result.Minimizing_delay"); + }); + } + + /// + /// TestCase for Redundancy.ReadSyncupProgress method + /// + /// + [Test] + public async Task T081_2_ApiRedundancyReadSyncupProgress_copying_memory_card() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RedundancyReadSyncupProgress_CopyingMemoryCardResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyReadSyncupProgressAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Syncup_phase, Is.EqualTo(ApiRedundancySyncupPhase.Copying_memory_card)); + Assert.That(result.Copying_memory_card.Current_filename, Is.EqualTo("/DataLogs/MyDataLog_1.csv"), "result.Copying_memory_card.Current"); + Assert.That(result.Copying_memory_card.Current, Is.EqualTo(17024)); + Assert.That(result.Copying_memory_card.Total, Is.EqualTo(2045000)); + Assert.That(result.Copying_work_memory, Is.Null, "result.Copying_work_memory"); + Assert.That(result.Minimizing_delay, Is.Null, "result.Minimizing_delay"); + }); + } + + /// + /// TestCase for Redundancy.ReadSyncupProgress method + /// + /// + [Test] + public async Task T081_3_ApiRedundancyReadSyncupProgress_minimizing_delay() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RedundancyReadSyncupProgress_MinimizingDelayResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiRedundancyReadSyncupProgressAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Syncup_phase, Is.EqualTo(ApiRedundancySyncupPhase.Minimizing_delay)); + Assert.That(result.Minimizing_delay.Hypothetical_cycle_time, Is.EqualTo(new TimeSpan(0, 0, 1)), "result.Minimizing_delay.Hypothetical_cycle_time"); + Assert.That(result.Minimizing_delay.Tolerable_cycle_time, Is.EqualTo(new TimeSpan(0, 0, 0, 0, 800)), "result.Minimizing_delay.Tolerable_cycle_time"); + Assert.That(result.Copying_work_memory, Is.Null, "result.Copying_work_memory"); + Assert.That(result.Copying_memory_card, Is.Null, "result.Copying_memory_card"); + }); + } + + /// + /// TestCase for WebServer.ReadResponseHeaders method + /// + /// + [Test] + public async Task T082_ApiWebServerReadResponseHeaders_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.WebServerReadResponseHeadersResponse); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiWebServerReadResponseHeadersAsync()).Result; + Assert.Multiple(() => + { + Assert.That(result.Configured_headers.Count, Is.EqualTo(1), "result.Configured_headers.Count"); + Assert.That(result.Allowed_headers.Count, Is.EqualTo(1), "result.Allowed_headers.Count"); + }); + Assert.Multiple(() => + { + Assert.That(result.Configured_headers[0].Pattern, Is.EqualTo("~**/*"), "result.Configured_headers[0].Pattern"); + Assert.That(result.Configured_headers[0].Header, Is.EqualTo("Content-Security-Policy: frame-ancestors *.somesite.com;"), "result.Configured_headers[0].Header"); + Assert.That(result.Allowed_headers[0].Pattern, Is.EqualTo("~**/*"), "result.Allowed_headers[0].Pattern"); + Assert.That(result.Allowed_headers[0].Key, Is.EqualTo("Content-Security-Policy"), "result.Allowed_headers[0].Key"); + }); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public async Task T083_1_ApiWebServerChangeResponseHeaders_Works() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TrueOnSuccess); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + var result = (await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")).Result; + Assert.That(result, Is.True); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public void T083_2_ApiWebServerChangeResponseHeaders_InvalidpatternException() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.InvalidPattern); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public void T083_3_ApiWebServerChangeResponseHeaders_HTTPHeaderNotAllowed() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.HTTPHeaderNotAllowed); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public void T083_4_ApiWebServerChangeResponseHeaders_HTTPHeaderNotAllowed() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.HTTPHeaderInvalid); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public void T083_5_ApiWebServerChangeResponseHeaders_TooManyHTTPHeaders() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.TooManyHTTPHeaders); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")); + } + + /// + /// TestCase for WebServer.ChangeResponseHeaders method + /// + [Test] + public void T083_6_ApiWebServerChangeResponseHeaders_RequestTooLarge() + { + var mockHttp = new MockHttpMessageHandler(); + // Setup a respond for the user api (including a wildcard in the URL) + mockHttp.When(HttpMethod.Post, $"https://{Ip.ToString()}/api/jsonrpc") + .Respond("application/json", ResponseStrings.RequestTooLarge); // Respond with JSON + // Inject the handler or client into your application code + var client = new HttpClient(mockHttp); + client.BaseAddress = new Uri($"https://{Ip.ToString()}"); + TestHandler = new ApiHttpClientRequestHandler(client, ApiRequestFactory, ApiResponseChecker); + Assert.ThrowsAsync(async () => await TestHandler.ApiWebServerChangeResponseHeadersAsync("this is the header")); + } } } diff --git a/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs b/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs index fdf545d..0c1d46a 100644 --- a/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs +++ b/tests/Webserver.API.UnitTests/ApiWebAppDataSaverTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; diff --git a/tests/Webserver.API.UnitTests/Base.cs b/tests/Webserver.API.UnitTests/Base.cs index 26e5a14..faaff15 100644 --- a/tests/Webserver.API.UnitTests/Base.cs +++ b/tests/Webserver.API.UnitTests/Base.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Siemens.Simatic.S7.Webserver.API.Services.Backup; diff --git a/tests/Webserver.API.UnitTests/EnumTests.cs b/tests/Webserver.API.UnitTests/EnumTests.cs index 3b102d1..2f82276 100644 --- a/tests/Webserver.API.UnitTests/EnumTests.cs +++ b/tests/Webserver.API.UnitTests/EnumTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/ExtensionTests.cs b/tests/Webserver.API.UnitTests/ExtensionTests.cs index 3dd8bbf..9635999 100644 --- a/tests/Webserver.API.UnitTests/ExtensionTests.cs +++ b/tests/Webserver.API.UnitTests/ExtensionTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/FileParserTests.cs b/tests/Webserver.API.UnitTests/FileParserTests.cs index 9337a7f..1c9dd4f 100644 --- a/tests/Webserver.API.UnitTests/FileParserTests.cs +++ b/tests/Webserver.API.UnitTests/FileParserTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using Newtonsoft.Json; @@ -80,7 +80,8 @@ public void ValidApplicationAsExpected() { Name = "validName", State = ApiWebAppState.Disabled, - Type = ApiWebAppType.User + Type = ApiWebAppType.User, + Redirect_mode = ApiWebAppRedirectMode.Redirect }; var serializedAppString = JsonConvert.SerializeObject(TypeApp); string fileName = "webappconfig.json"; diff --git a/tests/Webserver.API.UnitTests/IdGeneratorTests.cs b/tests/Webserver.API.UnitTests/IdGeneratorTests.cs index 32e0314..ee109f0 100644 --- a/tests/Webserver.API.UnitTests/IdGeneratorTests.cs +++ b/tests/Webserver.API.UnitTests/IdGeneratorTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/MIMETypeTests.cs b/tests/Webserver.API.UnitTests/MIMETypeTests.cs index fd1f40d..bfd0b68 100644 --- a/tests/Webserver.API.UnitTests/MIMETypeTests.cs +++ b/tests/Webserver.API.UnitTests/MIMETypeTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/ModelTests.cs b/tests/Webserver.API.UnitTests/ModelTests.cs index f692411..a3a5c2e 100644 --- a/tests/Webserver.API.UnitTests/ModelTests.cs +++ b/tests/Webserver.API.UnitTests/ModelTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/RequestFactoryTests.cs b/tests/Webserver.API.UnitTests/RequestFactoryTests.cs index ad25820..e121cf5 100644 --- a/tests/Webserver.API.UnitTests/RequestFactoryTests.cs +++ b/tests/Webserver.API.UnitTests/RequestFactoryTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs b/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs index 546c678..940f8e0 100644 --- a/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs +++ b/tests/Webserver.API.UnitTests/RequestParameterCheckerTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; @@ -156,21 +156,21 @@ public void CheckPlcProgramBrowseMode() public void CheckPlcProgramReadOrWriteMode() { var requestParameterChecker = new ApiRequestParameterChecker(); - List invModes = new List() { - ApiPlcProgramReadOrWriteMode.None + List invModes = new List() { + ApiPlcDataRepresentation.None }; foreach (var mode in invModes) { Assert.Throws(() => - requestParameterChecker.CheckPlcProgramReadOrWriteMode(mode, true)); - requestParameterChecker.CheckPlcProgramReadOrWriteMode(mode, false); + requestParameterChecker.CheckPlcDataRepresentationMode(mode, true)); + requestParameterChecker.CheckPlcDataRepresentationMode(mode, false); } - List validModes = new List() - { ApiPlcProgramReadOrWriteMode.Raw, ApiPlcProgramReadOrWriteMode.Simple, null }; + List validModes = new List() + { ApiPlcDataRepresentation.Raw, ApiPlcDataRepresentation.Simple, null }; foreach (var mode in validModes) { - requestParameterChecker.CheckPlcProgramReadOrWriteMode(mode, true); - requestParameterChecker.CheckPlcProgramReadOrWriteMode(mode, false); + requestParameterChecker.CheckPlcDataRepresentationMode(mode, true); + requestParameterChecker.CheckPlcDataRepresentationMode(mode, false); } } @@ -260,7 +260,7 @@ public void CheckUsername() var requestParameterChecker = new ApiRequestParameterChecker(); Assert.Throws(() => requestParameterChecker.CheckUsername("", true)); - Assert.Throws(() => + Assert.Throws(() => requestParameterChecker.CheckUsername("Anonymous", true)); } diff --git a/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs b/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs index b3f142b..8333ad1 100644 --- a/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs +++ b/tests/Webserver.API.UnitTests/ResponseCheckerTest.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT using NUnit.Framework; diff --git a/tests/Webserver.API.UnitTests/ResponseStrings.cs b/tests/Webserver.API.UnitTests/ResponseStrings.cs index e5e423c..fb8628e 100644 --- a/tests/Webserver.API.UnitTests/ResponseStrings.cs +++ b/tests/Webserver.API.UnitTests/ResponseStrings.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2023, Siemens AG +// Copyright (c) 2024, Siemens AG // // SPDX-License-Identifier: MIT @@ -19,7 +19,7 @@ public static class ResponseStrings public const string TrueOnSuccess = "{\"jsonrpc\":\"2.0\",\"id\":\"y9vz5kb9\",\"result\":true}"; - public const string ApiGetAuthenticationModeMany = "{\"jsonrpc\":\"2.0\",\"id\":\"eebdd95f-96ed-418e-bd41-785056c4d016\",\"result\":{\"authentication_modes\":[\"local\",\"static\",\"disabled\"]}}"; + public const string ApiGetAuthenticationModeMany = "{\"jsonrpc\":\"2.0\",\"id\":\"eebdd95f-96ed-418e-bd41-785056c4d016\",\"result\":{\"authentication_modes\":[\"local\",\"static\",\"disabled\",\"umc\"]}}"; public const string CertificateUrl = "{\"jsonrpc\":\"2.0\",\"id\":\"rgkz2p1k\",\"result\":\"/MiniWebCA_Cer.crt\"}"; @@ -40,7 +40,9 @@ public static class ResponseStrings public const string NoResources = "{\"jsonrpc\":\"2.0\",\"id\":\"d6jhjsjq\",\"error\":{\"code\":4,\"message\":\"No Resources\"}}"; - public const string ProjectReadLanguagesMany = "{\"jsonrpc\":\"2.0\",\"id\":\"5f95240c-8a3e-4c03-b34d-a2d5ee4582d4\",\"result\":{\"languages\":[{\"language\":\"en-US\"},{\"language\":\"en-GB\"},{\"language\":\"es-BR\"},{\"language\":\"ne-IN\"}]}}"; + public const string ProjectReadLanguagesMany_V31 = "{\"jsonrpc\":\"2.0\",\"id\":\"5f95240c-8a3e-4c03-b34d-a2d5ee4582d4\",\"result\":{\"languages\":[{\"language\":\"en-US\"},{\"language\":\"en-GB\"},{\"language\":\"es-BR\"},{\"language\":\"ne-IN\"}]}}"; + public const string ProjectReadLanguagesOne_V40 = "{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"languages\":[{\"language\":\"en-US\",\"active\":true,\"user_interface_languages\":[\"de-DE\",\"en-US\",\"fr-FR\",\"es-ES\",\"it-IT\",\"ja-JP\",\"zh-CN\",\"ko-KR\",\"ru-RU\",\"tr-TR\",\"pt-BR\"]}]}}"; + public const string ProjectReadLanguagesMany_V40 = "{\"jsonrpc\":\"2.0\",\"id\":3,\"result\":{\"languages\":[{\"language\":\"en-US\",\"active\":true,\"user_interface_languages\":[\"de-DE\",\"en-US\",\"fr-FR\"]},{\"language\":\"ja-JP\",\"active\":false,\"user_interface_languages\":[]}]}}"; public const string PlcProgramBrowseAll = "{\"jsonrpc\":\"2.0\",\"id\":\"jc0qvjz4\",\"result\":[{\"name\":\"TRACE_DB\",\"has_children\":true,\"db_number\":4710,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE1\",\"has_children\":true,\"db_number\":13,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE1\",\"has_children\":true,\"db_number\":8,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE1\",\"has_children\":true,\"db_number\":14,\"datatype\":\"datablock\"},{\"name\":\"DataLogCreate_DB_MODE2\",\"has_children\":true,\"db_number\":7,\"datatype\":\"datablock\"},{\"name\":\"DataLogOpen_DB_MODE2\",\"has_children\":true,\"db_number\":20,\"datatype\":\"datablock\"},{\"name\":\"DataLogWrite_DB_MODE2\",\"has_children\":true,\"db_number\":6,\"datatype\":\"datablock\"},{\"name\":\"DataLogClose_DB_MODE2\",\"has_children\":true,\"db_number\":21,\"datatype\":\"datablock\"},{\"name\":\"DataLogDelete_DB_MODE2\",\"has_children\":true,\"db_number\":9,\"datatype\":\"datablock\"},{\"name\":\"DataLogsDB\",\"has_children\":true,\"db_number\":12,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_DB\",\"has_children\":true,\"db_number\":11,\"datatype\":\"datablock\"},{\"name\":\"OptionHandling_ET200_DB\",\"has_children\":true,\"db_number\":16,\"datatype\":\"datablock\"},{\"name\":\"TRACE_INIT_DB\",\"has_children\":true,\"db_number\":27,\"datatype\":\"datablock\"},{\"name\":\"DataTypesInstance\",\"has_children\":true,\"db_number\":3,\"datatype\":\"datablock\"},{\"name\":\"Alarms_DB\",\"has_children\":true,\"db_number\":10,\"datatype\":\"datablock\"},{\"name\":\"Get_Name_DB\",\"has_children\":true,\"db_number\":5,\"datatype\":\"datablock\"},{\"name\":\"DataTypes\",\"has_children\":true,\"db_number\":1,\"datatype\":\"datablock\"},{\"name\":\"DataTypesClassic\",\"has_children\":true,\"db_number\":2,\"datatype\":\"datablock\"},{\"name\":\"SpecialVariables\",\"has_children\":true,\"db_number\":4,\"datatype\":\"datablock\"},{\"name\":\"DB 333\",\"has_children\":true,\"db_number\":333,\"datatype\":\"datablock\"},{\"name\":\"Main_Safety_RTG1_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":15,\"datatype\":\"datablock\"},{\"name\":\"F_SystemInfo_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30001,\"datatype\":\"datablock\"},{\"name\":\"RTG1SysInfo\",\"read_only\":true,\"has_children\":true,\"db_number\":30000,\"datatype\":\"datablock\"},{\"name\":\"RTG2SysInfo\",\"read_only\":true,\"has_children\":true,\"db_number\":30002,\"datatype\":\"datablock\"},{\"name\":\"DB15_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30003,\"datatype\":\"datablock\"},{\"name\":\"DB17_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30004,\"datatype\":\"datablock\"},{\"name\":\"FB32770_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30005,\"datatype\":\"datablock\"},{\"name\":\"FB32770_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30006,\"datatype\":\"datablock\"},{\"name\":\"FB32771_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30007,\"datatype\":\"datablock\"},{\"name\":\"FB32771_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30008,\"datatype\":\"datablock\"},{\"name\":\"FB32772_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30009,\"datatype\":\"datablock\"},{\"name\":\"FB32772_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30010,\"datatype\":\"datablock\"},{\"name\":\"FB32773_IDB_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30011,\"datatype\":\"datablock\"},{\"name\":\"FB32773_IDB2_C\",\"read_only\":true,\"has_children\":true,\"db_number\":30012,\"datatype\":\"datablock\"},{\"name\":\"FOB_RTG1_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30013,\"datatype\":\"datablock\"},{\"name\":\"FB6_C_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30014,\"datatype\":\"datablock\"},{\"name\":\"FOB_RTG2_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30015,\"datatype\":\"datablock\"},{\"name\":\"FB0_C_GCTX_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":30016,\"datatype\":\"datablock\"},{\"name\":\"Main_Safety_RTG2_DB\",\"read_only\":true,\"has_children\":true,\"db_number\":17,\"datatype\":\"datablock\"},{\"name\":\"Clock_Byte\",\"address\":\"%MB0\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Clock_10Hz\",\"address\":\"%M0.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_5Hz\",\"address\":\"%M0.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2.5Hz\",\"address\":\"%M0.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_2Hz\",\"address\":\"%M0.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1.25Hz\",\"address\":\"%M0.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_1Hz\",\"address\":\"%M0.5\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.625Hz\",\"address\":\"%M0.6\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Clock_0.5Hz\",\"address\":\"%M0.7\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"FirstScan\",\"address\":\"%M1.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"DiagStatusUpdate\",\"address\":\"%M1.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"RET_VAL\",\"address\":\"%MW333\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"WWW_Ret\",\"address\":\"%MW334\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"AlwaysTRUE\",\"address\":\"%M1.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"AlwaysFALSE\",\"address\":\"%M1.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Bool\",\"address\":\"%M200.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Byte\",\"address\":\"%MB201\",\"area\":\"M\",\"datatype\":\"byte\"},{\"name\":\"Char\",\"address\":\"%MB202\",\"area\":\"M\",\"datatype\":\"char\"},{\"name\":\"Date\",\"address\":\"%MW203\",\"area\":\"M\",\"datatype\":\"date\"},{\"name\":\"DInt\",\"address\":\"%MD205\",\"area\":\"M\",\"datatype\":\"dint\"},{\"name\":\"DWord\",\"address\":\"%MD209\",\"area\":\"M\",\"datatype\":\"dword\"},{\"name\":\"Int\",\"address\":\"%MW213\",\"area\":\"M\",\"datatype\":\"int\"},{\"name\":\"LDT\",\"address\":\"P#M215.0\",\"area\":\"M\",\"datatype\":\"ldt\"},{\"name\":\"LInt\",\"address\":\"P#M223.0\",\"area\":\"M\",\"datatype\":\"lint\"},{\"name\":\"LReal\",\"address\":\"P#M231.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"LTime\",\"address\":\"P#M239.0\",\"area\":\"M\",\"datatype\":\"ltime\"},{\"name\":\"LTime_Of_Day\",\"address\":\"P#M247.0\",\"area\":\"M\",\"datatype\":\"ltime_of_day\"},{\"name\":\"LWord\",\"address\":\"P#M255.0\",\"area\":\"M\",\"datatype\":\"lword\"},{\"name\":\"Real\",\"address\":\"%MD263\",\"area\":\"M\",\"datatype\":\"real\"},{\"name\":\"S5Time\",\"address\":\"%MW267\",\"area\":\"M\",\"datatype\":\"s5time\"},{\"name\":\"SInt\",\"address\":\"%MB269\",\"area\":\"M\",\"datatype\":\"sint\"},{\"name\":\"Time\",\"address\":\"%MD270\",\"area\":\"M\",\"datatype\":\"time\"},{\"name\":\"Time_Of_Day\",\"address\":\"%MD274\",\"area\":\"M\",\"datatype\":\"time_of_day\"},{\"name\":\"UDInt\",\"address\":\"%MD278\",\"area\":\"M\",\"datatype\":\"udint\"},{\"name\":\"UInt\",\"address\":\"%MW282\",\"area\":\"M\",\"datatype\":\"uint\"},{\"name\":\"ULInt\",\"address\":\"P#M284.0\",\"area\":\"M\",\"datatype\":\"ulint\"},{\"name\":\"USInt\",\"address\":\"%MB292\",\"area\":\"M\",\"datatype\":\"usint\"},{\"name\":\"WChar\",\"address\":\"%MW293\",\"area\":\"M\",\"datatype\":\"wchar\"},{\"name\":\"Word\",\"address\":\"%MW295\",\"area\":\"M\",\"datatype\":\"word\"},{\"name\":\"Merker\",\"address\":\"%M100.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length20 10000000001\",\"address\":\"%M300.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length50 10000000001000000000100000000010000000001\",\"address\":\"%M300.1\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"Length100 000000000100000000010000000001000000000100000000010000000001000000000100000000010000000001\",\"address\":\"%M300.2\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"MiXeDcAsEs\",\"address\":\"%M300.3\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"?=)(/&%$§!°ß0987654321^+*#-_.:,;<>\",\"address\":\"%M300.4\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_speed\",\"address\":\"P#M310.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_override\",\"address\":\"%M318.0\",\"area\":\"M\",\"datatype\":\"bool\"},{\"name\":\"turbine_max_speed\",\"address\":\"P#M336.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_acceleration\",\"address\":\"P#M344.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_max_jerk\",\"address\":\"P#M352.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbineNumber\",\"address\":\"P#M360.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"turbine_speed_sp\",\"address\":\"P#M368.0\",\"area\":\"M\",\"datatype\":\"lreal\"},{\"name\":\"IBool\",\"address\":\"%I100.0\",\"area\":\"I\",\"datatype\":\"bool\"},{\"name\":\"IByte\",\"address\":\"%IB101\",\"area\":\"I\",\"datatype\":\"byte\"},{\"name\":\"IWord\",\"address\":\"%IW102\",\"area\":\"I\",\"datatype\":\"word\"},{\"name\":\"IDWord\",\"address\":\"%ID104\",\"area\":\"I\",\"datatype\":\"dword\"},{\"name\":\"IInt\",\"address\":\"%IW108\",\"area\":\"I\",\"datatype\":\"int\"},{\"name\":\"QBool\",\"address\":\"%Q100.0\",\"area\":\"Q\",\"datatype\":\"bool\"},{\"name\":\"QByte\",\"address\":\"%QB101\",\"area\":\"Q\",\"datatype\":\"byte\"},{\"name\":\"QWord\",\"address\":\"%QW102\",\"area\":\"Q\",\"datatype\":\"word\"},{\"name\":\"QDWord\",\"address\":\"%QD104\",\"area\":\"Q\",\"datatype\":\"dword\"},{\"name\":\"QInt\",\"address\":\"%QW108\",\"area\":\"Q\",\"datatype\":\"int\"},{\"name\":\"Timer\",\"address\":\"%T0\",\"area\":\"T\",\"datatype\":\"s5time\"},{\"name\":\"Counter\",\"address\":\"%C0\",\"area\":\"C\",\"datatype\":\"word\"}]}"; public const string PlcProgramBrowseDataTypes = "{\"jsonrpc\":\"2.0\",\"id\":\"h4sxre28\",\"result\":[{\"name\":\"Bool\",\"db_number\":1,\"datatype\":\"bool\"},{\"name\":\"Byte\",\"db_number\":1,\"datatype\":\"byte\"},{\"name\":\"Char\",\"db_number\":1,\"datatype\":\"char\"},{\"name\":\"DInt\",\"db_number\":1,\"datatype\":\"dint\"},{\"name\":\"DWord\",\"db_number\":1,\"datatype\":\"dword\"},{\"name\":\"Date\",\"db_number\":1,\"datatype\":\"date\"},{\"name\":\"Int\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"LInt\",\"db_number\":1,\"datatype\":\"lint\"},{\"name\":\"LReal\",\"db_number\":1,\"datatype\":\"lreal\"},{\"name\":\"LTime\",\"db_number\":1,\"datatype\":\"ltime\"},{\"name\":\"LWord\",\"db_number\":1,\"datatype\":\"lword\"},{\"name\":\"Real\",\"db_number\":1,\"datatype\":\"real\"},{\"name\":\"String\",\"db_number\":1,\"max_length\":254,\"datatype\":\"string\"},{\"name\":\"Time\",\"db_number\":1,\"datatype\":\"time\"},{\"name\":\"UDInt\",\"db_number\":1,\"datatype\":\"udint\"},{\"name\":\"UInt\",\"db_number\":1,\"datatype\":\"uint\"},{\"name\":\"ULInt\",\"db_number\":1,\"datatype\":\"ulint\"},{\"name\":\"USInt\",\"db_number\":1,\"datatype\":\"usint\"},{\"name\":\"WChar\",\"db_number\":1,\"datatype\":\"wchar\"},{\"name\":\"WString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"wstring\"},{\"name\":\"Word\",\"db_number\":1,\"datatype\":\"word\"},{\"name\":\"AOM_IDENT\",\"db_number\":1,\"datatype\":\"aom_ident\"},{\"name\":\"ArrayBool\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"CONN_ANY\",\"db_number\":1,\"datatype\":\"conn_any\"},{\"name\":\"CONN_OUC\",\"db_number\":1,\"datatype\":\"conn_ouc\"},{\"name\":\"CONN_PRG\",\"db_number\":1,\"datatype\":\"conn_prg\"},{\"name\":\"CONN_R_ID\",\"db_number\":1,\"datatype\":\"conn_r_id\"},{\"name\":\"CREF\",\"has_children\":true,\"db_number\":1,\"datatype\":\"cref\"},{\"name\":\"DB_ANY\",\"db_number\":1,\"datatype\":\"db_any\"},{\"name\":\"DB_DYN\",\"db_number\":1,\"datatype\":\"db_dyn\"},{\"name\":\"DB_WWW\",\"db_number\":1,\"datatype\":\"db_www\"},{\"name\":\"Date_And_Time\",\"db_number\":1,\"datatype\":\"date_and_time\"},{\"name\":\"EVENT_ANY\",\"db_number\":1,\"datatype\":\"event_any\"},{\"name\":\"EVENT_ATT\",\"db_number\":1,\"datatype\":\"event_att\"},{\"name\":\"EVENT_HWINT\",\"db_number\":1,\"datatype\":\"event_hwint\"},{\"name\":\"ErrorStruct\",\"has_children\":true,\"db_number\":1,\"datatype\":\"error_struct\"},{\"name\":\"HW_ANY\",\"db_number\":1,\"datatype\":\"hw_any\"},{\"name\":\"HW_DEVICE\",\"db_number\":1,\"datatype\":\"hw_device\"},{\"name\":\"HW_DPMASTER\",\"db_number\":1,\"datatype\":\"hw_dpmaster\"},{\"name\":\"HW_DPSLAVE\",\"db_number\":1,\"datatype\":\"hw_dpslave\"},{\"name\":\"HW_HSC\",\"db_number\":1,\"datatype\":\"hw_hsc\"},{\"name\":\"HW_IEPORT\",\"db_number\":1,\"datatype\":\"hw_ieport\"},{\"name\":\"HW_INTERFACE\",\"db_number\":1,\"datatype\":\"hw_interface\"},{\"name\":\"HW_IO\",\"db_number\":1,\"datatype\":\"hw_io\"},{\"name\":\"HW_IOSYSTEM\",\"db_number\":1,\"datatype\":\"hw_iosystem\"},{\"name\":\"HW_MODULE\",\"db_number\":1,\"datatype\":\"hw_module\"},{\"name\":\"HW_PTO\",\"db_number\":1,\"datatype\":\"hw_pto\"},{\"name\":\"HW_PWM\",\"db_number\":1,\"datatype\":\"hw_pwm\"},{\"name\":\"HW_SUBMODULE\",\"db_number\":1,\"datatype\":\"hw_submodule\"},{\"name\":\"IEC_COUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_counter\"},{\"name\":\"IEC_DCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_dcounter\"},{\"name\":\"IEC_LCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_lcounter\"},{\"name\":\"IEC_LTIMER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ltimer\"},{\"name\":\"IEC_SCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_scounter\"},{\"name\":\"IEC_TIMER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_timer\"},{\"name\":\"IEC_UCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ucounter\"},{\"name\":\"IEC_UDCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_udcounter\"},{\"name\":\"IEC_ULCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_ulcounter\"},{\"name\":\"IEC_USCOUNTER\",\"has_children\":true,\"db_number\":1,\"datatype\":\"iec_uscounter\"},{\"name\":\"LDT\",\"db_number\":1,\"datatype\":\"ldt\"},{\"name\":\"NREF\",\"has_children\":true,\"db_number\":1,\"datatype\":\"nref\"},{\"name\":\"OB_ANY\",\"db_number\":1,\"datatype\":\"ob_any\"},{\"name\":\"OB_ATT\",\"db_number\":1,\"datatype\":\"ob_att\"},{\"name\":\"OB_CYCLIC\",\"db_number\":1,\"datatype\":\"ob_cyclic\"},{\"name\":\"OB_DELAY\",\"db_number\":1,\"datatype\":\"ob_delay\"},{\"name\":\"OB_DIAG\",\"db_number\":1,\"datatype\":\"ob_diag\"},{\"name\":\"OB_HWINT\",\"db_number\":1,\"datatype\":\"ob_hwint\"},{\"name\":\"OB_PCYCLE\",\"db_number\":1,\"datatype\":\"ob_pcycle\"},{\"name\":\"OB_STARTUP\",\"db_number\":1,\"datatype\":\"ob_startup\"},{\"name\":\"OB_TIMEERROR\",\"db_number\":1,\"datatype\":\"ob_timeerror\"},{\"name\":\"OB_TOD\",\"db_number\":1,\"datatype\":\"ob_tod\"},{\"name\":\"PIP\",\"db_number\":1,\"datatype\":\"pip\"},{\"name\":\"PORT\",\"db_number\":1,\"datatype\":\"port\"},{\"name\":\"RTM\",\"db_number\":1,\"datatype\":\"rtm_id\"},{\"name\":\"S5Time\",\"db_number\":1,\"datatype\":\"s5time\"},{\"name\":\"SInt\",\"db_number\":1,\"datatype\":\"sint\"},{\"name\":\"Struct1L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Time_Of_Day\",\"db_number\":1,\"datatype\":\"time_of_day\"},{\"name\":\"LTime_Of_Day\",\"db_number\":1,\"datatype\":\"ltime_of_day\"},{\"name\":\"DTL\",\"has_children\":true,\"db_number\":1,\"datatype\":\"dtl\"},{\"name\":\"ArrayChar\",\"db_number\":1,\"datatype\":\"char\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayInt\",\"db_number\":1,\"datatype\":\"int\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayReal\",\"db_number\":1,\"datatype\":\"real\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"string\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayNeg\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":-1,\"count\":3}]},{\"name\":\"Struct2L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct3L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct4L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"Struct5L\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"ArrayTest\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"Enum1\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"Enum2\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"Enum3\",\"db_number\":1,\"datatype\":\"int\"},{\"name\":\"ArrayMax\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":20000}]},{\"name\":\"ArrayMulti\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":2},{\"start_index\":0,\"count\":2}]},{\"name\":\"StructArray\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"StructDataTypes\",\"has_children\":true,\"db_number\":1,\"datatype\":\"struct\"},{\"name\":\"ArrayDate\",\"db_number\":1,\"datatype\":\"date\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayDateAndTime\",\"db_number\":1,\"datatype\":\"date_and_time\",\"array_dimensions\":[{\"start_index\":0,\"count\":2}]},{\"name\":\"ArrayWord\",\"db_number\":1,\"datatype\":\"word\",\"array_dimensions\":[{\"start_index\":0,\"count\":4}]},{\"name\":\"ArrayWString\",\"db_number\":1,\"max_length\":254,\"datatype\":\"wstring\",\"array_dimensions\":[{\"start_index\":0,\"count\":3}]},{\"name\":\"ArrayMultiBigger\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":7},{\"start_index\":0,\"count\":7}]},{\"name\":\"ArrayBoolSeven\",\"db_number\":1,\"datatype\":\"bool\",\"array_dimensions\":[{\"start_index\":0,\"count\":7}]}]}"; @@ -70,9 +72,13 @@ public static class ResponseStrings public const string PlcReadOpModeStop = "{\"jsonrpc\":\"2.0\",\"id\":\"aofv3yj\",\"result\":\"stop\"}"; public const string PlcReadOpModeRun = "{\"jsonrpc\":\"2.0\",\"id\":\"i9zb7voq\",\"result\":\"run\"}"; + public const string PlcReadOpModeRunRedundant = "{\"jsonrpc\":\"2.0\",\"id\":\"i9zb7voq\",\"result\":\"run_redundant\"}"; + public const string PlcReadOpModeSyncup = "{\"jsonrpc\":\"2.0\",\"id\":\"i9zb7voq\",\"result\":\"syncup\"}"; public const string PlcReadOpModeStartup = "{\"jsonrpc\":\"2.0\",\"id\":\"a9zr5voc\",\"result\":\"startup\"}"; public const string PlcReadOpModeHold = "{\"jsonrpc\":\"2.0\",\"id\":\"a2zy1var\",\"result\":\"hold\"}"; public const string PlcReadOpModeStopFwUpdate = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"stop_fwupdate\"}"; + public const string PlcReadOpModeRunSyncup = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"run_syncup\"}"; + public const string PlcReadOpModeRemoteUnknown = "{\"jsonrpc\":\"2.0\",\"id\":\"z2fq1haj\",\"result\":\"remote_unknown\"}"; public const string PlcReadSystemTime = "{\"jsonrpc\":\"2.0\",\"id\":\"hqrs30u\",\"result\":{\"timestamp\":\"2022-03-01T17:02:04.23829595Z\"}}"; public const string PlcReadTimeSettings = "{\"jsonrpc\":\"2.0\",\"id\":\"ya3ih0h\",\"result\":{\"current_offset\":\"PT0H\",\"utc_offset\":\"PT0H\",\"rule\":{\"std\":{\"start\":{\"minute\":0,\"hour\":2,\"day_of_week\":\"sun\",\"week\":5,\"month\":10}},\"dst\":{\"offset\":\"PT1H\",\"start\":{\"minute\":0,\"hour\":1,\"day_of_week\":\"sun\",\"week\":5,\"month\":3}}}}}"; @@ -109,7 +115,7 @@ public static class ResponseStrings public const string WebAppAlreadyExists = "{\"jsonrpc\":\"2.0\",\"id\":\"f7dyz7hm\",\"error\":{\"code\":500,\"message\":\"Application name already exists\"}}"; public const string WebAppLimitReached = "{\"jsonrpc\":\"2.0\",\"id\":\"nayr44k2r\",\"error\":{\"code\":502,\"message\":\"Application limit reached\"}}"; - public const string WebAppBrowse = "{\"jsonrpc\":\"2.0\",\"id\":\"b1criaj9\",\"result\":{\"max_applications\":4,\"applications\":[{\"name\":\"customerExampleManualAdjusted\",\"state\":\"enabled\",\"type\":\"user\",\"default_page\":\"index.html\",\"not_authorized_page\":\"login.html\"},{\"name\":\"anotherWebApp\",\"state\":\"enabled\",\"type\":\"user\",\"default_page\":\"index.html2\",\"not_found_page\":\"index.html1\",\"not_authorized_page\":\"index.html\"}]}}"; + public const string WebAppBrowse = "{\"jsonrpc\":\"2.0\",\"id\":\"b1criaj9\",\"result\":{\"max_applications\":4,\"applications\":[{\"name\":\"customerExampleManualAdjusted\",\"state\":\"enabled\",\"type\":\"user\",\"version\":\"V1.2\",\"redirect_mode\":\"redirect\",\"default_page\":\"index.html\",\"not_found_page\":\"index2.html\",\"not_authorized_page\":\"login.html\"},{\"name\":\"anotherWebApp\",\"state\":\"enabled\",\"type\":\"user\",\"default_page\":\"index.html2\",\"not_found_page\":\"index.html1\",\"not_authorized_page\":\"index.html\"}]}}"; public const string WebAppDoesNotExist = "{\"jsonrpc\":\"2.0\",\"id\":\"w1y410f\",\"error\":{\"code\":501,\"message\":\"Application does not exist\"}}"; @@ -148,5 +154,41 @@ public static class ResponseStrings public const string ApiAlarmsBrowseResponse = "{\"jsonrpc\": \"2.0\",\"id\": 4,\"result\": {\"entries\": [{\"id\": 9947888669857743000,\"alarm_number\": 512,\"status\": \"incoming\",\"timestamp\": \"2012-01-01T01:01:42.047Z\",\"origin\": \"program_alarm\",\"acknowledgement\": {\"state\": \"not_acknowledged\"},\"alarm_text\": \"#1, 1\",\"info_text\": \"#1, 0\",\"text_inconsistent\": false},{\"id\": 9947888669857808000,\"alarm_number\": 513,\"status\": \"incoming\",\"timestamp\": \"2012-01-01T01:01:42.048Z\",\"origin\": \"program_alarm\",\"alarm_text\": \"#2, 1\",\"info_text\": \"#2, 0\",\"text_inconsistent\": false}],\"last_modified\": \"2012-01-01T01:01:42.099Z\",\"count_current\": 51,\"count_max\": 500,\"language\": \"en-US\"}}"; public const string DiagnosticBufferBrowseResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"entries\":[{\"timestamp\": \"2012-04-23T18:25:43.511854547Z\",\"status\": \"outgoing\",\"long_text\": \"CPU info: Boot up memory card type: Program card (external load memory) CPU changes from OFF to STOP (initialization) mode PLC_2 / PLC_2\",\"short_text\": \"Boot up - CPU changes from OFF to STOP (initialization) mode\",\"event\":{\"textlist_id\": 2,\"text_id\": 16385}},{\"timestamp\": \"2023-06-07T18:25:43.511854547Z\",\"status\": \"incoming\",\"long_text\": \"LONG TEXT\",\"short_text\": \"SHORT TEXT\",\"help_text\": \"HELP TEXT\",\"event\":{\"textlist_id\": 3,\"text_id\": 26315}}],\"last_modified\": \"2023-06-07T18:25:43.514678531Z\",\"count_current\": 1234,\"count_max\": 3200,\"language\": \"en-US\"}}"; + + public const string LoginFailedInfrastructureError = "{\"jsonrpc\":\"2.0\",\"id\":\"a36jhe04\",\"error\":{\"code\":105,\"message\":\"Authentication on the UMC server was not successful.\"}}"; + public const string WebServerReadResponseHeadersResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"configured_headers\":[{\"pattern\": \"~**/*\",\"header\": \"Content-Security-Policy: frame-ancestors *.somesite.com;\"}],\"allowed_headers\":[{\"pattern\": \"~**/*\",\"key\": \"Content-Security-Policy\"}]}}"; + + public const string InvalidPattern = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":1301,\"message\":\"The provided pattern is not in the allowed list. The user can choose a pattern that is allowed to be configured.\"}}"; + + public const string HTTPHeaderNotAllowed = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":1302,\"message\":\"At least one of the provided HTTP headers is not part in the allowed list. The user can choose a HTTP header that is allowed to be set.\"}}"; + + public const string HTTPHeaderInvalid = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":1303,\"message\":\"At least one of the provided HTTP headers represents an invalid HTTP header. The user shall verify the provided HTTP header string and correct it as required.\"}}"; + + public const string TooManyHTTPHeaders = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":1304,\"message\":\"Too many HTTP response headers are configured by the user. The user shall reduce the number to a supported number of headers. The number is currently capped at 1.\"}}"; + + public const string RequestTooLarge = "{\"jsonrpc\":\"2.0\",\"id\":\"j8higif\",\"error\":{\"code\":1305,\"message\":\"The overall size of all HTTP headers requested to be configured is too large. The user shall either reduce the number of headers or the length of an individual HTTP header.\"}}"; + public const string RedundancyReadSyncupProgress_CopyingWorkMemoryResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"syncup_phase\": \"copying_work_memory\",\"copying_work_memory\":{\"current\": 1000,\"total\": 100000}}}"; + + public const string RedundancyReadSyncupProgress_CopyingMemoryCardResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"syncup_phase\": \"copying_memory_card\",\"copying_memory_card\":{\"current_filename\": \"/DataLogs/MyDataLog_1.csv\",\"current\": 17024,\"total\": 2045000}}}"; + + public const string RedundancyReadSyncupProgress_MinimizingDelayResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"syncup_phase\": \"minimizing_delay\",\"minimizing_delay\":{\"hypothetical_cycle_time\": \"PT1S\",\"tolerable_cycle_time\": \"PT0.800S\"}}}"; + public const string EmptyResult = "{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":[]}"; + public const string TechnologyBrowseObjectsResponse = "{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":{\"objects\":[{\"number\":2,\"name\":\"Kinematics_1\",\"type\":\"to_kinematics\",\"version\":6},{\"number\":3,\"name\":\"Int_1\",\"type\":\"to_interpreter\",\"version\":5}]}}"; + public const string TechnologyBrowseObjectsResponseEmpty = "{\"jsonrpc\":\"2.0\",\"id\":2,\"result\":{\"objects\":[]}}"; + public const string RedundancyReadSystemInformationResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"pairing_state\": \"paired_single\",\"syncup_lock\": false,\"connected_redundancy_id\": 1,\"standalone_operation\": false,\"plcs\":{\"plc_1\":{\"redundancy_id\": 1,\"role\": \"backup\",\"hwid\": 65149},\"plc_2\":{\"redundancy_id\": 2,\"role\": \"primary\",\"hwid\": 65349}}}}"; + + public const string RedundancyReadSystemStateResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"mkCqtF2j\",\"result\":{\"state\":\"run_redundant\"}}"; + + public const string InvalidVersionString = "{\"jsonrpc\":\"2.0\",\"id\":\"w1y410f\",\"error\":{\"code\":510,\"message\":\"Invalid version string\"}}"; + + public const string ApiPlcReadCpuTypeResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"cf151dd9-428b-4d53-a6b7-7d6c5768853a\",\"result\":{\"product_name\":\"CPU 1513F-1 PN\",\"order_number\":\"6ES7 513-1FM03-0AB0\"}}"; + + public const string ApiPlcReadStationNameResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"8d5b4591-dad1-4068-a8a3-6b8f02f9d8fb\",\"result\":{\"station_name\":\"1513F\"}}"; + + public const string ApiPlcReadModuleNameResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"7bcf16c5-6ac5-42d3-8e25-2ba17f332bdd\",\"result\":{\"module_name\":\"1513F\"}}"; + + public const string ApiSessionInfoFullResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"7693bb35-754c-41cf-a65e-011a7be6af5e\",\"result\":{\"authentication_mode\":\"local\",\"username\":\"MyUser\",\"runtime_timeout\": \"PT30M\",\"password_expiration\":{\"timestamp\":\"2012-04-23T18:25:43Z\",\"warning\":true}}}"; + + public const string ApiSessionInfoMinimumResponse = "{\"jsonrpc\":\"2.0\",\"id\":\"7693bb35-754c-41cf-a65e-011a7be6af5e\",\"result\":{\"authentication_mode\":\"none\",\"username\":\"Anonymous\"}}"; } } diff --git a/version.json b/version.json index 6aba552..15e165d 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json", - "version": "2.2", + "version": "3.0", "publicReleaseRefSpec": [ "^refs/heads/main$" ],