I am working on a project which requires the data from BMS of our building. The BMS system is using BACNET protocol.
WE want data from many objects. If we make requests one by one for each object, it takes large time. So, we want to make many “bacnet -- readproperty” request in parallel.
To do this, I made a console based application which starts many threads (on same machine). Each thread corresponds to one object and keep logging data it receives from that object. For this, each thread starts a bacrp.exe which is provided with bacnet stack. (in demo applications).
At first, when we send parallel requests, the data got jumbled between different requests. This was because on same machine, different bacrp processes could not differentiate between different responses. We made a tweak in code of bacrp.exe so that it takes the invoke_id from user. With this, we are able to differentiate responses. So now, we are sending different invoke id as a parameter to bacrp.exe.
But now, there is other problem which I am facing. Sometimes, the response which I get from bacrp.exe is empty. I thought it may be that I need to restrict the number of parallel threads running. So, I reduced the number of parallel threads to five. Even then, I was getting empty response from bacrp.exe. The non-empty responses, however, were correctly mapped.
In short, I think I am facing following problem:
If I run more than one instance of bacrp.exe, each with different invoke_id, I get empty result from bacrp.exe.
Can somebody help me to solve this problem.
P.S. - Note that, I am using application and I am not working on network layer.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It is likely that one of the other threads stole the response,
assuming that they are all running using the same UDP port. One
solution is to run a local BBMD (i.e. bacserv) and to have the clients
(i.e. bacrp) use Foreign Device Registration using an alternate and
unique UDP port number (i.e. 47809) through the BBMD. There is also a
more elegant solution of using a virtual router, contributed by Obvius
(use the SVN history for the specific patch): http://svn.code.sf.net/p/bacnet/code/branches/obvius/bacnet-stack/
In another note, there is an environment variable BACNET_INVOKE_ID
that sets the initial Invoke_ID of a client application before it
runs, and that variable can be incremented before each run.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
In our system, there is a system which have a server. All i am doing is to call bacrp with device/object/type i and read the values for the response. When you say i need to run bacserv, do you mean that i have to run one more server and then register all the devices to this server? If so, then it will be difficult task for me as i have large number of devices.
Or you want me to change UDP port on bacrp processes only?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
"bacserv" is just supplying the BBMD (BACnet Broadcast Management Device) so that you can run more than one bacrp process at the same time on the same device. You should only need to change the UDP port and indicate to "bacrp" that it should use Foreign Device Registration (via the BBMD info).
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thank you for helping me out. I am using several UDP ports to request data in parallel and I am able to get data. Sometimes there is an APDU timeout, but retrying will solve that issue. Thanks for your time.
One doubt though - When barserv gets requests, it says device is registered for 60000 seconds. Does it mean that I can collect data for 60000 seconds at max? Or will it register the device again after 60000 seconds?
Harmeet
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The way the demo applications are written, they Register as a Foreign Device every time the application runs, so the timeout is fairly superfluous. It should never timeout for the single bacrp operation, and it will re-register and re-start the timer every time.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi All,
I am working on a project which requires the data from BMS of our building. The BMS system is using BACNET protocol.
WE want data from many objects. If we make requests one by one for each object, it takes large time. So, we want to make many “bacnet -- readproperty” request in parallel.
To do this, I made a console based application which starts many threads (on same machine). Each thread corresponds to one object and keep logging data it receives from that object. For this, each thread starts a bacrp.exe which is provided with bacnet stack. (in demo applications).
At first, when we send parallel requests, the data got jumbled between different requests. This was because on same machine, different bacrp processes could not differentiate between different responses. We made a tweak in code of bacrp.exe so that it takes the invoke_id from user. With this, we are able to differentiate responses. So now, we are sending different invoke id as a parameter to bacrp.exe.
But now, there is other problem which I am facing. Sometimes, the response which I get from bacrp.exe is empty. I thought it may be that I need to restrict the number of parallel threads running. So, I reduced the number of parallel threads to five. Even then, I was getting empty response from bacrp.exe. The non-empty responses, however, were correctly mapped.
In short, I think I am facing following problem:
If I run more than one instance of bacrp.exe, each with different invoke_id, I get empty result from bacrp.exe.
Can somebody help me to solve this problem.
P.S. - Note that, I am using application and I am not working on network layer.
It is likely that one of the other threads stole the response,
assuming that they are all running using the same UDP port. One
solution is to run a local BBMD (i.e. bacserv) and to have the clients
(i.e. bacrp) use Foreign Device Registration using an alternate and
unique UDP port number (i.e. 47809) through the BBMD. There is also a
more elegant solution of using a virtual router, contributed by Obvius
(use the SVN history for the specific patch):
http://svn.code.sf.net/p/bacnet/code/branches/obvius/bacnet-stack/
In another note, there is an environment variable BACNET_INVOKE_ID
that sets the initial Invoke_ID of a client application before it
runs, and that variable can be incremented before each run.
Thanks Steve for your reply. I am using different invoke_id for requests which are made by threads.
Steve, if possible, please point me to some references which may help me to try out the fix you suggested. As i am very new to the bacnet.
Thanks in advance
In one process, start bacserv:
In another process, set the environment and begin reading:
In another process, set the environment and begin reading:
etc.
Hi Steve,
In our system, there is a system which have a server. All i am doing is to call bacrp with device/object/type i and read the values for the response. When you say i need to run bacserv, do you mean that i have to run one more server and then register all the devices to this server? If so, then it will be difficult task for me as i have large number of devices.
Or you want me to change UDP port on bacrp processes only?
"bacserv" is just supplying the BBMD (BACnet Broadcast Management Device) so that you can run more than one bacrp process at the same time on the same device. You should only need to change the UDP port and indicate to "bacrp" that it should use Foreign Device Registration (via the BBMD info).
Hi Steve,
Thank you for helping me out. I am using several UDP ports to request data in parallel and I am able to get data. Sometimes there is an APDU timeout, but retrying will solve that issue. Thanks for your time.
One doubt though - When barserv gets requests, it says device is registered for 60000 seconds. Does it mean that I can collect data for 60000 seconds at max? Or will it register the device again after 60000 seconds?
Harmeet
The way the demo applications are written, they Register as a Foreign Device every time the application runs, so the timeout is fairly superfluous. It should never timeout for the single bacrp operation, and it will re-register and re-start the timer every time.
Thanks Steve. Your useful comments really helped me to work out things at my end. Keep up the good work.