Pytapo 3.3.42 et caméra C210 inopérants

La commande chown sert à modifier le propriétaire des fichiers. Par exemple

là on voit que c’est root:root qui est propriétaire (syntaxe : user:group).

Comme tu te connectes avec l’utilisateur jeedom, peut-être qu’il faut modifier le propriétaire en jeedom:jeedom pour que les testes fonctionnent. Ensuite il faudra passer en www-data:www-data pour que tout fonctionne depuis le plugin script.

De mémoire, Jeedom exécute un chown www-data:www-data sur toute l’arborescence de Jeedom.

Que retournent ls -l ~www-data/html/plugins/script/data/ et ls -l ~www-data/html/plugins/script/data/venv_pytapo/ ?

Je test ça ce soir en rentrant chez moi.
Pour changer le propriétaire en jeedom:jeedom au lieu de root:root, il faudra que je me connecte en root ? Je ne suis pas sûr de savoir comment… (quel MDP?)

non non, le root:root:, c’était un exmple pour te montrer comment voir qui est propriétaire.

jeedom@JeedomAtlas:~$ ls -l ~www-data/html/plugins/script/data/
total 28
-rwxrwxr-x 1 www-data www-data  347 14 mars  13:43 Initiate.PY
-rwxrwxr-x 1 www-data www-data   79  9 juil.  2023 LedOff
-rwxrwxr-x 1 www-data www-data   78  9 juil.  2023 LedOn
-rwxrwxr-x 1 www-data www-data 1142 17 mars   2024 mdate2srt.py
-rwxrwxr-x 1 www-data www-data  577 14 mars  14:18 moveX.PY
drwxrwxr-x 5 www-data www-data 4096 16 mars  08:39 pytapo_venv
-rwxrwxr-x 1 www-data www-data  792 17 mars   2024 start_timelapse.sh
jeedom@JeedomAtlas:~$ ls -l ~www-data/html/plugins/script/data/pytapo_venv/
total 16
drwxrwxr-x 2 www-data www-data 4096 16 mars  08:39 bin
drwxrwxr-x 3 www-data www-data 4096 16 mars  08:39 include
drwxrwxr-x 3 www-data www-data 4096 16 mars  08:39 lib
lrwxrwxrwx 1 www-data www-data    3 16 mars  08:39 lib64 -> lib
-rwxrwxr-x 1 www-data www-data  254 16 mars  08:39 pyvenv.cfg

(J’ai corrigé venv_pytapo par pytapo_venv )

On voit que c’est www-data qui en est propriétaire et c’est certainement pour cela que tu n’arrives pas à installer des module en tant que jeedom.
Il faut donc modifier le propriétaire en jeedom afin de pouvoir faire des essais en ssh avec l’utilisateur jeedom. Pour ce faire :

chown -R jeedom:jeedom ~www-data/html/plugins/script/data/pytapo_venv

Si tu as un message t’indiquant que ce n’est pas possible, ajoute sudo devant.
Ensuite, tu peux relancer les 1ere, 3eme, 4eme et 7eme commandes.

Si tout se passe bien mais que tu as les anciennes versions .

python3 -m pip install --upgrade pytapo python-kasa
jeedom@JeedomAtlas:~$ sudo chown -R jeedom:jeedom ~www-data/html/plugins/script/dat
a/pytapo_venv
[sudo] Mot de passe de jeedom :
jeedom@JeedomAtlas:~$ sudo chown -R jeedom:jeedom ~www-data/html/plugins/script/dat
a/pytapo_venv
jeedom@JeedomAtlas:~$ python3 --version
Python 3.9.2
jeedom@JeedomAtlas:~$ source ~www-data/html/plugins/script/data/pytapo_venv/bin/act
ivate
(pytapo_venv) jeedom@JeedomAtlas:~$ python3 --version
Python 3.11.11
(pytapo_venv) jeedom@JeedomAtlas:~$ python3 -m pip freeze
aiohappyeyeballs==2.6.1
aiohttp==3.11.14
aiosignal==1.3.2
anyio==4.9.0
asyncclick==8.1.8.0
attrs==25.3.0
certifi==2025.1.31
cffi==1.17.1
charset-normalizer==3.4.1
cryptography==44.0.2
frozenlist==1.5.0
idna==3.10
mashumaro==3.15
multidict==6.2.0
propcache==0.3.0
pycparser==2.22
pycryptodome==3.22.0
pytapo==3.3.42
python-kasa==0.10.2
requests==2.32.3
rtp==0.0.4
sniffio==1.3.1
typing_extensions==4.12.2
urllib3==2.3.0
yarl==1.18.3

