Good day!
In the GuruxDLMSClientExample example, the application is launched with the parameters - IP, port, as well as the parameter 'o' - OutputFile (as I understand the file with DLMS meters objects)
Is there an example of the application launch line and this file (any) for Windows? This would make learning code easier.
thanks
The command-line parameters depend from the meter. -o is optional and it's used to make meter reading faster. I understand that reading DLMS meters can be a real pain. You should also check GXDLMSDirector. I believe it can help you to read your meter.
Thanks for the answer.
Did I understand correctly - if an OutputFile is used, then variables from it are read, otherwise all meter variables are read?
I don’t have a meter yet, but I plan to get it soon. Therefore the question was more theoretical - I wanted to study the code in more detail.
Maybe you have an example of such a file and an example of a launch line (from any meter )?
Or maybe GXDLMSDirector can generate this file (I have not studied this product yet).
There is an association view that describes what kind of functionality meter can offer (registers, etc). Reading the association view is taking a long time and for this reason, the output file parameter is added. You can save it to the file and read it from there.
You can start GuruxDLMSServerExample. It's a simple meter and work against that.
Thanks, the connection with the GuruxDLMSServerExample was established, the file was generated. Now trying to read individual OBIS. Please tell me in what format to specify readObjects variable?
I understand this is a comma-separated OBIS, but in this code uses colon too.
If I indicate this:
readObjects = "1.1.0.0.0.255: 0";
Does not read.
If so:
readObjects = "1.1.0.0.0.255";
Fails with error (p2 == NULL)
How to specify the OBIS I need?
Thanks for the answer.
Trying to read Profile Generic from GuruxDLMSServerExample - OBIS 1.0.99.1.0.255. I try to read ByRange - the server responds with a short message. Does it support reading in this mode?
I try to read ByEntry. The SetValue method returns 258 (DLMS_ERROR_CODE_INVALID_PARAMETER). How to read rows from a profile?
Thanks.
Only an attribute list attribute index is 3.
Another question. I correctly understood that in DLMS each OBIS and its indexes are read by individual requests? There is no possibility of polling several OBIS?
Thanks for the answer. Two more questions:
1. If the exchange is carried out via HDLC, it is necessary to indicate the physical address of the counter (on the bus). How to do it correctly?
2. The Profile Generic object has attribute 4 — the capture period. By standard, it returns a value in seconds (or 0 if not automatic capture). When polling GuruxServer an object 1.0.99.1.0.255 of index 4, value 60 is returned. Do you convert the value to minutes? What will be returned if there is a monthly capture interval?
1. If you have only one counter in the bus you USUALLY can use address 1 for it. There are some older meters that can't handle this.
2. This value is not converted. This is set to zero for monthly interval and "End of billing period" -Script table object calls capture-method of profile generic.
1. If I understand correctly, there is a Wrapper mode - on TCP, there is an HDLC - COM (Rs-485 etc). If there are several counters on the RS-485 bus, then how to correctly set the address in the client?
2. "This value is not converted" - then 60 is what? Minutes?
About the monthly archive - I understood
Each meter has own server address. You can try to count it from the serial number but all the meters are not supporting it. Try to read your meter with GXDLMSDirector. Change "Address Type" from Default to SerialNumber.
How to get the value of CGXDLMSVariant from the classes GXDLMSData, GXDLMSRegister and others without using a row vector (GetValues)?
These classes have a GetValue function, but the GXDLMSObject base class does not. How then is it better to do it?
I wrote a virtual function in GXDLMSObject, which returns an empty CGXDLMSVariant from it. Everything works, but I would not want to change your code.
Of course, I know and tried this method.
It works however, but it is not considered an example of "good" programming.
Why not make the base class a virtual function? For heirs whose function is not overridden, an empty value (or exception) will be returned.
GetValue will work for Register and Data objects, but there are tens of objects that are not using value, and more importantly they are using complex data structures.
GetValue does not work because the data structure of each object is so different. There is no way to return collection of COSEM objects that is required for example with Push Setup.
You're right. Redid it.
Another question. There is a group survey in DLMS. I tried using ReadList. It works fine with GuruxServer, but not with my device. Doesn't even try to send requests to the device. What is the reason for this?
Gurux Director have a group survey? I did not find such a setting.
Do I understand correctly that the Gurux server simulator supports encryption through port 4060?
What parameters should be specified when (password, authentication type, security)? I drove the parameters that are issued in the console window - an error is issued.
Through DLMS Director also failed to connect.
Encryption is supported.
If you are using Short Name referencing use port 4060, but I believe that you want to use Logical Name referencing (it's the default) and you should use port 4061.
Hi,
Do you try to connect to GuruxDLMSServerExample or what is your meter model and type?
You have not set a password because this error is given. AARQRequest failed (258) Invalid parameter.
I am trying from GuruxDLMSClientExample to connect to GuruxDLMSServerExample with encryption. And I can’t do it. What parameters should be specified, for example, in DLMS_AUTHENTICATION_HIGH_GMAC mode
The polling went when I removed the assignment of values to the dedicatedKey, systemTitle, etc. arrays.
Do they need to be set? I thought that you need to specify the value that the server displays in the window.
About SHA I understood. Now I set GMAC but anyway i get a mistake.
Please give an example of the client launch line in DLMS_AUTHENTICATION_HIGH_GMAC mode and the systemTitle, blockCipherKey, dedicatedKey parameters with those parameters that the server has by default (parameters -T,-A,-D,-B). Particularly interested in blockCipherKey
About SHA I understood. Now I set GMAC but anyway i get a mistake.
Please give me an example of the client launch line in DLMS_AUTHENTICATION_HIGH_GMAC mode and the systemTitle, blockCipherKey, dedicatedKey parameters with those parameters that the server has by default (parameters -T,-A,-D,-B). Particularly interested in blockCipherKey
You can command line parameters given below. Those are default keys used by the server. You need to update them to the server-side also if you change them.
-T 4775727578313233 -A D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF -B 000102030405060708090A0B0C0D0E0F -D 00112233445566778899AABBCCDDEEFF
Your meter returns wrong value and indicates that GetApplicationAssociationRequest is not needed.
This is meter issue, but you can fix this if you change this:
if (m_Parser->IsAuthenticationRequired())
to
if (m_Parser->GetAuthentication() > DLMS_AUTHENTICATION_LOW)
If the exchange is carried out over unstable networks (for example, GSM), then it is possible to lose parts of the response. In this case, you need to do a second poll of the same parameter, but for some reason it cannot be done.
I have made the following repeat option:
for (int error_count = 0; error_count < BreakFlagLimit; error_count++)
{
std::vector<CGXByteBuffer> data;
CGXReplyData reply;
int ret = 0;
if ((ret = m_Parser->Read(obj, AttributeIndex, data)) != DLMS_ERROR_CODE_OK ||
(ret = ReadDataBlock(data, reply)) != DLMS_ERROR_CODE_OK ||
(ret = m_Parser->UpdateValue(*obj, AttributeIndex, reply.GetValue()) != DLMS_ERROR_CODE_OK))
{
continue;
}
ret = GetValue(obj, AttributeIndex, Value);
return ret;
}
return DLMS_ERROR_CODE_FALSE;
However, when a second request is executed, the counter responds correctly, but the m_Parser-> GetData method returns DLMS_ERROR_CODE_FALSE until you open and close the session.
This code returns an error:
if (!target->IsComplete())
{
return DLMS_ERROR_CODE_FALSE;
}
The link is a piece of the log.
What is the correct way to re-poll the parameter in case of such errors? https://drive.google.com/uc?export=download&id=1Df0neuXFuTAwnz3pPAj1CKh…
I tried a new version of the client, unfortunately it doesn't work.
I put in 9 tries.
Immediately after the start, I disconnect the wire from the meter, and immediately set it back. The connection is not restored.
Here is the link to the log: https://drive.google.com/uc?export=download&id=1QX1BGiIJPtdwZBOsXrHx10B…
As I understand it, every DLMS request must have a new request ID. And in your implementation, the request is always the same with every new attempt:
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 1/3
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 2/3
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 3/3
Therefore, if the device received a request, but the response was lost, then it will not work.
Client example can handle if message is lost, What you do is you break the connection. The only way to handle it is you established the connection again.
I didn't really understand your answer. If the client loses connection, will it be possible to establish it only if the connection is closed and opened?
Look at my last log (dated August 7) - there I make new polling attempts, and the counter replies something, but the client himself discards such an answer. Why?
The current example tries to resend data if the reply is not received from the meter.
In this case, the connection is still up. What you do when you remove the cable is that you broke the connection. There is no way to find out what is the reason for this and how long the application must wait before trying to establish a new connection.
The application can handle if the GSM network is not working well. It'll try to resend the data,
but it can't handle if GSM network is down.
"The application can handle if the GSM network is not working well."
In the log from August 7th, a situation arose in which the request went away, and the response was lost or corrupted. If you send a request similar to the previous one (as in the current implementation of the example), then the device does not respond.
Now I'm wondering why, if I send a new request as I do in the example of August 7, the counter responds (and it seems even correct), and the client himself discards such an answer. Or is the counter response incorrect?
Hi,
Hi,
The command-line parameters depend from the meter. -o is optional and it's used to make meter reading faster. I understand that reading DLMS meters can be a real pain. You should also check GXDLMSDirector. I believe it can help you to read your meter.
BR,
Mikko
Thanks for the answer.
Thanks for the answer.
Did I understand correctly - if an OutputFile is used, then variables from it are read, otherwise all meter variables are read?
I don’t have a meter yet, but I plan to get it soon. Therefore the question was more theoretical - I wanted to study the code in more detail.
Maybe you have an example of such a file and an example of a launch line (from any meter )?
Or maybe GXDLMSDirector can generate this file (I have not studied this product yet).
Hi,
Hi,
There is an association view that describes what kind of functionality meter can offer (registers, etc). Reading the association view is taking a long time and for this reason, the output file parameter is added. You can save it to the file and read it from there.
You can start GuruxDLMSServerExample. It's a simple meter and work against that.
BR,
Mikko
Thanks, the connection with
Thanks, the connection with the GuruxDLMSServerExample was established, the file was generated. Now trying to read individual OBIS. Please tell me in what format to specify readObjects variable?
I understand this is a comma-separated OBIS, but in this code uses colon too.
If I indicate this:
readObjects = "1.1.0.0.0.255: 0";
Does not read.
If so:
readObjects = "1.1.0.0.0.255";
Fails with error (p2 == NULL)
How to specify the OBIS I need?
Hi,
Hi,
Give command line parameter ex. -g 1.1.0.0.0.255:2
#2 is attribute index number that you want to read.
BR,
Mikko
Thanks for the answer.
Thanks for the answer.
Trying to read Profile Generic from GuruxDLMSServerExample - OBIS 1.0.99.1.0.255. I try to read ByRange - the server responds with a short message. Does it support reading in this mode?
I try to read ByEntry. The SetValue method returns 258 (DLMS_ERROR_CODE_INVALID_PARAMETER). How to read rows from a profile?
Hi,
Hi,
Have you read the capture objects list (Attribute index 2) before reading the buffer?
You must read it first.
BR,
Mikko
Thanks.
Thanks.
Only an attribute list attribute index is 3.
Another question. I correctly understood that in DLMS each OBIS and its indexes are read by individual requests? There is no possibility of polling several OBIS?
Hi,
Hi,
You can read multiple objects using ReadList-method.
Not all meters support it.
BR,
Mikko
Thanks for the answer. Two
Thanks for the answer. Two more questions:
1. If the exchange is carried out via HDLC, it is necessary to indicate the physical address of the counter (on the bus). How to do it correctly?
2. The Profile Generic object has attribute 4 — the capture period. By standard, it returns a value in seconds (or 0 if not automatic capture). When polling GuruxServer an object 1.0.99.1.0.255 of index 4, value 60 is returned. Do you convert the value to minutes? What will be returned if there is a monthly capture interval?
Hi,
Hi,
1. If you have only one counter in the bus you USUALLY can use address 1 for it. There are some older meters that can't handle this.
2. This value is not converted. This is set to zero for monthly interval and "End of billing period" -Script table object calls capture-method of profile generic.
BR,
Mikko
1. If I understand correctly,
1. If I understand correctly, there is a Wrapper mode - on TCP, there is an HDLC - COM (Rs-485 etc). If there are several counters on the RS-485 bus, then how to correctly set the address in the client?
2. "This value is not converted" - then 60 is what? Minutes?
About the monthly archive - I understood
So how to work with several
So how to work with several counters (set addresses) on the RS-485 when working through HDLC?
Hi,
Hi,
Each meter has own server address. You can try to count it from the serial number but all the meters are not supporting it. Try to read your meter with GXDLMSDirector. Change "Address Type" from Default to SerialNumber.
BR,
Mikko
How to get the value of
How to get the value of CGXDLMSVariant from the classes GXDLMSData, GXDLMSRegister and others without using a row vector (GetValues)?
These classes have a GetValue function, but the GXDLMSObject base class does not. How then is it better to do it?
I wrote a virtual function in GXDLMSObject, which returns an empty CGXDLMSVariant from it. Everything works, but I would not want to change your code.
Hi,
Hi,
GXDLMSData::GetValue or GXDLMSRegister::GetValue methods returns value attribute (index #2).
If you have GXDLMSObject* you can check the object type and then get the data.
Something like this:
CGXDLMSObject* it =...
if (it->GetObjectType() == DLMS_OBJECT_TYPE_DATA)
{
CGXDataObject* d = (CGXDataObject*)it;
d->GetValue();
}
BR,
Mikko
Of course, I know and tried
Of course, I know and tried this method.
It works however, but it is not considered an example of "good" programming.
Why not make the base class a virtual function? For heirs whose function is not overridden, an empty value (or exception) will be returned.
Hi,
Hi,
GetValue will work for Register and Data objects, but there are tens of objects that are not using value, and more importantly they are using complex data structures.
GetValue does not work because the data structure of each object is so different. There is no way to return collection of COSEM objects that is required for example with Push Setup.
BR,
Mikko
You're right. Redid it.
You're right. Redid it.
Another question. There is a group survey in DLMS. I tried using ReadList. It works fine with GuruxServer, but not with my device. Doesn't even try to send requests to the device. What is the reason for this?
Gurux Director have a group survey? I did not find such a setting.
Hi,
Hi,
Your meter don't support Multiple references. For this reason, each object must read separately.
https://www.gurux.fi/Gurux.DLMS.Conformance
BR,
Mikko
Do I understand correctly
Do I understand correctly that the Gurux server simulator supports encryption through port 4060?
What parameters should be specified when (password, authentication type, security)? I drove the parameters that are issued in the console window - an error is issued.
Through DLMS Director also failed to connect.
Hi Ingvar,
Hi Ingvar,
Encryption is supported.
If you are using Short Name referencing use port 4060, but I believe that you want to use Logical Name referencing (it's the default) and you should use port 4061.
BR,
Mikko
DLMS Director connected. I'm
DLMS Director connected. I'm trying to connect with my encryption from my code. The keys is set just like an array
Hammered like this:
char* password = NULL;
authentication = DLMS_AUTHENTICATION_HIGH_SHA256;
security = DLMS_SECURITY_AUTHENTICATION;
char dedicatedKey[16]={0x31,0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
char systemTitle[8]={ 0x41,0x42,0x43 ,0x44 ,0x45 ,0x46 ,0x47 ,0x48 };
char authenticationKey[16]={0xD0,0xD1 ,0xD2 ,0xD3 ,0xD4 ,0xD5 ,0xD6 ,0xD7 ,0xD8 ,0xD9 ,0xDA ,0xDB ,0xDC ,0xDD ,0xDE ,0xDF};
char blockCipherKey[16]={ 0x00,0x01 ,0x02 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 ,0x08 ,0x09 ,0x0A ,0x0B ,0x0C ,0x0D ,0x0E ,0x0F };
int ServerAddress = CGXDLMSClient::GetServerAddress(ServerAddressIn,Address,4);
CGXDLMSSecureClient* cl = new CGXDLMSSecureClient(useLogicalNameReferencing, clientAddress, ServerAddress, authentication, password, interfaceType);
cl->GetCiphering()->SetSecurity(security);
cl->SetAutoIncreaseInvokeID(autoIncreaseInvokeID);
CGXByteBuffer bb;
if (systemTitle != NULL)
{
bb.Clear();
bb.SetHexString(systemTitle);
cl->GetCiphering()->SetSystemTitle(bb);
}
if (authenticationKey != NULL)
{
bb.Clear();
bb.SetHexString(authenticationKey);
cl->GetCiphering()->SetAuthenticationKey(bb);
}
if (blockCipherKey != NULL)
{
bb.Clear();
bb.SetHexString(blockCipherKey);
cl->GetCiphering()->SetBlockCipherKey(bb);
}
if (dedicatedKey != NULL)
{
bb.Clear();
bb.SetHexString(dedicatedKey);
cl->GetCiphering()->SetDedicatedKey(bb);
}
Connect does not occur:
[2020-06-02 17:40:15.530] TRACE : (127.0.0.1:4061) Tx: [0012] 7E A0 0A 00 02 00 03 03 93 A0 62 7E
[2020-06-02 17:40:16.036] TRACE : (127.0.0.1:4061) Rx: [0035] 7E A0 21 03 00 02 00 03 73 48 5C 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
[2020-06-02 17:40:16.036] SCRIPT : <<DLMS.Meter>> : AARQRequest failed (258) Invalid parameter.
What can be wrong?
Do you need a password in this mode?
Hi,
Hi,
SHA256 needs the password. Only GMAC doesn't use the password.
BR,
Mikko
What password then need to be
What password then need to be specified? It is not displayed in the server window.
I tried to specify DLMS_AUTHENTICATION_HIGH_GMAC- also does not establish a connection.
[2020-06-03 9:56:27.016] SCRIPT : <<DLMS.Meter>> : read start
[2020-06-03 9:56:27.032] TRACE : (127.0.0.1:4061) Tx: [0012] 7E A0 0A 00 02 00 03 03 93 A0 62 7E
[2020-06-03 9:56:27.536] TRACE : (127.0.0.1:4061) Rx: [0035] 7E A0 21 03 00 02 00 03 73 48 5C 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
[2020-06-03 9:56:27.536] SCRIPT : <<DLMS.Meter>> : AARQRequest failed (258) Invalid parameter.
Code:
char* password = NULL;
authentication = DLMS_AUTHENTICATION_HIGH_GMAC;
security = DLMS_SECURITY_AUTHENTICATION;
char dedicatedKey[16]={0x31,0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31};
char systemTitle[8]={ 0x41,0x42,0x43 ,0x44 ,0x45 ,0x46 ,0x47 ,0x48 };
char authenticationKey[16]={0xD0,0xD1 ,0xD2 ,0xD3 ,0xD4 ,0xD5 ,0xD6 ,0xD7 ,0xD8 ,0xD9 ,0xDA ,0xDB ,0xDC ,0xDD ,0xDE ,0xDF};
char blockCipherKey[16]={ 0x00,0x01 ,0x02 ,0x03 ,0x04 ,0x05 ,0x06 ,0x07 ,0x08 ,0x09 ,0x0A ,0x0B ,0x0C ,0x0D ,0x0E ,0x0F };
Specified the same parameters
Specified the same parameters in GuruxDLMSClientExample - also does not connect.
Log:
TX: 10:30:50 7E A0 07 03 03 93 8C 11 7E
RX: 10:30:50 7E A0 1E 03 03 73 40 CC 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
TX: 10:30:50 7E A0 07 03 03 53 80 D7 7E
RX: 10:30:50 7E A0 1E 03 03 73 40 CC 81 80 12 05 01 80 06 01 80 07 04 00 00 00 01 08 04 00 00 00 01 53 3B 7E
Hi,
Hi,
Do you try to connect to GuruxDLMSServerExample or what is your meter model and type?
You have not set a password because this error is given. AARQRequest failed (258) Invalid parameter.
BR,
Mikko
I am trying from
I am trying from GuruxDLMSClientExample to connect to GuruxDLMSServerExample with encryption. And I can’t do it. What parameters should be specified, for example, in DLMS_AUTHENTICATION_HIGH_GMAC mode
Hi,
Hi,
Try with this:
GuruxDLMSClientExample -h localhost -p 4061 -a HighGmac -t Verbose
BR,
Mikko
The polling went when I
The polling went when I removed the assignment of values to the dedicatedKey, systemTitle, etc. arrays.
Do they need to be set? I thought that you need to specify the value that the server displays in the window.
Hi,
Hi,
Those are default keys. You can also set them, but they must be the same for client and server.
BR,
Mikko
Ok.
Ok.
But why when I ask them - the survey does not go? Did I indicate them incorrectly?
Hi,
Hi,
You haven't set the correct authentication level or some of the keys are not valid.
WIth DLMS_AUTHENTICATION_HIGH_SHA256 you didn't set a password.
BR,
Mikko
About SHA I understood. Now I
About SHA I understood. Now I set GMAC but anyway i get a mistake.
Please give an example of the client launch line in DLMS_AUTHENTICATION_HIGH_GMAC mode and the systemTitle, blockCipherKey, dedicatedKey parameters with those parameters that the server has by default (parameters -T,-A,-D,-B). Particularly interested in blockCipherKey
About SHA I understood. Now I
About SHA I understood. Now I set GMAC but anyway i get a mistake.
Please give me an example of the client launch line in DLMS_AUTHENTICATION_HIGH_GMAC mode and the systemTitle, blockCipherKey, dedicatedKey parameters with those parameters that the server has by default (parameters -T,-A,-D,-B). Particularly interested in blockCipherKey
Hi,
Hi,
You can command line parameters given below. Those are default keys used by the server. You need to update them to the server-side also if you change them.
-T 4775727578313233 -A D0D1D2D3D4D5D6D7D8D9DADBDCDDDEDF -B 000102030405060708090A0B0C0D0E0F -D 00112233445566778899AABBCCDDEEFF
BR,
Mikko
I try with another device -
I try with another device - there is a problem.
In authentication mode Low - everything is correct. But when I set High, the parameter values are not read.
[2020-07-02 17:20:38.319] TRACE : (192.168.100.4:12160) Tx: [0010] 7E A0 08 02 31 61 93 F6 12 7E
[2020-07-02 17:20:39.474] TRACE : (192.168.100.4:12160) Rx: [0035] 7E A0 21 61 02 31 73 19 C2 81 80 14 05 02 00 80 06 02 00 80 07 04 00 00 00 01 08 04 00 00 00 01 CE 6A 7E
[2020-07-02 17:20:39.491] TRACE : (192.168.100.4:12160) Tx: [0079] 7E A0 4D 02 31 61 10 13 43 E6 E6 00 60 3E A1 09 06 07 60 85 74 05 08 01 01 8A 02 07 80 8B 07 60 85 74 05 08 02 02 AC 12 80 10 29 23 BE 84 E1 6C D6 AE 52 90 49 F1 F1 BB E9 EB BE 10 04 0E 01 00 00 00 06 5F 1F 04 00 00 1E 1D FF FF 6A 52 7E
[2020-07-02 17:20:40.739] TRACE : (192.168.100.4:12160) Rx: [0091] 7E A0 59 61 02 31 30 55 FD E6 E7 00 61 4A A1 09 06 07 60 85 74 05 08 01 01 A2 03 02 01 00 A3 05 A1 03 02 01 00 88 02 07 80 89 07 60 85 74 05 08 02 02 AA 12 80 10 31 32 33 34 35 36 37 38 39 30 41 42 43 44 45 46 BE 10 04 0E 08 00 06 5F 1F 04 00 00 18 1D 00 64 00 07 B7 69 7E
[2020-07-02 17:20:40.739] SCRIPT : <<DLMS.Meter>> : Read OBIS 0.0.1.0.0.255 Index 2
[2020-07-02 17:20:40.808] TRACE : (192.168.100.4:12160) Tx: [0028] 7E A0 1A 02 31 61 32 BD 04 E6 E6 00 C0 01 81 00 08 00 00 01 00 00 FF 02 00 65 D7 7E
[2020-07-02 17:20:41.911] TRACE : (192.168.100.4:12160) Rx: [0020] 7E A0 12 61 02 31 52 8F 3B E6 E7 00 C4 01 81 01 0D 7B 6D 7E
[2020-07-02 17:20:41.911] SCRIPT : <<DLMS.Meter>> : Error getting time
I tried it through the DLMSDirector - communication with him is normal. I found out that the request is not being executed in my client, but immediately proceeds to reading the parameters:
17:12:47 Authenticating.
7E A0 2C 02 31 61 32 F4 EB E6 E6 00 C3 01 C1 00 0F 00 00 28 00 00 FF 01 01 09 10 87 32 4A 5D 97 22 18 0E 37 8D EE 7B 05 AA 6D B1 D6 FD 7E
17:12:48
7E A0 25 61 02 31 52 82 DF E6 E7 00 C7 01 C1 00 01 00 09 10 30 4D E9 E3 D6 DD 43 57 59 EA FE 1D EC 2D A8 8B 42 4A 7E
In my client, this happens because the IsAuthenticationRequired method returns False. On the test client - the same thing.
What could be the problem?
Put logs:
https://drive.google.com/file/d/1kTOKY7WItMgCxkWS7N4xRRQgsnpxQIKO/view?…
Hi,
Hi,
Your meter returns wrong value and indicates that GetApplicationAssociationRequest is not needed.
This is meter issue, but you can fix this if you change this:
if (m_Parser->IsAuthenticationRequired())
to
if (m_Parser->GetAuthentication() > DLMS_AUTHENTICATION_LOW)
BR,
Mikko
If the exchange is carried
If the exchange is carried out over unstable networks (for example, GSM), then it is possible to lose parts of the response. In this case, you need to do a second poll of the same parameter, but for some reason it cannot be done.
I have made the following repeat option:
for (int error_count = 0; error_count < BreakFlagLimit; error_count++)
{
std::vector<CGXByteBuffer> data;
CGXReplyData reply;
int ret = 0;
if ((ret = m_Parser->Read(obj, AttributeIndex, data)) != DLMS_ERROR_CODE_OK ||
(ret = ReadDataBlock(data, reply)) != DLMS_ERROR_CODE_OK ||
(ret = m_Parser->UpdateValue(*obj, AttributeIndex, reply.GetValue()) != DLMS_ERROR_CODE_OK))
{
continue;
}
ret = GetValue(obj, AttributeIndex, Value);
return ret;
}
return DLMS_ERROR_CODE_FALSE;
However, when a second request is executed, the counter responds correctly, but the m_Parser-> GetData method returns DLMS_ERROR_CODE_FALSE until you open and close the session.
This code returns an error:
if (!target->IsComplete())
{
return DLMS_ERROR_CODE_FALSE;
}
The link is a piece of the log.
What is the correct way to re-poll the parameter in case of such errors?
https://drive.google.com/uc?export=download&id=1Df0neuXFuTAwnz3pPAj1CKh…
Hi,
Hi,
I can't access your google you shared.
You should sent the generated packet again and wait for the reply. Are you using HDLC or WRAPPER framing?
BR,
Mikko
Correct link:
Sorry. Correct link:
https://drive.google.com/uc?export=download&id=1Df0neuXFuTAwnz3pPAj1CKh…
I Use HDLC
Hi Ingvar,
Hi Ingvar,
We'll improve the client example for ANSI C++ to handle re-sending. It's released today.
BR,
Mikko
ANSI C? Not Cpp Client?
ANSI C? Not Cpp Client?
Is the release already uploaded?
I don't see new commits.
https://github.com/Gurux/GuruxDLMS.c
Hi,
Hi,
The original topic was Cpp DLMS client launch example. Please, if you have a new question create a new topic.
I'll check if we can improve the ANSI C example as well.
BR,
Mikko
I just need it CppClient -
I just need it CppClient - ANSI C not needed
Editing commiting on GitHub?
I tried a new version of the
I tried a new version of the client, unfortunately it doesn't work.
I put in 9 tries.
Immediately after the start, I disconnect the wire from the meter, and immediately set it back. The connection is not restored.
Here is the link to the log:
https://drive.google.com/uc?export=download&id=1QX1BGiIJPtdwZBOsXrHx10B…
As I understand it, every DLMS request must have a new request ID. And in your implementation, the request is always the same with every new attempt:
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 1/3
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 2/3
Read failed.
7E A0 37 03 03 B0 E7 4E 16 01 00 01 00 02 04 12 00 01 11 00 09 06 01 FFData send failed. Try to resend 3/3
Therefore, if the device received a request, but the response was lost, then it will not work.
Hi,
Hi,
Client example can handle if message is lost, What you do is you break the connection. The only way to handle it is you established the connection again.
BR,
Mikko
I didn't really understand
I didn't really understand your answer. If the client loses connection, will it be possible to establish it only if the connection is closed and opened?
Look at my last log (dated August 7) - there I make new polling attempts, and the counter replies something, but the client himself discards such an answer. Why?
Hi,
Hi,
The current example tries to resend data if the reply is not received from the meter.
In this case, the connection is still up. What you do when you remove the cable is that you broke the connection. There is no way to find out what is the reason for this and how long the application must wait before trying to establish a new connection.
The application can handle if the GSM network is not working well. It'll try to resend the data,
but it can't handle if GSM network is down.
BR,
Mikko
BR,
Mikko
"The application can handle
"The application can handle if the GSM network is not working well."
In the log from August 7th, a situation arose in which the request went away, and the response was lost or corrupted. If you send a request similar to the previous one (as in the current implementation of the example), then the device does not respond.
Now I'm wondering why, if I send a new request as I do in the example of August 7, the counter responds (and it seems even correct), and the client himself discards such an answer. Or is the counter response incorrect?