Binding for Beckhoff PLC - ADS Protocol

I am selecting a hom eautomation platform.

As I have a Beckhoff PLC for all basic switching and lighting, I am looking for a Platform that can include that.

I would need a binding with the native protocol called ADS.

Using a WebSercive of the controller or Modbus may not be helpful, als I have my switches and lamps managed via arrays in the controller - and converting these and transferring single values may generate quite some overhead.

I have seen attempts, like


and

but seems to lead nowhere.

Is there anything in the works?

From what I see, I like OpenHAB better then Home Assistant, that has at least a basic ADS binding…

If nothing at works, how would be the chance to find somebody on a platform like fiverr to crate a binding and how much effort may that be?

Thank you for your help
Stefan

1 Like

@stm Hello I just accomplished a fully integration of my Beckhoff TwinCat home automation to OpenHab using the TcPlcDataServiceDa Webservice on my CX9020.

Hello Simon,

Could you please elaborate a little?

Thanks,

Jan

Hello Jan and all other Beckhoff enthusiasts out there.

I’ve automated my entire house with a Beckhoff PLC control, based on a CX9020.

I use the Beckhoff TwinCat Building Automation Framework to realize most of my houses control logic. I do highly recomment the use of this framework for home control tasks with Beckhoff.

Beside the TwinCat runtime, the CX9020 comes also with an OPC XML-DA server that can be used to read and write the PLC’s variables through a SOAP webservice protocol.

The server’s binaries can be found under \Hard Disk\WWW on the CX9020 Windows CE image.
2018-05-10%2009_57_35-CX-1836C1
The service should already be running. I did not configure anything in that case on my CX9020.

The service can be reached with http POST under

http://<yoursCxIpAddress>/TcPlcDataServiceDa.dll

Here is an example on how I can ask for the current state value of a light and a sunblind trough the OPC XML-DA SOAP protocol in the POST body:

POST http://<yoursCxIpAddress>/TcPlcDataServiceDa.dll HTTP/1.1

Content-Type: text/xml; charset=utf-8
SOAPAction: Read
Cache-Control: no-cache

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Body><Read xmlns="http://opcfoundation.org/webservices/XMLDA/1.0/">
    <Options ReturnItemName="true" ReturnErrorText="false" ClientRequestHandle="1"/><ItemList>
    <Items ItemName="PLC1.arrLightingStates[1].lrAverageControlValue"/>
    <Items ItemName="PLC1.arrSunblindStates[1].lrAveragePosition"/>
    </ItemList></Read></soap:Body></soap:Envelope>

And here is the response SOAP from the OPC Server:

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://opcfoundation.org/webservices/XMLDA/1.0/">
    <SOAP-ENV:Body>
        <ns1:ReadResponse>
            <ns1:ReadResult xsi:type="ns1:ReplyBase" ServerState="running" RevisedLocaleID="en" ReplyTime="2018-05-10T08:19:07.270+00:00" RcvTime="2018-05-10T08:19:07.269+00:00" ClientRequestHandle="1"></ns1:ReadResult>
            <ns1:RItemList xsi:type="ns1:ReplyItemList">
                <ns1:Items xsi:type="ns1:ItemValue" ItemName="PLC1.arrLightingStates[1].lrAverageControlValue">
                    <ns1:Value xsi:type="xsd:double">0</ns1:Value>
                    <ns1:Quality xsi:type="ns1:OPCQuality" VendorField="0" LimitField="none" QualityField="good"></ns1:Quality>
                </ns1:Items>
                <ns1:Items xsi:type="ns1:ItemValue" ItemName="PLC1.arrSunblindStates[1].lrAveragePosition">
                    <ns1:Value xsi:type="xsd:double">0</ns1:Value>
                    <ns1:Quality xsi:type="ns1:OPCQuality" VendorField="0" LimitField="none" QualityField="good"></ns1:Quality>
                </ns1:Items>
            </ns1:RItemList>
        </ns1:ReadResponse>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

