feat: communicating with desktop app using mqtt.

This commit is contained in:
Ivan Li 2022-11-21 00:22:37 +08:00
parent 56f83e7258
commit 35d0ffe0c1
5 changed files with 226 additions and 6 deletions

View File

@ -21,6 +21,7 @@
"*.wxs": "javascript", "*.wxs": "javascript",
"*.inc": "c", "*.inc": "c",
"*.tcc": "c", "*.tcc": "c",
"*.ipp": "c" "*.ipp": "c",
"cstring": "cpp"
} }
} }

View File

@ -1,2 +1,2 @@
idf_component_register(SRCS "main.c" "wifi.c" "light.c" idf_component_register(SRCS "mqtt.c" "main.c" "wifi.c" "light.c" "mqtt.c"
INCLUDE_DIRS ".") INCLUDE_DIRS ".")

View File

@ -24,6 +24,9 @@ typedef enum light_mode_e {
light_mode_init = 0, light_mode_init = 0,
light_mode_connection_wifi = 1, light_mode_connection_wifi = 1,
light_mode_idle = 2, light_mode_idle = 2,
light_mode_mqtt_connected = 3,
light_mode_desktop_online = 4,
light_mode_desktop_sending_colors = 5,
} light_mode_t; } light_mode_t;
led_strip_t *light_led_strip; led_strip_t *light_led_strip;
@ -82,6 +85,43 @@ void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r,
} }
} }
void update_desktop_connection_state() {
static uint8_t tick = 0;
uint8_t mask = tick / 10 % 2 ? 0xff : 0x00;
switch (light_mode) {
case light_mode_desktop_online:
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 0, mask & 150,
mask & 50, mask & 0));
ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, 1, 30, 100, 0));
ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, 2, 30, 100, 0));
break;
case light_mode_mqtt_connected:
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 0, mask & 100,
mask & 30, mask & 0));
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 1, mask & 100,
mask & 30, mask & 0));
ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, 2, 50, 150, 0));
break;
case light_mode_idle:
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 0, mask & 100,
mask & 30, mask & 0));
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 1, mask & 100,
mask & 30, mask & 0));
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, 2, mask & 100,
mask & 30, mask & 0));
break;
default:
break;
}
tick++;
}
void light_for_init() { void light_for_init() {
ESP_LOGI(LIGHT_TAG, "light_for_init"); ESP_LOGI(LIGHT_TAG, "light_for_init");
ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100)); ESP_ERROR_CHECK(light_led_strip->clear(light_led_strip, 100));
@ -113,7 +153,6 @@ void light_for_connecting_wifi() {
ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip, ESP_ERROR_CHECK(light_led_strip->set_pixel(light_led_strip,
(tick_tock + 1) % 2, 0, 200, 0)); (tick_tock + 1) % 2, 0, 200, 0));
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100)); ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
ESP_LOGI(LIGHT_TAG, "tick_tock %d", tick_tock);
tick_tock = !tick_tock; tick_tock = !tick_tock;
vTaskDelay(pdMS_TO_TICKS(200)); vTaskDelay(pdMS_TO_TICKS(200));
} while (light_mode == light_mode_connection_wifi); } while (light_mode == light_mode_connection_wifi);
@ -126,7 +165,9 @@ void light_for_idle() {
uint32_t red = 0, green = 0, blue = 0; uint32_t red = 0, green = 0, blue = 0;
uint16_t step_length = 360 / STRIP_LED_NUMBER; uint16_t step_length = 360 / STRIP_LED_NUMBER;
for (uint16_t offset = 0; light_mode == light_mode_idle; for (uint16_t offset = 0; light_mode == light_mode_idle ||
light_mode == light_mode_mqtt_connected ||
light_mode == light_mode_desktop_online;
offset = (offset + 1) % 360) { offset = (offset + 1) % 360) {
for (uint16_t j = 0, hue = offset; j < STRIP_LED_NUMBER; for (uint16_t j = 0, hue = offset; j < STRIP_LED_NUMBER;
j++, hue += step_length) { j++, hue += step_length) {
@ -136,6 +177,7 @@ void light_for_idle() {
ESP_ERROR_CHECK( ESP_ERROR_CHECK(
light_led_strip->set_pixel(light_led_strip, j, red, green, blue)); light_led_strip->set_pixel(light_led_strip, j, red, green, blue));
} }
update_desktop_connection_state();
ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100)); ESP_ERROR_CHECK(light_led_strip->refresh(light_led_strip, 100));
vTaskDelay(pdMS_TO_TICKS(10)); vTaskDelay(pdMS_TO_TICKS(10));
} }
@ -147,7 +189,7 @@ void light_strip_running_task(void *pv_parameters) {
ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed 2"); ESP_LOGE(LIGHT_TAG, "install WS2812 driver failed 2");
} }
// Show simple rainbow chasing pattern // Show simple rainbow chasing pattern
ESP_LOGI(LIGHT_TAG, "light_strip_running_task"); ESP_LOGI(LIGHT_TAG, "light_strip_running_task: %d", light_mode);
switch (light_mode) { switch (light_mode) {
case light_mode_init: case light_mode_init:
light_for_init(); light_for_init();
@ -156,9 +198,12 @@ void light_strip_running_task(void *pv_parameters) {
light_for_connecting_wifi(); light_for_connecting_wifi();
break; break;
case light_mode_idle: case light_mode_idle:
case light_mode_mqtt_connected:
case light_mode_desktop_online:
light_for_idle(); light_for_idle();
break; break;
default: default:
vTaskDelay(pdMS_TO_TICKS(100));
break; break;
} }
} }
@ -191,4 +236,7 @@ void light_init_strip() {
1, NULL); 1, NULL);
} }
void light_play(light_mode_t mode) { light_mode = mode; } void light_play(light_mode_t mode) {
ESP_LOGI(LIGHT_TAG, "light_play: %d", mode);
light_mode = mode;
}

