Merge branch 'main' into cud

This commit is contained in:
Siwat Sirichai 2023-11-12 21:27:19 +07:00
commit 0754af5eea
5 changed files with 103 additions and 70 deletions

View File

@ -12,6 +12,7 @@
platform = espressif32 platform = espressif32
board = wt32-eth01 board = wt32-eth01
framework = arduino framework = arduino
board_build.f_cpu = 240000000L
lib_deps = siwats/ESPMegaPROR3@^1.3.0 lib_deps = siwats/ESPMegaPROR3@^1.3.0
knolleary/PubSubClient@^2.8 knolleary/PubSubClient@^2.8
ivanseidel/ArduinoThread@^2.1.1 ivanseidel/ArduinoThread@^2.1.1

View File

@ -19,7 +19,6 @@ uint16_t MQTT_PORT = 0;
WebServer otaserver(80); WebServer otaserver(80);
#endif #endif
bool standalone = true; bool standalone = true;
// #define MQTT_BASE_TOPIC "/espmega/ProR3"
char MQTT_BASE_TOPIC[20]; char MQTT_BASE_TOPIC[20];
uint8_t base_topic_length = 0; uint8_t base_topic_length = 0;
char STATE_REQUEST_TOPIC[40]; char STATE_REQUEST_TOPIC[40];
@ -104,8 +103,7 @@ char PWM_VALUE_TOPIC[75];
char INPUTS_TOPIC[75]; char INPUTS_TOPIC[75];
WiFiClient eth; WiFiClient eth;
PubSubClient mqtt_client(MQTT_SERVER, 1883, eth); PubSubClient mqtt(MQTT_SERVER, 1883, eth);
PubSubClientTools mqtt(mqtt_client);
#ifdef ENABLE_CLIMATE_MODULE #ifdef ENABLE_CLIMATE_MODULE
DHTNEW env_sensor(DHT22_PIN); DHTNEW env_sensor(DHT22_PIN);
@ -159,8 +157,9 @@ void setup()
lcd_send_command("boot_state.txt=\"Network Initializing . . .\""); lcd_send_command("boot_state.txt=\"Network Initializing . . .\"");
network_begin(); network_begin();
lcd_send_command("boot_state.txt=\"IoT Core Initializing . . .\""); lcd_send_command("boot_state.txt=\"IoT Core Initializing . . .\"");
mqtt_client.setSocketTimeout(1000); mqtt.setSocketTimeout(1000);
eth.setTimeout(1); eth.setTimeout(1);
mqtt.setCallback(&mqtt_callback);
mqtt_connect(); mqtt_connect();
lcd_send_command("boot_state.txt=\"Threads Initializing . . .\""); lcd_send_command("boot_state.txt=\"Threads Initializing . . .\"");
thread_initialization(); thread_initialization();
@ -176,7 +175,7 @@ void setup()
void loop() void loop()
{ {
virtual_interrupt_loop(); virtual_interrupt_loop();
mqtt_client.loop(); mqtt.loop();
ESPMega_loop(); ESPMega_loop();
#ifdef ENABLE_IR_MODULE #ifdef ENABLE_IR_MODULE
ir_loop(); ir_loop();
@ -243,7 +242,7 @@ void eeprom_retrieve_init()
eeprom_mqtt_useauth_retrieve(); eeprom_mqtt_useauth_retrieve();
eeprom_mqtt_username_retrieve(); eeprom_mqtt_username_retrieve();
eeprom_mqtt_password_retrieve(); eeprom_mqtt_password_retrieve();
mqtt_client.setServer(MQTT_SERVER, MQTT_PORT); mqtt.setServer(MQTT_SERVER, MQTT_PORT);
eeprom_basetopic_retrieve(); eeprom_basetopic_retrieve();
base_topic_length = strlen(MQTT_BASE_TOPIC) + 1; base_topic_length = strlen(MQTT_BASE_TOPIC) + 1;
memcpy(STATE_REQUEST_TOPIC, MQTT_BASE_TOPIC, 20); memcpy(STATE_REQUEST_TOPIC, MQTT_BASE_TOPIC, 20);
@ -465,15 +464,15 @@ void network_begin()
void mqtt_connect() void mqtt_connect()
{ {
if (!mqtt_client.connected()) if (!mqtt.connected())
{ {
Serial.print("MQTT not connected, connecting . . .\n"); Serial.print("MQTT not connected, connecting . . .\n");
lcd_send_stop_bit(); lcd_send_stop_bit();
if (MQTT_USE_AUTH) if (MQTT_USE_AUTH)
mqtt_client.connect(HOSTNAME, MQTT_USERNAME, MQTT_PASSWORD); mqtt.connect(HOSTNAME, MQTT_USERNAME, MQTT_PASSWORD);
else else
mqtt_client.connect(HOSTNAME); mqtt.connect(HOSTNAME);
if (mqtt_client.connected()) if (mqtt.connected())
{ {
mqtt_subscribe(); mqtt_subscribe();
Serial.print("MQTT connected\n"); Serial.print("MQTT connected\n");
@ -509,15 +508,40 @@ void mqtt_subscribe()
PWM_SET_VALUE_TOPIC[base_topic_length + 5] = (i % 10) + '0'; PWM_SET_VALUE_TOPIC[base_topic_length + 5] = (i % 10) + '0';
PWM_SET_STATE_TOPIC[base_topic_length + 4] = ((i - i % 10) / 10) + '0'; PWM_SET_STATE_TOPIC[base_topic_length + 4] = ((i - i % 10) / 10) + '0';
PWM_SET_STATE_TOPIC[base_topic_length + 5] = (i % 10) + '0'; PWM_SET_STATE_TOPIC[base_topic_length + 5] = (i % 10) + '0';
mqtt.subscribe(PWM_SET_STATE_TOPIC, pwm_state_callback); mqtt.subscribe(PWM_SET_STATE_TOPIC);
mqtt.subscribe(PWM_SET_VALUE_TOPIC, pwm_value_callback); mqtt.subscribe(PWM_SET_VALUE_TOPIC);
} }
#ifdef ENABLE_CLIMATE_MODULE #ifdef ENABLE_CLIMATE_MODULE
mqtt.subscribe(AC_SET_FAN_TOPIC, ac_state_callback); mqtt.subscribe(AC_SET_FAN_TOPIC);
mqtt.subscribe(AC_SET_TEMPERATURE_TOPIC, ac_state_callback); mqtt.subscribe(AC_SET_TEMPERATURE_TOPIC);
mqtt.subscribe(AC_SET_MODE_TOPIC, ac_state_callback); mqtt.subscribe(AC_SET_MODE_TOPIC);
#endif #endif
mqtt.subscribe(STATE_REQUEST_TOPIC, state_request_callback); mqtt.subscribe(STATE_REQUEST_TOPIC);
}
void mqtt_callback(char *topic, byte *payload, unsigned int length)
{
uint8_t topic_length = strlen(topic);
char topic_trim[50];
char payload_nt[length + 1];
memcpy(payload_nt, payload, length);
payload_nt[length] = NULL;
strncpy(topic_trim, topic + base_topic_length - 1, topic_length);
if ((!strncmp(topic_trim, "/pwm/", 5)) && !strncmp(topic_trim + 7, "/set/state", 10))
{
pwm_state_callback(topic_trim, topic_length, payload_nt, length);
}
else if ((!strncmp(topic_trim, "/pwm/", 5)) && !strncmp(topic_trim + 7, "/set/value", 10))
{
pwm_value_callback(topic_trim, topic_length, payload_nt, length);
} else if(!strcmp(topic,STATE_REQUEST_TOPIC)) {
state_request_callback();
}
else
{
ac_state_callback(topic, topic_length, payload_nt, length);
}
user_mqtt_callback(topic_trim, topic_length, payload_nt, length);
} }
void thread_initialization() void thread_initialization()
@ -536,27 +560,27 @@ void thread_initialization()
user_timer_tick.setInterval(15000); user_timer_tick.setInterval(15000);
} }
void pwm_state_callback(String topic, String message) void pwm_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
{ {
int a = topic.charAt(base_topic_length + 4) - '0'; int a = topic[5] - '0';
int b = topic.charAt(base_topic_length + 5) - '0'; int b = topic[6] - '0';
int id = 10 * a + b; int id = 10 * a + b;
if (message.compareTo("on") == 0) if (!strcmp(payload, "on"))
{ {
pwm_set_state(id, true); pwm_set_state(id, true);
} }
else if (message.compareTo("off") == 0) else if (!strcmp(payload, "off"))
{ {
pwm_set_state(id, false); pwm_set_state(id, false);
} }
} }
void pwm_value_callback(String topic, String message) void pwm_value_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
{ {
int a = topic.charAt(base_topic_length + 4) - '0'; int a = topic[5] - '0';
int b = topic.charAt(base_topic_length + 5) - '0'; int b = topic[6] - '0';
int id = 10 * a + b; int id = 10 * a + b;
int value = message.toInt(); int value = atoi(payload);
pwm_set_value(id, value); pwm_set_value(id, value);
} }
@ -610,13 +634,15 @@ void publish_pwm_state(int id)
PWM_VALUE_TOPIC[base_topic_length + 5] = (id % 10) + '0'; PWM_VALUE_TOPIC[base_topic_length + 5] = (id % 10) + '0';
if (state == 1) if (state == 1)
{ {
mqtt_client.publish(PWM_STATE_TOPIC, "on"); mqtt.publish(PWM_STATE_TOPIC, "on");
} }
else if (state == 0) else if (state == 0)
{ {
mqtt_client.publish(PWM_STATE_TOPIC, "off"); mqtt.publish(PWM_STATE_TOPIC, "off");
} }
mqtt.publish(String(PWM_VALUE_TOPIC), String(value)); char temp[6];
itoa(value, temp, DEC);
mqtt.publish(PWM_VALUE_TOPIC, temp);
} }
void pwm_set_state(int id, int state) void pwm_set_state(int id, int state)
@ -723,10 +749,10 @@ void publish_input_state(int id, int state)
{ {
INPUTS_TOPIC[base_topic_length + 6] = ((id - id % 10) / 10) + '0'; INPUTS_TOPIC[base_topic_length + 6] = ((id - id % 10) / 10) + '0';
INPUTS_TOPIC[base_topic_length + 7] = (id % 10) + '0'; INPUTS_TOPIC[base_topic_length + 7] = (id % 10) + '0';
mqtt.publish(String(INPUTS_TOPIC), state ? "1" : "0"); mqtt.publish(INPUTS_TOPIC, state ? "1" : "0");
} }
void state_request_callback(String topic, String message) void state_request_callback()
{ {
publish_input_states(); publish_input_states();
publish_pwm_states(); publish_pwm_states();
@ -749,80 +775,79 @@ void ir_loop()
#ifdef ENABLE_CLIMATE_MODULE #ifdef ENABLE_CLIMATE_MODULE
void publish_ac_state() void publish_ac_state()
{ {
String temp = "";
switch (ac_mode) switch (ac_mode)
{ {
case 0: case 0:
temp = "off"; mqtt.publish(AC_MODE_TOPIC, "off");
break; break;
case 1: case 1:
temp = "cool"; mqtt.publish(AC_MODE_TOPIC, "cool");
break; break;
case 2: case 2:
temp = "fan_only"; mqtt.publish(AC_MODE_TOPIC, "fan_only");
default: default:
break; break;
} }
mqtt.publish(String(AC_MODE_TOPIC), temp); char temp[5];
mqtt.publish(String(AC_TEMPERATURE_TOPIC), String(ac_temperature)); itoa(ac_temperature, temp, DEC);
mqtt.publish(AC_TEMPERATURE_TOPIC, temp);
switch (ac_fan_speed) switch (ac_fan_speed)
{ {
case 0: case 0:
temp = "auto"; mqtt.publish(AC_FAN_TOPIC, "auto");
break; break;
case 1: case 1:
temp = "high"; mqtt.publish(AC_FAN_TOPIC, "high");
break; break;
case 2: case 2:
temp = "med"; mqtt.publish(AC_FAN_TOPIC, "med");
break; break;
case 3: case 3:
temp = "low"; mqtt.publish(AC_FAN_TOPIC, "low");
break; break;
} }
mqtt.publish(String(AC_FAN_TOPIC), temp);
} }
void ac_state_callback(String topic, String message) void ac_state_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length)
{ {
if (topic.compareTo(String(AC_SET_TEMPERATURE_TOPIC)) == 0) if (!strcmp(topic, AC_SET_TEMPERATURE_TOPIC))
{ {
int new_temp = message.toInt(); int new_temp = atoi(payload);
if (new_temp >= AC_MIN_TEMPERATURE && new_temp <= AC_MAX_TEMPERATURE) if (new_temp >= AC_MIN_TEMPERATURE && new_temp <= AC_MAX_TEMPERATURE)
{ {
ac_set_state(ac_mode, new_temp, ac_fan_speed); ac_set_state(ac_mode, new_temp, ac_fan_speed);
} }
} }
else if (topic.compareTo(String(AC_SET_MODE_TOPIC)) == 0) else if (!strcmp(topic, AC_SET_MODE_TOPIC))
{ {
if (message.compareTo("off") == 0) if (!strcmp(payload, "off"))
{ {
ac_set_state(0, ac_temperature, ac_fan_speed); ac_set_state(0, ac_temperature, ac_fan_speed);
} }
else if (message.compareTo("cool") == 0) else if (!strcmp(payload, "cool"))
{ {
ac_set_state(1, ac_temperature, ac_fan_speed); ac_set_state(1, ac_temperature, ac_fan_speed);
} }
else if (message.compareTo("fan_only") == 0) else if (!strcmp(payload, "fan_only"))
{ {
ac_set_state(2, ac_temperature, ac_fan_speed); ac_set_state(2, ac_temperature, ac_fan_speed);
} }
} }
else if (topic.compareTo(String(AC_SET_FAN_TOPIC)) == 0) else if (!strcmp(topic, AC_SET_FAN_TOPIC))
{ {
if (message.compareTo("auto") == 0) if (!strcmp(payload, "auto"))
{ {
ac_set_state(ac_mode, ac_temperature, 0); ac_set_state(ac_mode, ac_temperature, 0);
} }
else if (message.compareTo("low") == 0) else if (!strcmp(payload, "low"))
{ {
ac_set_state(ac_mode, ac_temperature, 1); ac_set_state(ac_mode, ac_temperature, 1);
} }
else if (message.compareTo("med") == 0) else if (!strcmp(payload, "med"))
{ {
ac_set_state(ac_mode, ac_temperature, 2); ac_set_state(ac_mode, ac_temperature, 2);
} }
else if (message.compareTo("high") == 0) else if (!strcmp(payload, "high"))
{ {
ac_set_state(ac_mode, ac_temperature, 3); ac_set_state(ac_mode, ac_temperature, 3);
} }
@ -877,10 +902,12 @@ void publish_env_state()
case DHTLIB_OK: case DHTLIB_OK:
current_room_humid = env_sensor.getHumidity(); current_room_humid = env_sensor.getHumidity();
current_room_temp = env_sensor.getTemperature(); current_room_temp = env_sensor.getTemperature();
mqtt.publish(String(AC_ROOM_TEMPERATURE_TOPIC), String(current_room_temp)); char temp[5];
mqtt_client.loop(); dtostrf(current_room_temp, 0, 2, temp);
mqtt.publish(String(AC_HUMIDITY_TOPIC), String(current_room_humid)); mqtt.publish(AC_ROOM_TEMPERATURE_TOPIC, temp);
mqtt_client.loop(); dtostrf(current_room_humid, 0, 2, temp);
mqtt.publish(AC_HUMIDITY_TOPIC, temp);
mqtt.loop();
#ifdef ENABLE_INTERNAL_LCD #ifdef ENABLE_INTERNAL_LCD
if (lcd_current_page == 4) if (lcd_current_page == 4)
{ {
@ -892,10 +919,10 @@ void publish_env_state()
#endif #endif
break; break;
default: default:
mqtt.publish(String(AC_ROOM_TEMPERATURE_TOPIC), "ERROR"); mqtt.publish(AC_ROOM_TEMPERATURE_TOPIC, "ERROR");
mqtt_client.loop(); mqtt.loop();
mqtt.publish(String(AC_HUMIDITY_TOPIC), "ERROR"); mqtt.publish(AC_HUMIDITY_TOPIC, "ERROR");
mqtt_client.loop(); mqtt.loop();
} }
} }
#endif #endif

View File

@ -9,7 +9,6 @@
#endif #endif
#include <ETH.h> #include <ETH.h>
#include <PubSubClient.h> #include <PubSubClient.h>
#include <PubSubClientTools.h>
#include <Thread.h> #include <Thread.h>
#include <StaticThreadController.h> #include <StaticThreadController.h>
#ifdef ENABLE_IR_MODULE #ifdef ENABLE_IR_MODULE
@ -35,15 +34,16 @@
#endif #endif
#include "espmega_iot_timer.hpp" #include "espmega_iot_timer.hpp"
void mqtt_callback(char* topic, byte* payload, unsigned int length);
void virtual_interrupt_loop(); void virtual_interrupt_loop();
void virtual_interrupt_callback(int pin, int state); void virtual_interrupt_callback(int pin, int state);
void network_begin(); void network_begin();
void mqtt_connect(); void mqtt_connect();
void mqtt_subscribe(); void mqtt_subscribe();
void thread_initialization(); void thread_initialization();
void pwm_state_callback(String topic, String message); void pwm_state_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length);
void pwm_value_callback(String topic, String message); void pwm_value_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length);
void state_request_callback(String topic, String message); void state_request_callback();
void io_begin(); void io_begin();
void ir_loop(); void ir_loop();
@ -66,7 +66,7 @@ void publish_env_state();
uint8_t ac_get_temperature(); uint8_t ac_get_temperature();
uint8_t ac_get_mode(); uint8_t ac_get_mode();
uint8_t ac_get_fan_speed(); uint8_t ac_get_fan_speed();
void ac_state_callback(String topic, String message); void ac_state_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length);
void ac_set_state(int mode, int temperature, int fan_speed); void ac_set_state(int mode, int temperature, int fan_speed);
void publish_input_states(); void publish_input_states();