The important things here are the specific names of the PLC variables to address.

"PLC1.arrLightingStates[1].lrAverageControlValue"
"PLC1.arrSunblindStates[1].lrAveragePosition"

In my case this PLC variables are generated by the TwinCat Building Automation Framework.
These variables might differ in your project and depend on your PLC setting.

So far the theory on how to communicate to a Beckhoff OPC XML-DA Server on CX devices through http POST and SOAP.

And now how I adapted this in an OpenHab rule using the sendHttpPostRequest command for the request.
Then using XPATH to parse the response to an array of raw values, that I use to postUpdate the value states to the OH items at the end.


rule "<CX_Light_Sunblind_Lesen>"
when
    Time cron "0/1 * * ? * * *" //every 1 seconds
then

    var String url = "http://<yoursCxIpAddress>/TcPlcDataServiceDa.dll"
    var String contentType = "text/xml"    
    var String content = '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
                            <soap:Body>
                                <Read xmlns="http://opcfoundation.org/webservices/XMLDA/1.0/">
                                    <Options ReturnItemName="true" ReturnErrorText="false" ClientRequestHandle="1"/>
                                        <ItemList>    
                                            <Items ItemName="PLC1.arrLightingStates[1].lrAverageControlValue"/>
                                            <Items ItemName="PLC1.arrLightingStates[2].lrAverageControlValue"/>
                                            <Items ItemName="PLC1.arrSunblindStates[1].lrAveragePosition"/>
                                            <Items ItemName="PLC1.arrSunblindStates[2].lrAveragePosition"/>
                                        </ItemList>
                                </Read>
                            </soap:Body>
                        </soap:Envelope>'

    var String result = sendHttpPostRequest(url, contentType, content)
       
    //Lightings
    var lightings = transform("XPATH", "concat('0',';',
                                                //*[name()='ns1:Items'][@ItemName='PLC1.arrLightingStates[1].lrAverageControlValue'],';',
                                                //*[name()='ns1:Items'][@ItemName='PLC1.arrLightingStates[2].lrAverageControlValue'])", result).split(";")

    AL_Entre_Treppenhaus_Licht_EG.postUpdate(transform("SCALE", "OnOff.scale", lightings.get(1)))
    AL_Entre_Treppenhaus_Licht_OG.postUpdate(transform("SCALE", "OnOff.scale", lightings.get(2)))
    

    //Sunblinds
    var DateTime startSunnblindsTransform = now
    var sunblindStates = transform("XPATH", "concat('0',';',
                                                    //*[name()='ns1:Items'][@ItemName='PLC1.arrSunblindStates[1].lrAveragePosition'],';',
                                                    //*[name()='ns1:Items'][@ItemName='PLC1.arrSunblindStates[2].lrAveragePosition'])", result).split(";")
    
    EG_KuecheEssen_Storre_Kueche.postUpdate(new PercentType(sunblindStates.get(1)))
    EG_KuecheEssen_Storre_Essen.postUpdate(new PercentType(sunblindStates.get(2)))

end

This example can easily be extended with more light and sunblind states, or other variables depending on your PLC setup.

For me this construct works now with around 120 lights, 25 sunblinds, 20 HVAC and a few other parameters. It allows me to pull all my PLC variable states in a 1 second cycle to OH, what is quite nice.

I also managed to write all my OH commands in a similar manner direct do the PLC variables as well.

By the way, my OH runs on a raspbian pi 3, which limits the capability for all the XPATH parsing, but with the above parsing of all values in one step to an array I could reduce the parsing demands as good as possible so far.

If someone needs more detailed information on that variant of an Beckhoff <=> OH adaption, please ask.

2 Likes

@stm Working with PLC arrays is exactly what I did :wink:.

That’s a really cool way of implementing it. I am actually one of the Engineers at Beckhoff and I had been considering an ADS binding. Unfortunately there’s one limitation I’m still trying to overcome. The Beckhoff TwinCAT platform is written for a Windows environment. It’s not real easy to port to Linux.

So the trouble comes in when trying to send ADS commands to/from a Linux/MacOS device. You have to create a route from the device running OpenHAB to the device running TwinCAT which means there needs to be an ADS service running on the Linux/MacOS device. Beckhoff does not have an ADS service that does this. You might find a third party ADS service that does but I have not had time to research that.

So in short, this would work perfectly for those running OpenHAB on Windows, but it wouldn’t really work for those running Linux/MacOS. Which kind of defeats the purpose of OpenHAB. So that’s where I stopped. Otherwise if I find a third party ADS service that runs cross platform I think I could put together a binding for that. It would definitely make integrating with Beckhoff PLCs a much easier task.

1 Like

One other thing I thought of. With the newest version of TwinCAT 3 you can use MQTT and AMQP IOT protocols within TwinCAT. So if you haven’t implemented yet it might be a consideration. Depending on what hardware you have you could update to TwinCAT 3 and use those instead.

Wow, really impressed on your feedback ! Thank you!

@seimenb I do use the Building Automation Framework as well - great tool, I like it for the simplicity for basic functions and have extended some of the built in functionality.
Unfortunately my platform is a CX controller with Windows XP on it - first thing I did was shutting down the IIS as I do not want to have such old software in my network (and a couple of other Windows XP ports as well)
An other thing that may not make me feel too well to go for webservice access is that there is quite some overhead in sending out and receiving side as I have a couple of hundred switches and “lamps” with their activation commands and state values.
So still looking for native binding of ADS.

@mladams922 I have visited Beckhoff at a German trade fair - impressive setup and a lot of friendly and competent people.
I have seen the Data Agent as a independant piece of software to bridge ADS to MQTT - unfortunately currently there is the business decision of Beckhoff to offer that product just for a TwinCat 3 platform - and the Building Automation Framework is just available for Twincat 2 - so I would need an other Windows Box to put Twincat 3 on it.
An other hint from a very competent colleague there was to use the node.js platform, as there are ADS modules for node.js. - Unfortunately I am not so far to look for some other middleware.

My design goal for home automation are minimum amount of boxes and software to have long time stability and minimum amount of maintainance and update.

For bringing ADS to Linux, there seem to have been quite some pointers:

  • C++ source of a library for accessing ADS in a non windows environment by Beckhoff https://github.com/Beckhoff/ADS
  • a node.js based proxy to bring together ADS and MQTT - mentioned above (unfortunately a bit too specific for me/lacking info to put it in my environment) https://github.com/Sitebase/ads-proxy
  • an other home automation platform, “Home Assistant” available on RasPi, supporting ADS. Looking into the source it uses a python wrapper https://github.com/stlehmann/pyads that seems to use said Beckhoff Library either in a Windows bulid or a Linux build.

Hope some of these pointers help that we may end up with a working native ADS binding, as it looks to me that OpenHab is a strong and well supported platform.

I’m training customers this week but when I have some time I will take a look into these options. I did see the open source ADS server for Linux. I hadn’t looked into implementing that yet. Yes, Node.js is an option, but like you said, adds another piece you may not want. The real hurtle is getting and ADS server/client on Linux. If we can accomplish that then we can get quite a bit working. The trouble is Beckhoff has no plans to support Linux :frowning:

As someone who loves Linux this makes me a bit sad but we will have to find a workaround. I’ll look at how Home Assistant solved the problem.

1 Like

Dear Mattew,

did you have a chance to take a look at Beckhoff ADS Library and its use in Home Assistant?

It uses PYADS https://github.com/stlehmann/pyadsm, which is just a warpper to the Beckhoff C++ Library, and works independant it is on Linux (Raspberry) or Windows.

Something like that would be great for OpenHAB, especially if it works with Arrays as these are extensively used in Beckhoff Building Automation Framework.

So hopefully you have a chance to look at it.

I’m using OH2 at a Windows system and want to communicate with my Beckhoff Twincat 2.

Is there a way to do it with ADS now?

I have to apologize, I haven’t had the time to dig into it yet. I’d really love to but other things have taken priority. I will look into it as soon as I can get the chance.

Hi,
I am newbie what comes to OpenHAB. I have Beckhoff CX9020 in my house and I was able to solve the variables of the house lights from the TwinCat. I am able to do the POST to the service an I get back the answer if the light is on or off (true or false.) How can I implement rules UI, for example I want to see that light is on.
Could you or someone else who has the same Beckhoff system give me some hints and examples, please. I would really appreciate it!

Hi Toni

This might help you.
Using XPATH to parse the resolved xml

Thanks for the reply
My xpath is //SOAP-ENV:Body/ns1:ReadResponse/ns1:RItemList/ns1:Items[@ItemName=“PLC1.arrLampProcessOutputData[17].bData”]/ns1:Value@xsi:type=“xsd:boolean”

and with this I get the status of my lamp (true or false)

Should I use some item like String Info “Info [%s]” {http="<[http://192.168.178.30/data/Dynamic.xml:10:XPATH(MYXPATH_BELOW)]"} ?

Hi Jan @herrJones

Are you the author of this?
https://github.com/herrJones/beckhoffads

Is this a working solution? Can you elaborate a little about that beckhoffads project as well?

Thanks,

Simon

Hey Simon,

Unfortunately, it is not…

My knowledge of java is not what it should be.

I decided to use the node.js node-ams module.

One you get the hang of it, it is quite straightforward to use.

I now have a working setup based on oh2, node-ams and influx db for logging.

Success,

Jan

HI Simon My CX9010 is running my home for the last 12 years. I have built a html app on top of the embedded IIS using TCScriptCE. Now I need to renovate the app or just find a new Interface like OH.

I found this (https://github.com/tomcx/tame4) solution using WebService and JS. I have the feeling that this could be a good base for binding.

You are reading the SPS every second, which would generate a huge traffic in my case with over 200 variables. If I understood the concept of OH right (I’m new to it) a binding would allow to read and write the things related variables (channels) as needed.

I’m a Beckhoff SPS fan and asked the Beckhoff support if they have any planes to support OH but they denied.

I’m more than interested to find / build a good working solution.

In the meantime, could you give me some guidance on how you implemented it? Items, things, bindings?

Thanks for some guidance

Hi all,

I’ve put my own code online in github (https://github.com/herrJones/openhab-node) as a reference for anyone in need :slight_smile:
(because I searched long enough myself)

As I mentioned above, I abandoned OpenHAB addons and most of the rules scripting in favor of NodeJS.
This because I have more experience with javascript than java…
Not to mention the hugely important fact that I found a working Beckhoff solution in NodeJS.
Not to mention the fact that you can actually debug code with NodeJS, without trial and error…

Features:

  • Beckhoff CX9020 integration via node-ads-api
    (probably other models will work too)
  • timers (week-rules)(in development :slight_smile: )
  • pushing and fetching data to InfluxDB via HTTP API
  • has not crashed in the last 2 months :sunglasses:

Hope this helps!

Jan

Hey @herrJones,
Because of my earlier bacnet work I was approached by some members of Apache plc4x project who told me that their project have support for most popular PLCs using appropriate protocols - these include S7 (Siemens) and ADS (Beckhoff). According to project lead there is more goodness to come.

This means that there are client libraries available which have compatible source code license and been tested with real hardware in industry projects. Most importantly these are done in proper way, without hacks or necessity for additional middleman hardware.
I didn’t go over plc4x code base yet and I am not sure if there is a chance to have a full “discovery” of things/items from s7/ads data stream, however at API level there are few interesting concepts such subscription which might get implemented according to underlying protocol.

Maybe at some day, once we find someone stubborn enough, we will get integration for these? I leave links here so everyone who is up - can follow them up!

Cheers,
Łukasz

1 Like