BAC0 icon indicating copy to clipboard operation
BAC0 copied to clipboard

Difference latency in Read Services

Open Borrelio opened this issue 1 year ago • 9 comments

Hello,

I'm using BAC0 for logging data in SCADA-networks. High resolution of the measurement data is required for data analysis. Therefore, it should be possible to read data with one second per cycle. My program is starting a thread in a specified cycle. In this thread, the data points are updated with the Read Services.


The pictures below shows the updating process of seven data points in a four seconds cycle. Each point in the diagram is a Read Services (diagram1: ReadProperty; diagram2: ReadPropertyMultiple) and the y-axis is shown the latency between the read-request and returning a value.

Latency ReadProperty
ReadProperty
Latency ReadPropertyMultiple
ReadMultiple

Problem

I would expect the latencies to be in the 100ms range. But always the first value to be read in the new thread takes up to a second. The problem seems to be with IOCB.

iocb.wait()  # Wait for BACnet response

If I analyze the network-packages with Wireshark I can see that the bacnet-device answers the read request with few milliseconds.

So why does it take sometimes more than one second, from request to return the value?


To verify that this behavior is due to the library, I tried this:

  • different devices and data points
  • increase of the scanning cycle
  • run read()/ readMultiple() and meusure latency manual on cmd
  • check real latency of bacnet-messages with Wireshark

--> But the result is always the same.


Thank you!

Borrelio avatar Aug 17 '22 11:08 Borrelio

Many things can influence speed on a BACnet network. Especially if dealing with MSTP devices. I didn't design BAC0 for thins kind of speed. Maybe @joelbender can give a few advices.

ChristianTremblay avatar Aug 18 '22 12:08 ChristianTremblay

In threaded applications each thread will need some time to know if there is any work that it needs to do and there is overhead is switching between threads. The BACpypes run() function has a spin parameter which defaults to one second which is the maximum amount of time the asyncore.loop() function will block waiting for IO activity. Reducing the value of this parameter will cause the run() function to "spin" faster giving other Python threads a chance to work.

There is an additional function enable_sleeping() which sets a similar value in case you do not want to change the call to run().

For these types of applications I would recommend using the BACpypes library in a non-threaded application, the MultipleReadProperty.py sample application might be a good starting point. The MultipleReadPropertyHammer.py might be a little harsh because it allows multiple pending read requests to the same device and you can very easily overrun the pending request APDU buffers. You can also adjust the application to use the Read Property Multiple service if it is supported by the target device.

JoelBender avatar Aug 18 '22 14:08 JoelBender

Thanks for the quick response,

@JoelBender I looked at the example programs. In retrospect, the pure use of bacpypes without BAC0 would be more suitable for my application. But at the current time, a general restructuring is to much work.

I have tried to understand what the run() function does and how synchron.loop() is working. The SPIN variable is exactly what the problem caused. For my usage, set SPIN=0.25 manually solved it. Although I'm not sure how this affects efficiency.

The function enable_sleeping() sets only the value between the 'tasks'. So it has no effect of the latency of the first call.

@ChristianTremblay I'm not sure how to be able to change the parameter of the SPIN value from outside the modules, because of its constant. The transfer parameter of function run(spin=SPIN, ...) is also not used in the BAC0 routine.

Maybe I missed a simple solution. But How can I deal with the problem, to change the SPIN value?

Borrelio avatar Aug 20 '22 13:08 Borrelio

@Borrelio If you dont mind me asking what is the use case SCADA and BACnet? At least in north America I have ever seen it used outside of building automation industry typically for commercial building HVAC and lighting systems. Would you be connecting dots between industrial control systems with smart grid and building systems?

bbartling avatar Aug 22 '22 18:08 bbartling

@bbartling
Not quite sure what you are meaning with 'SCADA and BACnet'?! ...but of course can I explain my use case.

I am working on a project at a university in Germany. the focus is on the model-based analysis of control circuits in HVAC systems. A lot of energy saving potential is often available with the correct design of control algorithms. A high resolution of the measurement data is important for the analysis of dynamic processes. But most manufacturers of SCADA software (Sauter, Johnson Controls, ...) limit the resolution and each of them has a different way of exporting the data. In order to generalize all of this, we are currently creating software with the described requirements for the most important bus protocols in building automation.

Borrelio avatar Aug 23 '22 06:08 Borrelio

