How to use EUInformation on a OPC-UA server (C#)? - c#

I'm new in OPC-UA. I looked into the reference SDK and some online tutorial.
I'm creating a OPC-UA server for a simulation of an industrial machine.
I created my xml model with some motors and sensors. They both have an AnalogItemType variable.
I'm taking the motor in example:
<opc:ObjectType SymbolicName="Motor" BaseType="ua:BaseObjectType">
<opc:Description>A motor.</opc:Description>
<opc:Children>
<opc:Variable SymbolicName="Speed" DataType="ua:Double" ValueRank="Scalar" TypeDefinition="ua:AnalogItemType" AccessLevel="ReadWrite" />
<opc:Method SymbolicName="Start" ModellingRule="Mandatory"></opc:Method>
<opc:Method SymbolicName="Stop" ModellingRule="Mandatory"></opc:Method>
</opc:Children>
</opc:ObjectType>
I use the UA.ModelCompiler (from OPC-UA Foundation) to compile the xml and generate the code for the server.
I use the Reference client in the Reference SDK.
When I run my server, I can see only the EURange property of the AnalogItem and not the EngineeringUnits (both should be optional and not mandatory).
I tried to set both in my NodeManager.cs :
Server.Motor.Speed.EURange.Value = new Opc.Ua.Range() {Hingh = 900, Low = 100};
Server.Motor.Speed.EngineeringUnits.Value = new EUInformation("rad", "radiants", "http://www.opcfoundation.org/UA/units/un/cefact");
The first instruction is ok but the second throws an exception because, it says, the EngineeringUnits is null (while the EURange is of type [Variable]EURange).
How can I set the EngineeringUnits (and maybe diable EURange) in my C# code?
How can I enable the EngineeringUnits (and maybe diable EURange) in the MyModelDesign.xml?

Related

Create new items in QuickBooks via C#

I have a C# tool that I wrote to sync orders from a DB to QB, and every step has been a giant pain.
I'm trying to create the line items that we have in our DB in QB so I can attach the invoice items correctly, but our system allows sales staff to enter custom words, so I can't just add all the possible line items to QB through the QB interface.
I have this piece of code here
IMsgSetRequest AddItemRequestMsgSet = sessionManager.CreateMsgSetRequest("US", 8, 0);
AddItemRequestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IItemServiceAdd itemAddRq = AddItemRequestMsgSet.AppendItemServiceAddRq();
itemAddRq.Name.SetValue(Item);
// itemAddRq.ORSalesPurchase.
IMsgSetResponse ItemAddResponseMsgSet = sessionManager.DoRequests(AddItemRequestMsgSet);
IResponse ItemAddResponse = ItemAddResponseMsgSet.ResponseList.GetAt(0);
But this is throwing an error that:
ORSalesPurchase: required field is missing
I haven't the slightest idea of what that means, and for the life of me I can't find anything about ORSalesPurchase or IItemServiceAdd elsewhere on the Internet, including their docs.
I can tell with Visual Studio's autocomplete that itemAddRq.ORSalesPurchase has a bunch of options, but I haven't been able to infer from that what QB is asking for.
What are the required fields for adding a service item to QB?
And if someone can point me to where this is in their docs that would be extra wonderful:)
Stack trace:
System.Runtime.InteropServices.COMException (0x80040307):
ItemServiceAdd ORSalesPurchase: required field is missing End of
ItemServiceAdd
at QBFC12Lib.IQBSessionManager.DoRequests(IMsgSetRequest request)
at SterlingQBExport.Form1.CheckNewInvoices(Object source,
ElapsedEventArgs e) in C:\Users\brian\Documents\Visual Studio
2015\Projects\SterlingQBExport\SterlingQBExport\Form1.cs:line 537
Based on an article I found while searching for ORSalesPurchase ...
C# .NET Application with QuickBooks Desktop Edition
This article is an introduction on how to integrate a .NET application with QuickBooks Desktop Edition using the QuickBooks Foundation Classes (QBFC) Library and C#.
... and the error message, it would seem that you are missing certain fields expected to be part of the requests ORSalesPurchase
Using a sample from the article I would suspect it looks something like the following
//Create the message set request object to hold our request
IMsgSetRequest addItemRequestMsgSet = sessionManager.CreateMsgSetRequest("US", 8, 0);
addItemRequestMsgSet.Attributes.OnError = ENRqOnError.roeContinue;
IItemServiceAdd itemServiceAddRq = addItemRequestMsgSet.AppendItemServiceAddRq();
itemServiceAddRq.Name.SetValue(Item.Name);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.Desc.SetValue(Item.Description);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.ORPrice.Price.SetValue(Item.Price);
itemServiceAddRq.ORSalesPurchase.SalesOrPurchase.AccountRef.FullName.SetValue("Some custom service description here");
//...
Now there was more which seems to infer that the fields set differ based on the items already having a quickbooks id where it was set using
itemServiceModRq.ListID.SetValue(Item.QuickBooksID);
Now, I am not entirely certain what the required fields are at this point, but this should be a good starting point to check if providing the fields above helps.

