Qt 6.6.2 c++ opc ua custom structure
-
Hi,
i have to pass data from opc ua server with custom extension object to a cloned structure in my application in order to read/manage data.Custom structure:
i can connect to server and monitoring some node:
void MainWindow::clientConnected() { mClientConnected = true; updateUiState(); connect(mOpcUaClient, &QOpcUaClient::namespaceArrayUpdated, this, &MainWindow::namespacesArrayUpdated); mOpcUaClient->updateNamespaceArray(); //Ore Taglio m_machineCuttingHoursNode.reset(mOpcUaClient->node("ns=2;s=Machine.CuttingHours")); //Job Taglio m_machineActualJobNode.reset(mOpcUaClient->node("ns=2;s=Work.CurrentJob")); //Message Info m_MessageInfos.reset(mOpcUaClient->node("ns=2;s=SystemMessenger.MessageInfos")); //connect QObject::connect(m_machineCuttingHoursNode.data(), &QOpcUaNode::dataChangeOccurred, this, &MainWindow::machineCuttingHoursUpdated); QObject::connect(m_machineActualJobNode.data(), &QOpcUaNode::dataChangeOccurred, this, &MainWindow::machineActualJobUpdated); QObject::connect(m_MessageInfos.data(), &QOpcUaNode::dataChangeOccurred, this, &MainWindow::machineMessageInfosUpdated); //Monitoraggio Parametri m_machineCuttingHoursNode->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(15000)); m_machineActualJobNode->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(15000)); m_MessageInfos->enableMonitoring(QOpcUa::NodeAttribute::Value, QOpcUaMonitoringParameters(15000)); //Lettura Dati m_machineCuttingHoursNode->readAttributes(QOpcUa::NodeAttribute::Value); m_machineActualJobNode->readAttributes(QOpcUa::NodeAttribute::Value); m_MessageInfos->readAttributes(QOpcUa::NodeAttribute::Value); //Monitoraggio Dati QObject::connect(m_machineCuttingHoursNode.data(), &QOpcUaNode::attributeRead, this, &MainWindow::OreTaglio); QObject::connect(m_machineActualJobNode.data(), &QOpcUaNode::attributeRead, this, &MainWindow::ActualJob); QObject::connect(m_MessageInfos.data(), &QOpcUaNode::attributeRead, this, &MainWindow::MessageInfo); //Monitor Finish QObject::connect(m_machineCuttingHoursNode.data(), &QOpcUaNode::enableMonitoringFinished, this, &MainWindow::enableMonitoringFinished); QObject::connect(m_machineActualJobNode.data(), &QOpcUaNode::enableMonitoringFinished, this, &MainWindow::enableMonitoringFinished); QObject::connect(m_MessageInfos.data(), &QOpcUaNode::enableMonitoringFinished, this, &MainWindow::enableMonitoringFinished); }
void MainWindow::machineMessageInfosUpdated(QOpcUa::NodeAttribute attr, const QVariant &value) { Q_UNUSED(attr); MessageInfos = value; qDebug() << "Data Type" << MessageInfos.typeId() << MessageInfos.typeName(); qDebug() << "Variant Type:" << MessageInfos.metaType(); qDebug() << "Raw Data:" << MessageInfos;
qDebug output:
Data Type 65574 QOpcUaExtensionObject
Variant Type: QMetaType(QOpcUaExtensionObject)
Raw Data: QVariant(QOpcUaExtensionObject, )now i have to pass tha data to my custom structure:
struct MessageInfo { QDateTime Timestamp; int MessageLevel; QString MessageSource; QString MessageName; QString MessageText; };
but i can't decode data and store every variable
this is what i can view with my application:
someone can help me?
-
Without real knowledge (so it is easy for me :) ), with some intuition that in the machineMessageInfosUpdated try:
MessageInfo mi = value.value<MessageInfo>();
qDebug() << mi.Timestamp;
etc...@sbelai've tried the same code but all variable was empty
UTC Time QDateTime(Invalid)
MessageLevel 0
MessageName ""
MessageSource ""
MessageText ""probably i can't decode QVariant that contains QOpcUaExtensionObject?
how i can view data contained in QVariant(QOpcUaExtensionObject, )?
-
I think that there is no automatic conversion from an OPC UA object to
struct MessageInfo { QDateTime Timestamp; int MessageLevel; QString MessageSource; QString MessageName; QString MessageText; };
Because QDateTime and QString needs other data to serialize like length... but in the second image the Body is encoded, so some code made that bytes from the MessageInfo struct, therefore if you have that code you should be able to reverse the bytes from that ByteString back to struct. If you do not have access to that code than you have to debug it with changing parts of the input and watching what changes in the stream of bytes.
-
I think that there is no automatic conversion from an OPC UA object to
struct MessageInfo { QDateTime Timestamp; int MessageLevel; QString MessageSource; QString MessageName; QString MessageText; };
Because QDateTime and QString needs other data to serialize like length... but in the second image the Body is encoded, so some code made that bytes from the MessageInfo struct, therefore if you have that code you should be able to reverse the bytes from that ByteString back to struct. If you do not have access to that code than you have to debug it with changing parts of the input and watching what changes in the stream of bytes.
@sbela you're right!
if (value.canConvert<QOpcUaExtensionObject>()) { const auto obj = value.value<QOpcUaExtensionObject>(); std::string EB = obj.encodedBody().toStdString(); qDebug() << "EB" << EB; QString EncodedBody = QString::fromLocal8Bit(EB); qDebug() << "EncodedBody" << EncodedBody; }
give me this:
EB "6\x87\xAC""c6\xF5\xDA\x01\x01\x00\x00\x00\x03\x00\x00\x00""CNC\x0B\x00\x00\x00""CuttingPlan\x03\x02\x00\x00\x00it\f\x00\x00\x00Taglia piano"
EncodedBody "6‡¬c6õÚ\u0001\u0001\u0000\u0000\u0000\u0003\u0000\u0000\u0000CNC\u000B\u0000\u0000\u0000CuttingPlan\u0003\u0002\u0000\u0000\u0000it\f\u0000\u0000\u0000Taglia piano"Now i have to convert data in order to pass it to my struct
any ideas how to do it?TimeStamp ---> yyyy-mm-ddThh:mm:ss:cccZ
MessageLevel ---> 1 (Info)
Message Souce ---> CNC
Message Name ---> Cutting Plan
Message Text ---> it|Taglia PianoThis "format" viewed with UaExpert
-
This part looks somewhat easy :
"6\x87\xAC""c6\xF5\xDA\x01\x01\x00\x00\x00\x03\x00\x00\x00""CNC\x0B\x00\x00\x00""CuttingPlan\x03\x02\x00\x00\x00it\f\x00\x00\x00Taglia piano"
number of bytes then content. But the time is weird but after that 01 value 01 00 00 00 after that 03 00 00 00 CNC after that 0b (11) CuttingPlan(11) after that 02 00 00 00 'it' after that 0f 00 00 00 Taglia piano(15?)
Date should be encoded in milliseconds: https://reference.opcfoundation.org/Core/Part6/v104/docs/5.2.2.5
This should be the same:"6‡¬c6õÚ\u0001\u0001\u0000\u0000\u0000\u0003\u0000\u0000\u0000CNC\u000B\u0000\u0000\u0000CuttingPlan\u0003\u0002\u0000\u0000\u0000it\f\u0000\u0000\u0000Taglia piano"
but that fromLocal8Bit makes it weird.
What is the output of this ? :if (value.canConvert<QOpcUaExtensionObject>()) { const auto obj = value.value<QOpcUaExtensionObject>(); qDebug() << "EB: " << obj.encodedBody().toHex(); }
-
This part looks somewhat easy :
"6\x87\xAC""c6\xF5\xDA\x01\x01\x00\x00\x00\x03\x00\x00\x00""CNC\x0B\x00\x00\x00""CuttingPlan\x03\x02\x00\x00\x00it\f\x00\x00\x00Taglia piano"
number of bytes then content. But the time is weird but after that 01 value 01 00 00 00 after that 03 00 00 00 CNC after that 0b (11) CuttingPlan(11) after that 02 00 00 00 'it' after that 0f 00 00 00 Taglia piano(15?)
Date should be encoded in milliseconds: https://reference.opcfoundation.org/Core/Part6/v104/docs/5.2.2.5
This should be the same:"6‡¬c6õÚ\u0001\u0001\u0000\u0000\u0000\u0003\u0000\u0000\u0000CNC\u000B\u0000\u0000\u0000CuttingPlan\u0003\u0002\u0000\u0000\u0000it\f\u0000\u0000\u0000Taglia piano"
but that fromLocal8Bit makes it weird.
What is the output of this ? :if (value.canConvert<QOpcUaExtensionObject>()) { const auto obj = value.value<QOpcUaExtensionObject>(); qDebug() << "EB: " << obj.encodedBody().toHex(); }
-
Hex
"7203811f7ef7da010100000003000000434e430b00000043757474696e67506c616e030200000069740c0000005461676c6961207069616e6f"
7203811f7ef7da01 01000000 03000000 434e43 0b000000 43757474696e67506c616e 03 02000000 6974 0c000000 5461676c6961207069616e6f (timestamp LE?) (3) C N C (11) C u t t i n g P l a n (2) i t (12) T a g l i aSP p i a n o
for a decoding more needs more data with different content. And it would be nice to know if possible what is expected to be seen there.
-
7203811f7ef7da01 01000000 03000000 434e43 0b000000 43757474696e67506c616e 03 02000000 6974 0c000000 5461676c6961207069616e6f (timestamp LE?) (3) C N C (11) C u t t i n g P l a n (2) i t (12) T a g l i aSP p i a n o
for a decoding more needs more data with different content. And it would be nice to know if possible what is expected to be seen there.
@sbela as i've already posted with OpcUaExpert i can view the data :
TimeStamp ---> yyyy-mm-ddThh:mm:ss:mmmZ
MessageLevel ---> 1 (Info)
Message Souce ---> CNC
Message Name ---> Cutting Plan
Message Text ---> it|Taglia PianoEnumeration types defines Message Level:
1 -> Info Level
2 -> Warning Level
3 -> Error LevelIt's also possible that i have more of 1 message:
example: Info and Warning -
@sbela as i've already posted with OpcUaExpert i can view the data :
TimeStamp ---> yyyy-mm-ddThh:mm:ss:mmmZ
MessageLevel ---> 1 (Info)
Message Souce ---> CNC
Message Name ---> Cutting Plan
Message Text ---> it|Taglia PianoEnumeration types defines Message Level:
1 -> Info Level
2 -> Warning Level
3 -> Error LevelIt's also possible that i have more of 1 message:
example: Info and Warning@TheCipo76
I did not mean this. Sorry for my english.
I mean that needs multiple different input data with their respective output bytes to determine what is it used for the 01000000 after the date and the 03 between the text and the 02000000 and of course to decode the date format (is it milliseconds since when, or is it nanoseconds since 1600 as the standard describes and so on...) .7203811f7ef7da01 01000000 03000000 434e43 0b000000 43757474696e67506c616e 03 02000000 6974 0c000000 5461676c6961207069616e6f (timestamp LE?) (3) C N C (11) C u t t i n g P l a n (2) i t (12) T a g l i aSP p i a n o
-
@sbela as i've already posted with OpcUaExpert i can view the data :
TimeStamp ---> yyyy-mm-ddThh:mm:ss:mmmZ
MessageLevel ---> 1 (Info)
Message Souce ---> CNC
Message Name ---> Cutting Plan
Message Text ---> it|Taglia PianoEnumeration types defines Message Level:
1 -> Info Level
2 -> Warning Level
3 -> Error LevelIt's also possible that i have more of 1 message:
example: Info and Warning@TheCipo76 said in Qt 6.6.2 c++ opc ua custom structure:
OpcUaExpert
As I see the OpcUaExpert is a software which you can buy and ask for support... Is it true? Did you try to ask them how they decode this custom struct ?
-
@TheCipo76 said in Qt 6.6.2 c++ opc ua custom structure:
OpcUaExpert
As I see the OpcUaExpert is a software which you can buy and ask for support... Is it true? Did you try to ask them how they decode this custom struct ?
-
@TheCipo76
I did not mean this. Sorry for my english.
I mean that needs multiple different input data with their respective output bytes to determine what is it used for the 01000000 after the date and the 03 between the text and the 02000000 and of course to decode the date format (is it milliseconds since when, or is it nanoseconds since 1600 as the standard describes and so on...) .7203811f7ef7da01 01000000 03000000 434e43 0b000000 43757474696e67506c616e 03 02000000 6974 0c000000 5461676c6961207069616e6f (timestamp LE?) (3) C N C (11) C u t t i n g P l a n (2) i t (12) T a g l i aSP p i a n o
-
@TheCipo76
I did not mean this. Sorry for my english.
I mean that needs multiple different input data with their respective output bytes to determine what is it used for the 01000000 after the date and the 03 between the text and the 02000000 and of course to decode the date format (is it milliseconds since when, or is it nanoseconds since 1600 as the standard describes and so on...) .7203811f7ef7da01 01000000 03000000 434e43 0b000000 43757474696e67506c616e 03 02000000 6974 0c000000 5461676c6961207069616e6f (timestamp LE?) (3) C N C (11) C u t t i n g P l a n (2) i t (12) T a g l i aSP p i a n o
-
@TheCipo76 It is simple. You need an ASCII code table and two hex number is one byte (eg. CNC = 43 4e 43 ) 8 hex number is one 32 bit int and so on ...
If you post a few more different outputs (and inputs if you have) i will try to help you reverse engineer the bytes! -
@TheCipo76 It is simple. You need an ASCII code table and two hex number is one byte (eg. CNC = 43 4e 43 ) 8 hex number is one 32 bit int and so on ...
If you post a few more different outputs (and inputs if you have) i will try to help you reverse engineer the bytes!Hex "6915640ba6fada010100000003000000434e430b00000043757474696e67506c616e030200000069740c0000005461676c6961207069616e6f"
i can't understand why some bytes can converted and others give unreadable result
id���������CNC���CuttingPlan���it���Taglia piano
any ideas?
-
Hex "6915640ba6fada010100000003000000434e430b00000043757474696e67506c616e030200000069740c0000005461676c6961207069616e6f"
i can't understand why some bytes can converted and others give unreadable result
id���������CNC���CuttingPlan���it���Taglia piano
any ideas?
@TheCipo76 do you mean things like this '�' ?
It is because it is not a character code.
From the last post as I see the Hex output those bytes which I can not reverse engineer it does not changed. But the content is also the same so it might be that is the problem. Can you post Hex output with different content ?
The open62541 have DateTime conversion routines, did you try any of those ? -
@TheCipo76 do you mean things like this '�' ?
It is because it is not a character code.
From the last post as I see the Hex output those bytes which I can not reverse engineer it does not changed. But the content is also the same so it might be that is the problem. Can you post Hex output with different content ?
The open62541 have DateTime conversion routines, did you try any of those ?@sbela my goal is to check when machine is working and when not working..
the info i've posted is normal operativityi haven't find any DateTime conversion routines in the documentation
can you show me where do you see about this routines?the documentation tell that encoding type is ByteString but if Server mix different type of data how i can separate and decode it
without any other information (i.e. length..)? I think this is the real question.. -
@sbela my goal is to check when machine is working and when not working..
the info i've posted is normal operativityi haven't find any DateTime conversion routines in the documentation
can you show me where do you see about this routines?the documentation tell that encoding type is ByteString but if Server mix different type of data how i can separate and decode it
without any other information (i.e. length..)? I think this is the real question..@TheCipo76 said in Qt 6.6.2 c++ opc ua custom structure:
decode it
without any other information (i.e. length..)?You have to know the datatype. The length is there as you can see it.