add connect wifi mqtt auto.
This commit is contained in:
parent
7f3491094f
commit
8413ce1fa9
@ -65,3 +65,12 @@ void Application::initializeWifi() {
|
||||
ESP_ERROR_CHECK(esp_wifi_start());
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
bool Application::contains(const std::string &key) {
|
||||
nvs_handle_t hanlde;
|
||||
esp_err_t error = nvs_open(Namespace, NVS_READWRITE, &hanlde);
|
||||
nvs_type_t type;
|
||||
error = nvs_find_key(hanlde, key.c_str(), &type);
|
||||
nvs_close(hanlde);
|
||||
return error == ESP_OK;
|
||||
}
|
@ -26,11 +26,12 @@ public:
|
||||
if (error != ESP_OK) {
|
||||
ESP_LOGI("App", "nvs_open() failed.");
|
||||
}
|
||||
|
||||
if (std::is_same_v<char *, std::decay_t<T>>) {
|
||||
if constexpr (std::is_same_v<char *, std::decay_t<T>>) {
|
||||
error = nvs_set_str(hanlde, key.c_str(), value);
|
||||
} else if constexpr (std::is_same_v<std::string, T>) {
|
||||
error = nvs_set_str(hanlde, key.c_str(), value.c_str());
|
||||
} else if constexpr (std::is_same_v<int32_t, T> || std::is_same_v<int, T>) {
|
||||
error = nvs_set_i32(hanlde, key.c_str(), value);
|
||||
} else {
|
||||
ESP_LOGW("App", "unknown data");
|
||||
}
|
||||
@ -43,7 +44,24 @@ public:
|
||||
|
||||
template <typename T>
|
||||
T field(const std::string &key) {
|
||||
T ret{};
|
||||
nvs_handle_t hanlde;
|
||||
nvs_open(Namespace, NVS_READWRITE, &hanlde);
|
||||
if constexpr (std::is_same_v<char *, std::decay_t<T>> || std::is_same_v<std::string, T>) {
|
||||
size_t requiredSize;
|
||||
nvs_get_str(hanlde, key.c_str(), nullptr, &requiredSize);
|
||||
ret.resize(requiredSize);
|
||||
nvs_get_str(hanlde, key.c_str(), ret.data(), &requiredSize);
|
||||
} else if constexpr (std::is_same_v<int, T>) {
|
||||
ret = field<int32_t>(key);
|
||||
} else if constexpr (std::is_same_v<int32_t, T>) {
|
||||
nvs_get_i32(hanlde, key.c_str(), &ret);
|
||||
}
|
||||
nvs_close(hanlde);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool contains(const std::string &key);
|
||||
|
||||
protected:
|
||||
static void eventHandler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "MqttClient.h"
|
||||
#include "Application.h"
|
||||
#include "LedController.h"
|
||||
#include <cJSON.h>
|
||||
#include <esp_log.h>
|
||||
@ -17,7 +18,7 @@ void MqttClient::onConnected(struct esp_mqtt_client *client) {
|
||||
cJSON_AddStringToObject(root, "cmd_t", "~/set");
|
||||
cJSON_AddStringToObject(root, "stat_t", "~/state");
|
||||
cJSON_AddStringToObject(root, "schema", "json");
|
||||
cJSON_AddNumberToObject(root, "brightness_scale", 100);
|
||||
cJSON_AddNumberToObject(root, "brightness_scale", LedController::Resolution);
|
||||
|
||||
const char *modes[] = {
|
||||
"color_temp",
|
||||
@ -33,20 +34,62 @@ void MqttClient::onConnected(struct esp_mqtt_client *client) {
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
|
||||
m_setStatusTopic = "homeassistant/light/bedroom/set";
|
||||
m_statusTopic = "homeassistant/light/bedroom/state";
|
||||
msg_id = esp_mqtt_client_subscribe(client, m_setStatusTopic.c_str(), 0);
|
||||
ESP_LOGI(TAG, "sent subscribe successful, msg_id=%d", msg_id);
|
||||
|
||||
reportLedState();
|
||||
}
|
||||
|
||||
void MqttClient::onSetStatus(const char *data, int size) {
|
||||
ESP_LOGI(TAG, "set: %s", data);
|
||||
ESP_LOGI(TAG, "set: %.*s", size, data);
|
||||
cJSON *root = cJSON_Parse(data);
|
||||
cJSON *brightness = cJSON_GetObjectItem(root, "brightness");
|
||||
if (brightness != nullptr) {
|
||||
ESP_LOGI(TAG, "brightness: %d", brightness->valueint);
|
||||
LedController::instance()->setDuty(1, brightness->valueint);
|
||||
LedController::instance()->setBrightness(brightness->valueint);
|
||||
Application::instance()->setField("brightness", brightness->valueint);
|
||||
}
|
||||
|
||||
cJSON *color_temp = cJSON_GetObjectItem(root, "color_temp");
|
||||
if (color_temp != nullptr) {
|
||||
ESP_LOGI(TAG, "color_temp: %d", color_temp->valueint);
|
||||
LedController::instance()->setColorTemperature(color_temp->valueint);
|
||||
Application::instance()->setField("color_temp", color_temp->valueint);
|
||||
}
|
||||
|
||||
cJSON *state = cJSON_GetObjectItem(root, "state");
|
||||
if (state != nullptr) {
|
||||
if (std::string_view(state->valuestring) == "ON") {
|
||||
LedController::instance()->setEnabled(true);
|
||||
} else {
|
||||
LedController::instance()->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
reportLedState();
|
||||
}
|
||||
|
||||
void MqttClient::reportLedState() {
|
||||
cJSON *root = cJSON_CreateObject();
|
||||
cJSON_AddStringToObject(root, "state", LedController::instance()->enabled() ? "ON" : "OFF");
|
||||
cJSON_AddNumberToObject(root, "brightness", LedController::instance()->brightness());
|
||||
cJSON_AddNumberToObject(root, "color_temp", LedController::instance()->colorTemperature());
|
||||
|
||||
auto text = cJSON_PrintUnformatted(root);
|
||||
if (text != nullptr) {
|
||||
auto messageId = esp_mqtt_client_publish(m_client, m_statusTopic.c_str(), text, strlen(text), 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", messageId);
|
||||
free(text);
|
||||
}
|
||||
cJSON_Delete(root);
|
||||
}
|
||||
|
||||
MqttClient::~MqttClient() {
|
||||
if (m_client != nullptr) {
|
||||
esp_mqtt_client_destroy(m_client);
|
||||
}
|
||||
}
|
||||
|
||||
static void log_error_if_nonzero(const char *message, int error_code) {
|
||||
@ -60,7 +103,6 @@ void MqttClient::eventHandler(void *handler_args, esp_event_base_t base, int32_t
|
||||
ESP_LOGD(TAG, "Event dispatched from event loop base=%s, event_id=%" PRIi32 "", base, event_id);
|
||||
auto event = reinterpret_cast<esp_mqtt_event_handle_t>(event_data);
|
||||
esp_mqtt_client_handle_t client = event->client;
|
||||
int msg_id;
|
||||
switch ((esp_mqtt_event_id_t)event_id) {
|
||||
case MQTT_EVENT_CONNECTED:
|
||||
self->onConnected(client);
|
||||
@ -71,8 +113,6 @@ void MqttClient::eventHandler(void *handler_args, esp_event_base_t base, int32_t
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
msg_id = esp_mqtt_client_publish(client, "/topic/qos0", "data", 0, 0, 0);
|
||||
ESP_LOGI(TAG, "sent publish successful, msg_id=%d", msg_id);
|
||||
break;
|
||||
case MQTT_EVENT_UNSUBSCRIBED:
|
||||
ESP_LOGI(TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
|
||||
@ -111,10 +151,10 @@ bool MqttClient::initialize(const std::string &username, const std::string &pass
|
||||
config.credentials.username = username.c_str();
|
||||
config.credentials.authentication.password = password.c_str();
|
||||
|
||||
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&config);
|
||||
esp_mqtt_client_register_event(client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID),
|
||||
m_client = esp_mqtt_client_init(&config);
|
||||
esp_mqtt_client_register_event(m_client, static_cast<esp_mqtt_event_id_t>(ESP_EVENT_ANY_ID),
|
||||
&MqttClient::eventHandler, this);
|
||||
esp_mqtt_client_start(client);
|
||||
esp_mqtt_client_start(m_client);
|
||||
ESP_LOGI(TAG, "connect to %s, username: %s, password: %s", config.broker.address.uri, config.credentials.username,
|
||||
config.credentials.authentication.password);
|
||||
return true;
|
||||
|
@ -9,6 +9,9 @@ public:
|
||||
static MqttClient *instance();
|
||||
bool initialize(const std::string &username, const std::string &password);
|
||||
|
||||
void reportLedState();
|
||||
~MqttClient();
|
||||
|
||||
protected:
|
||||
static void eventHandler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data);
|
||||
void onConnected(struct esp_mqtt_client *client);
|
||||
@ -17,5 +20,7 @@ protected:
|
||||
|
||||
private:
|
||||
std::string m_setStatusTopic;
|
||||
std::string m_statusTopic;
|
||||
esp_mqtt_client_handle_t m_client = nullptr;
|
||||
};
|
||||
#endif // __MQTTCLIENT_H__
|
@ -10,7 +10,7 @@ bool LedController::initialize() {
|
||||
ledc_timer_config_t ledc_timer;
|
||||
memset(&ledc_timer, 0, sizeof(ledc_timer));
|
||||
ledc_timer.speed_mode = LEDC_HIGH_SPEED_MODE;
|
||||
ledc_timer.duty_resolution = LEDC_TIMER_13_BIT;
|
||||
ledc_timer.duty_resolution = TimerBit;
|
||||
ledc_timer.timer_num = LEDC_TIMER_0;
|
||||
ledc_timer.freq_hz = 4000;
|
||||
ledc_timer.clk_cfg = LEDC_AUTO_CLK;
|
||||
@ -41,16 +41,58 @@ bool LedController::initialize() {
|
||||
std::cout << "ledc_timer_config() failed." << std::endl;
|
||||
}
|
||||
|
||||
ledc_set_duty(m_channels[i].speed_mode, m_channels[i].channel, 4096);
|
||||
ledc_set_duty(m_channels[i].speed_mode, m_channels[i].channel, 0);
|
||||
ledc_update_duty(m_channels[i].speed_mode, m_channels[i].channel);
|
||||
}
|
||||
std::cout << "led controller initialize finished." << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LedController::setDuty(int32_t channel, int32_t duty) {
|
||||
duty = static_cast<float>(0x1FFF * duty) / 100;
|
||||
int32_t LedController::brightness() const {
|
||||
return m_brightness;
|
||||
}
|
||||
|
||||
void LedController::setBrightness(int32_t brightness) {
|
||||
if (m_brightness != brightness) {
|
||||
m_brightness = brightness;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
int32_t LedController::colorTemperature() const {
|
||||
return m_colorTemp;
|
||||
}
|
||||
|
||||
void LedController::setColorTemperature(int32_t temp) {
|
||||
if (m_colorTemp != temp) {
|
||||
m_colorTemp = temp;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
bool LedController::enabled() const {
|
||||
return m_enabled;
|
||||
}
|
||||
|
||||
void LedController::setEnabled(bool enabled) {
|
||||
if (m_enabled != enabled) {
|
||||
m_enabled = enabled;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void LedController::update() {
|
||||
if (!m_enabled) {
|
||||
setDuty(Warm, 0);
|
||||
setDuty(Cold, 0);
|
||||
return;
|
||||
}
|
||||
auto warm = static_cast<float>(m_colorTemp - MinimumColorTemp) / (MaximumColorTemp - MinimumColorTemp);
|
||||
auto wamDuty = m_brightness * warm;
|
||||
setDuty(Warm, wamDuty);
|
||||
setDuty(Cold, m_brightness - wamDuty);
|
||||
}
|
||||
|
||||
void LedController::setDuty(Channel channel, int32_t duty) {
|
||||
if ((channel < 0) || (channel >= sizeof(m_channels) / sizeof(m_channels[0]))) return;
|
||||
std::cout << "set channle " << channel << " duty: " << duty << std::endl;
|
||||
ledc_set_duty(m_channels[channel].speed_mode, m_channels[channel].channel, duty);
|
||||
|
@ -5,12 +5,38 @@
|
||||
|
||||
class LedController {
|
||||
public:
|
||||
constexpr static ledc_timer_bit_t TimerBit = LEDC_TIMER_12_BIT;
|
||||
constexpr static int32_t Resolution = 1 << LEDC_TIMER_12_BIT;
|
||||
|
||||
constexpr static int32_t MinimumColorTemp = 153;
|
||||
constexpr static int32_t MaximumColorTemp = 500;
|
||||
|
||||
enum Channel {
|
||||
Warm = 0,
|
||||
Cold = 1,
|
||||
};
|
||||
static LedController *instance();
|
||||
bool initialize();
|
||||
void setDuty(int32_t channel, int32_t duty);
|
||||
|
||||
int32_t brightness() const;
|
||||
void setBrightness(int32_t brightness);
|
||||
|
||||
int32_t colorTemperature() const;
|
||||
void setColorTemperature(int32_t temp);
|
||||
|
||||
bool enabled() const;
|
||||
void setEnabled(bool enabled);
|
||||
|
||||
void setDuty(Channel channel, int32_t duty);
|
||||
|
||||
protected:
|
||||
LedController();
|
||||
void update();
|
||||
ledc_channel_config_t m_channels[2];
|
||||
|
||||
private:
|
||||
bool m_enabled = false;
|
||||
int32_t m_brightness = 0;
|
||||
int32_t m_colorTemp = 0;
|
||||
};
|
||||
#endif // __LEDCONTROLLER_H__
|
@ -16,13 +16,14 @@ static int led_command(int argc, char **argv) {
|
||||
for (int i = 0; i < argc; i++) {
|
||||
std::cout << i << " " << argv[i] << std::endl;
|
||||
}
|
||||
LedController::instance()->setDuty(atoi(argv[1]), atoi(argv[2]));
|
||||
|
||||
LedController::instance()->setDuty(static_cast<LedController::Channel>(atoi(argv[1])), atoi(argv[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mqtt_command(int argc, char **argv) {
|
||||
MqttClient::instance()->initialize(argv[1], argv[2]);
|
||||
Application::instance()->setField("mqtt_username", std::string(argv[1]));
|
||||
Application::instance()->setField("mqtt_password", std::string(argv[2]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -52,6 +53,8 @@ static int wifi_connect(int argc, char **argv) {
|
||||
ESP_LOGW(__func__, "Connection timed out");
|
||||
return 1;
|
||||
}
|
||||
Application::instance()->setField("ssid", std::string(join_args.ssid->sval[0]));
|
||||
Application::instance()->setField("psk", std::string(join_args.password->sval[0]));
|
||||
ESP_LOGI(__func__, "Connected");
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "Application.h"
|
||||
#include "CustomCommand.h"
|
||||
#include "LedController.h"
|
||||
#include "MqttClient.h"
|
||||
#include "cmd_nvs.h"
|
||||
#include "cmd_system.h"
|
||||
#include "driver/uart.h"
|
||||
@ -31,7 +32,7 @@ extern "C" void app_main() {
|
||||
initialize_filesystem();
|
||||
initialize_console();
|
||||
Application::instance()->initialize();
|
||||
Application::instance()->setField("author", "amass");
|
||||
|
||||
esp_console_register_help_command();
|
||||
register_system_common();
|
||||
register_system_sleep();
|
||||
@ -39,6 +40,34 @@ extern "C" void app_main() {
|
||||
register_nvs();
|
||||
|
||||
LedController::instance()->initialize();
|
||||
if (Application::instance()->contains("brightness")) {
|
||||
int brightness = Application::instance()->field<int>("brightness");
|
||||
LedController::instance()->setBrightness(brightness);
|
||||
ESP_LOGI("main", "last brightness: %d \n", brightness);
|
||||
}
|
||||
if (Application::instance()->contains("color_temp")) {
|
||||
int color_temp = Application::instance()->field<int>("color_temp");
|
||||
LedController::instance()->setColorTemperature(Application::instance()->field<int>("color_temp"));
|
||||
ESP_LOGI("main", "last color_temp: %d \n", color_temp);
|
||||
}
|
||||
|
||||
bool connected = false;
|
||||
if (Application::instance()->contains("ssid")) {
|
||||
auto ssid = Application::instance()->field<std::string>("ssid");
|
||||
auto psk = Application::instance()->field<std::string>("psk");
|
||||
connected = Application::instance()->wifiConnect(ssid, psk);
|
||||
} else {
|
||||
ESP_LOGI("main", "please connect wifi use command.\n");
|
||||
}
|
||||
if (connected) {
|
||||
if (Application::instance()->contains("mqtt_username")) {
|
||||
auto username = Application::instance()->field<std::string>("mqtt_username");
|
||||
auto password = Application::instance()->field<std::string>("mqtt_password");
|
||||
MqttClient::instance()->initialize(username, password);
|
||||
} else {
|
||||
ESP_LOGI("main", "please connect mqtt use command.\n");
|
||||
}
|
||||
}
|
||||
|
||||
while (true) {
|
||||
char *line = linenoise(prompt);
|
||||
|
Loading…
Reference in New Issue
Block a user