My shopping list of what I have been using and some pictures of the lab setup:
ESP32-C6 ESP32-C6-DevKitC-1-N4 Development Board link
Hailege 2pcs PC817 4-Channel Optocoupler Insulation Module 817 Voltage Isolation Voltage Converter Module 3.6-30V Photoelectric Insulated Module
link
I chose this one as all 3 buttons need an optocoupler, this thing a) it screws the connecting wires in place which is nice and b) it is a 4 in 1. I know one too many, but it is a solid solution.
So far, when I push the OPEN button in HA, the LED on the optocoupler flashes shortly and then the LED ont the remote flashes and the awning actually opens.
This is NOT working for the STOP and CLOSE buttons for some awkward reason. It’s not the soldering, because when I short the + and - wires of the STOP or CLOSE button, the both function. Polarity I checked by switchin
ChatGPT suggest that the current could be “not enough” when the optocoupler is making the connection, but I doubt that, to be honest.
Any suggestions ???
The code has some flaws still.
For example as you can see, the % open is not yet properly displayed and there is more but here is what I have and what basically does what it needs to do: send a signal on a push in HA to a button on the remote and so operating the awning.
// main/awning_main.c
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_err.h"
#include "secret.h"
#include "mqtt_client.h"
#include "driver/gpio.h" // Include the GPIO driver
#define TAG "awning_example"
#define GPIO_OPEN 18
#define GPIO_STOP 19
#define GPIO_CLOSE 21
static esp_mqtt_client_handle_t client;
// Event handler for catching system events
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
ESP_LOGI(TAG, "Retry to connect to the AP");
} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
}
}
void wifi_init_sta(void) {
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&cfg);
esp_event_handler_instance_t instance_any_id;
esp_event_handler_instance_t instance_got_ip;
esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL, &instance_any_id);
esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL, &instance_got_ip);
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASSWORD,
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
},
};
esp_wifi_set_mode(WIFI_MODE_STA);
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
esp_wifi_start();
ESP_LOGI(TAG, "wifi_init_sta finished.");
ESP_LOGI(TAG, "connect to ap SSID:%s password:%s", WIFI_SSID, WIFI_PASSWORD);
}
static void mqtt_event_handler(void *handler_args, esp_event_base_t base, int32_t event_id, void *event_data) {
esp_mqtt_event_handle_t event = event_data;
client = event->client;
switch (event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_CONNECTED");
esp_mqtt_client_subscribe(client, "home/awning/set", 0);
break;
case MQTT_EVENT_DISCONNECTED:
ESP_LOGI(TAG, "MQTT_EVENT_DISCONNECTED");
break;
case MQTT_EVENT_DATA:
ESP_LOGI(TAG, "MQTT_EVENT_DATA");
if (strncmp(event->topic, "home/awning/set", event->topic_len) == 0) {
if (strncmp(event->data, "open", event->data_len) == 0) {
gpio_set_level(GPIO_OPEN, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_OPEN, 0);
} else if (strncmp(event->data, "stop", event->data_len) == 0) {
gpio_set_level(GPIO_STOP, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_STOP, 0);
} else if (strncmp(event->data, "close", event->data_len) == 0) {
gpio_set_level(GPIO_CLOSE, 1);
vTaskDelay(1000 / portTICK_PERIOD_MS);
gpio_set_level(GPIO_CLOSE, 0);
}
}
break;
default:
break;
}
}
void mqtt_app_start(void) {
esp_mqtt_client_config_t mqtt_cfg = {
.broker = {
.address.uri = MQTT_BROKER_URI,
},
.credentials = {
.username = MQTT_USER,
.authentication = {
.password = MQTT_PASSWORD,
}
}
};
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);
}
void app_main(void) {
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
ESP_ERROR_CHECK(ret);
wifi_init_sta();
gpio_reset_pin(GPIO_OPEN);
gpio_set_direction(GPIO_OPEN, GPIO_MODE_OUTPUT);
gpio_reset_pin(GPIO_STOP);
gpio_set_direction(GPIO_STOP, GPIO_MODE_OUTPUT);
gpio_reset_pin(GPIO_CLOSE);
gpio_set_direction(GPIO_CLOSE, GPIO_MODE_OUTPUT);
mqtt_app_start();
}