fbarresi / beckhoffhttpclient Goto Github PK
View Code? Open in Web Editor NEWUnofficial TwinCAT function for HTTP-Client and Json conversion
License: MIT License
Unofficial TwinCAT function for HTTP-Client and Json conversion
License: MIT License
@fbarresi Hi again!
Continues from previous issue that was closed .
So it turns out, the library is not functioning on my existing twincat project, the exact same code was copied over from the sample project which had everything working properly, but the client does not make any calls and ResponseCode remains 0 inside Global_Variables
. Now that I have the sample project working fine I can confirm TFU001
is installed successfully and the library is referenced properly as well, do you have any idea as to what could be causing this? I have the same set up on both twincat projects.
Thanks so much,
KK
This happens because when the response is in the form of a JSON array and starts with "[" it is of type JArray not JObject. I created a conditional to check for this and handle accordingly as well as use the base Response tag path to point to the array in the plc then add the [index] in a loop to iterate through all results and write to the plc. There may be a better way to handle this. Just wanted to raise the issue and a possible soultion.
Hello! It is me again...
Is there a way to hide permanently the console window that shows up every http command?
I was looking in the TFU code and you could maybe implement a variable to enable or disable the LOG window.
Thanks!
Thank you for your work on this awesome library!
Should we be able to pass JSON strings in the Body of a POST request? Am I not using the Client correctly?
Body := ''
) because my endpoint validates the request.MAIN.TcPOU
Client : HttpClient;
Execute : BOOL := TRUE;
HasError : BOOL;
ErrorId : UDINT;
Client(
Execute := Execute,
Address := 'https://www.fake-example.com/ExampleController/Post',
CallMethod := 'POST',
Body := '{"stringProperty": "string", "dintProperty": 1, "arrayProperty": ["string"]}',
ResponseCode := 'GVL.ResponseCode', // This is not updated from the default value of 0.
Response := '',
HasError => HasError, // No error returned
ErrorId => ErrorId);
IF Execute THEN
Execute := FALSE;
END_IF
GVL.TcGVL
{attribute 'qualified_only'}
VAR_GLOBAL
ResponseCode : INT;
END_VAR
header.json
{
"Accept": "*/*",
"Content-Type": "application/json"
}
ExampleController.cs
namespace ExampleProject.API.Controllers;
[ApiController, Route("[controller]/[action]")]
public class ExampleController : ControllerBase
{
// "/ExampleController/Post"
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Post([FromBody] Request request) => return Ok();
}
Request.cs
namespace ExampleProject.API.Models;
public class Request
{
// JSON must include this property with a non-empty string value.
[Required(AllowEmptyStrings = false)]
public string StringProperty { get; set; } = string.Empty;
// JSON must include this property with any int value.
[Required]
public int DintProperty { get; set; }
// JSON must include this property with 0 or more strings in an array.
[Required]
public IEnumerable<string> ArrayProperty { get; set; } = Enumerable.Empty<string>();
}
MAIN.TcPOU
Client : HttpClient;
Execute : BOOL := TRUE;
HasError : BOOL;
ErrorId : UDINT;
Client(
Execute := Execute,
Address := 'https://www.fake-example.com/ExampleController/Post',
CallMethod := 'POST',
Body := 'GVL.Body',
ResponseCode := 'GVL.ResponseCode', // This is 200 on success.
Response := '',
HasError => HasError,
ErrorId => ErrorId);
IF Execute THEN
Execute := FALSE;
END_IF
GVL.TcGVL
{attribute 'qualified_only'}
VAR_GLOBAL
Body : Body;
ResponseCode : INT;
END_VAR
Body.TcDUT
TYPE Body :
STRUCT
{attribute 'json' := 'stringProperty'}
StringProperty : STRING := 'string';
{attribute 'json' := 'dintProperty'}
DintProperty : INT := 1;
{attribute 'json' := 'arrayProperty'}
ArrayProperty : ARRAY[0..9] OF STRING := ['string'];
END_STRUCT
END_TYPE
header.json
{
"Accept": "*/*",
"Content-Type": "application/json"
}
In my working example above, the DUT contains a property of type ARRAY[0..9] OF STRING
, a static array, but the REST API endpoint takes in a dynamic array of strings, expected to vary with each call. For this use case, it is preferred to send:
{"stringProperty": "string", "dintProperty": 1, "arrayProperty": ["string"]}
instead of what the DUT deserializes to:
{"stringProperty": "string", "dintProperty": 1, "arrayProperty": ["string","","","","","","","","",""]}
Passing a JSON string to the HttpClient Body would be a workaround for all requests with dynamic arrays that do not serialize appropriately.
Hello!
When I'm trying to compile, I get the following errors in the HttpClient POU:
String variable 'in' too short for the VAR_IN_OUT parameter 'Body' of 'F_STRING'
String variable 'in' too short for the VAR_IN_OUT parameter 'Address' of 'F_STRING'
String variable 'in' too short for the VAR_IN_OUT parameter 'CallMethod' of 'F_STRING'
String variable 'in' too short for the VAR_IN_OUT parameter 'ResponseCode' of 'F_STRING'
String variable 'in' too short for the VAR_IN_OUT parameter 'Response' of 'F_STRING'
Hello and Thank you for your work!
I try to accomplish a communication to a CLI from my Beckhoff CX5040 (Win 10). I can send the desired commands, but i dont recive any response.
Maybe i just dont unterstand how the variables "reponse" and "ResponseCode" work proberly, is ther an furhter documentation of your library?
Even if i try to catch the respons from https://dog.ceo/api/breeds/image/random i dont get anything back.
The commands i send work fine, i recive anything of the CLI-side.
My example-Code:
MAIN:
client(
Execute:=bSend ,
Address:= 'https://dog.ceo/api/breeds/image/random',
CallMethod:= 'GET' ,
Body:= '',
ResponseCode:= 'Globale_Spez.iResponseCode',
Response:= 'Globale_Spez.asBody',
HasError=> bError,
ErrorId=> udiErrorId);
bSend := FALSE;
Globale_Spez:
VAR_Global
iResponseCode : INT;
asResponse : JsonRadioStatus;
END_VAR
DUT:
TYPE JsonRadioStatus :
STRUCT
{attribute 'json' := 'message'}
sMessage : STRING;
{attribute 'json' := 'status'}
sStatus : STRING;
END_STRUCT
END_TYPE
What am i missing?
Thanks for your replay!
Hi
I´m new to Beckhoff but not to automation.
The functionality i want to accomplish is quite simple and searching for the simplest way to do this without buying a license.
I have a INT variable in the PLC that i want to input to a http-address to post a form on a php-page
like this:
http://ipadress-to-remote-server/index.php?submit=1&MaxAmps=xxx
Where the XXX is my INT.
It's a very basic functionality.
Can I use this 'BeckhoffHttpClient' for this?
Or maybe there is a much simpler way to do it?
Hello @fbarresi ,
I want to create a POST but the request body asks me for an application/octet-stream [Binary image data],
I attached a photo so you can see
how can i do it?
Thank you very much for everything, Victor.
I have a post request to Telegram:
Invoke-RestMethod -Uri https://api.telegram.org/botTTT/sendMessage -Method 'POST' -ContentType 'applicatiomn/json' -Body '{"chat_id": "12345", "text": "This is a test from curl", "disable_notification": true}'
The json Object in the PLC is like that:
TYPE Json_Telegram :
STRUCT
{attribute 'json' := 'chat_id'}
chat_id : STRING := '1020187857';
//iResponse : INT;
{attribute 'json' := 'text'}
text : STRING := 'ScreenCut';
END_STRUCT
END_TYPE
I think, the content-type text/json is not ok, but it comes directly from you program.
Any suggestions?
BTW: Great work! This is a very nice and useful application!
Im having issues trying to run this on a local machine Win10x64 machine...
Does this have to run on Beckhoff Win 10 IoT machine?
The TFU0001.exe module is located in the right folder, code it pointing to it, but I dont think it is running when executed. Any ideas?
Hi, im trying to use this extension with the JSON extension as well in order to send data to the POWER BI API via a POST, could you explain how is the TFU001 supposed to installed, I'm not really sure how to install the extension.
Thanks
Hello,
its me again :D
i am trying to parse a Json String from httpget.
(In my case reading data from BYD Battery)
In the log file i get the right Json response.
I "rebuild" the Json Structure in Twincat DUT.
See attached pics.
Log:
[23.05. 10:22:25.028] DEBUG - Program.GetOrCreateHeader - No header file found...
[23.05. 10:22:25.190] DEBUG - Program.GetOrCreateHeader - Writing an example header
[23.05. 10:22:25.907] DEBUG - Program+d__33.MoveNext - Starting API Call
[23.05. 10:22:25.908] DEBUG - Program+d__33.MoveNext - Connecting to Beckhoff Port: 851 - AdsNet: ''
[23.05. 10:22:26.385] DEBUG - Program+d__33.MoveNext - Beckhoff connection state: Connected
[23.05. 10:22:26.389] DEBUG - Program+d__33.MoveNext - Url: http://192.168.2.140/solar_api/v1/GetStorageRealtimeData.cgi?Scope=Device&DeviceId=0&DataCollection=CommonInverterData
[23.05. 10:22:26.390] DEBUG - Program+d__33.MoveNext - Method: GET
[23.05. 10:22:26.486] DEBUG - Program+d__33.MoveNext - Body: {}
[23.05. 10:22:26.486] DEBUG - Program+d__33.MoveNext - Executing...
[23.05. 10:22:27.030] DEBUG - Program+d__33.MoveNext - Response code: OK
[23.05. 10:22:27.067] DEBUG - Program+d__33.MoveNext - Response content: {
"Body" : {
"Data" : {
"Controller" : {
"Capacity_Maximum" : 7680.0,
"Current_DC" : 8.4901065449010655,
"DesignedCapacity" : 7680.0,
"Details" : {
"Manufacturer" : "BYD",
"Model" : "BYD Battery-Box Premium HV",
"Serial" : "Pxxxxxxxxxxxxxx "
},
"Enable" : 1,
"StateOfCharge_Relative" : 89.900000000000006,
"Status_BatteryCell" : 3.0,
"Temperature_Cell" : 21.5,
"TimeStamp" : 1716452545,
"Voltage_DC" : 328.5
},
"Modules" : []
}
},
"Head" : {
"RequestArguments" : {
"DeviceId" : "0",
"Scope" : "Device"
},
"Status" : {
"Code" : 0,
"Reason" : "",
"UserMessage" : ""
},
"Timestamp" : "2024-05-23T08:22:28+00:00"
}
}
[23.05. 10:22:27.067] DEBUG - Program+d__33.MoveNext - Writing status code into GVL.ResponseCode...
[23.05. 10:22:28.612] DEBUG - Program+d__33.MoveNext - Written status code into GVL.ResponseCode.
[23.05. 10:22:28.613] DEBUG - Program+d__33.MoveNext - Writing json response into GVL.Body...
[23.05. 10:22:28.961] DEBUG - Program+d__33.MoveNext - Written response into GVL.Body.
[23.05. 10:22:28.962] DEBUG - Program+d__33.MoveNext - Disconnecting to Beckhoff
Hello! I'm looking to utilize this library in one of our Twincat programs, and right now I'm just trying to get started with this library.
I've copied over the code in the readme to test out a simple API call on my local computer (not PLC) , but I'm not getting any responses.
My code is as shown below:
Main
:
VAR
bError: BOOL;
udiErrorId : UDINT;
client : HttpClient;
END_VAR
client(
Execute:=FALSE ,
Address:= 'https://dog.ceo/api/breeds/image/random',
CallMethod:= 'GET' ,
Body:= '',
ResponseCode:= 'Global_Variables.ResponseCode',
Response:= 'Global_Variables.ResponseBody',
HasError=> bError,
ErrorId=> udiErrorId);
Global_Variables (under GVL):`
`VAR_GLOBAL
ResponseCode: INT;
ResponseBody : JsonRadioStatus;
END_VAR
After starting the program, the response body and response both do not change as they are expected to. I've also tried out the sample project existing in this repository by cloning it, and the same goes for that project, I'm getting no errors and no responses.
Could you please enlighten me as to what could be possibly causing this? Thank you so much, and thanks so much for the work on this library.
Has anyone done any use of this library with twincat c++ modules, i.e. calling an Http POST command from a c++ module?
I've been trying to follow along with the twincat documentation, but I feel like I am missing steps.
Hello, I would like to ask for help in order to use this library to generate notifications via the PushOver service (https://pushover.net/api)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.