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

device.open() => self.send_packet_sync_and_get_response(packet_to_send) # raises TimeoutException #7

Closed
tieum357 opened this issue Dec 1, 2017 · 18 comments
Labels

Comments

@tieum357
Copy link

tieum357 commented Dec 1, 2017

Hello,
I'm not sure if it is the good place to post my problem..
I try to use this library with a xbee S2C 2.4ghz digimesh, plugged on a sparkfun usb explorer.
Xbee configured on API2 with XCTU.

I try to make the delivered example of receive data. So I write the python script and run it.
But when it enter in device.open() I have this error :

File "C:\Program Files (x86)\Python36-32\lib\site-packages\digi_xbee-1.0.0-py3.6.egg\digi\xbee\devices.py", line 1290, in open
self.read_device_info()
File "C:\Program Files (x86)\Python36-32\lib\site-packages\digi_xbee-1.0.0-py3.6.egg\digi\xbee\devices.py", line 309, in read_device_info
self._hardware_version = HardwareVersion.get(self.get_parameter("HV")[0])
File "C:\Program Files (x86)\Python36-32\lib\site-packages\digi_xbee-1.0.0-py3.6.egg\digi\xbee\devices.py", line 1028, in dec_function
return func(self, *args, **kwargs)
File "C:\Program Files (x86)\Python36-32\lib\site-packages\digi_xbee-1.0.0-py3.6.egg\digi\xbee\devices.py", line 1336, in get_parameter
response = self.send_packet_sync_and_get_response(packet_to_send) # raises TimeoutException
File "C:\Program Files (x86)\Python36-32\lib\site-packages\digi_xbee-1.0.0-py3.6.egg\digi\xbee\devices.py", line 2450, in send_packet_sync_and_get_response
raise TimeoutException("Response not received in the configured timeout.")
digi.xbee.exception.TimeoutException

I have same error on Windows7 or on Raspbian. I try different settings of Baud_rate but same error.

Could anyone help me to understand if I make a configuration error ?

Thank you

@rubenmoral
Copy link
Member

Hi @tieum357,

Thanks for reporting this problem, we have just fixed it in master (840c024), it will be included in the next release. In the meantime, if you don't want to download the fix, you can change the operating mode of your module to API1 with XCTU.

Best regards.

@pdtwonotes
Copy link

pdtwonotes commented Jan 22, 2018

Shouldn't this have also fixed remoteDevice.set_io_sampling_rate ? I installed the fix and got past xbee.open() but now it times out when I try to set the sampling rate of one of my End nodes.

Traceback (most recent call last):
  File "./robot.py", line 284, in <module>
    pir_rate( 1.2 )
  File "./robot.py", line 32, in pir_rate
    pir.set_io_sampling_rate( interval )
  File "/usr/local/lib/python3.5/dist-packages/digi_xbee-1.1.0-py3.5.egg/digi/xbee/devices.py", line 682, in set_io_sampling_rate
  File "/usr/local/lib/python3.5/dist-packages/digi_xbee-1.1.0-py3.5.egg/digi/xbee/devices.py", line 4807, in set_parameter
  File "/usr/local/lib/python3.5/dist-packages/digi_xbee-1.1.0-py3.5.egg/digi/xbee/devices.py", line 2425, in send_packet_sync_and_get_response
digi.xbee.exception.TimeoutException

@hgonzaleDigi
Copy link
Collaborator

Hello pdtwonotes,

In order to help you try to find this problem you are seeing, we would need to know more information about your setup:

  • What protocol are you using (ZigBee, DigiMesh, 802.15.4, Cellular...)? Could you give us the hardware and firmware version of your modules, both local and remote (HV and VR commands)?
  • What operating mode are your modules working on (API1 or API2)?
  • Do your modules see each other? To verify this, you can add your local device to XCTU and use the discovery option to see if the remote node gets added to the list of discovered modules.
  • Is your end node an End Device? If so, does it have a sleep setting configured (SM different than 0)? If your module sleeps for too long, maybe the request could get lost.

Regards.

@pdtwonotes
Copy link

pdtwonotes commented Jan 24, 2018

