Salut ![]()
Dans le cadre d’un projet ESPHome, qui comprend l’utilisation d’un module SIM7600E, j’ai explorer l’envoi/réception de SMS.
Ce n’est pas une fonction maîtresse de mon projet, mais dans le paquet de toutes mes lectures sur ce SIM7600E, j’ai relu ce post de @Argonaute (et il y en a quelques autres qui évoquent le sujet)
Et comme j’ai vu que les puces SIM7600 étaient évoquées, mais que personne ne s’était aventuré à les tester, je me suis dit que cela me ferais un bon sujet de départ pour tenter d’apprivoiser la bête.
Pour rappel, à contrario des SIM800L, les SIM7600 ne sont pas (encore) intégrée à ESPHome.
Il faut dés lors jouer avec les commande « AT » en UART.
Le matériel utilisé :
Un ESP32S
Un SIM7600E-L1C avec antenne LTE et antenne GPS
Une carte SIM valide
Une alimentation USB (5V / 2A)
Les connections :
ESP32 SIM7600
TX GPIO17 ---> R (RX)
RX GPIO16 ---> T (TX)
GND ---> G (GND)
5V ---> V (VCC)
Il existe une commande « AT » pour communiquer le code PIN de la carte SIM. Mais pour des raisons de simplicité, j’ai d’abord désactivé la demande de code PIN de ma carte SIM.
Une fois le système sous tension (branchement de l’alimentation USB sur l’entrée USB de l’ESP32), la LED rouge de l’ESP32 et la LED rouge du SIM7600E sont allumée fixe. C’est le signe que tout est alimenté correctement.
Ensuite, si le SIM7600E accroche le réseau (4G), sa LED verte clignote.
Pour ce qui est de l’envoi de SMS avec le SIM7600E, c’est assez simple. Il faut connaître les bonnes commandes « AT ».
Moi, comme s’était juste pour jouer, j’ai utilisé un « button » avec l’instruction « uart.write »
Ce « button » remonte dans Home Assistant et peut-être utilisé soit dans une automatisation, soit dans un script, … et ce, soit dans l’ESP ou dans Home Assistant.
Code button :
button:
# Déclanche l'envoi d'un SMS
- platform: template
name: "Envoyer SMS Test"
on_press:
then:
- if:
condition:
lambda: |-
return id(ha_tel_num_select).has_state() && id(ha_message_select).has_state();
then:
- uart.write:
id: uart_sim7600
data: "AT+CMGF=1\r\n"
- delay: 1s
- uart.write: !lambda
std::string cmd = (std::string("AT+CMGS=") + id(ha_tel_num_select).state + "\r\n");
return std::vector<unsigned char>(cmd.begin(), cmd.end());
- delay: 1s
- uart.write: !lambda
std::string msg = (id(ha_message_select).state + "\x1A");
return std::vector<unsigned char>(msg.begin(), msg.end());
else:
- logger.log: "ERREUR: Les valeurs du numéro de téléphone ou du message n'ont pas été définies."
Pour recevoir et et analyser des SMS reçus par le SIM7600E, c’est une autre paire de manches.
Le plus simple est d’utiliser le « debug » de l’UART. Ce n’est sans doute pas ce qu’il y a de plus propre, mais je ne sais pas (encore) faire avec des « external_components » gavé de C++.
Voici le code ESPHome :
esphome:
name: esphome-web-5165f0
friendly_name: Bidouille
on_boot:
priority: 80
then:
# Initialisation du text_sensor via lambda (méthode C++)
- lambda: |-
id(sms_status).publish_state("En attente de SMS...");
# On force le mode texte et la notification SMS au boot
- uart.write:
id: uart_sim7600
data: "AT+CMGF=1\r\n"
- delay: 500ms
- uart.write:
id: uart_sim7600
data: "AT+CPMS=\"SM\",\"SM\",\"SM\"\r\n"
- delay: 500ms
# Demander la livraison directe (+CMT) au terminal pour recevoir le message complet
- uart.write:
id: uart_sim7600
data: "AT+CNMI=2,2,0,0,0\r\n"
- delay: 500ms
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
level: VERBOSE #Ca cause un max pour développer, c'est bien
# Enable Home Assistant API
api:
encryption:
key: !secret encryption_key
ota:
- platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
static_ip: 192.168.5.40
gateway: 192.168.5.1
subnet: 255.255.255.0
ap:
ssid: "bidouille"
password: !secret bidouille_wifi_ap_password
captive_portal:
web_server:
port: 80
# Définition de 2 select qui servent de listes de N° de tel et de messages prédéfinis
select:
- platform: template
name: "Numero Telephone HA"
id: ha_tel_num_select
options:
- '"+32123456789"'
- '"+32987654321"'
initial_option: '"+32123456789"'
optimistic: true
- platform: template
name: "Message HA"
id: ha_message_select
options:
- "Test SMS depuis ESP32/SIM7600"
- "Hello World"
- "Ce message est envoye depuis mon module 4G\nC'est un processus automatique\nMerci de ne pas repondre !"
initial_option: "Test SMS depuis ESP32/SIM7600"
optimistic: true
text_sensor:
- platform: template
name: "Statut Reception SMS"
id: sms_status
- platform: template
name: "SMS Sender"
id: sms_sender
- platform: template
name: "SMS Body"
id: sms_body
globals:
- id: wait_for_sms_content
type: bool
initial_value: 'false'
- id: last_sms_sender
type: std::string
initial_value: '""'
uart:
id: uart_sim7600
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 115200
data_bits: 8
parity: NONE
stop_bits: 1
debug:
direction: RX
dummy_receiver: true
after:
delimiter: "\n"
sequence:
- lambda: |-
// Convert bytes vector to std::string et enlever '\r'
std::string data(bytes.begin(), bytes.end());
data.erase(std::remove(data.begin(), data.end(), '\r'), data.end());
ESP_LOGD("uart_rx", "Recu: %s", data.c_str());
// 1) Réception directe (mode CNMI=2,2): en-tête +CMT: suivi de la ligne(s) du message.
if (data.find("+CMT:") != std::string::npos) {
// Extraire le numéro d'expéditeur entre guillemets
size_t q1 = data.find('"');
size_t q2 = std::string::npos;
if (q1 != std::string::npos) {
q2 = data.find('"', q1 + 1);
}
std::string sender = "";
if (q1 != std::string::npos && q2 != std::string::npos && q2 > q1) {
sender = data.substr(q1 + 1, q2 - q1 - 1);
}
id(last_sms_sender) = sender;
id(wait_for_sms_content) = true;
id(sms_status).publish_state("=> Nouveau SMS detecte de: " + (sender.empty() ? "inconnu" : sender));
ESP_LOGI("uart_rx", "ALERTE SMS RECUS de: %s", sender.c_str());
return;
}
// 2) Si on attend le corps du SMS, la prochaine ligne est le message
if (id(wait_for_sms_content)) {
// data contient le corps du SMS (une ligne). Publier dans text_sensor(s)
id(sms_body).publish_state(data);
id(sms_sender).publish_state(id(last_sms_sender));
id(sms_status).publish_state("SMS recu de " + id(last_sms_sender));
ESP_LOGI("uart_rx", "Contenu SMS: %s", data.c_str());
// Reset du flag d'attente
id(wait_for_sms_content) = false;
return;
}
// 3) Pour compatibilité, si le modem continue à renvoyer +CMTI (nouveau message stocké),
// on peut le détecter et éventuellement appeler AT+CMGR=<index> (non implémenté ici).
if (data.find("+CMTI:") != std::string::npos) {
id(sms_status).publish_state("=> Nouveau SMS detecte (stocke): " + data);
ESP_LOGI("uart_rx", "CMTI detecte: %s", data.c_str());
// Optionnel: lancer lecture via AT+CMGR si vous préférez cette méthode
}
button:
# Déclanche l'envoi d'un SMS
- platform: template
name: "Envoyer SMS Test"
on_press:
then:
- if:
condition:
lambda: |-
return id(ha_tel_num_select).has_state() && id(ha_message_select).has_state();
then:
- uart.write:
id: uart_sim7600
data: "AT+CMGF=1\r\n"
- delay: 1s
- uart.write: !lambda
std::string cmd = (std::string("AT+CMGS=") + id(ha_tel_num_select).state + "\r\n");
return std::vector<unsigned char>(cmd.begin(), cmd.end());
- delay: 1s
- uart.write: !lambda
std::string msg = (id(ha_message_select).state + "\x1A");
return std::vector<unsigned char>(msg.begin(), msg.end());
else:
- logger.log: "ERREUR: Les valeurs du numéro de téléphone ou du message n'ont pas été définies."
# Permet d'effacer tous les SMS de la carte SIM logée dans le module SIM
- platform: template
name: "Nettoyer tous les SMS (AT+CMGD)"
on_press:
then:
- uart.write:
id: uart_sim7600
data: "AT+CMGD=,4\r\n"
- logger.log: "Commande de nettoyage de tous les SMS envoyée."
- delay: 1s
- lambda: |-
id(sms_status).publish_state("Nettoyage des SMS effectué. En attente de nouveau SMS...");
Et dans Home Assistant :
Comme, dans mon projet, je n’ai pas besoin d’envoi de SMS, je ne suis pas aller plus loin que de vérifier s’il était possible d’envoyer des SMS avec ce système au départ de Home Assistant.
Maintenant qu’il est confirmé que cela fonctionne, pour les personnes intéressées, il vous reste à développer / adapter le code pour vos propre besoins.
Pour ce code, l’IA m’a beaucoup aidé ![]()
Si quelqu’un à une solution pour éviter d’utiliser le bloc debug de l’UART, je suis preneur.
Maintenant, je vais continuer sur mon projet … ![]()
@+ Guy
