Using RESTful API to get values from multiple devices or pins with Python without timeout errors

Hello Blynk,

I believe this is more a Python question but I would like to check if you have faced this before and could give me some help.

I am trying to build a Python script which monitors the device state (online) and get some pin values from Blynk Server using the code below:

import urllib.request
import time

while True:
    #Checks if device is connected and ONLINE
    device_status_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/isHardwareConnected')
    time.sleep(2) # Delay for 2 seconds.
    device_status = device_status_buffer.read()
    device_status = str(device_status,'utf-8')
    
    #Checks if SMS button is active (SMS notifications YES/NO)
    sms_notification_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V122')
    time.sleep(2) # Delay for 2 seconds.
    sms_notification = sms_notification_buffer.read()
    sms_notification = str(sms_notification,'utf-8')

    #Gets Celphone numbers from App
    cel_1_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V117')
    time.sleep(2) # Delay for 2 seconds.
    cel_1 = cel_1_buffer.read()
    cel_1 = str(cel_1,'utf-8')
    
    cel_2_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V118')
    time.sleep(2) # Delay for 2 seconds.
    cel_2 = cel_2_buffer.read()
    cel_2 = str(cel_2,'utf-8')
    
    cel_3_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V119')
    time.sleep(2) # Delay for 2 seconds.
    cel_3 = cel_3_buffer.read()
    cel_3 = str(cel_3,'utf-8')
    
    cel_4_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V120')
    time.sleep(2) # Delay for 2 seconds.
    cel_4 = cel_4_buffer.read()
    cel_4 = str(cel_4,'utf-8')

    cel_5_buffer = urllib.request.urlopen('http://blynk-cloud.com/AUTH_TOKEN/get/V121')
    time.sleep(2) # Delay for 2 seconds.
    cel_5 = cel_5_buffer.read()
    cel_5 = str(cel_5,'utf-8')

    
    print(device_status)
    print(sms_notification)
    print(cel_1)
    print(cel_2)
    print(cel_3)
    print(cel_4)
    print(cel_5)

As you can see I have added some time.sleep of 2 seconds and the script works fine for some loops, but after a short while it gets 2 errors (below strong) I suspect this is caused by several url request in short time but I dont know how to solve yet any idea?

Traceback (most recent call last):
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 1317, in do_open
encode_chunked=req.has_header(‘Transfer-encoding’))
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 1229, in request
self._send_request(method, url, body, headers, encode_chunked)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 1275, in _send_request
self.endheaders(body, encode_chunked=encode_chunked)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 1224, in endheaders
self._send_output(message_body, encode_chunked=encode_chunked)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 1016, in _send_output
self.send(msg)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 956, in send
self.connect()
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\http\client.py”, line 928, in connect
(self.host,self.port), self.timeout, self.source_address)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\socket.py”, line 727, in create_connection
raise err
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\socket.py”, line 716, in create_connection
sock.connect(sa)
TimeoutError: [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “C:\Users\clucas\Desktop\Blynk_Test.py”, line 21, in
cel_1_buffer = urllib.request.urlopen(‘http://blynk-cloud.com/XXXXX/get/V117’)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 222, in urlopen
return opener.open(url, data, timeout)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 525, in open
response = self._open(req, data)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 543, in _open
‘_open’, req)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 503, in _call_chain
result = func(*args)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 1345, in http_open
return self.do_open(http.client.HTTPConnection, req)
File “C:\Users\clucas\AppData\Local\Programs\Python\Python37-32\lib\urllib\request.py”, line 1319, in do_open
raise URLError(err)
urllib.error.URLError: <urlopen error [WinError 10060] A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond>

I am not familiar with python, but my first guess is that delaying for 2 seconds after accessing a URL means your device is not receiving data when the server is trying to send data. That certainly sound like what those error messages are saying.

Instead of time.sleep - can you do a read() within a loop until the 2 seconds is up?

Hello Dale,

I just tried this, but I still have the same 2 errors. =/

Try putting some debug/print statements before the .urlopen and before the sleep and after the sleep to confirm when the problem happens exactly.

The url in your error message worked for me from a browser returning the content within 46ms

Hello Dale,

Yes the script works if I put big delay, in my example now I have used only one time.sleep(60) at the last line of the code and I dont get errors anymore, but this is only for 1 device, I am planning to use this for several devices which means multiple urlopen. I dont know if this is possible. But if I use a delay of 60 seconds for each device, then the entire script will take around 1 hour to complete (considering 60 devices) this is too much…

well perhaps 10s is enough…

not sure if im too late, but this script works awesome for me. (using python3)

import urllib.request
import time

while True:
 time.sleep( 2 )

 dv = urllib.request.urlopen('http://blynk-cloud.com/AUTHTOKEN/isHardware$')
 mybytes = dv.read()
 devicestatus = mybytes.decode("utf8")
 dv.close()

 d4 = urllib.request.urlopen('http://blynk-cloud.com/AUTHTOKEN/get/d4')
 mybytes = d4.read()
 d4.val = mybytes.decode("utf8")
 d4.close()


 print(devicestatus)
 print(d4.val)

Hello Larry, of course you are not late, maybe you can give me some tips…

Yes it works for 1 or 2 devices, but how can I make it work if for an example I have more than 10 devices? Looks like I cannot make so many url requests in a short time because I get those two error messages… I am not an expert in Python and I believe I am missing something…

I saw somewhere in the forums to not run more that 10 queries per second…

maybe every 5-7 queries, put in a 2 sec sleep ?

how man devices exactly , i’ll just re-run my d4 multi times to test quick.

The example I put on the first topic has 6 queries and I have just tested with a time.sleep(15) and after some successful reads it fails and stop with the same 2 error messages.

with a 60 seconds sleep it runs for a long time and I didn’t see any error, but 60 seconds is too much…

Try this script for me? (edit auth value)

import urllib.request
import time
import json

AUTH = "auth"
while True:
 time.sleep( 2 )

 dv = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/isHardwareConnected')
 mybytes = dv.read()
 devicestatus = mybytes.decode("utf8")
 dv.close()

 print(devicestatus)

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v122')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v117')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v118')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

 time.sleep( 2 )

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v119')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v120')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

 apin = urllib.request.urlopen('http://blynk-cloud.com/'+AUTH+'/get/v121')
 mybytes = apin.read()
 apin.val = mybytes.decode("utf8")
 apin_half = apin.val.strip('["')
 apin.final = apin_half.strip('"]')
 apin.close()

 print(apin.final)

Hello Larry,

I just tested, and the loop was completed succesfully for 3 times and after that the two error messages again…

=(

bummer… it ran for me for a long time (pulling one variable) until i manually stopped it.

Im out of ideas, unless we look at your network speed, internet provider, that kind of stuff.

sorry bout that.

Hey no problem, I appreciate your ideas.

I will try to find or make a kind of script which waits for the response of one urllib request before continue the script so this will not be influenced by any possible slow network… I expect that the responses are delivered in a longer time without stopping the script beause of those two errors.