Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to recover from NoResponseFromController #60

Closed
fgervais opened this issue Dec 8, 2017 · 7 comments
Closed

How to recover from NoResponseFromController #60

fgervais opened this issue Dec 8, 2017 · 7 comments

Comments

@fgervais
Copy link
Contributor

fgervais commented Dec 8, 2017

I get a NoResponseFromController exception from Read.py while doing a simple:

bacnet = BAC0.connect("10.59.78.20")
vav = BAC0.device('10.59.50.50', 410, bacnet)
for i in vav.points:
    ...

It's pretty obvious what the problem is but since it happens in an internal BAC0 thread, I'd like to make sure how to properly recover from it.

Should I just:

bacnet = BAC0.connect("10.59.78.20")
vav = BAC0.device('10.59.50.50', 410, bacnet)
for retry in range(10):
    try:
        for i in vav.points:
            ...
    catch NoResponseFromController:
        continue
    break

Also on top of your head could you tell what kind of error handling is done internally on this to get a feel of how bad the exception is. Does it retry like a hundred times before throwing the exception?

@ChristianTremblay
Copy link
Owner

You are pointing to something I should have looked to from a while :)
Since bacpypes switch its internal to use iocb, the code have been changed but not made error proof.

If you look into the core/Read.py file, you will see that each iocb error raise an error. This is proabable not a good choice here.... Depending on the error, it could probably best to return a None.... so the system could continue and as you say, recover from a "no response from controller".

We should not have to handle those errors outside of BAC0.

I'm thinking maybe a simple log.error would be nice enough just to tell the user it didn't work... and continued...

That said, the error handling is done by bacpypes itself and system will not try more than once. I will try something in the "bokeh" branch as I'm working on it these days. Maybe you can have a look and give me feedback

@henkwitte
Copy link

henkwitte commented Dec 11, 2017

Hi, not sure if this would work for you but I have some troubles with connecting to and reading from controllers. Sometimes it works and sometimes it does not.
To catch that in the calling program I set a timout :

import signal

def timeout(signum,frame):
    raise TimeoutError

def my_bacnetroutine
   
    # set signal handler
    signal.signal(signal.SIGALRM, timeout)
    # set signal handler for 60 seconds timeout
    signal.alarm(60)
    try:
        # BAC0 call, in this case connect but could be retrieving data as well
        cntry_pco = BAC0.device(pco_ip, 77000, bacnet, object_list=pco_obj_list,segmentation_supported=False)

     except TimeoutError:
        # your error handing here

    # disable signal handler, if no faults else you will generate a timeouterror after timeout has lapsed
     signal.alarm(0)

In this way your code is not broken but will continue to run.

Cheers,

Henk

@ChristianTremblay
Copy link
Owner

I'm actually working on some FieldServers that trigger a Segmentation Not supported error that leads to this error. I think it's probably the most common source for this trouble.

BAC0 want to get the objects list but the controller is unable to support segmentation and the list is huge...

I've modified the Read.py file so when making a simple read property (which should be done when asking for the object list) if there is a segmentation not supported exception, I'll make another request that will read each property one by one.

Pretty long process (it is faster to pass a custom object_list) like @henkwitte did.... but sometimes, you don't know it yet.

You can test that here : https://github.com/ChristianTremblay/BAC0/tree/bokeh

That said, hope you'll forgive me to put everything in this branch which is the next version of BAC0... I'm not enough confident with my git skills to re-merge this patch after...

@henkwitte
Copy link

henkwitte commented Dec 11, 2017 via email

@fgervais
Copy link
Contributor Author

Thanks I will give the bokeh branch a try probably this week.

@ChristianTremblay
Copy link
Owner

New version is better at handling connectivity errors. I’ll close and see what happen.

@IntoCpp
Copy link

IntoCpp commented Jan 17, 2020

For the conversation: with pull-request #181 which insures that an Except of type "NoResponseFromController" is raised to user, we now simply trap it and do nothing, waiting for things to just start working again. This was sufficient for our needs (power/network issues recovery).

Code sample:

from BAC0.core.io import IOExceptions as BAC0_IOExceptions

device = BAC0.device(ip_address, device_id, bacnet, poll=0)
try:
    print(device[point_index])
except BAC0_IOExceptions.NoResponseFromController as e:
    print("Warning: waiting for device that is no longer responding: [{}].".format(e))
    pass 
except Exception as e:
    print("Warning: device IO Error: [{}].".format(e))
    raise```

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants