Recevoir des notifications et effectuer
des commandes envoyées par GSM

avec le modem Ebyre 4G/LTE E840-DTU


 

 

Le matériel .


Le manuel : https://www.ebyte.com/en/downpdf.aspx?id=755.

Ce modem qui possède des entrées RS232 et RS485 est alimenté en 12 ou 24 Volts.
Il possède un nombre restreint de commandes AT aussi l'envoi et la réception de SMS est assez simple ; il faut toutefois respecter la temporisation recommandée par Ebyte pur accéder au mode AT:
'+++' est la séquence d'échappement par défaut. cette commande transfère le modem du mode "données" au mode "commande", elle doit être précédée d'au moins 1 seconde sans caractère et suivi d'une seconde sans caractère.
La commande AT+EXAT remet le modem en mode données.

extrait du manuel PDF, traduit de l'anglais

Entrez dans le mode commande AT et envoyez +++ dans l'assistant port série (sauf que +++ ne permet pas d'envoyer une nouvelle ligne, les autres commandes AT doivent vérifier pour envoyer une nouvelle ligne pour être valide)
vous devez envoyer +++ commande 3s Envoyez toute autre commande AT (sauf pour redémarrer la commande AT) pour entrer complètement dans le mode de commande AT

Envoyer une commande AT valide dans un délai de plus de 2000ms et moins de 3000ms pour entrer normalement en mode AT

 

eb1

Pour le raccordement à un mini PC ou un Raspberry , il faut utiliser un cordon USB/RS232

eb2

- LED rouge fixe: modem sous tension
- LED verte :
.................clignote boot du system
.................fixe le modem est prêt

 

 

Premier pas avec le logiciel Configuration Tools

https://www.ebyte.com/en/pdf-down.aspx?id=1388

eb3

Config Mode exécute la séquence +++ en respectant le timing de 3 secondes comme expliqué plus haut.
Après être passé en Mode AT, nous pouvons envoyer des commandes:

eb4

Vérification carte SIM :

eb5

Vérification de l'enregistrement sur le réseau

eb6

Envoyer un message

eb7

Faire un Reset

eb8

Avec AiThinker Serial Tool V1.2.3 sur W10 : le modem est déjà en Mode Config

eb9

Restons sur W10 avec Python(Python3.8)pour essayer la séquence +++
il faut au préalable être passé en Mode Datas avec la commande AT+EXAT
afin de revenir avec +++ en mode AT

 

eb10

eb11

TRES IMPORTANT:
le message ne doit pas comporter d'espaces, uniquement des lettres et des nombres et quelques caractères spéciaux.

pour séparer des données , j'utilise soit un tiret, soit 3 points soit un #.

 

 

Recevoir des commandes

L'envoi d'un SMS est plutôt simple, la réception est encore plus simple.

L'appareil peut recevoir des SMS en mode de transmission transparent. Le format reçu est le suivant :
+SMS REC:number
Pour passer en mode transparent, exécuter cette commande: AT+EXAT,
un essai avec Configuration Tools:

eb12

Comme pour l'envoi d'un SMS nous utiliserons un script Python .
Si le module serial n'est pas installé :il faut installé avec pip3 :

eb80

Essai sous W10 et Python3.8: le port sous Windows est COMx , il sera à modifier sous Linux suivant le matériel utilisé (ttyUSB0 ou ttyS0)
le script,

 

eb15

eb13

eb14

Pour plus d'explications concernant l'utilisation de la variable dans Domoticz , voir la page consacrée au modem GSM GPRS 2G(notifications par SMS).

Pour une confirmation de la réception de la commande envoyée , vous pouvez vous inspirer de cette même page.

 

 

Connexion du modem au Raspberry

plusieurs solutions possibles :
- avec un cordon adaptateur USB-Série, le port sera ttyUSB0

eb17

- avec un module RS232-TTL , le port sera ttyS0 , il faut activer le port série du PI , voir cette page (liaison série PC-PI)

eb16

 

 

Connexion au PI4 assurant déjà les sauvegardes raid1 et le monitoring

les essais sur W10 et mon PI4 2G0( pi pour les essais) ont été concluant ....
.....mais sur mon PI4 qui assurent déjà d'autres fonctions avec comme système d'exploitation Ubuntu,la connexion s'est avérée plus difficile.
Le cordon adaptateur CH341 a fonctionné correctement sur le PC mais sur PI les caractères Unicode sont erronés( problème de puce chinoise je suppose) , j'ai donc utilisé un module RS232-TTL
Je ne sais pas pourquoi la connexion sur l'UART1 'GPIO14et GPIO15 n'a pas fonctionné également, pire elle empêchait le pi de démarrer ???
je suppose que mes 2 disques durs Raid1sont peut être les fautifs , qu'à cela ne tienne , j'ai donc utiliser l'UART4.

