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