esphome/esphome/components/sim800l/sim800l.h
2022-02-15 17:01:50 +13:00

134 lines
3.5 KiB
C++

#pragma once
#include <utility>
#include "esphome/core/defines.h"
#include "esphome/core/component.h"
#ifdef USE_BINARY_SENSOR
#include "esphome/components/binary_sensor/binary_sensor.h"
#endif
#ifdef USE_SENSOR
#include "esphome/components/sensor/sensor.h"
#endif
#include "esphome/components/uart/uart.h"
#include "esphome/core/automation.h"
namespace esphome {
namespace sim800l {
const uint8_t SIM800L_READ_BUFFER_LENGTH = 255;
enum State {
STATE_IDLE = 0,
STATE_INIT,
STATE_CHECK_AT,
STATE_CREG,
STATE_CREGWAIT,
STATE_CSQ,
STATE_CSQ_RESPONSE,
STATE_IDLEWAIT,
STATE_SENDINGSMS1,
STATE_SENDINGSMS2,
STATE_SENDINGSMS3,
STATE_CHECK_SMS,
STATE_PARSE_SMS,
STATE_PARSE_SMS_RESPONSE,
STATE_RECEIVESMS,
STATE_READSMS,
STATE_RECEIVEDSMS,
STATE_DELETEDSMS,
STATE_DISABLE_ECHO,
STATE_PARSE_SMS_OK,
STATE_DIALING1,
STATE_DIALING2
};
class Sim800LComponent : public uart::UARTDevice, public PollingComponent {
public:
/// Retrieve the latest sensor values. This operation takes approximately 16ms.
void update() override;
void loop() override;
void dump_config() override;
#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
void add_on_sms_received_callback(std::function<void(std::string, std::string)> callback) {
this->callback_.add(std::move(callback));
}
void send_sms(const std::string &recipient, const std::string &message);
void dial(const std::string &recipient);
protected:
void send_cmd_(const std::string &message);
void parse_cmd_(std::string message);
void set_registered_(bool registered);
#ifdef USE_BINARY_SENSOR
binary_sensor::BinarySensor *registered_binary_sensor_{nullptr};
#endif
#ifdef USE_SENSOR
sensor::Sensor *rssi_sensor_{nullptr};
#endif
std::string sender_;
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_;
bool send_pending_;
bool dial_pending_;
CallbackManager<void(std::string, std::string)> callback_;
};
class Sim800LReceivedMessageTrigger : public Trigger<std::string, std::string> {
public:
explicit Sim800LReceivedMessageTrigger(Sim800LComponent *parent) {
parent->add_on_sms_received_callback(
[this](const std::string &message, const std::string &sender) { this->trigger(message, sender); });
}
};
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_;
};
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_;
};
} // namespace sim800l
} // namespace esphome