For old guys like me the building automation systems were Supervisory Control And Data Acquisition (SCADA) systems, it was only until the mid 1980's that the "control logic" was moved. Then somehow the term Industrial Process Control became distinct from Building Automation to emphasize that "we are not them because we need 'real-time' data" and to explain the extra expense of "industrial strength" vs "commodity" components.

There is a cool picture of the Honeywell Selectrographic 6 on slide 3 of this presentation in the Weinhold Chilled Water Plant with Jim Flood at the controls. That same panel also ran the Carrier 19C 1200 ton chillers and the Hydroelectric Plant.

Every application has its own concept of real-time, with the understanding that there will always be some time delay between when a sample was taken and when that value is available for some algorithm to use. Sampling interval, latency and throughput are important and can work against each other. So COV notifications reduce traffic compared to polling, Read Property Multiple reduces round-trip times for multiple KPIs, both of which can reduce network contention, removing store-and-forward routers between differing media, etc.

The while loop inside the run() function is an example of polling at an application level (which is compounded by context switching when using threads), BACpypes3 is based on asyncio which is more like COV notifications and does away with threads.

JoelBender avatar Aug 23 '22 21:08 JoelBender

Super cool information thanks @Joel Bender @.***> ! So what will BACnet S/C throw into this mix??

On Tue, Aug 23, 2022 at 4:25 PM Joel Bender @.***> wrote:

For old guys like me the building automation systems were Supervisory Control And Data Acquisition (SCADA) systems, it was only until the mid 1980's that the "control logic" was moved. Then somehow the term Industrial Process Control became distinct from Building Automation to emphasize that " we are not them because we need 'real-time' data" and to explain the extra expense of "industrial strength" vs "commodity" components.

There is a cool picture of the Honeywell Selectrographic 6 on slide 3 of this presentation http://www.cscos.com/wp-content/uploads/MechHVAC2_HMNewman.pdf in the Weinhold Chilled Water Plant https://fcs.cornell.edu/departments/energy-sustainability/utilities/cooling-home with Jim Flood at the controls. That same panel also ran the Carrier 19C 1200 ton chillers and the Hydroelectric Plant https://fcs.cornell.edu/departments/energy-sustainability/utilities/hydroelectric-plant .

Every application has its own concept of real-time, with the understanding that there will always be some time delay between when a sample was taken and when that value is available for some algorithm to use. Sampling interval, latency and throughput are important and can work against each other. So COV notifications reduce traffic compared to polling, Read Property Multiple reduces round-trip times for multiple KPIs, both of which can reduce network contention, removing store-and-forward routers between differing media, etc.

The while loop inside the run() function is an example of polling at an application level (which is compounded by context switching when using threads), BACpypes3 is based on asyncio which is more like COV notifications and does away with threads.

— Reply to this email directly, view it on GitHub https://github.com/ChristianTremblay/BAC0/issues/341#issuecomment-1224902820, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHC4BHK6VQ4HAEPLXE63UE3V2U6UTANCNFSM56ZIFW5A . You are receiving this because you were mentioned.Message ID: @.***>

bbartling avatar Aug 24 '22 21:08 bbartling

Overhead. More CPU and RAM to wrap packets (small cost), more CPU to encrypt packets (large), more network bandwidth to get the packet to the other end (small with respect to wired Ethernet, large with respect to wireless), more on the destination to validate the source (bi-directional encryption on the TCP connection), more packets if they are fragmented, I've probably forgotten some more of something else.

The tradeoff gained is "secure distance" between the source and destination. Direct wired is nice if you can get it and you can trust that the wires aren't going to be tapped, secured network behind firewalls if you have the IT support and trust the infrastructure (wires, hub/switches, routers, etc), and a point-to-point encrypted tunnel between trusted endpoints may be easier to manage than IP/VPN tunnels.

All of that is going to increase the delay between when the data is sampled and when it's available for work, and all the intermediate spots where the traffic could be delayed is going to increase "delay jitter" or your ability to predict when the data is available.

JoelBender avatar Aug 24 '22 23:08 JoelBender

@Borrelio you can make your tests using develop branch. I've activated the spin parameter as an argument

bacnet = BAC0.lite(spin=0.25)

Let me know if this helps

ChristianTremblay avatar Aug 25 '22 02:08 ChristianTremblay

This issue had no activity for a long period of time. If this issue is still required, please update the status or else, it will be closed. Please note that an issue can be reopened if required.

github-actions[bot] avatar Oct 24 '22 04:10 github-actions[bot]