Ça m’a pas l’air mal tout ça :slight_smile:

En effet, les versions sont les dernières.
Maintenant, tu peux tester le message plus haut.

(pytapo_venv) jeedom@JeedomAtlas:~$ python3 -m pip list | grep kasa
python-kasa        0.10.2
(pytapo_venv) jeedom@JeedomAtlas:~$ python3
Python 3.11.11 (main, Jan 27 2025, 19:41:40) [GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from kasa.transports import KlapTransportV2, KlapTransport
>>> exit()

Bien ! Donc le script pourrait fonctionner maintenant, avec ce venv. Tu peux l’essayer en ssh après avoir activé le venv.

Yes, le script a l’air de se lancer ! Bon y a des erreurs mais parce que maintenant ma caméra est débranchée, il faudra que je regarde ce soir.
Maintenant la question c’est comment je peux travailler dans ce venv via le plugin script ?

(pytapo_venv) jeedom@JeedomAtlas:~$ /var/www/html/plugins/script/data/Initiate.PY
Traceback (most recent call last):
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connection.py", line 198, in _new_conn
    sock = connection.create_connection(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/util/connection.py", line 85, in create_connection
    raise err
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/util/connection.py", line 73, in create_connection
    sock.connect(sa)
OSError: [Errno 113] No route to host

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connectionpool.py", line 787, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connectionpool.py", line 488, in _make_request
    raise new_e
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connectionpool.py", line 464, in _make_request
    self._validate_conn(conn)
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connectionpool.py", line 1093, in _validate_conn
    conn.connect()
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connection.py", line 704, in connect
    self.sock = sock = self._new_conn()
                       ^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connection.py", line 213, in _new_conn
    raise NewConnectionError(
urllib3.exceptions.NewConnectionError: <urllib3.connection.HTTPSConnection object a
t 0xffff8fb2cb90>: Failed to establish a new connection: [Errno 113] No route to ho
st

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
requests/adapters.py", line 667, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/connectionpool.py", line 841, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
urllib3/util/retry.py", line 519, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='192.168.1.47', port=443
): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connect
ion.HTTPSConnection object at 0xffff8fb2cb90>: Failed to establish a new connection
: [Errno 113] No route to host'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/www/html/plugins/script/data/Initiate.PY", line 9, in <module>
    tapo = Tapo(host, user, password)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 132, in __init__
    self.basicInfo = self.getBasicInfo()
                     ^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 1543, in getBasicInfo
    return self.executeFunction(
           ^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 644, in executeFunction
    data = self.performRequest(
           ^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 700, in performRequest
    self.executeAsyncExecutorJob(self.ensureAuthenticated)
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 695, in executeAsyncExecutorJob
    return asyncio.run(job(*args))
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.11.11/lib/python3.11/asyncio/runners.py", line 190, i
n run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.11.11/lib/python3.11/asyncio/runners.py", line 118, i
n run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/pyenv/versions/3.11.11/lib/python3.11/asyncio/base_events.py", line 65
4, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 248, in ensureAuthenticated
    return self.refreshStok()
           ^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 447, in refreshStok
    if self.isSecureConnection():
       ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 354, in isSecureConnection
    res = self.request(
          ^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
pytapo/__init__.py", line 305, in request
    response = session.request(method, url, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/var/www/html/plugins/script/data/pytapo_venv/lib/python3.11/site-packages/
requests/adapters.py", line 700, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='192.168.1.47', port=
443): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.conn
ection.HTTPSConnection object at 0xffff8fb2cb90>: Failed to establish a new connect
ion: [Errno 113] No route to host'))

Il faudra faire un script bash qui reprend les commandes. Il va ressembler à ceci :

#!/bin/sh

#Activation du venv
source ~www-data/html/plugins/script/data/pytapo_venv/bin/activate
# Execution de ton script python
~www-data/html/plugins/script/data/ton_script_python.py $1 $2 $3 $4 # .... et ainsi de suite pour tous les paramètres

Et dans le plugin script, tu dois paramétrer la commande qui lance ce script shell avec les paramètres que tu lui passes. Si les paramètres sont fixes (pas des valeurs de commandes Jeedom du genre #[Maison][Salon][Température]#), alors tu peux les mettre dans le script au lieu des $1 $2 etc.

Si ce n’est pas fait automatiquement par Jeedom, il faut faire chown -R www-data:www-data ~www-data/html/plugins/script/data/pytapo_venv afin de ne pas avoir de problème d’autorisations.

1 « J'aime »

Je ne comprends pas pourquoi tu recommandes d’activer le venv depuis le début. C’est super risqué d’après moi.
Si une autre app/démon utilise la commande « python3 » sans préciser de path alors c’est ce venv ci qui va être utilisé, ca n’est pas ce qu’on veut.

Et comme il est sur debian 11 c’est tout à fait plausible que ca arrive avec plusieurs plugin jeedom.

Le venv ne sera activé que pour l’environnement du script. A la sortie du script et pour tout autre script, le venv n’est pas actif.

Ok merci pour l’explication il faut que je paramètre ça. En terme de performance ça ralentit l’exécution du script d’activer le venv ?

Pas du tout, non. C’est juste un environnement python différent de celui du système qui est chargé.

Mips je suppose que tu imagines un cas où au même moment où j’exécute mon script avec activation du venv, un autre plugin lance une commande simultanée qui se lancerait dans le même venv ?
Moi j’ai pas d’avis sur la question mais j’étais curieux de tester ce que propose Michel :).

@Michel_F j’ai créé et lancé le script bash et je retrouve le même message d’erreur (connexion impossible) que quand je le lance en ssh donc ça fonctionne comme prévu. Maintenant faut que je trouve le temps de reconnecter ma caméra pour tester plus loin.

C’est très certainement ça. Mais je peux t’assurer que l’activation d’un venv n’a d’impacte que sur l’environnement courant (l’instance de shell). Aucun impact sur toutes les commandes simultanées des autres environnements, même du même utilisateur.
Je vais faire un script de test pour démontrer ça.

EDIT : Test fait

Contenu du script cron_venv.sh :

#!/bin/bash

# Sauvegarde de la date et de l'heure
date_heure=$(date +"%Y-%m-%d %H:%M:%S")

# Fonction pour obtenir la version de Python
get_python_version() {
  local version=$(python3 --version 2>&1)
  echo "$date_heure - $version"
}

# Obtention de la version de Python système
get_python_version

# activation du venv
source ~/venv_test/bin/activate

# Obtention de la version de Python du venv
get_python_version

sleep 60
get_python_version

sleep 60
get_python_version

sleep 60
get_python_version

J’ai fait un cron * * * * * ~/cron_venv.sh >> ~/out.t
J’ai laissé 2 exécutions se faire et j’ai testé la version de python3 dans le shell, c’est bien celle du système. J’ai exécuté le script et l’ai interrompu, la version python3 était la même. out.t contenait le résultat de la commande whoami lancée depuis la crontab, d’où le root en première ligne, c’était un test :

root@Jeedom-dev:~# cat out.t
root
2025-03-18 21:23:01 - Python 3.9.2
2025-03-18 21:23:01 - Python 3.11.8
root@Jeedom-dev:~# python3 --version
Python 3.9.2
root@Jeedom-dev:~# ./cron_venv.sh
2025-03-18 21:24:13 - Python 3.9.2
2025-03-18 21:24:13 - Python 3.11.8
^C
root@Jeedom-dev:~# python3 --version
Python 3.9.2

# ...attente et édition de la crontab

root@Jeedom-dev:~# cat out.t
root
2025-03-18 21:23:01 - Python 3.9.2
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.9.2
2025-03-18 21:24:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.11.8
root@Jeedom-dev:~# python3 --version
Python 3.9.2
root@Jeedom-dev:~# ps xf
    PID TTY      STAT   TIME COMMAND
# ... filtré
    415 ?        Ss     0:52 /usr/sbin/cron -f
 861331 ?        S      0:00  \_ /usr/sbin/CRON -f
 861333 ?        Ss     0:00  |   \_ /bin/sh -c ~/cron_venv.sh >> ~/out.t
 861335 ?        S      0:00  |       \_ /bin/bash /root/cron_venv.sh
 861484 ?        S      0:00  |           \_ sleep 60
 861407 ?        S      0:00  \_ /usr/sbin/CRON -f
 861409 ?        Ss     0:00      \_ /bin/sh -c ~/cron_venv.sh >> ~/out.t
 861411 ?        S      0:00          \_ /bin/bash /root/cron_venv.sh
 861488 ?        S      0:00              \_ sleep 60
# ... il y a bien 2 exécutions du script qui tournent en tâche de fond

root@Jeedom-dev:~# cat out.t
root
2025-03-18 21:23:01 - Python 3.9.2
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.9.2
2025-03-18 21:24:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.11.8
root@Jeedom-dev:~# cat out.t
root
2025-03-18 21:23:01 - Python 3.9.2
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.9.2
2025-03-18 21:24:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.11.8
2025-03-18 21:23:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.11.8
2025-03-18 21:24:01 - Python 3.11.8

Voilà comment démontrer que ce que j’avançais est vrai.

EDIT2 : j’ai aussi testé sans interrompre le script si jamais quelqu’un se posait la question :

root@Jeedom-dev:~# python3 --version
Python 3.9.2
root@Jeedom-dev:~# ./cron_venv.sh
2025-03-18 21:45:18 - Python 3.9.2
2025-03-18 21:45:18 - Python 3.11.8
2025-03-18 21:45:18 - Python 3.11.8
2025-03-18 21:45:18 - Python 3.11.8
2025-03-18 21:45:18 - Python 3.11.8
root@Jeedom-dev:~# python3 --version
Python 3.9.2
1 « J'aime »

effectivement, j’ai lu trop vite

bref, on est d’accord qu’il ne faut activer le venv que pour l’execution en cours

2 « J'aime »

Michel j’abuse encore un peu de ton savoir maintenant que ça semble foncctionner. Je vais implémenter les différents scripts listés notamment ici pour piloter ma caméra et je me pose deux questions :

  • vu que pour chaque script je dois créer un « script.PY » lui-même appelé par un « script.sh » qui lance d’abord le venv avant d’appeler le ‹ script.py › , y-at-il un moyen de simplifier ça en créant un seul script « script_venv.sh » qui servirait à activer le venv puis lancer n’importe quel script que je passerai en argument ? Par exemple : (syntaxe à confirmer) :
    2025-03-20 15_07_26-Window

  • pour chacun des scripts listés plus haut, les premières instructions consistent toujours à renseigner les logins/ip de la caméra. Pas pratique à mettre à jour si ces infos changent. J’imagine que je pourrais aisément (si j’étais calé :D) créer un fichier txt avec ces informations, et aller les chercher dans le script ?

  1. Tu peux aussi lancer le script de cette manière (pas sûr de la version de python, c’est pour exemple) et sans activer le venv :
/opt/pyenv/versions/3.11.10/bin/python3 ton_script.py
  1. En effet, tu pourrais. Il s’agirait d’importer une classe qui contient ces informations et non pas un fichier texte.
    Fichier classe info.py à mettre dans le répertoire data :
class Info():
  USER = 'ton user'
  PASSWORD = 'ton mot de passe'
  HOST = '192.168.1.123'

Depuis ton script (dans le même répertoire data) :


from .info import Info # j'ai rajouté le point devant pour être sûr d'importer le fichier dans le même répertoire et pas un module appelé info

login(Info.USER, Info.PASSWORD) # exemple d'utilisation des variables

Au niveau sécurité c’est pareil que de mettre ces infos dans les scripts, mais ça correspond à ce que tu cherches.

1 « J'aime »