View File

@ -2,6 +2,7 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "light.c" #include "light.c"
#include "mqtt.c"
#include "sdkconfig.h" #include "sdkconfig.h"
#include "wifi.c" #include "wifi.c"
@ -14,4 +15,15 @@ void app_main(void) {
if (connect_wifi()) { if (connect_wifi()) {
light_play(light_mode_idle); light_play(light_mode_idle);
} }
vTaskDelay(pdMS_TO_TICKS(1000));
mqtt_app_start();
if (waiting_for_mqtt_connected()) {
light_play(light_mode_mqtt_connected);
}
if (waiting_for_desktop_online()) {
light_play(light_mode_desktop_online);
}
if (waiting_for_desktop_sending_colors()) {
light_play(light_mode_desktop_sending_colors);
}
} }

159
main/mqtt.c Normal file
View File

@ -0,0 +1,159 @@
#include <stdio.h>
#include <string.h>
#include "esp_bit_defs.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "freertos/queue.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
#include "mqtt_client.h"
#define MQTT_FAILED_BIT BIT0
#define MQTT_CONNECTED_BIT BIT1
#define MQTT_DISCONNECTED_BIT BIT2
#define MQTT_DESKTOP_ONLINE_BIT BIT3
#define MQTT_DESKTOP_OFFLINE_BIT BIT4
#define MQTT_DESKTOP_SENDING_BIT BIT5
#define MQTT_BOARD_KEY_PREFIX "screen-bg-light/board/"
#define MQTT_DESKTOP_KEY_PREFIX "screen-bg-light/desktop/"
#define MQTT_ONLINE_SUFFIX "online"
#define MQTT_COLORS_SUFFIX "colors"
#define MQTT_ALL_SUFFIX "#"
#define MQTT_KEY_BOARD_ONLINE MQTT_BOARD_KEY_PREFIX MQTT_ONLINE_SUFFIX
#define MQTT_KEY_DESKTOP_ONLINE MQTT_DESKTOP_KEY_PREFIX MQTT_ONLINE_SUFFIX
#define MQTT_KEY_DESKTOP_COLORS MQTT_DESKTOP_KEY_PREFIX MQTT_COLORS_SUFFIX
#define MQTT_KEY_DESKTOP_ALL MQTT_DESKTOP_KEY_PREFIX MQTT_ALL_SUFFIX
static const char *MQTT_TAG = "ScreenBgLight_MQTT";
static EventGroupHandle_t s_mqtt_event_group;
static void log_error_if_nonzero(const char *message, int error_code) {
if (error_code != 0) {
ESP_LOGE(MQTT_TAG, "Last error %s: 0x%x", message, error_code);
}
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base,
int32_t event_id, void *event_data) {
ESP_LOGD(MQTT_TAG, "Event dispatched from event loop base=%s, event_id=%d",
base, event_id);
esp_mqtt_event_handle_t event = 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:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_CONNECTED");
xEventGroupSetBits(s_mqtt_event_group, MQTT_CONNECTED_BIT);
msg_id = esp_mqtt_client_publish(client, MQTT_KEY_BOARD_ONLINE, "ONLINE",
0, 1, 0);
ESP_LOGI(MQTT_TAG, "sent publish successful, msg_id=%d", msg_id);
esp_mqtt_client_subscribe(client, MQTT_KEY_DESKTOP_ALL, 0);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DISCONNECTED");
xEventGroupSetBits(s_mqtt_event_group, MQTT_DISCONNECTED_BIT);
break;
case MQTT_EVENT_SUBSCRIBED:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_UNSUBSCRIBED:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_UNSUBSCRIBED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_PUBLISHED:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_PUBLISHED, msg_id=%d", event->msg_id);
break;
case MQTT_EVENT_DATA:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_DATA");
if (strcmp(event->topic, MQTT_KEY_BOARD_ONLINE)) {
xEventGroupSetBits(s_mqtt_event_group, MQTT_DESKTOP_ONLINE_BIT);
ESP_LOGE(MQTT_TAG, "AAA MQTT_DESKTOP_ONLINE_BIT");
} else if (strcmp(event->topic, MQTT_KEY_DESKTOP_COLORS)) {
ESP_LOGE(MQTT_TAG, "AAA MQTT_DESKTOP_SENDING_BIT");
xEventGroupSetBits(s_mqtt_event_group, MQTT_DESKTOP_SENDING_BIT);
}
printf("TOPIC=%.*s\r\n", event->topic_len, event->topic);
printf("DATA=%.*s\r\n", event->data_len, event->data);
break;
case MQTT_EVENT_ERROR:
ESP_LOGI(MQTT_TAG, "MQTT_EVENT_ERROR");
xEventGroupSetBits(s_mqtt_event_group, MQTT_FAILED_BIT);
if (event->error_handle->error_type == MQTT_ERROR_TYPE_TCP_TRANSPORT) {
log_error_if_nonzero("reported from esp-tls",
event->error_handle->esp_tls_last_esp_err);
log_error_if_nonzero("reported from tls stack",
event->error_handle->esp_tls_stack_err);
log_error_if_nonzero("captured as transport's socket errno",
event->error_handle->esp_transport_sock_errno);
ESP_LOGI(MQTT_TAG, "Last errno string (%s)",
strerror(event->error_handle->esp_transport_sock_errno));
}
break;
default:
ESP_LOGI(MQTT_TAG, "Other event id:%d", event->event_id);
break;
}
}
static void mqtt_app_start() {
s_mqtt_event_group = xEventGroupCreate();
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = "mqtt://192.168.31.11",
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, mqtt_event_handler,
client);
esp_mqtt_client_start(client);
}
static bool waiting_for_mqtt_connected() {
EventBits_t bits = xEventGroupWaitBits(s_mqtt_event_group,
MQTT_CONNECTED_BIT | MQTT_FAILED_BIT,
pdFALSE, pdFALSE, portMAX_DELAY);
if (bits & MQTT_CONNECTED_BIT) {
return 1;
} else if (bits & MQTT_FAILED_BIT) {
ESP_LOGE(MQTT_TAG, "BBB Failed to connect to MQTT.");
return 0;
} else {
ESP_LOGE(MQTT_TAG, "UNEXPECTED EVENT");
return 0;
}
}
static bool waiting_for_desktop_online() {
EventBits_t bits = xEventGroupWaitBits(
s_mqtt_event_group, MQTT_DESKTOP_ONLINE_BIT | MQTT_DESKTOP_SENDING_BIT,
pdFALSE, pdFALSE, portMAX_DELAY);
if (bits & MQTT_DESKTOP_ONLINE_BIT) {
return 1;
} else if (bits & MQTT_DESKTOP_SENDING_BIT) {
return 1;
} else {
ESP_LOGE(MQTT_TAG, "UNEXPECTED EVENT");
return 0;
}
}
static bool waiting_for_desktop_sending_colors() {
EventBits_t bits =
xEventGroupWaitBits(s_mqtt_event_group, MQTT_DESKTOP_SENDING_BIT, pdFALSE,
pdFALSE, portMAX_DELAY);
ESP_LOGE(MQTT_TAG, "MQTT_DESKTOP_SENDING_BIT");
if (bits & MQTT_DESKTOP_SENDING_BIT) {
return 1;
} else {
ESP_LOGE(MQTT_TAG, "UNEXPECTED EVENT");
return 0;
}
}