Siemens.Simatic.S7.Webserver.API
1.0.1
Prefix Reserved
See the version list below for details.
dotnet add package Siemens.Simatic.S7.Webserver.API --version 1.0.1
NuGet\Install-Package Siemens.Simatic.S7.Webserver.API -Version 1.0.1
<PackageReference Include="Siemens.Simatic.S7.Webserver.API" Version="1.0.1" />
paket add Siemens.Simatic.S7.Webserver.API --version 1.0.1
#r "nuget: Siemens.Simatic.S7.Webserver.API, 1.0.1"
// Install Siemens.Simatic.S7.Webserver.API as a Cake Addin #addin nuget:?package=Siemens.Simatic.S7.Webserver.API&version=1.0.1 // Install Siemens.Simatic.S7.Webserver.API as a Cake Tool #tool nuget:?package=Siemens.Simatic.S7.Webserver.API&version=1.0.1
WebserverApi Client Library for .NET
This package targeting .NET Framework 4.8 or greater and .NET Standard 2.0 and above provides the user with Method calls to the PLC Webserver Api using the HttpClient to make the usage of Api functionalities easier.
- Package name: Siemens.Simatic.S7.Webserver.API
Table of contents
- WebserverApi Client Library for .NET
- Table of contents
- License
- Dependencies
- Usage
- ApiHttpClientRequestHandler
- WebApps
- PlcProgram Browse Read and Write
- Compatibility
- Limitations
- Further Information about PLC (Webserver)
License
Dependencies
Usage
The Functionalities come together in the ApiHttpClientRequestHandler that implements the IAsyncApiRequesthandler (and also in any implementation of the IApiRequestHandler - not given by example).
In the following example code you'll have to adjust the IpAddress ("192.168.1.1") and the login for your system - the Login "Everybody" with the password "" is a default user that is downloaded to the plc for the webserver once the webserver is activated in TIA portal. The used functions would fail for the default case that he doesn't have the permissions call the method (that he tried to call). It is not good practice to give a lot of rights to the user "Everybody" therefore please adjust the connectionconfiguration to your configured user with a safe password that should be able to call the methods.
Further examples of usage are also provided in the UnitTests of the component.
ApiHttpClientRequestHandler
To use e.g. the Api Method "Api.Browse" to get all the Methods supported by the PLC Api do the following
...
using Siemens.Simatic.S7.Webserver.API.Models;
using Siemens.Simatic.S7.Webserver.API.Requests;
using Siemens.Simatic.S7.Webserver.API.RequestHandler;
...
var connectionConfiguration = new HttpClientConnectionConfiguration("192.168.1.1", "Everybody", "");
var client = await ApiHttpClientAuthorizationHandler.GetAuthorizedHTPPClientAsync(connectionConfiguration);
var requestFactory = new ApiRequestFactory();
var requestHandler = new ApiHttpClientRequestHandler(client, requestFactory);
var apiBrowseResponse = await requestHandler.ApiBrowseAsync();
foreach(var method in apiBrowseResponse.Result)
{
Console.WriteLine(method.Name);
}
Hint: The PLC Certificate is by default not accepted by your PC - therefor you have to either download and store the certificate in the trusted root ca certificates or implement the validation callback for your system - a "plain" check for ⇒ true is not good practice but it will get you started in case you dont want to download and install the certificate.
...
using System.Net;
...
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
Of course you can also implement a check for the sender and so on.
WebApps
For the PLC WebApps Further Comfort can be accomplished by using the ApiWebAppData and ApiWebAppResource implementations: Generally you are free to configure everything on your own:
...
using Siemens.Simatic.S7.Webserver.API.Models;
using Siemens.Simatic.S7.Webserver.API.RequestHandler;
using Siemens.Simatic.S7.Webserver.API.Enums;
using Siemens.Simatic.S7.Webserver.API.Exceptions;
using System.IO;
using System.Linq;
...
public static DirectoryInfo CurrentExeDir
{
get
{
string dllPath = System.Reflection.Assembly.GetExecutingAssembly().Location;
return (new FileInfo(dllPath)).Directory;
}
}
...
var app = new ApiWebAppData() { Name = "customerExample", State = ApiWebAppState.Enabled };
await requestHandler.WebAppCreateAsync(app);
app = (await requestHandler.WebAppBrowseAsync(app)).Result.Applications.First();
var ticketForCreation = await requestHandler.WebAppCreateResourceAsync(app, "index.html", "text/html", "2020-07-29T14:52:22Z");
await requestHandler.UploadTicketAsync(ticketForCreation.Result, Path.Combine(CurrentExeDir.FullName, "_WebApps", "customerExample", "index.html"));
// (optional) check for the Ticket state
var ticket = (await requestHandler.ApiBrowseTicketsAsync(ticketForCreation.Result)).Result.Tickets.First();
// close the ticket again!
await requestHandler.ApiCloseTicketAsync(ticket.Id);
if (ticket.State != ApiTicketState.Completed)
{
throw new ApiTicketNotInCompletedStateException(ticket);
}
await requestHandler.WebAppSetDefaultPageAsync(app, "index.html");
// do this in a loop for all resources and perform management yourself OR
but further comfort can be accomplished with:
AsyncWebAppDeployer, WebAppConfigParser
You can use Implementations to comfortably deploy the apps to the plc with a Deployer and FileParser for your WebAppDirectory:
...
using Siemens.Simatic.S7.Webserver.API.Deployer;
using Siemens.Simatic.S7.Webserver.API.FileParser;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
...
var parser = new WebAppConfigParser(Path.Combine(CurrentExeDir.FullName, "_WebApps", "customerExample"), "WebAppConfig.json");
app = parser.Parse();
var deployer = new AsyncWebAppDeployer(requestHandler);
await deployer.DeployOrUpdateAsync(app);
var apiWebAppBroseResourcesResponse = await requestHandler.WebAppBrowseResourcesAsync("customerExample");
foreach(var resource in apiWebAppBroseResourcesResponse.Result.Resources)
{
Console.WriteLine(JsonConvert.SerializeObject(resource, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver(), NullValueHandling = NullValueHandling.Ignore }));
}
The Parser and Deployer also use a set of comfort functions - in case you want to know or take a look they are using:
...
// Extension methods on IAsyncRequestHandler and AsyncRequestHandler: DeployResource (static async Task) - also contains DownloadResource
using Siemens.Simatic.S7.Webserver.API.Extensions;
// contains static ApiWebAppResourceBuilder.BuildResourceFromFile to get the resource information from the windows file -
// which also usees MimeMapping.MimeUtility.GetMimeMapping to get the according MimeType
using Siemens.Simatic.S7.Webserver.API.StaticHelpers;
...
Hint: It is possible to add another parameter to the new WebAppConfigParser(,,bool ignoreBOMDifference = false): This is the case because uploading files using javascript on a webpage has shown that the BOM (Byte Order Mark) is not transmitted! Therefor if you upload a file using javascript and then make the deployer do the comparison between the file locally (windows explorer) and the one on the server(plc) the files would be different since the size is different by three bytes. To get rid of this "false positive" on a difference you can set the ignoreBOMDifference to true - but keep in mind that a change of 3 bytes would then also be accepted as no difference. The deployer would still reupload the file since the last_modified dates would not match!
PlcProgram Browse Read and Write
The PlcProgram Methods can be used to Browse available variables and to read or write their value.
...
using Siemens.Simatic.S7.Webserver.API.Models;
using Siemens.Simatic.S7.Webserver.API.RequestHandler;
using Siemens.Simatic.S7.Webserver.API.Responses;
using Siemens.Simatic.S7.Webserver.API.Models.ApiPlcProgramDataTypes;
...
// PlcProgramRead example: object will work for any plcdatatype that is implemented by the api, you could also provide "bool" here
var boolReadResult = await requestHandler.PlcProgramReadAsync<object>("\"DataTypes\".\"Bool\"");
Console.WriteLine(boolReadResult.Result);
// Tia Data Type "Date_And_Time" and "S5Time" are returned as objects - therefore an Implementation is done as the "ApiDateAndTime" and "ApiS5Time"
ApiResultResponse<ApiDateAndTime> dateAndTimeReadResult =
await requestHandler.PlcProgramReadAsync<ApiDateAndTime>("\"DataTypes\".\"TIA_Dates\".\"Date_And_Time\"");
DateTime myDt = dateAndTimeReadResult.Result.GetDateTime();
myDt = (new DateTime(2021, 04, 26, 16, 53, 22).AddMilliseconds(13));
await requestHandler.PlcProgramWriteAsync("\"DataTypes\".\"TIA_Dates\".\"Date_And_Time\"", new ApiDateAndTime(myDt));
dateAndTimeReadResult =
await requestHandler.PlcProgramReadAsync<ApiDateAndTime>("\"DataTypes\".\"TIA_Dates\".\"Date_And_Time\"");
Console.WriteLine(dateAndTimeReadResult.Result.GetDateTime().ToString("dd/MM/yyyy hh:mm:ss.fff tt"));
ApiResultResponse<ApiS5Time> s5TimeReadResult =
await requestHandler.PlcProgramReadAsync<ApiS5Time>("\"DataTypes\".\"TIA_Dates\".\"S5Time\"");
Console.WriteLine(s5TimeReadResult.Result.GetTimeSpan());
// TIA Data types like "Date", "Time", "LTime", "Time_Of_Day", "LTime_Of_Day" are returned as int/uint values when using
// the "simple" mode for PlcProgram.Read => it makes sense to know how to get those into a DateTime/TimeSpan:
// Example for "Date" (you'll have to adjust this for "Time","LTime",...)
var dateReadResult = await requestHandler.PlcProgramReadAsync<uint>("\"DataTypes\".\"TIA_Dates\".\"Date\"");
DateTime date = new DateTime(1990, 1, 1) + TimeSpan.FromDays(dateReadResult.Result);
date = new DateTime(2021, 04, 26);
// for writing: determine the amount of days that is between 1/1/1990 and the time you want to write => write the value as a uint
// or int or long, ... a number that is no double/float => (2 not 2.0) - thats what the plc expects
TimeSpan ts = date - new DateTime(1990, 1, 1);
await requestHandler.PlcProgramWriteAsync("\"DataTypes\".\"TIA_Dates\".\"Date\"", (uint)ts.TotalDays);
Also for these PlcProgram methods there is an Implementation for an ApiPlcProgramData object that can be used for the Api methods:
...
using System.Collections.Generic;
...
// Do not provide any variable when browsing to browse the "root" "directory" of the plc program data:
List<ApiPlcProgramData> allMyPlcProgramBlocks = (await requestHandler.PlcProgramBrowseAsync(ApiPlcProgramBrowseMode.Children)).Result;
// A DB called "DataTypes" has the variables we care about:
var myPlcProgramDataBlock = allMyPlcProgramBlocks.First(el => el.Name == "DataTypes");
var myPlcProgramDataBlockChildren = (await requestHandler.PlcProgramBrowseAsync(ApiPlcProgramBrowseMode.Children, myPlcProgramDataBlock)).Result;
myPlcProgramDataBlock.Children = myPlcProgramDataBlockChildren;
// It is important to set the Parent list correctly so the variable name will be provided correctly to read/write the value of the variable
foreach(var child in myPlcProgramDataBlock.Children)
{
child.Parents = new List<ApiPlcProgramData>() { myPlcProgramDataBlock };
}
// now we want to read the value of a variable called "Bool":
var myBool = myPlcProgramDataBlock.Children.First(el => el.Name == "Bool");
myBool.Value = (await requestHandler.PlcProgramReadAsync<bool>(myBool)).Result;
Console.WriteLine(myBool.Value);
// write the "Bool" variable
await requestHandler.PlcProgramWriteAsync(myBool, true);
// and read the value again:
myBool.Value = (await requestHandler.PlcProgramReadAsync<bool>(myBool)).Result;
Console.WriteLine(myBool.Value);
Compatibility
Use the following table to find the correct client version for each Plc version (server)
SIMATIC S71500:
Plc Version | WebApi Wrapper Version |
---|---|
2.9.x | 1.0.0 |
SIMATIC S71200:
Plc Version | WebApi Wrapper Version |
---|---|
4.5.x | 1.0.0 |
Hint: The current (first) Wrapper Version supports more API calls than the current S71200 does - the S71200 will likely(!) support the API calls of the wrapper with the next version.
Limitations
Currently some Features are not implemented yet.
Arrays
Only the Array_Dimensions are set for an ApiPlcProgramData, the Children are not set by it yet - we are currently debating possible implementations on this.
Reading Structs by Children containing Arrays
By above reason this is not implemented.
.NetCore Apps
Having tried the RequestHandler in a .netcore app has shown that the requests didn't work as expected - we currently don't know why this is an issue.
Further Information about PLC (Webserver)
See Also:
SIMATIC S71500:
- SIMATIC S71500: https://new.siemens.com/global/en/products/automation/systems/industrial/plc/simatic-s7-1500.html
- SIMATIC S71500 Webserver Manual: https://support.industry.siemens.com/cs/us/en/view/59193560
- SIMATIC S71500 Manual Collection: https://support.industry.siemens.com/cs/us/en/view/86140384
SIMATIC S71200:
- SIMATIC S71200: https://new.siemens.com/global/en/products/automation/systems/industrial/plc/s7-1200.html
- SIMATIC S71200 Manual: https://support.industry.siemens.com/cs/ch/en/view/109797241
- SIMATIC S71200 Manual: https://support.industry.siemens.com/cs/us/en/view/91696622/45063671307
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 is compatible. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.8
- MimeMapping (>= 1.0.1.37)
- Newtonsoft.Json (>= 13.0.1)
- System.Net.Http (>= 4.3.4)
-
.NETStandard 2.0
- MimeMapping (>= 1.0.1.37)
- Newtonsoft.Json (>= 13.0.1)
- System.Net.Http (>= 4.3.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
2.2.24 | 177 | 10/24/2024 |
2.2.23 | 75 | 10/24/2024 |
2.2.22 | 124 | 10/21/2024 |
2.2.21 | 67 | 10/21/2024 |
2.2.20 | 108 | 10/18/2024 |
2.2.19 | 106 | 10/18/2024 |
2.2.18 | 98 | 10/18/2024 |
2.2.17 | 96 | 10/18/2024 |
2.2.16 | 100 | 10/18/2024 |
2.2.15 | 97 | 10/18/2024 |
2.2.14 | 1,012 | 12/18/2023 |
2.2.13 | 121 | 12/18/2023 |
2.2.12 | 167 | 12/18/2023 |
2.2.11 | 142 | 12/18/2023 |
2.2.10 | 119 | 12/18/2023 |
2.2.9 | 130 | 12/18/2023 |
2.2.8 | 115 | 12/18/2023 |
2.2.7 | 121 | 12/18/2023 |
2.2.6 | 117 | 12/18/2023 |
2.2.5 | 117 | 12/18/2023 |
2.2.4 | 120 | 12/18/2023 |
2.2.3 | 177 | 12/4/2023 |
2.2.2 | 127 | 12/4/2023 |
2.2.1 | 229 | 12/2/2023 |
2.1.4 | 1,209 | 1/3/2023 |
2.1.3 | 311 | 1/3/2023 |
2.1.2 | 334 | 1/2/2023 |
2.1.1 | 330 | 1/2/2023 |
2.0.3 | 762 | 11/27/2022 |
2.0.2 | 718 | 11/23/2021 |
2.0.1 | 300 | 11/23/2021 |
1.0.1 | 400 | 11/5/2021 |
first release