Dernier problème(mineur) , pendant les essais j'envoyais le message, entre 2 virgules, (tout le message ,numéro+texte formait un ensemble de bytes) il n'est évidemment pas possible d'y insérer une chaine de caractères , j'ai du modifier légèrement le script.

Pour utiliser dtoverlay sous Ubuntu: voir cette page
Si sur Ubuntu lors de apt update vous rencontrer une erreur concernant "bcm2711-rpi-4-b.dtb" , voir cette page

eb18

eb19

Connexion au PI: GPIO8 et GPIO9

eb27

eb20

Configuration du PI
- Sauvegarder les fichiers originaux config.txt et cmdline.txt

Sur Ubuntu

eb21

 

Sur PI OS

eb74

- Modifier le fichier config.txt

Sur Ubuntu
en commentant "enable_uart=1" et en activant UART4

eb22

 

Sur PI OS
en ajoutant "dtoverlay=uart4" et "enable_uart=4"

eb75

- Supprimer le paramètre "console=serial0,115200" du fichier cmdline.txt

eb23

eb76

eb24

- ajouter l'utilisateur au groupe dialout

eb25

- Reboot

eb26

uart0: serial@7e201000
uart1: serial@7e215040
uart2: serial@7e201400
uart3: serial@7e201600
uart4: serial@7e201800
uart5: serial@7e201a00

Il est temps maintenant d'essayer la communication avec les scripts d'envoi et de réception de SMS,
le script Python pour l'envoi d'un message:

eb30

le script bash :

eb31

eb29

eb28

 

Réception de SMS,
le script:

eb32

eb33

Ce script affiche le nom de la variable(123) et sa valeur(456) , il ne reste plus :
- qu'à organiser les données émises pour correspondre aux choix que l'on s'est fixés
- qu'à utiliser l’api de Domoticz pour mettre à jour les variables ou exécuter des commandes.

Dans des tutos précédents j'envoyais des commandes de ce type:
- ID#sms#valeur# pour les variables
- ID#switch#valeur# pour les commandes

Après plus d'expérience , je pense qu'i faut filtrer les SMS et le format ci dessous me donne entière satisfaction:
Protocole#ID#type d'action#valeur# ....mais tout est possible suivant l'organisation que vous avez choisie
:

- protocole = (à part ces types les SMS seront ignorés)
...........smsip (mise à jour Domoticz par le réseau)
...........smsse (mise à jour Domoticz par la liaison série)
- ID = id domoticz de la variable ou du dispositif
- type d'action=
..........switch pour un interrupteur
..........nom de la variable
- valeur= valeur pour la variable ou type de commande On ou Off pour les switchs

 

un essai complet avec la confirmation de l'exécution de la commande envoyée avec le SMS

eb35

eb34

