tinytuya icon indicating copy to clipboard operation
tinytuya copied to clipboard

How do I wait for internet connection before

Open Electrik-rich546456 opened this issue 3 years ago • 2 comments

Hi @jasonacox Hope you are keeping well?

I have a new problem and thought you may be able to help. I am trying to send signals to smart plug depending if pc is on or in standby the problem is that when the system wakes up it takes about 10s for network to become alive again and in that time my code fails.

So question how do wait for internet connection before proceeding with control attempts.

#!/usr/bin/env python3
from datetime import datetime
import socket
import time
import tinytuya

#time.sleep(80)

def is_connected():
    try:
        #global sleep_time
        #time.sleep(sleep_time)
        # connect to the host -- tells us if the host is actually
        # reachable
        socket.create_connection(("1.1.1.1", 53))
        #print("yes")
        #sleep_time +=1
        return True
    except OSError:
        pass
    return False

c = tinytuya.Cloud() 
id = "<maybe secret>" #Amplifier

turn_off = {
	'commands': [{
		'code': 'switch_1',
		'value': False
	}, {
		'code': 'countdown_1',
		'value': 0
	}]
}

turn_on = {
	'commands': [{
		'code': 'switch_1',
		'value': True
	}, {
		'code': 'countdown_1',
		'value': 0
	}]
}

sleep_time  = 1
time.sleep(sleep_time)
while True:
    time.sleep(sleep_time)
    now = datetime.now()
    print( "connected" ,now if is_connected() else "no internet!" ,now )
    print(sleep_time)
    sleep_time +=1
    if is_connected():
        c.sendcommand(id,turn_on)
        break
    else:
        sleep_time +=1

and the error is socket.gaierror: [Errno -3] Temporary failure in name resolution

So am i missing something? I thought id ask just in case there is a method iI not considered

Electrik-rich546456 avatar Jul 04 '22 11:07 Electrik-rich546456

Your concept is sound. You run an infinite loop waiting for the network to come up then run your commands. I may simplify it a bit:

import socket
import time

def is_connected():
    try:
        socket.setdefaulttimeout(3)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        host = "1.1.1.1"
        port = 53
        server_address = (host, port)
        s.connect(server_address)
    except OSError as error:
        return False
    else:
        s.close()
        return True

while True:
    if(is_connected()):
        print("connected!")
        # do your magic
    else:
        print("not connected!")
        # take a nap
    time.sleep(1)


jasonacox avatar Jul 04 '22 19:07 jasonacox

The tinytuya.Cloud() call connects to the Cloud API to get an auth token, so you can't call it before you have internet.

Personally I wouldn't bother trying to connect to some random server such as 1.1.1.1 and instead just try/except the cloud calls:

#!/usr/bin/env python3
from datetime import datetime
import socket
import time
import tinytuya

id = "<maybe secret>" #Amplifier

turn_off = {
	'commands': [{
		'code': 'switch_1',
		'value': False
	}, {
		'code': 'countdown_1',
		'value': 0
	}]
}

turn_on = {
	'commands': [{
		'code': 'switch_1',
		'value': True
	}, {
		'code': 'countdown_1',
		'value': 0
	}]
}

sleep_time  = 2
retry = 30
while retry > 0:
    time.sleep(sleep_time)
    try:
        c = tinytuya.Cloud(**apiconfig) 
        c.sendcommand(id,turn_on)
        break
    except socket.gaierror:
        retry -= 1

print( "connected" if retry > 0 else "no internet!", datetime.now() )

uzlonewolf avatar Jul 04 '22 19:07 uzlonewolf