tinytuya icon indicating copy to clipboard operation
tinytuya copied to clipboard

no timeout if wrong IP

Open ramonetnet opened this issue 2 years ago • 11 comments

I have problems with the DHCP server so my Tuya device changes the IP quite often. I want to detect the "connect timeout" situation, but get a "KeyError" exception instead Any ideas ? My code, quite simple :

d = tinytuya.OutletDevice( DEVICE_ID, DEVICE_IP, DEVICE_KEY )     # connect to device and fetch state
d.set_version(3.3)
d.set_socketRetryLimit(2)                                      # set retry count limit [default 5]
d.set_socketTimeout(2)                                         # set connection timeout in seconds [default 5]
d.set_sendWait(1)                                                 # seconds to wait after sending for a response

try:
        dps = d.detect_available_dps()
except KeyError:
        print( "key error - bye" )
        sys.exit()

ramonetnet avatar Apr 25 '23 09:04 ramonetnet

You could have tinytuya scan for the IP address each time you use it:

d = tinytuya.OutletDevice( DEVICE_ID, "Auto", DEVICE_KEY )     # connect to device and fetch state
d.set_version(3.3)
d.set_socketRetryLimit(2)                                      # set retry count limit [default 5]
d.set_socketTimeout(2)                                         # set connection timeout in seconds [default 5]
d.set_sendWait(1)                                                 # seconds to wait after sending for a response

try:
        dps = d.detect_available_dps()
except:
        print( "error - bye" )
        sys.exit()

jasonacox avatar Apr 26 '23 02:04 jasonacox

There's no way to do that directly, but you can fake it by checking the return value:

d = tinytuya.OutletDevice( DEVICE_ID, DEVICE_IP, DEVICE_KEY )     # connect to device and fetch state
d.set_version(3.3)
d.set_socketRetryLimit(2)                                      # set retry count limit [default 5]
d.set_socketTimeout(2)                                         # set connection timeout in seconds [default 5]
d.set_sendWait(1)                                                 # seconds to wait after sending for a response

try:
        dps = d.detect_available_dps()
        if not dps:
                raise KeyError('Not Found')
except KeyError:
        print( "key error - bye" )
        sys.exit()

uzlonewolf avatar Apr 26 '23 04:04 uzlonewolf

You could have tinytuya scan for the IP address each time you use it:

d = tinytuya.OutletDevice( DEVICE_ID, "Auto", DEVICE_KEY )     # connect to device and fetch state
d.set_version(3.3)
d.set_socketRetryLimit(2)                                      # set retry count limit [default 5]
d.set_socketTimeout(2)                                         # set connection timeout in seconds [default 5]
d.set_sendWait(1)                                                 # seconds to wait after sending for a response

try:
        dps = d.detect_available_dps()
except:
        print( "error - bye" )
        sys.exit()

This is fantastic !!! Where is this feature documented ?

ramonetnet avatar Apr 28 '23 19:04 ramonetnet

Did that work for you @ramonetnet ? Keep in mind that it can be slow (it waits for the device to emit its discovery packet), but can be helpful for devices with low DHCP lease times.

As for documentation... Oops. 😊 I'll tag this for us to add something to README.

jasonacox avatar Apr 29 '23 02:04 jasonacox

Hi, Jason - thanks for your help. It is working right now, yes I dont mind if it's slow, as I read the temperature .. once every 15 minutes. The device is (nice "device scanner" of yours) :

{
    "name": "termometre",
    "id": "bfe483b0ac18224f06dqww",
    "key": "fb9d5ba086f97ed4",
    "mac": "1c:90:ff:da:ad:42",
    "category": "wsdcg",
    "product_name": "LED WIFI T&H Sensor",
    "product_id": "o2c5btmpepi9pzf8",
    "biz_type": 18,
    "model":

"\u63d2\u7535\u6b3e\u6a21\u7ec4\u5f00\u53d1\u5e38\u4f9b\u7535\u6b3e", "sub": false, "icon": " https://images.tuyaeu.com/smart/icon/ay15427647462366edzT/1e738d42af8bebcca4f802f0074f134d.png " },

My problem is not low DHCP lease times, but router power off occuring once a week, and it loses (sometimes) the MAC to IP table.

Never mind - I got the solution I needed.

Documentation : I found a place where you mention this parameter : in this page

https://pypi.org/project/tinytuya/1.12.5/

it says ...