le script :remplacer ¶ par "voir ci-dessous)" (problème d'affichage html)

eb77

pour envoyer les commandes par une liaison série , il faut ajouter un autre port, voir la page consacrée à ce sujet afin de compléter ce script

eb36

 

 

Démarrage auto lors du reboot

-Avec Crontab, voir cette page :

eb37

Ligne à insérer :
@reboot sh /home/michel/start_rec_sms.sh > /home/michel/rec_sms.log
remplacer les fichiers en italique par les vôtres

eb79

Pour utiliser PM2 au lieu de Crontab , c'est sur cette autre page

 

 

Utilisation d'une liaison série entre le PI et domoticz


Domoticz , dans mon cas est installé sur une VM Proxmox
c'est une simple communication série entre 2 machines mais , comme je j'ai déjà expliqué, ce système a l'avantage de s'auto surveiller; Nagios sur le PI surveille tout le monde et domoticz surveille que le pi est opérationnel.....le routeur peut tomber en panne , l'essentiel du système domotique reste opérationnel.

voir cette page concernant la liaison série entre Domoticz et un mini PC

 

Connexion entre le PI4 et le mini PC:

j'ai utilisé un cordon USB/TTL

eb38

L'UART4 étant déjà utilisé pour le modem , j'ai utilisé l'UART5,
Connexion au pc GPIO12 &GPIO13 , pin 32 & 33 et alimentation , pin4 et gnd

eb39

Ajout de UART5 dans config.txt:

pour Ubuntu

eb40

 

pour PI OS

eb79

redémarrer le PI
Ports ouvert avant et après l'ajout de UART5 :

eb41

eb42

Autoriser l'accès pour les ports:

eb43

Installation de minicom sur le pi et la vm (sur la VM domoticz , je n'ai pas installé d'interface graphique , je ne peux utiliser Gtkterm)

eb44

On vérifie le port utilisé sur le serveur de domoticz:
non nécessaire , si vous utilisez le script développé plus après(test du port)

eb45

On vérifie la connexion avec minicom:

eb46

C’est OK.....on passe aux programmes python

 

 

Scripts Python pour commander des dispositifs dans Domoticz:

Installation de python-periphery sur les 2 machines

eb47

eb48

Un essai avec un script léger:

#!/usr/bin/env python3.7 -*- coding: utf-8 -*-
from periphery import Serial
import time
# control
serial = Serial("/dev/ttyUSB0", 115200) #pour le PI , ttyAMA1
while True:
    serial.write(b"Bonjour michel") # pour le PI bonjour Domoticz
    time.sleep(5)
    # Read up to 128 bytes with 500ms timeout
    buf = serial.read(128, 0.5).decode()
    print("read {:d} bytes: _{:s}_".format(len(buf), buf))
    time.sleep(5)

eb49

eb50

les scripts sont lancés : python3.7(ou8) ./essai.py

eb51

Piloter Domoticz avec cette liaison série en plus du pilotage par IP
- Le PI:
Il suffit de compléter le script vu précédemment

#!/usr/bin/env python3.8
# -*- coding: utf-8 -*-

import time,serial,requests
from periphery import Serial
ip_domoticz="http://192.168.1.21:8082/" 
se_domoticz="http://127.0.0.1:8082/" # VOIR REMARQUE
def convert_to_string(buf):
    try:
        tt =  buf.decode('utf-8').strip()
        return tt
    except UnicodeError:
        tmp = bytearray(buf)
        for i in range(len(tmp)):
            if tmp[i]>127:
                tmp[i] = ord('?')
        return bytes(tmp).decode('utf-8').strip()

def not_reception(content):
    message = ('AT+SMSSEND=0670065886,'+content+'\r\n').encode('utf-8')
    phone.write(b'+++')
    time.sleep(2)
    phone.write(b'AT+VER\r\n')
    time.sleep(1)
    phone.write(message)
    phone.write(b'AT+EXAT');
    time.sleep(1);

def ip_serie(ip_se,url):
    if ip_se == 1:
        response = requests.get(url)
        contenu = response.json()
        if contenu['status']=="OK":
            content=contenu['title']
        else :
            content="erreur"
        #print(content)
        not_reception(content)
    elif ip_se == 2:
        print("Connexion série")
        url=url.encode('utf-8')
        serie.write(url)
        time.sleep(1)
    else:
        print("erreur")

phone = serial.Serial(port="/dev/ttyAMA1",baudrate=115200,timeout=2)
serie = Serial("/dev/ttyAMA2", 115200)
phone.close() #Cloture du port pour le cas ou il serait déjà ouvert ailleurs
phone.open() #Ouverture du port
phone.write(b'AT+EXAT');
time.sleep(1);
while True:
    line = phone.readline() # copie d’une ligne entiere jusqu’a \n dans “line”
    #print(line)
    buf_dz = serie.read(128, 0.5)
    #print(buf_dz)
    id="none"
    value="none"
    name="none"
    if buf_dz:
        buf_dz = convert_to_string(buf_dz)
        not_reception(buf_dz)
    if line:
        line = convert_to_string(line)
        print(line) #pour essai
        params=line.split('#')
        if params[0] and (params[0]=='smsip' or params[0]=='smsse'):
            if params[0]=="smsip":
                domoticz=ip_domoticz
                ip_se=1
            if params[0]=="smsse":
                domoticz=se_domoticz
                ip_se=2
            if params[1]:
                id = params[1]
                #print('Id:'+id)
            if params[2]:
                name = params[2]
                #print('name:'+name)
            if params[3]:
                value = params[3]
                #print('valeur:'+value)
            if (id!="none" and name!="none" and value!="none"):
                if name == 'switch':
                    url = domoticz+'json.htm?type=command¶m=switchlight&idx='+id+'&switchcmd='+value
                else :
                    url = domoticz+'json.htm?type=command¶m=updateuservariable&idx='+id+'&vname='+name+'&vtype=2&vvalue='+value
            else :
                ip_se=""

            ip_serie(ip_se,url)
	

eb52

eb53

REMARQUE :
il peut être nécessaire d'indiquer un mot de passe même si localhost est mentionné pour faciliter l'accès dans les paramètres de domoticz

ser35

- Le mini PC
le programme python installé dans le répertoire scripts/python de domoticz

eb66

L’ URL pour l’API domoticz a déjà été configuré lors de la réception du SMS par le modem , le programme inspiré du tuto est donc simplifié

#!/usr/bin/env python3.7 -*- coding: utf-8 -*-

import requests , time ,json, os
from periphery import Serial

if os.path.exists("/dev/ttyUSB0"):
    ser = Serial("/dev/ttyUSB0", 115200)
else :
    ser = Serial("/dev/ttyUSB1", 115200)
ser.flush()
#effacer le tampon série pour supprimer le courrier indésirable et le bruit
while True:
        url = ser.read(128, 0.5).decode(errors='ignore')
        if url:
           response = requests.get(url)
           contenu = response.json()
           message = contenu['title']
           print(message)
           bmessage = message.encode('utf-8')
           ser.write(bmessage)
        time.sleep(4)

eb54

Remarque: Flushinput() qui fonctionnait avec la précédente installation (serial) ne fonctionne pas remplacé par flush() de periphery

Création du service pour un démarrage auto :

eb55

eb56

Pour un copier/coller du script c'est sur cette page

eb57

eb58

eb59

Quelques copies d'écran:

eb60

eb61

 

 

Scripts Python pour l'envoi d'un SMS GSM depuis Domoticz

Plusieurs solutions sont possibles:
- 1ère solution: en utilisant principalement l’api de Domoticz et en créant une variable dans Domoticz
- 2eme solution: en utilisant l'importation d'un module python mis à jour par Domoticz , c'est la solution que j' ai privilégiée.

1ère solution :
- Création de la variable et exemple de modification du script lua de l'alarme :

eb62

eb63

le fichier "sms_dz.py", précédemment crée:

eb64

#!/usr/bin/env python3.7 -*- coding: utf-8 -*-

import requests , time ,json, os, chardet
from periphery import Serial

if os.path.exists("/dev/ttyUSB0"):
    ser = Serial("/dev/ttyUSB0", 115200)
else:
    ser = Serial("/dev/ttyUSB1", 115200)

url_gsm = 'http://127.0.0.1:8082/json.htm?type=command¶m=getuservariable&idx=23'
url_dz = 'http://127.0.0.1:8082/json.htm?type=command¶m=updateuservariable&idx=23&vname=alarme_gsm&vtype=2&vvalue=0'
ser.flush()
#effacer le tampon série pour supprimer le courrier indésirable et le bruit
while True:
        response = requests.get(url_gsm)
        result= json.loads(response.content.decode(chardet.detect(response.content)["encoding"]))
        statut = result['status']
        if(statut=="OK"):
            value= result['result'][0]['Value']
            print(value)
        if value != "0":
            print(value)
            bmessage = value.encode('utf-8')
            ser.write(bmessage)
            response = requests.get(url_dz)
        url = ser.read(128, 0.5).decode(errors='ignore')
        if url:
           response = requests.get(url)
           contenu = response.json()
           message = contenu['title']
           print(message)
           bmessage = message.encode('utf-8')
           ser.write(bmessage)
        time.sleep(4)

On simplifie le script avec des fonctions :

eb65

Résultat , pour l'essai on modifie la variable de domoticz:

eb67

eb68

Avec Putty , le programme est lancé avec : python3 sms_dz.py

eb69

 

2eme solution:
On utilise un module python en import reload et on modifie ce module :
- avec domoticz pour envoyer un message
- avec python pour arrêter l’envoi du message
Création d’un fichier python : aldz.py , il ne contient qu'une variable x="0" ("pas de message")

eb70

On fait une copie de ce fichier : aldz.bak.py, ce dernier permettra de remettre à zéro la variable x (en remplaçant le fichier original qui aura été modifié par Domoticz.)

eb71

Dans Domoticz , pas besoin de créer une variable , simplement modifier le fichier aldz.py pour inclure à la variable x , le texte du SMS
on reécrit le module python.
exemple pour mon script "alarme":

eb72

Le fichier sms_dz est modifié (simplifié) :

eb73

 

 

 

 

 

 

crée le 08-10/07/2021
maj 22/09/2021 ajout envoi SMS par GSM et par la liaison série
maj 22/10/2021 modifications mineures erreurs de frappe
maj 27/12/2022 ajout remarque concernant l'accès localhost de domoticz

page:73