2019-06-17 20:13:52 +02:00
|
|
|
#pragma once
|
|
|
|
|
2021-06-10 13:04:40 +02:00
|
|
|
#include <utility>
|
|
|
|
|
2022-02-15 05:01:50 +01:00
|
|
|
#include "esphome/core/defines.h"
|
2019-06-17 20:13:52 +02:00
|
|
|
#include "esphome/core/component.h"
|
2022-02-15 05:01:50 +01:00
|
|
|
#ifdef USE_BINARY_SENSOR
|
|
|
|
#include "esphome/components/binary_sensor/binary_sensor.h"
|
|
|
|
#endif
|
|
|
|
#ifdef USE_SENSOR
|
|
|
|
#include "esphome/components/sensor/sensor.h"
|
|
|
|
#endif
|
2019-06-17 20:13:52 +02:00
|
|
|
#include "esphome/components/uart/uart.h"
|
|
|
|
#include "esphome/core/automation.h"
|
|
|
|
|
|
|
|
namespace esphome {
|
|
|
|
namespace sim800l {
|
|
|
|
|
2022-09-14 21:43:03 +02:00
|
|
|
const uint16_t SIM800L_READ_BUFFER_LENGTH = 1024;
|
2019-10-19 22:31:32 +02:00
|
|
|
|
2019-06-17 20:13:52 +02:00
|
|
|
enum State {
|
|
|
|
STATE_IDLE = 0,
|
|
|
|
STATE_INIT,
|
2022-09-14 21:43:03 +02:00
|
|
|
STATE_SETUP_CMGF,
|
|
|
|
STATE_SETUP_CLIP,
|
2019-06-17 20:13:52 +02:00
|
|
|
STATE_CREG,
|
2022-09-14 21:43:03 +02:00
|
|
|
STATE_CREG_WAIT,
|
2019-06-17 20:13:52 +02:00
|
|
|
STATE_CSQ,
|
|
|
|
STATE_CSQ_RESPONSE,
|
2022-09-14 21:43:03 +02:00
|
|
|
STATE_SENDING_SMS_1,
|
|
|
|
STATE_SENDING_SMS_2,
|
|
|
|
STATE_SENDING_SMS_3,
|
2019-06-17 20:13:52 +02:00
|
|
|
STATE_CHECK_SMS,
|
|
|
|
STATE_PARSE_SMS_RESPONSE,
|
2022-09-14 21:43:03 +02:00
|
|
|
STATE_RECEIVE_SMS,
|
|
|
|
STATE_RECEIVED_SMS,
|
2019-06-17 20:13:52 +02:00
|
|
|
STATE_DISABLE_ECHO,
|
2021-02-25 22:11:15 +01:00
|
|
|
STATE_DIALING1,
|
2022-09-14 21:43:03 +02:00
|
|
|
STATE_DIALING2,
|
|
|
|
STATE_PARSE_CLIP,
|
|
|
|
STATE_ATA_SENT,
|
|
|
|
STATE_CHECK_CALL,
|
|
|
|
STATE_SETUP_USSD,
|
|
|
|
STATE_SEND_USSD1,
|
|
|
|
STATE_SEND_USSD2,
|
|
|
|
STATE_CHECK_USSD,
|
|
|
|
STATE_RECEIVED_USSD
|
2019-06-17 20:13:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class Sim800LComponent : public uart::UARTDevice, public PollingComponent {
|
|
|
|
public:
|
|
|
|
/// Retrieve the latest sensor values. This operation takes approximately 16ms.
|
|
|
|
void update() override;
|
|
|
|
void loop() override;
|
2019-10-23 14:43:41 +02:00
|
|
|
void dump_config() override;
|
2022-02-15 05:01:50 +01:00
|
|
|
#ifdef USE_BINARY_SENSOR
|
|
|
|
void set_registered_binary_sensor(binary_sensor::BinarySensor *registered_binary_sensor) {
|
|
|
|
registered_binary_sensor_ = registered_binary_sensor;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef USE_SENSOR
|
|
|
|
void set_rssi_sensor(sensor::Sensor *rssi_sensor) { rssi_sensor_ = rssi_sensor; }
|
|
|
|
#endif
|
2019-06-17 20:13:52 +02:00
|
|
|
void add_on_sms_received_callback(std::function<void(std::string, std::string)> callback) {
|
2022-09-14 21:43:03 +02:00
|
|
|
this->sms_received_callback_.add(std::move(callback));
|
|
|
|
}
|
|
|
|
void add_on_incoming_call_callback(std::function<void(std::string)> callback) {
|
|
|
|
this->incoming_call_callback_.add(std::move(callback));
|
|
|
|
}
|
|
|
|
void add_on_call_connected_callback(std::function<void()> callback) {
|
|
|
|
this->call_connected_callback_.add(std::move(callback));
|
|
|
|
}
|
|
|
|
void add_on_call_disconnected_callback(std::function<void()> callback) {
|
|
|
|
this->call_disconnected_callback_.add(std::move(callback));
|
|
|
|
}
|
|
|
|
void add_on_ussd_received_callback(std::function<void(std::string)> callback) {
|
|
|
|
this->ussd_received_callback_.add(std::move(callback));
|
2019-06-17 20:13:52 +02:00
|
|
|
}
|
2021-06-10 13:04:40 +02:00
|
|
|
void send_sms(const std::string &recipient, const std::string &message);
|
2022-09-14 21:43:03 +02:00
|
|
|
void send_ussd(const std::string &ussd_code);
|
2021-06-10 13:04:40 +02:00
|
|
|
void dial(const std::string &recipient);
|
2022-09-14 21:43:03 +02:00
|
|
|
void connect();
|
|
|
|
void disconnect();
|
2019-06-17 20:13:52 +02:00
|
|
|
|
|
|
|
protected:
|
2022-01-23 08:39:07 +01:00
|
|
|
void send_cmd_(const std::string &message);
|
|
|
|
void parse_cmd_(std::string message);
|
2022-02-15 05:01:50 +01:00
|
|
|
void set_registered_(bool registered);
|
|
|
|
|
|
|
|
#ifdef USE_BINARY_SENSOR
|
|
|
|
binary_sensor::BinarySensor *registered_binary_sensor_{nullptr};
|
|
|
|
#endif
|
2019-06-17 20:13:52 +02:00
|
|
|
|
2022-02-15 05:01:50 +01:00
|
|
|
#ifdef USE_SENSOR
|
|
|
|
sensor::Sensor *rssi_sensor_{nullptr};
|
|
|
|
#endif
|
2019-06-17 20:13:52 +02:00
|
|
|
std::string sender_;
|
2022-09-14 21:43:03 +02:00
|
|
|
std::string message_;
|
2019-06-17 20:13:52 +02:00
|
|
|
char read_buffer_[SIM800L_READ_BUFFER_LENGTH];
|
|
|
|
size_t read_pos_{0};
|
|
|
|
uint8_t parse_index_{0};
|
|
|
|
uint8_t watch_dog_{0};
|
|
|
|
bool expect_ack_{false};
|
|
|
|
sim800l::State state_{STATE_IDLE};
|
|
|
|
bool registered_{false};
|
|
|
|
|
|
|
|
std::string recipient_;
|
|
|
|
std::string outgoing_message_;
|
2022-09-14 21:43:03 +02:00
|
|
|
std::string ussd_;
|
2019-06-17 20:13:52 +02:00
|
|
|
bool send_pending_;
|
2021-02-25 22:11:15 +01:00
|
|
|
bool dial_pending_;
|
2022-09-14 21:43:03 +02:00
|
|
|
bool connect_pending_;
|
|
|
|
bool disconnect_pending_;
|
|
|
|
bool send_ussd_pending_;
|
|
|
|
uint8_t call_state_{6};
|
|
|
|
|
|
|
|
CallbackManager<void(std::string, std::string)> sms_received_callback_;
|
|
|
|
CallbackManager<void(std::string)> incoming_call_callback_;
|
|
|
|
CallbackManager<void()> call_connected_callback_;
|
|
|
|
CallbackManager<void()> call_disconnected_callback_;
|
|
|
|
CallbackManager<void(std::string)> ussd_received_callback_;
|
2019-06-17 20:13:52 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class Sim800LReceivedMessageTrigger : public Trigger<std::string, std::string> {
|
|
|
|
public:
|
|
|
|
explicit Sim800LReceivedMessageTrigger(Sim800LComponent *parent) {
|
|
|
|
parent->add_on_sms_received_callback(
|
2021-09-30 16:25:08 +02:00
|
|
|
[this](const std::string &message, const std::string &sender) { this->trigger(message, sender); });
|
2019-06-17 20:13:52 +02:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-09-14 21:43:03 +02:00
|
|
|
class Sim800LIncomingCallTrigger : public Trigger<std::string> {
|
|
|
|
public:
|
|
|
|
explicit Sim800LIncomingCallTrigger(Sim800LComponent *parent) {
|
|
|
|
parent->add_on_incoming_call_callback([this](const std::string &caller_id) { this->trigger(caller_id); });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Sim800LCallConnectedTrigger : public Trigger<> {
|
|
|
|
public:
|
|
|
|
explicit Sim800LCallConnectedTrigger(Sim800LComponent *parent) {
|
|
|
|
parent->add_on_call_connected_callback([this]() { this->trigger(); });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
class Sim800LCallDisconnectedTrigger : public Trigger<> {
|
|
|
|
public:
|
|
|
|
explicit Sim800LCallDisconnectedTrigger(Sim800LComponent *parent) {
|
|
|
|
parent->add_on_call_disconnected_callback([this]() { this->trigger(); });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
class Sim800LReceivedUssdTrigger : public Trigger<std::string> {
|
|
|
|
public:
|
|
|
|
explicit Sim800LReceivedUssdTrigger(Sim800LComponent *parent) {
|
|
|
|
parent->add_on_ussd_received_callback([this](const std::string &ussd) { this->trigger(ussd); });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2019-06-17 20:13:52 +02:00
|
|
|
template<typename... Ts> class Sim800LSendSmsAction : public Action<Ts...> {
|
|
|
|
public:
|
|
|
|
Sim800LSendSmsAction(Sim800LComponent *parent) : parent_(parent) {}
|
|
|
|
TEMPLATABLE_VALUE(std::string, recipient)
|
|
|
|
TEMPLATABLE_VALUE(std::string, message)
|
|
|
|
|
|
|
|
void play(Ts... x) {
|
|
|
|
auto recipient = this->recipient_.value(x...);
|
|
|
|
auto message = this->message_.value(x...);
|
|
|
|
this->parent_->send_sms(recipient, message);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Sim800LComponent *parent_;
|
|
|
|
};
|
|
|
|
|
2022-09-14 21:43:03 +02:00
|
|
|
template<typename... Ts> class Sim800LSendUssdAction : public Action<Ts...> {
|
|
|
|
public:
|
|
|
|
Sim800LSendUssdAction(Sim800LComponent *parent) : parent_(parent) {}
|
|
|
|
TEMPLATABLE_VALUE(std::string, ussd)
|
|
|
|
|
|
|
|
void play(Ts... x) {
|
|
|
|
auto ussd_code = this->ussd_.value(x...);
|
|
|
|
this->parent_->send_ussd(ussd_code);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Sim800LComponent *parent_;
|
|
|
|
};
|
|
|
|
|
2021-02-25 22:11:15 +01:00
|
|
|
template<typename... Ts> class Sim800LDialAction : public Action<Ts...> {
|
|
|
|
public:
|
|
|
|
Sim800LDialAction(Sim800LComponent *parent) : parent_(parent) {}
|
|
|
|
TEMPLATABLE_VALUE(std::string, recipient)
|
|
|
|
|
|
|
|
void play(Ts... x) {
|
|
|
|
auto recipient = this->recipient_.value(x...);
|
|
|
|
this->parent_->dial(recipient);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Sim800LComponent *parent_;
|
|
|
|
};
|
2022-09-14 21:43:03 +02:00
|
|
|
template<typename... Ts> class Sim800LConnectAction : public Action<Ts...> {
|
|
|
|
public:
|
|
|
|
Sim800LConnectAction(Sim800LComponent *parent) : parent_(parent) {}
|
|
|
|
|
|
|
|
void play(Ts... x) { this->parent_->connect(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Sim800LComponent *parent_;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<typename... Ts> class Sim800LDisconnectAction : public Action<Ts...> {
|
|
|
|
public:
|
|
|
|
Sim800LDisconnectAction(Sim800LComponent *parent) : parent_(parent) {}
|
|
|
|
|
|
|
|
void play(Ts... x) { this->parent_->disconnect(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Sim800LComponent *parent_;
|
|
|
|
};
|
2021-02-25 22:11:15 +01:00
|
|
|
|
2019-06-17 20:13:52 +02:00
|
|
|
} // namespace sim800l
|
|
|
|
} // namespace esphome
|