Call a SAP transaction/program with the SAP 3.0 .NET Connector

I am aware of the option to call RFC-functions with .NCo 3.0 but is it possible to call transactions/programs directly with the SAP Connector? (Like using the fields defined in SAP as parameters and fill them, or use a variation, something like this?).
This answer provides a workaround that I am aware of, and sure - I could call a VBScript from my C# code but that is not what I want to do.
I also checked all of the 64 Questions tagged with sap-connector but there was nowhere a direct answer if it is possible or not.
Also the SAP documentations I got from the SAP marketplace aren't mentioning transactions/programs at all. Does this mean it is not wanted/possible ?
If so, why is it possible to do it with macros/pre-recorded VBScripts but not with the .NET-Connector ? Or am I just doing something wrong ?
When I try to call a program/transaction with the standart-code:
SAPHandle.ECCDestinationConfig cfg = new SAPHandle.ECCDestinationConfig();
RfcDestinationManager.RegisterDestinationConfiguration(cfg);
RfcDestination dest = RfcDestinationManager.GetDestination("QP2");
dest.Ping(); //works fine -> Connection is OK
RfcRepository repo = dest.Repository;
IRfcFunction zzmkalzzm23fnc = repo.CreateFunction("ZMZKALZZM23");
it gives me the following (expectable) error:
metadata for function ZMZKALZZM23 not available: FU_NOT_FOUND:
function module ZMZKALZZM23 is not available
CreateFunction, as the name already suggests, creates a proxy to call a remote-enabled function module in the SAP system. You can't call a transaction or program this way. I am not aware of any way to call a report with SAP .Net Connector. The solution you linked uses SAP Gui, which provides the SAP system with a UI to display graphical elements. AFAIK, SAP NCo doesn't provide such an interface and you can't call reports from NCo.
However, there are products that allow you to execute transactions and catch their output. We are using the product Theobald Xtract to extract SAP ERP data for BI purposes, but they also have a more generic .Net library (Theobald ERPConnect) available that may be able to provide this functionality. It won't be as simple as calling a function and extracting the strongly typed data, but with some filtering you should be able to get the output you need. Those products are not cheap, but they do provide a nice set of functionality you otherwise would have to reinvent yourself.
Some example code how you could call the transaction you ended up calling through VBS-Scripts.
From the Theobald ERPConnect Knowledgbase:
private void button1_Click(object sender, System.EventArgs e)
{
// Reset the batch steps
transaction1.BatchSteps.Clear();
// fill new steps
transaction1.ExecutionMode = ERPConnect.Utils.TransactionDialogMode.ShowOnlyErrors;
transaction1.TCode = "MMBE";
transaction1.AddStepSetNewDynpro("RMMMBEST","1000");
transaction1.AddStepSetOKCode("ONLI");
transaction1.AddStepSetCursor("MS_WERKS-LOW");
transaction1.AddStepSetField("MS_MATNR-LOW",textBox1.Text);
transaction1.AddStepSetField("MS_WERKS-LOW",textBox2.Text);
// connect to SAP
r3Connection1.UseGui = true;
R3Connection r3Connection1= new R3Connection("SAPServer",00,"SAPUser","Password","EN","800");
r3Connection1.Open(false);
// Run
transaction1.Execut e();
}

getVersion in SAP BI 4.1 web-service C# .Net Implementation

I am writing a C# code to connect to QAAWS web-service of SAP BI 4.1. Below is the code for same:
BO_Session.EnterpriseCredential objCredential = new BO_Session.EnterpriseCredential();
objCredential.Login = txtUser.Text;
objCredential.Password = TxtPassword.Text;
objCredential.Domain = "server:6400";
objCredential.AuthType = "secEnterprise";
BO_Session.Session objSession = new BO_Session.Session();
BO_Session.SessionInfo objSessionInfo = objSession.login(objCredential,objSession.getVersion([sessionId]));
I need to pass sessionId value to getVersion function in the last line of code. Please help in understanding what value should I pass here.
The Web-service resides in SAP BI 4.1 environment.
Thanks
Well, I found a way which worked. I had added the Web Reference to use the web-service api where-in Session Id needs to be passed as a parameter.
But then I added the dll files as a reference to the project from below mentioned path (where Business Objects Client tools are installed), the code no more needs to pass Session Id as a parameter and thus, the code does not throw any error.
[InstallDirectory]\SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\win32_x86\dotnet\web services\dsws_consumer

WIA 2.0 Duplex scanning

