jasonacox / tinytuya

Python API for Tuya WiFi smart devices using a direct local area network (LAN) connection or the cloud (TuyaCloud API).
MIT License
868 stars 157 forks source link

Why tinytuya doesn't work with python supervisord? #416

Open castus opened 8 months ago

castus commented 8 months ago

Why is that the tinytuya doesn't work with supervisord? I have a tiny script to control my lights:

#!/usr/bin/python3

import tinytuya
from ping3 import ping

def setDevices():
    val = 990
    tvHost = "192.168.0.10"
    if ping(tvHost, timeout=10) is not None:
        dtv = tinytuya.OutletDevice(
            dev_id="bf55405d047f481050e0a8",
            address=tvHost,
            version=3.3,
            connection_timeout = 10,
            connection_retry_limit = 2,
            connection_retry_delay = 5)
        dtv.set_socketPersistent(True)
        dtv.set_multiple_values({
            '22': val,
            '23': val
        })
        print('Dictionary %r' % dtv.status())
        print("INFO Value set for TV")
    else:
        print("ERRO Value not set, TV is offline")

setDevices()

but when I run this using supervisord, it do nothing. I have log info INFO Value set for Tree , but actually no visible change in the light brightness or color has been made. If I run the script manually using python3 setLights.py, then everything work as expected.

Could you help me resolve this mystery? :)

jasonacox commented 8 months ago

Do you see any errors in the logs with supervisord?

I don't know anything about that supervisord, but it would need to import tinytuya somewhere and your code for the tinytuya functions to work. Your code doesn't show that.

castus commented 8 months ago

Hi @jasonacox, I've updated the code, so that it contains everything. Supervisord is a program to easily set programs to be executed on startup of Linux. Similar to systemd but with the easier configuration.

I've added dtv.status() to the code, and the difference is:

When I run it using: python3 lights.py

Dictionary {'dps': {'23': 990}, 't': 1698783153}

When executing the same script, but under supervisord:

Dictionary {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}

One thing that comes to my mind, is that tinytuya somehow deamonized the process so that it is not under the supervisor child processes.

Are there any other options to debug it more?

castus commented 8 months ago

I've also checked running that python script under systemd and the result is the same. Configuration used:

[Unit]
Description=Lights
After=network.target

[Service]
ExecStart=python3 /root/led-lights/lights.py
Restart=always
User=root

[Install]
WantedBy=multi-user.target

and the result

Dictionary {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}
jasonacox commented 8 months ago

Dictionary {'Error': 'Network Error: Unable to Connect', 'Err': '901', 'Payload': None}

This means that the OS is not allowing it to connect. I suspect some firewall or iptables is blocking this access. Are you using SELinux or AppArmor?

To test, do you get the same thing with this:

sudo python3 lights.py
castus commented 8 months ago

The system that runs it is Proxmox (Proxmox uses Debian GNU/Linux and uses a custom Linux Kernel).

apparmor_status gives me this:

apparmor module is loaded.
18 profiles are loaded.
18 profiles are in enforce mode.
   /usr/bin/lxc-start
   /usr/bin/man
   /usr/lib/NetworkManager/nm-dhcp-client.action
   /usr/lib/NetworkManager/nm-dhcp-helper
   /usr/lib/connman/scripts/dhclient-script
   /usr/sbin/chronyd
   /{,usr/}sbin/dhclient
   lsb_release
   lxc-container-default
   lxc-container-default-cgns
   lxc-container-default-with-mounting
   lxc-container-default-with-nesting
   man_filter
   man_groff
   nvidia_modprobe
   nvidia_modprobe//kmod
   swtpm
   tcpdump
0 profiles are in complain mode.
0 profiles are in kill mode.
0 profiles are in unconfined mode.
2 processes have profiles defined.
2 processes are in enforce mode.
   /usr/sbin/chronyd (805)
   /usr/sbin/chronyd (820)
0 processes are in complain mode.
0 processes are unconfined but have a profile defined.
0 processes are in mixed mode.
0 processes are in kill mode.

Does anything here sounds familiar to you? :)

jasonacox commented 8 months ago

Can you test this and let me know if it works?

sudo python3 lights.py
castus commented 8 months ago

I don't have sudo, I run it as a root user.

I've managed it to work with systemd, by writing a simple bash script to run python in the background

#!/bin/bash

HOME=/root/
python3 /root/led-lights/lights.py &

The issue with this approach is that the python script has to save pid to remove it later.

Now, when I run it with systemctl start lights, they change their dimming and color.

jasonacox commented 8 months ago

I'm not sure if this is helpful, but I asked ChatGPT how to convert a python script into a systemd service: https://chat.openai.com/share/d8c0a9f5-b106-4f18-a3d3-cff3dca4873c and I have done something simliar with tinyllm: https://github.com/jasonacox/TinyLLM/tree/main/llmserver#option---run-as-a-service

DEVARCHI84 commented 6 months ago

Hi @castus ,

have you solved your issue ? I have the same problem using a java program executing tiny script.

DEVARCHI84 commented 6 months ago

I finally fixed my issue. The problem were in localKey. It contains special chars and was bad interpreted.