[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS 3

Vous avez créé un script LUA dont vous êtes fier, un .sh génial, un programme Python hors du commun, un Tuto, c'est ici que vous pouvez les partager.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Envoyer des commandes à DomoticZ via SMS

Message par Keros »

Envoyer des commandes à DomoticZ via SMS

Ok jusque-là, c'est DomoticZ qui me parlait. Je voudrais bien pouvoir communiquer avec lui.

Pour cette partie, le script de Vil1driver fonctionne très bien :arrow: [LUA] Contrôler domoticz par SMS
  • Le principe
Quand un SMS arrive sur le téléphone, l'application SMS Gateway Utlimate envoi une requête HTTP pour mettre à jour la userviariable SMS (ou un autre nom).
Quand la userviariable SMS change, DomoticZ le détecte et lance le script qui analyse le SMS et réalise différentes opérations.


Il faut faire quelques ajustements pour rendre ce principe compatible avec RaspiSMS.
  • Le transfert des SMS vers DomoticZ
Normalement, si vous en êtes ici, lorsque vous envoyez un SMS à votre modem, il apparait dans les SMS reçus de RapiSMS. Si ce n'est pas le cas, ce n'est pas la peine d'aller plus loin.

RaspiSMS n'a pas de fonction pour transférer les SMS, par contre, c'est un script en python qui traite l'arrivée des SMS et qui envoi les données dans RaspiSMS. J'ai modifié ce fichier pour que les SMS soient également envoyés vers DomoticZ.

Attention, lors d'une mise à jour de RaspiSMS, il est possible que ce fichier soit réinitialisé : vous perdez ainsi la fonction "transfert".

Le fichier gammu_get_unread_sms.py à modifier :

Par défaut, il n'est pas accessible en écriture.
J'ai fait sudo chown pi:pi gammu_get_unread_sms.py pour pouvoir le modifier puis un sudo chown raspisms:www-data gammu_get_unread_sms.py pour le remettre comme il était.

Code : Tout sélectionner

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
# vim: expandtab sw=4 ts=4 sts=4:
#

from __future__ import print_function
import gammu
import sys
import json
import requests

def main():
    state_machine = gammu.StateMachine()
    
    if len(sys.argv) < 2:
        sys.exit(1)
    else :
        state_machine.ReadConfig(Filename=sys.argv[1])
        del sys.argv[1]

    state_machine.Init()

    status = state_machine.GetSMSStatus()

    remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed']

    start = True

    try:
        while remain > 0:
            if start:
                sms = state_machine.GetNextSMS(Start=True, Folder=0)
                start = False
            else:
                sms = state_machine.GetNextSMS(
                    Location=sms[0]['Location'], Folder=0
                )
            remain = remain - len(sms)

            for m in sms :
                if m['State'] != 'UnRead' :
                    continue
                #Mise a jour dans Domoticz
                r = requests.get("http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&idx=1&vname=sms&vtype=2&vvalue="+m['Text']+";%2B"+m['Number'][1:])

                    print(json.dumps({
                        'number': m['Number'],
                        'at': str(m['DateTime']),
                        'status': m['State'],
                        'text': m['Text'],
                        })
                    )
                

    except gammu.ERR_EMPTY:
        #do noting
        return True


if __name__ == '__main__':
    main()

Il a fallu ajouter import requests et la ligne

Code : Tout sélectionner

r = requests.get("http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&idx=1&vname=sms&vtype=2&vvalue="+m['Text']+";%2B"+m['Number'][1:])
Pensez à mettre l'idx de votre uservariable utilisée pour les SMS.

Note : le m['Number'][1:] permet d'enlever le + contenu dans le numéro qui ne passait pas d'ans l'URL.
  • L'envoi des SMS
Il faut remplacer la ligne d'envoi des SMS par l'application par celle que vous avez paramétré au paragraphe Envoyer des SMS depuis un script LUA.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Forcer un reboot de DomoticZ via SMS

Message par Keros »

Forcer un reboot de DomoticZ via SMS

Tout ça, c'est bien, mais ça repose sur le principe que DomoticZ est fonctionnel. En effet, si on lui envoi une demande pour redémarrer alors qu'il est planté, il ne se passera rien.

L'idée est de traiter cette commande directement au niveau du script Python vu au paragraphe précédent. Le script Python voit le SMS avant quelle ne soit transférée à DomoticZ donc, même si DomoticZ est planté, il pourra lancer la commande.

Mon fichier .py avec la gestion du reboot :

Code : Tout sélectionner

    #!/usr/bin/env python3
    # -*- coding: UTF-8 -*-
    # vim: expandtab sw=4 ts=4 sts=4:
    #

    from __future__ import print_function
    import gammu
    import sys
    import json
    import requests
    import subprocess

    def main():
        state_machine = gammu.StateMachine()
        
        if len(sys.argv) < 2:
            sys.exit(1)
        else :
            state_machine.ReadConfig(Filename=sys.argv[1])
            del sys.argv[1]

        state_machine.Init()

        status = state_machine.GetSMSStatus()

        remain = status['SIMUsed'] + status['PhoneUsed'] + status['TemplatesUsed']

        start = True

        try:
            while remain > 0:
                if start:
                    sms = state_machine.GetNextSMS(Start=True, Folder=0)
                    start = False
                else:
                    sms = state_machine.GetNextSMS(
                        Location=sms[0]['Location'], Folder=0
                    )
                remain = remain - len(sms)

                for m in sms :
                    if m['State'] != 'UnRead' :
                        continue
                    #Mise a jour dans Domoticz
                    r = requests.get("http://127.0.0.1:8080/json.htm?type=command&param=updateuservariable&idx=1&vname=sms&vtype=2&vvalue="+m['Text']+";%2B"+m['Number'][1:])
                    
                    #Action directe
                    if m['Number'][1:] == '33612345678' and m['Text'] == 'Reboot DZ --hard':
                        subprocess.run(["/home/pi/domoticz/scripts/restart_domoticz"], shell=True)
                    else :
                        print(json.dumps({
                            'number': m['Number'],
                            'at': str(m['DateTime']),
                            'status': m['State'],
                            'text': m['Text'],
                            })
                        )
                    

        except gammu.ERR_EMPTY:
            #do noting
            return True


    if __name__ == '__main__':
        main()
Vous pouvez même prévoir un sudo reboot ;)