Classes OutletDevice(dev_id, address, local_key=None, dev_type='default') CoverDevice(dev_id, address, local_key=None, dev_type='default') BulbDevice(dev_id, address, local_key=None, dev_type='default') dev_id (str): Device ID e.g. 01234567891234567890 address (str): Device Network IP Address e.g. 10.0.1.99 or 0.0.0.0 to auto-find local_key (str, optional): The encryption key. Defaults to None. dev_type (str): Device type for payload options (see below)

:-))

Missatge de Jason Cox @.***> del dia ds., 29 d’abr. 2023 a les 4:10:

Did that work for you @ramonetnet https://github.com/ramonetnet ? Keep in mind that it can be slow (it waits for the device to emit its discovery packet), but can be helpful for devices with low DHCP lease times.

As for documentation... Oops. 😊 I'll tag this for us to add something to README.

— Reply to this email directly, view it on GitHub https://github.com/jasonacox/tinytuya/issues/337#issuecomment-1528484977, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQU74ICM4MEOY436VHGYSB3XDR2A3ANCNFSM6AAAAAAXKXCNHU . You are receiving this because you were mentioned.Message ID: @.***>

ramonetnet avatar Apr 29 '23 09:04 ramonetnet

Thanks @ramonetnet ! I just added a note to the example in the README as well. Hopefully this will help others.

https://github.com/jasonacox/tinytuya#programming-with-tinytuya

Programming with TinyTuya

After importing tinytuya, you create a device handle for the device you want to read or control. Here is an example for a Tuya smart switch or plug:

import tinytuya

# Connect to Device
d = tinytuya.OutletDevice(
    dev_id='DEVICE_ID_HERE',
    address='IP_ADDRESS_HERE',      # Or set to 'Auto' to auto-discover IP address
    local_key='LOCAL_KEY_HERE', 
    version=3.3)

# Get Status
data = d.status() 
print('set_status() result %r' % data)

# Turn On
d.turn_on()

# Turn Off
d.turn_off()

jasonacox avatar Apr 29 '23 15:04 jasonacox

Hi, Jason - the comment seems good to me

A question, just to know : is "Auto" equivalent to "0.0.0.0" ?

Have a nice day and thanks a lot for your job.

Missatge de Jason Cox @.***> del dia ds., 29 d’abr. 2023 a les 17:28:

Thanks @ramonetnet https://github.com/ramonetnet ! I just added a note to the example in the README as well. Hopefully this will help others.

https://github.com/jasonacox/tinytuya#programming-with-tinytuya Programming with TinyTuya

After importing tinytuya, you create a device handle for the device you want to read or control. Here is an example for a Tuya smart switch or plug:

import tinytuya

Connect to Deviced = tinytuya.OutletDevice(

dev_id='DEVICE_ID_HERE',
address='IP_ADDRESS_HERE',      # Or set to 'Auto' to auto-discover IP address
local_key='LOCAL_KEY_HERE',
version=3.3)

Get Statusdata = d.status() print('set_status() result %r' % data)

Turn Ond.turn_on()

Turn Offd.turn_off()

— Reply to this email directly, view it on GitHub https://github.com/jasonacox/tinytuya/issues/337#issuecomment-1528812838, or unsubscribe https://github.com/notifications/unsubscribe-auth/AQU74IHQZ63ARAOP3BLTH6LXDUXS3ANCNFSM6AAAAAAXKXCNHU . You are receiving this because you were mentioned.Message ID: @.***>

ramonetnet avatar May 01 '23 10:05 ramonetnet

Yes, that works as well (and others) but "Auto" seemed the most intuitive. The code that controls it is here:

https://github.com/jasonacox/tinytuya/blob/06bf90403d7e046d54906509189466efc167dc0c/tinytuya/core.py#L784-L792

jasonacox avatar May 02 '23 03:05 jasonacox

FWIW - if you have a dns server that allows assigning hostnames you can use that instead. Tinytuya resolves them fine from what I can tell.. at least the home assistant add on does lol.

For example I have a cree light given the hostname "kitchen.light.canopy-1.iot.arpa" which always points to the ip based on the MAC address of whatever light I have plugged into the canopy 1 socket.

Beats dealing with dhcp assignments anyway while maintaining centralized dynamic network flexibility (DHCP).

bradennapier avatar Sep 03 '23 06:09 bradennapier

Thanks @bradennapier - What DNS server or router are you using that sets those iot.arpa records?

jasonacox avatar Sep 03 '23 14:09 jasonacox

UniFi udm pro but in general using hostname resolution is useful over IP

bradennapier avatar Sep 06 '23 09:09 bradennapier