Since Vista, Windows is shipped with WIA 2.0 (wiaaut.dll).
According to the following KB article and many of my findings on various forums, duplex scanning is no longer possible using WIA 2.0. Yet, the article mentions the use of native WIA 2.0, what would make duplex scanning possible.
(https://support.microsoft.com/en-us/kb/2709992)
According to the WIA 2.0 documentation (https://msdn.microsoft.com/en-us/library/windows/desktop/ms630196(v=vs.85).aspx), duplex scanning is possible but using the new WIA_IPS_DOCUMENT_HANDLING_SELECT (3088) property.
My issues are:
I have no idea how to use native WIA, I suspect when using C# its just not possible.
I cant find a way to set the new WIA_IPS_DOCUMENT_HANDLING_SELECT property, as the property is not present in my wiaDevice properties. According to WiaDef.h, its property id is still 3088 and the only possible value is 0x400 (1024).
If anyone could help me (and I think many others) out on this, it would be much appreciated!
Greetings,
M.
After a few more hours of searching I found a clue in the following post.
https://stackoverflow.com/a/7580686/3641369
As I used a one-pass duplex scanner, both front and back sides where scanned at the same time. By setting the device properties (device properties, not item properties) Document_Handling_Select to 5 (Feeder + Duplex) and Pages to 1 and calling the transfer method 2 times, I finally got the font and back side of the scan.
Setting wiaDev.Properties["Document Handling Select"] = 5 specifies the use of the feeder and scanning duplex.
Setting wiaDev.Properties["Pages"] = 1 specifies that the scanner should keep 1 page in memory, this allowing to keep both front side and back side of the page in memory during 1 scan pass.
if (duplex)
{
wiaDev.Properties["Document Handling Select"].set_Value(5);
wiaDev.Properties["Pages"].set_Value(1);
}
Getting the Wia item and setting item properties such as color and dpi.
var item = wiaDev.Items[1];
item.Properties["6146"].set_Value((int)clr);
item.Properties["6147"].set_Value(dpi);
item.Properties["6148"].set_Value(dpi);
Then calling the transfer method twice returns two different images
var img = (ImageFile)wiaCommonDialog.ShowTransfer(item, FormatID.wiaFormatJPEG);
ImageFile imgduplex = null;
if(duplex)
imgduplex = (ImageFile)wiaCommonDialog.ShowTransfer(item, FormatID.wiaFormatJPEG);
Hope this helps someone!

IronPython and Nodebox in C#

My plan:
I'm trying to setup my C# project to communicate with Nodebox to call a certain function which populates a graph and draws it in a new window.
Current situation: [fixed... see Update2]
I have already included all python-modules needed, but im still getting a
Library 'GL' not found
it seems that the pyglet module needs a reference to GL/gl.h, but can't find it due to IronPython behaviour.
Requirement:
The project needs to stay as small as possible without installing new packages. Thats why i have copied all my modules into the project-folder and would like to keep it that or a similar way.
My question:
Is there a certain workaround for my problem or a fix for the library-folder missmatch.
Have read some articles about Tao-Opengl and OpenTK but can't find a good solution.
Update1:
Updated my sourcecode with a small pyglet window-rendering example. Problem is in pyglet and referenced c-Objects. How do i include them in my c# project to be called? No idea so far... experimenting alittle now. Keeping you updated.
SampleCode C#:
ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(null);
ScriptRuntime runtime = new ScriptRuntime(setup);
ScriptEngine engine = Python.GetEngine(runtime);
ScriptSource source = engine.CreateScriptSourceFromFile("test.py");
ScriptScope scope = engine.CreateScope();
source.Execute(scope);
SampleCode Python (test.py):
from nodebox.graphics import *
from nodebox.graphics.physics import Vector, Boid, Flock, Obstacle
flock = Flock(50, x=-50, y=-50, width=700, height=400)
flock.sight(80)
def draw(canvas):
canvas.clear()
flock.update(separation=0.4, cohesion=0.6, alignment=0.1, teleport=True)
for boid in flock:
push()
translate(boid.x, boid.y)
scale(0.5 + boid.depth)
rotate(boid.heading)
arrow(0, 0, 15)
pop()
canvas.size = 600, 300
def main(canvas):
canvas.run(draw)
Update2:
Line 139 [pyglet/lib.py] sys.platform is not win32... there was the error. Fixed it by just using the line:
from pyglet.gl.lib_wgl import link_GL, link_GLU, link_WGL
Now the following Error:
'module' object has no attribute '_getframe'
Kind of a pain to fix it. Updating with results...
Update3:
Fixed by adding following line right after first line in C#-Code:
setup.Options["Frames"] = true;
Current Problem:
No module named unicodedata, but in Python26/DLLs is only a *.pyd file`. So.. how do i implement it now?!
Update4:
Fixed by surfing: link text and adding unicodedata.py and '.pyd to C# Projectfolder.
Current Problem:
'libGL.so not found'... guys.. im almost giving up on nodebox for C#.. to be continued
Update5:
i gave up :/ workaround: c# communicating with nodebox over xml and filesystemwatchers. Not optimal, but case solved.
-X:Frames enables the frames option as runtime (it slows code down a little to have access to the Python frames all the time).
To enable frames when hosting you just need to do:
ScriptRuntimeSetup setup = Python.CreateRuntimeSetup(new Dictionary<string, object>() {
{ "Frames", true }
});
Instead of the null that you're passing now. That's just creating a new dictionary for the options dictionary w/ the contents "Frames" set to true. You can set other options in there as well and in general the -X:Name option is the same here as it is for the command line.

Categories

Resources