Edit 1 :

jackyhi a rencontré des difficultés avec ce code qui plantaiT son RapsiSMS. Il a modifié l'ordre des conditions. Lien vers ses explications.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Avoir une alerte quand RaspiSMS change de version

Message par Keros »

Avoir une alerte quand RaspiSMS change de version

Nous avons vu précédemment qu'il était nécessaire de modifier le fichier gammu_get_unread_sms.py pour pouvoir transférer les SMS vers DomoticZ. Sauf que RaspiSMS se met à jour avec les mises à jour du Pi : les modifications sont écrasées > RaspiSMS ne transfert plus les SMS vers DomoticZ :?

La solution que j'ai trouvée est de faire un script de vérification de la version : si' la version change, je lance une alerte en envoyant un SMS :mrgreen:

Je trouve la version en lisant le fichier /usr/share/raspisms/VERSION.

J'ai créé un fichier check-raspisms.sh avec le code :

Code : Tout sélectionner

#!/bin/bash

for Raspisms in $(cat /usr/share/raspisms/VERSION); do
	echo $Raspisms
done

if [ $Raspisms = "v3.2.7" ];
then
	echo "Ok"
else
	echo "Raspisms a changé de version"
	/CHEMIN/sendsms.sh "+33612345678" "Raspimsms a change de version." "4d4a00210bc5ed4b9b0e16dc6bfd5d4a"
fi
Il ne reste plus qu'à lancer le fichier pour automatiser la vérification. Voici la ligne que j'ai rajoutée dans ma crontab -e pour avoir une vérification tous les jours à 20h00 :

Code : Tout sélectionner

00 20 * * * /CHEMIN/check_raspisms.sh

Maintenant, je suis prévenu si RaspiSMS change de version. Il me suffit de refaire les modifications dans le fichier gammu_get_unread_sms.py et mettre à jour le numéro de version à contrôler dans le fichier check-raspisms.sh.

Je ne connais pas la fréquence de mise à jour. J'ai mis ceci en place après la première mise à jour que j'ai eue.
Je verrai avec le temps, si les mises à jour sont trop souvent, j'améliorerai le script pour contrôler si le fichier gammu_get_unread_sms.py d'origine a été modifié par la mise à jour. Si non (ce qui doit généralement être le cas), je recollerai le fichier gammu_get_unread_sms.py avec mes modifications automatiquement.
Il restera le cas où le fichier gammu_get_unread_sms.py à évoluer avec la mise à jour : là il faudra refaire le boulot et adapter si besoin.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS

Message par Keros »

Message réservé pour le tuto
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS

Message par Keros »

Message réservé pour le tuto
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS

Message par Keros »

Message réservé pour le tuto
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS

Message par Keros »

Message réservé pour le tuto
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

[Tuto] Communiquer avec DomoticZ en SMS en utilisant RaspiSMS

Message par Keros »

Message réservé pour le tuto
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Utiliser un téléphone avec une application au lieu d'un modem

Message par Keros »

Utiliser un téléphone avec une application au lieu d'un modem

En allant sur le site https://raspisms.fr, je viens de voir qu'ils avaient développé une application pour qu'un téléphone serve de relai des SMS.

Je ne l'ai pas testé, mais cela pourra éviter d'avoir à acheter un modem et de configurer Gamu.
Keros
Messages : 6638
Inscription : 23 juil. 2019, 20:57

Solution native de commande

Message par Keros »

Solution native de commande

Pour info, il existe une fonction native de RaspiSMS pour traiter des commandes par SMS : voici le lien.

Il serait possible de refaire complètement le système en utilisant cette solution, mais c'est du boulot et j'y vois plusieurs limitations :
  • Faire un SMS au format Json
  • Remettre les identifiants dans tous les SMS
  • Refaire le script de gestion
C'est quelque chose que je n'utiliserai pas. Mais je me devais de vous partager cette possibilité afin que vous puissiez faire vos choix ;)

Ce point ne sera donc pas traiter dans le cadre de ce tuto. Merci d'ouvrir une demande séparée.
Répondre