These are all ZigBee devices in API2 mode, firmware 405F, but I think I found the problem. XCTU works fine. Doing some testing, I found that the timeouts happened only some of the time. This made me think that it is just an unreliable form of communication and that all I need to do is retry it. So I put a loop around each synchronous get or set operation that retries in the case of a TimeoutException, and now it works.
This was easy enough to do on the host Python side, where precise timing and memory is not an issue, but now I have to accomplish the same thing in the real-time environment of my Arduino in C++, where I have not been checking for the Transmit Status returns, matching frame_id, and so on..

@MYeager1967
Copy link

I am using this library and sending packets in asynchronous mode and am getting the following error at random times. It repeats many time and then goes back to operating as it should.

Traceback (most recent call last):
File "/usr/local/lib/python3.5/dist-packages/digi/xbee/devices.py", line 5743, in __calculate_timeout
discovery_timeout = utils.bytes_to_int(self.__xbee_device.get_parameter("NT")) / 10
File "/usr/local/lib/python3.5/dist-packages/digi/xbee/devices.py", line 1028, in dec_function
return func(self, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/digi/xbee/devices.py", line 1309, in get_parameter
response = self.send_packet_sync_and_get_response(packet_to_send) # raises TimeoutException
File "/usr/local/lib/python3.5/dist-packages/digi/xbee/devices.py", line 2423, in send_packet_sync_and_get_response
raise TimeoutException("Response not received in the configured timeout.")
digi.xbee.exception.TimeoutException

I thought I had installed the "fix" mentioned here, but maybe not. My XBee's are using API mode 2 and have been rock solid until now. How exactly does one install the fix? Maybe I did something wrong and only thought I fixed it. Maybe this has nothing to do with it. I don't know. The program does what it's supposed to, I just get a log full of errors....

@rubenmoral
Copy link
Member

Hi @MYeager1967,

The fix we mentioned in this issue is included in the latest release, 1.1.1 (https://github.com/digidotcom/python-xbee/releases/tag/1.1.1). If you installed the library through pip, make sure that you have the latest version: pip install digi-xbee --upgrade.

Regards.

@MYeager1967
Copy link

MYeager1967 commented May 28, 2018 via email

@MYeager1967
Copy link

MYeager1967 commented May 29, 2018 via email

@rubenmoral
Copy link
Member

Alright @MYeager1967, then we need more information in order to investigate the issue in depth.

  • What type of modules do you have (hardware version, firmware version)?
  • How many do you have in the network?
  • Could you please send us the code snippet that is failing?

Thanks.

@MYeager1967
Copy link

MYeager1967 commented May 29, 2018 via email

@rubenmoral
Copy link
Member

Hi @MYeager1967,

After taking a look at the code and exception you get, I realized that that exception is produced because the library cannot read the network discovery timeout (NT parameter), which is used to know the maximum time the library should be trying to discover that specific remote device (in xbee_network.discover_device(where)).

If that time cannot be read, as in your case, a default timeout of 20 seconds is used and the TimeoutException is printed out in the console, but the execution continues and the remote device should be discovered without any problem. That's why you cannot catch that exception, because it is not thrown but it is just logged to inform the user.

Regards.

@Hitheshkaranth
Copy link

Hitheshkaranth commented Jun 20, 2018

Hi @rubenmoral

I do have the same problem however in my case :

  Traceback (most recent call last):
  File "/usr/lib/python3.4/threading.py", line 920, in _bootstrap_inner
  self.run()
  File "/usr/lib/python3.4/threading.py", line 868, in run
  self._target(*self._args, **self._kwargs)
  File "RemoteADCSample.py", line 70, in read_adc_task
  value10 = remote_device.get_dio_value(IOLINE_IN_10)
  File "/usr/local/lib/python3.4/dist-packages/digi_xbee-1.1.1-py3.4.egg/digi/xb                                                                                        ee/devices.py", line 852, in get_dio_value
  sample = self.read_io_sample()
  File "/usr/local/lib/python3.4/dist-packages/digi_xbee-1.1.1-py3.4.egg/digi/xb                                                                                        ee/devices.py", line 738, in read_io_sample
  return IOSample(self.get_parameter("IS"))
  File "/usr/local/lib/python3.4/dist-packages/digi_xbee-1.1.1-py3.4.egg/digi/xb                                                                                        ee/devices.py", line 4776, in get_parameter
  response = self._local_xbee_device.send_packet_sync_and_get_response(packet_                                                                                        to_send)  # raises TimeoutException
  File "/usr/local/lib/python3.4/dist-packages/digi_xbee-1.1.1-py3.4.egg/digi/xb                                                                                      ee/devices.py", line 2423, in send_packet_sync_and_get_response
  raise TimeoutException("Response not received in the configured timeout.")
  digi.xbee.exception.TimeoutException

this exception is shooted upon execution of IO sampling for like 4-20 times(it varies almost all the time) I did increase NT value the result remains the same. Post printing of this exception the program seems to be stuck and doesnt execute or close. If you say NT cannot be read by the timeout exception then there should be manual way of entering the time out period am I right here ? If not how can I solve this?
Note: Im using beaglebone Black Rev C with python 3.4 for running IO sampling code Im using python-xbee.1.1.1 and did update it as you mentioned. Im using Xbee S2C hardware with API 1 and firmware version of 405F. Can you guide me here?

My code goes like this:

from digi.xbee.devices import XBeeDevice
from digi.xbee.io import IOLine, IOMode
import time
import threading

# TODO: Replace with the serial port where your local module is connected to.
PORT = "/dev/ttyO1"
# TODO: Replace with the baud rate of your local module.
BAUD_RATE = 9600

REMOTE_NODE_ID = "XBEE_A"

IOLINE_IN = IOLine.DIO0_AD0
IOLINE_IN_1= IOLine.DIO1_AD1
IOLINE_IN_2= IOLine.DIO2_AD2
IOLINE_IN_3= IOLine.DIO3_AD3
IOLINE_IN_4= IOLine.DIO4_AD4
IOLINE_IN_5= IOLine.DIO5_AD5
IOLINE_IN_8= IOLine.DIO8
IOLINE_IN_9= IOLine.DIO9
IOLINE_IN_10=IOLine.DIO10_PWM0
#IOLINE_IN_11=IOLine.DIO11_PWM1
IOLINE_IN_12=IOLine.DIO12

def main():
   stop = False
   th = None
   local_device = XBeeDevice(PORT, BAUD_RATE)
   try:
    local_device.open()

    # Obtain the remote XBee device from the XBee network.
    xbee_network = local_device.get_network()
    remote_device = xbee_network.discover_device(REMOTE_NODE_ID)
    if remote_device is None:
        print("Could not find the remote device")
        exit(1)

    #remote_device.set_io_configuration(IOLine.DIO10_PWM0, IOMode.PWM)

def read_adc_task():
        while not stop:
            # Read the analog value from the remote input line.
            value = remote_device.get_adc_value(IOLINE_IN)
            value = remote_device.get_adc_value(IOLINE_IN)
            value1 = remote_device.get_adc_value(IOLINE_IN_1)
            value2 = remote_device.get_adc_value(IOLINE_IN_2)
            value3 = remote_device.get_adc_value(IOLINE_IN_3)
            value4 = remote_device.get_dio_value(IOLINE_IN_4)
            value5 = remote_device.get_dio_value(IOLINE_IN_5)
            value8 = remote_device.get_dio_value(IOLINE_IN_8)
            value9 = remote_device.get_dio_value(IOLINE_IN_9)
            value10 = remote_device.get_dio_value(IOLINE_IN_10)
            value12 = remote_device.get_dio_value(IOLINE_IN_12)
            if (str(value4)=="IOValue.HIGH"):
              print ("%$XG1"+"1"+"/",end="")
            if (str(value4)=="IOValue.LOW"):
              print ("%$XG1"+"0"+"/",end="")
            if (str(value5)=="IOValue.HIGH"):
              print ("$XG2"+"1"+"/",end="")
            if (str(value5)=="IOValue.LOW"):
              print ("$XG2"+"0"+"/",end="")
            if (str(value8)=="IOValue.HIGH"):
              print ("$XG3"+"1"+"/",end="")
            if (str(value8)=="IOValue.LOW"):
              print ("$XG3"+"0"+"/",end="")
            if (str(value9)=="IOValue.HIGH"):
              print ("%$XGI1"+"1"+"/",end="")
            if (str(value9)=="IOValue.LOW"):
              print ("%$XGI1"+"0"+"/",end="")
            if (str(value10)=="IOValue.HIGH"):
              print ("$XGI2"+"1"+"/",end="")
            if (str(value10)=="IOValue.LOW"):
              print ("$XGI2"+"0"+"/",end="")
            if (str(value12)=="IOValue.HIGH"):
              print ("$XGI3"+"1"+"/",end="")
            if (str(value12)=="IOValue.LOW"):
              print ("$XGI3"+"0"+"/",end="")

            print("%$XA0"+str(value)+"/",end="")
            print("$XA1"+str(value1)+"/",end="")
            print("$XA2"+str(value2)+"/",end="")
            print("$XA3"+str(value3)+"/",end="")
            print(" ")
            time.sleep(0.3)

      th = threading.Thread(target=read_adc_task)
      th.start()
      input()

    finally:
      stop = True
      if th is not None and th.isAlive():
        th.join()
      if local_device is not None and local_device.is_open():
        local_device.close()


if __name__ == '__main__':
    main()

@MYeager1967
Copy link

Rubenmoral, is there any way I can hide that warning? Better would be to do away with it altogether by increasing the timeout but it makes a log EXTREMELY large. Had to go back to the Python 2 version of this program as I can't be eating up that much space with a log. Sorry it's taken me so long to get back to this, work has been hectic...

Thanks!!!

@MYeager1967
Copy link

Ok, I'm now available to dig into this as far as I need to. What can be done to correct this? I've had no luck going back to the Python 2 method of using the hard coded device addresses. The current code polls the network for the address and then uses it. I can print the address and see it, but I haven't had a lot of luck with reproducing the results. I'm assuming that the timeout is during the lookup of the address, so this would be the easiest way to eliminate that. The NT variable is set on the devices, so I'm at a loss there...

@rubenmoral
Copy link
Member

Hi @Hitheshkaranth,

Sorry for the late response. The exception you are getting might be caused by a known issue when obtaining IO samples very frequently. Could you please verify that the IR setting of your remote XBee device (XBEE_A) is set to 0?

Also, as a suggestion, I would change the read_adc_task() method with this one:

def read_adc_task():
    while not stop:
        try:
            # Read all the IO values from the remote device.
            sample = remote_device.read_io_sample()
            value = sample.get_analog_value(IOLINE_IN)
            value1 = sample.get_analog_value(IOLINE_IN_1)
            value2 = sample.get_analog_value(IOLINE_IN_2)
            value3 = sample.get_analog_value(IOLINE_IN_3)
            value4 = sample.get_digital_value(IOLINE_IN_4)
            value5 = sample.get_digital_value(IOLINE_IN_5)
            [...]
        except Exception as e:
            [...]

        time.sleep(0.3)

Here is why:

  • The get_adc_value and get_dio_value methods send the IS command to the remote device to query an IO sample. This sample contains the information of all the active IO lines. To avoid unnecessary traffic on the network, it's much better to use the read_io_sample method and read all the IO values from the sample obtained instead of calling multiple times to the first two methods.
  • It's highly recommended to use a try/except block when working with remote devices to avoid the program to exit in case the communication with them is lost momentarily.

Regards.

@rubenmoral
Copy link
Member

Hi @MYeager1967,

Sorry for the late response. The Python's logging package allows you to change the logging level or even disable all logging calls. To do so, add these lines to your code:

import logging

[...]

logging.disable(logging.ERROR)

You can find more information at https://docs.python.org/3/library/logging.html#logging.disable.

Regards.

@MYeager1967
Copy link

No problem on the time issue @rubenmoral . This will reduce the log size and allow me to see if it's actually interfering with the function of the script itself. Moving things into a virtual environment has bee a challenge. Do you know if it's possible to run the graphical python (IDLE) in the virtual environment???

@rubenmoral
Copy link
Member

@MYeager1967 I'm not very familiar with IDLE, but I think what you want is possible by running python -m idlelib inside your virtual environment.

Regards.

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

No branches or pull requests

6 participants