Connecting to SAP with 3rd party Python lib or SAP JCo jar

I’m trying to determine if there is a method to call SAP RFCs from Ignition. I know Sepasoft has a Business Connector and Interface for SAP but it will probably be cost prohibitive for this particular project where I only need to call one RFC remotely.

I can successfully call the SAP RFC via PyRFC (which uses their Netweaver RFC SDK - NWRFCSDK) on a test Windows box. However, I’m not sure if this is something I can import into Ignition. It would be really great if I could. I’ve read the following:
https://support.inductiveautomation.com/index.php?/Knowledgebase/Article/View/98/2/importing-and-using-3rd-party-python-libraries-in-ignition

And I think I can find a version of the PyRFC for Python 2.7 (I’m running Ignition 8) but I’m just not that experienced to know if it will work because it depends on some other .dlls in the NWRFCSDK. I mean, can a 3rd party Python library if imported into the user-lib\pylib directory even connect to a dependent .dll or .exe in a Windows directory? Or is Ignition isolated completely in its own JVM or something? Sorry this may be intuitive for some people but I just don’t have the background.

So then I was also wondering about importing a Java Connector for SAP called SAP JCo (sapjco3.jar). I’ve read a few posts about people trying this. Mostly people that could write their own Module with the SDK and that seems way above my knowledge. I also noticed where @Kevin.Herron mentioned putting 3rd party jars in lib/core/gateway but it seems that sapjco3.jar for some reason gets renamed and the .jar itself it hard-coded to look for it’s exact name sapjco3.jar when launched.

So I’m just wondering if any of these options are a possibility for someone without a lot of module SDK or Java experience. Like I said, I was successful with using PyRFC on Windows which provides me with the ease of use of Python but I’m open to other options if you guys have them.

Unfortunately there is no web REST or SOAP endpoint that I can call on the SAP side.

1 Like

It's unlikely to work if it relies on a DLL.

Unfortunately the SAP JCo connector seems to be a complete dead end even if you are a module developer because module dependencies are unpacked and renamed the same way JAR files placed in lib/core/gateway are.

Maybe another user here has figured something out though?

I briefly looked at the same jars that Sepasoft ended up deploying–official SAP jars. Looked reasonable to use, but that project died (customer’s in-house IT wrote their own interface with the official .NET API for SAP).

{Yeah, I was shocked when I recently saw the price tag Sepasoft put on their SAP and Connector combo. Someone’s going to re-implement it cheaper, eventually. Might even be me.)

Hi Phil,
We’re currently using the .NET Connector but I’d really like to have some scripting functions I could use in Ignition. Don’t get me wrong, the modules from Sepasoft looks to have great features and is certified by SAP but it’s pretty expensive for calling just one BAPI.

I did notice their instructions https://help.sepasoft.com/docs/display/BC/JCo+Library+for+SAP make it seem as though they figured out a way to import the jars and dll. Maybe they’re only using Gateway scope or using a separate process entirely to hook into the SAP JCo jars.

BTW- we’re still using your Batik SVG Canvas for displaying Cognex camera images and overlays. It’s working great! And we’d definitely be interested if you decide to move forward with an SAP connector. I’ll send you an email.

It won’t be soon, unfortunately. I’m solidly booked for the next couple months. The only module I’m likely to release in the interim is the Modbus Server I’m hacking at. (Plus any v8.1-induced bugs found in my other modules.)

4 Likes

Hi Phil,

More on this “hacked Modbus Server”? Any plan for a UDP Modbus?

I've mentioned it a few times around here, but it implements the server (slave) side of the Modbus protocol so that other masters can connect to Ignition. It supports simultaneous Modbus TCP, Modbus Serial RTU, and Modbus RTU over TCP connections to the configured virtual device. Within the virtual device, multiple units are supported, each with their own data format setttings (word swapping, etc) and configurable ranges of bits and registers to expose. It also supports a configurable number of Modbus "File" registers in each unit (function codes 20 & 21). As a server, the DI and IR memory areas are fully writable.

The driver uses the same general syntax as IA's Modbus driver, with the following enhancements:

  1. Multiple Consecutive Coils or Discrete Inputs can be treated as an integer by adding :n to the bit address, where n is the number of bits (up to 63). LSB first only.
  2. Multiple Bits in any 16-bit register may be treated as an integer by adding .m:n to the register address, where m is the start (low) bit, and n is the number of bits (up to 15). Cannot span registers.
  3. File aka "Extended" registers use the XR prefix and support all of the bit access, conversion, and multiword datatype modifiers available for holding registers (and input registers).

There are two major features not present in this module:

  1. No mappings. Not supported and not going to be supported.
  2. No one-based addressing. Zero-based only.

However, in lieu of the above, this driver implements browsing of configured units and the configured address ranges of each units memory areas. Available data type modifiers are displayed in the browse tree under each 16-bit register. Large lists of addresses are broken into groups of 1000 to minimize browse delays. Each displayed base address shows the one-based classic address equivalent as an "AKA" in the description. Here's a tease from my testing server:

Oh, no support for Modbus UDP is planned.

1 Like

Oh, one more thing:

My new Modbus module also implements client connections with the above addressing and browsing functionality. (:

1 Like

I’m using SAPJco3 for RFC calls to SAP and it works nicely.

  • Place the SAPJco3 library in a folder on your gateway. (c:\SAPJco3 for example) Be sure to get the bit version to match your Java environment. (i.e.: 64 bit SAPJco3 library)

  • Edit the ignition.conf file and add wrapper.java.classpath.3=c:\SAPJco3/sapjco3.jar

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=lib/wrapper.jar
wrapper.java.classpath.2=lib/catapult.jar
wrapper.java.classpath.3=c:\SAPJco3/sapjco3.jar
  • Place required .jcoDestination files in the \Program Files\Inductive Automation\Ignition folder.

This could be something like: DEV.jcoDestination, QAS.jcoDestination, PRD.jcoDestination
This format works for me.

ashost=192.168.x.x
sysnr=00
client=110
user=username
passwd=password  (The SAPJco3 library will update a clear text password with an encrypted version after the first connection.)
lang=en
pool_capacity=0

Limit your function calls to the gateway scope or you’ll need the SAPJco3 setup on your clients!

Sample function to return a table from SAP. Note: sapSystem is a string representing the file name of your destination file without the ‘.jcoDestination’ extension.

def Z_OEE_RATE_LIST(werks,sapSystem):
# Plant Number (werks) is passed in - Datasets returned
from com.sap.conn.jco import JCoDestinationManager
destination = JCoDestinationManager.getDestination(sapSystem)
function = destination.getRepository().getFunction("Z_OEE_RATE_LIST")
function.getImportParameterList().setValue("WERKS", werks)
function.execute(destination)
#
ds = function.getTableParameterList().getTable("OEE_RATE_LIST")
return ds

You can send and receive tables and individual values as needed.

I hope that helps. Let me know if you need clarification.

Paul

7 Likes

Nice job @phyatt, I hadn’t thought about approaching it this way.

Thanks @phyatt! I followed your example and it was enough to get me started but I did have one issue. Maybe due to the version of SAP JCo that I’m running (3.1.3). My .jcoDestination file parameters needed to include the jco.client prefix like this:

jco.client.ashost=fqdn_of_SAP_server
jco.client.sysnr=00
jco.client.client=100
jco.client.user=SAP_username
jco.client.passwd=SAP_password
jco.client.lang=en
jco.destination.pool_capacity=0

Here’s an RFC_READ_TABLE example I cobbled together:

    sapSystem="QAS"
	from com.sap.conn.jco import JCoDestinationManager
	destination = JCoDestinationManager.getDestination(sapSystem)
	function = destination.getRepository().getFunction("RFC_READ_TABLE")
	
	inputTableParam = function.getTableParameterList().getTable("FIELDS")
	inputTableParam.appendRow()
	inputTableParam.setValue("FIELDNAME", "CHECT")
	
	inputParamList = function.getImportParameterList()
	inputParamList.setValue("QUERY_TABLE", "PAYR")
	inputParamList.setValue("DELIMITER", ";")
	
	optionsTableParam = function.getTableParameterList().getTable("OPTIONS")
	optionsTableParam.appendRow()
	optionsTableParam.setValue("TEXT", "CHECT = '436396'")
	
	function.execute(destination)
	table = function.getTableParameterList().getTable("DATA")
	print table

Hope this helps someone else.

For those interested, beta Modbus announcement here:

Hello All,
I followed everything as described, but I don’t succeed.
I suspect I already fail importing the jar file into Ignition 7.9.12. I get always the error: “ImportError: No module named sap” with the link to the line “from com.sap.conn.jco import JCoDestinationManager”
Does anyone have any idea what I can try here. With the / \ I have already tested all variations in the ignition.conf file. The gateway runs on a Windows Server 2012 R2 but also on my testenvironment a Windows 7 machine it give the same error. The SAP Java Connector seams to be setup well.
Thanks

What scope are you testing your script in? The approach outlined above would only make the classes available in the gateway, so you can’t test using the Designer script console for example.

Hi Kevin, thank you for your fast reply. The script did run as a Global script but called from a button action scrip of a client. When I call the script now from a tag change script it works.

we are trying to map those 3 jar files but we don't have catapult.jar. How we can get this file? Do we need to download or suggest how we can get it.
..........................................................................

Java Classpath (include wrapper.jar) Add class path elements as

needed starting from 1

wrapper.java.classpath.1=lib/wrapper.jar
wrapper.java.classpath.2=lib/core/common/*
wrapper.java.classpath.3=lib/core/gateway/*
...............................................................................................
we got this from our ignition.conf file. Do we need to replace or do we need make any changes in this??

Pretty sure you don't need the catapult.jar. Rather you need to add an additional class path to your conf file.

It should look something like:

# Java Classpath (include wrapper.jar)  Add class path elements as
#  needed starting from 1
wrapper.java.classpath.1=lib/wrapper.jar
wrapper.java.classpath.2=lib/core/common/*
wrapper.java.classpath.3=lib/core/gateway/*
wrapper.java.classpath.4=c:\Path/To/SAP Jco3/library/sapjco3.jar

You'll need to replace c:\Path/To/SAP Jco3/library with the correct path to where you placed the library on the Gateway Machine.

And no backslashes, IIRC.

You can also drop your jars in one of the existing folders, usually lib/core/gateway.

1 Like

Not this one. We copy and rename JARs to another location before loading them (for reasons lost to time) and this idiotic library does some kind of introspection that requires the JAR name to be completely unmodified from how they shipped it.

2 Likes

Could you show me how you got the JCoDestinationManager to work? I am always getting SAP destination does not exist. Script is executing from gateway event and I have tried tag scripts with same result...

I have read the examples from sapjco but I really can't figute how to register the destination.

SAPJCO seems to be loading correctly.

EDIT: It looks like having Sepasoft connector and this kind of script will block from getting a new provider:

It is working fine now!

Thanks!

1 Like