python-broadlink icon indicating copy to clipboard operation
python-broadlink copied to clipboard

timeout too short

Open tyjtyj opened this issue 8 years ago • 7 comments

line 238 Sorry, i dont know how to submit a pull request but please include this change. 1 sec timeout is too short for long packet.

       try:
          self.cs.sendto(packet, self.host)
          self.cs.settimeout(1)
          response = self.cs.recvfrom(1024)
          break

change to

        try:
          self.cs.sendto(packet, self.host)
          self.cs.settimeout(self.timeout)
          response = self.cs.recvfrom(1024)
          break

tyjtyj avatar Dec 26 '16 16:12 tyjtyj

The existing code is supposed to work like this:

  1. Send a packet
  2. Wait up to a second for a response
  3. If there's no response within a second, assume that the packet was dropped and try again
  4. Give up retransmitting once the overall timeout is reached

Just changing the timeout to self.timeout would mean that (3) will never happen, it'll just skip to (4) instead. That means that if a packet is dropped, we'll never try retransmitting it. We'll need to fix this differently. How long a timeout do you actually need?

mjg59 avatar Dec 29 '16 20:12 mjg59

It take 2 sec to send rf code because it super long. So keep retry until throw error because it still takes more than a sec to send

tyjtyj avatar Dec 30 '16 00:12 tyjtyj

Ok, I'll try increasing the timeout to 3 seconds?

mjg59 avatar Dec 30 '16 03:12 mjg59

yeah.. that would be sufficient.

tyjtyj avatar Jan 02 '17 12:01 tyjtyj

It appears that the retry logic isn't working as it should, and an exception is getting thrown after 1 second regardless of the timeout setting. Looking at the code, it appears that the issue is with this code:

try:
    self.cs.sendto(packet, self.host)
    self.cs.settimeout(1)
    response = self.cs.recvfrom(1024)
    break
except socket.timeout:
    if (time.time() - starttime) < self.timeout:
        pass
    raise

The way I read this is that when the send times out after 1 second, the pass statement will simply cause the execution to continue at the next statement which is the raise statement.

It should be:

try:
      self.cs.sendto(packet, self.host)
      self.cs.settimeout(1)
      response = self.cs.recvfrom(1024)
      break
except socket.timeout:
    if (time.time() - starttime) < self.timeout:
        pass
    else:
        raise

gadgetchnnel avatar Jan 14 '17 15:01 gadgetchnnel

Hi

I have had this code change running for a day or so and am still getting numerous timeouts ( 19 in the last 5 hours ). There was an earlier suggested code fix that seemed to work better for me. https://github.com/mjg59/python-broadlink/issues/45#issuecomment-272631782. This change seemed to eliminate the timeouts. Can someone confirm which is the correct logic ?

scrimpys avatar Feb 23 '17 22:02 scrimpys

I have suggested a fix here #70 It is the same logic as suggested by @gadgetchnnel

But the timeout probably still have to be increased to allow sending long signals.

Danielhiversen avatar Feb 24 '17 08:02 Danielhiversen