View File

@ -301,4 +301,9 @@ void mqtt_connected_user_callback() {
void user_state_request_callback() { void user_state_request_callback() {
ac_lock_report(); ac_lock_report();
}
void user_mqtt_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length) {
} }

View File

@ -10,7 +10,7 @@
#define ESPMEGA_REV "ESPMega PRO R3.3b (CUD)" #define ESPMEGA_REV "ESPMega PRO R3.3b (CUD)"
// Enable Software Module(s) // Enable Software Module(s)
#define ENABLE_INTERNAL_LCD //#define ENABLE_INTERNAL_LCD
#define ENABLE_IR_MODULE #define ENABLE_IR_MODULE
#define ENABLE_CLIMATE_MODULE // Require IR Module #define ENABLE_CLIMATE_MODULE // Require IR Module
#define ENABLE_WEBUI #define ENABLE_WEBUI
@ -90,6 +90,7 @@ void pwm_update_lcd();
void mqtt_connected_user_callback(); void mqtt_connected_user_callback();
void ac_lock_report(); void ac_lock_report();
void user_state_request_callback(); void user_state_request_callback();
void user_mqtt_callback(char* topic, uint8_t topic_length, char* payload, unsigned int payload_length);
// ESPMega IoT Core Build-in Functions // ESPMega IoT Core Build-in Functions
extern void pwm_set_state(int id, int state); extern void pwm_set_state(int id, int state);
@ -106,6 +107,5 @@ extern uint8_t ac_get_temperature();
extern uint8_t ac_get_mode(); extern uint8_t ac_get_mode();
extern uint8_t ac_get_fan_speed(); extern uint8_t ac_get_fan_speed();
extern bool standalone; extern bool standalone;
extern PubSubClient mqtt_client;
extern PubSubClientTools mqtt;
extern char MQTT_BASE_TOPIC[]; extern char MQTT_BASE_TOPIC[];
extern PubSubClient mqtt;