implement IR MQTT functions

This commit is contained in:
Siwat Sirichai 2023-08-29 00:49:11 +07:00
parent 58a79eb1ad
commit 81da4402b2
3 changed files with 242 additions and 35 deletions

View File

@ -18,4 +18,5 @@ lib_deps = siwats/espmegapror3@^1.0.2
arduino-libraries/Arduino_BuiltIn@^1.0.0 arduino-libraries/Arduino_BuiltIn@^1.0.0
dersimn/PubSubClientTools@^0.6 dersimn/PubSubClientTools@^0.6
z3t0/IRremote@^4.2.0 z3t0/IRremote@^4.2.0
robtillaart/DHTNEW@^0.4.18
monitor_speed = 115200 monitor_speed = 115200

View File

@ -4,22 +4,61 @@
#include <ESPMegaPRO.h> #include <ESPMegaPRO.h>
#endif #endif
extern const uint16_t daikin_ir_code_cool[3][10][750] = { extern const uint16_t ir_code_cool[3][13][750] = {
// Fan Speed High
{
{0}, // 18C
{0}, // 19C
{0}, // 20C
{0}, // 21C
{0}, // 22C
{0}, // 23C
{0}, // 24C
{0}, // 25C
{0}, // 26C
{0}, // 27C
{0}, // 28C
{0}, // 29C
{0} // 30C
},
// Fan Speed Med
{
{0}, // 18C
{0}, // 19C
{0}, // 20C
{0}, // 21C
{0}, // 22C
{0}, // 23C
{0}, // 24C
{0}, // 25C
{0}, // 26C
{0}, // 27C
{0}, // 28C
{0}, // 29C
{0} // 30C
},
// Fan Speed Low // Fan Speed Low
{ {
{0}, // 16C {0}, // 18C
{0} // 17C {0}, // 19C
}, {0}, // 20C
// Fan Speed MED {0}, // 21C
{ {0}, // 22C
{0}, // 16C {0}, // 23C
{0} // 17C {0}, // 24C
{0}, // 25C
{0}, // 26C
{0}, // 27C
{0}, // 28C
{0}, // 29C
{0} // 30C
}}; }};
extern const uint16_t daikin_ir_code_fan[3][750] = { extern const uint16_t ir_code_fan[3][750] = {
{0}, // LOW {0}, // LOW
{0}, // MED {0}, // MED
{0} // HIGH {0} // HIGH
}; };
extern const uint16_t daikin_ir_code_off[750] = {0}; extern const uint16_t ir_code_off[750] = {0};
#endif #endif

View File

@ -7,6 +7,7 @@
#include <StaticThreadController.h> #include <StaticThreadController.h>
#include <IRremote.hpp> #include <IRremote.hpp>
#include <daikin_ir.hpp> #include <daikin_ir.hpp>
#include <dhtnew.h>
// Network Connectivity // Network Connectivity
#define HOSTNAME "espmega-pro-r3" #define HOSTNAME "espmega-pro-r3"
@ -17,6 +18,7 @@ const IPAddress DNS(10, 192, 1, 1);
const IPAddress MQTT_SERVER(192, 168, 0, 26); const IPAddress MQTT_SERVER(192, 168, 0, 26);
const int MQTT_PORT = 1883; const int MQTT_PORT = 1883;
#define MQTT_BASE_TOPIC "/espmega/ProR3" #define MQTT_BASE_TOPIC "/espmega/ProR3"
char STATE_REQUEST_TOPIC[75] = MQTT_BASE_TOPIC "/requeststate";
// #define MQTT_USE_AUTH // #define MQTT_USE_AUTH
#ifdef MQTT_USE_AUTH #ifdef MQTT_USE_AUTH
const char MQTT_USERNAME[] = "username"; const char MQTT_USERNAME[] = "username";
@ -39,13 +41,35 @@ const float pwm_linear_scaling_m[PWM_COUNT] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
const float pwm_linear_scaling_c[PWM_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; const float pwm_linear_scaling_c[PWM_COUNT] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
#define PWM_CYCLE_VALUES_COUNT 3 #define PWM_CYCLE_VALUES_COUNT 3
const int PWM_CYCLE_VALUES[PWM_CYCLE_VALUES_COUNT] = {50, 125, 255}; const int PWM_CYCLE_VALUES[PWM_CYCLE_VALUES_COUNT] = {50, 125, 255};
char PWM_SET_STATE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/state";
char PWM_SET_VALUE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/value";
// Infrared Transciever // Infrared Transciever
#define IR_RECIEVER_PIN 4 #define IR_RECIEVE_PIN 32
#define IR_TRANSMITTER_PIN 15 #define IR_SEND_PIN 15
#define MARK_EXCESS_MICROS 20 #define MARK_EXCESS_MICROS 20
#define RAW_BUFFER_LENGTH 750 #define RAW_BUFFER_LENGTH 750
// Air Conditioner Control
/*
Mode 0: Off, 1: Cool, 2: Fan
Fan Speed 0: Auto, 1: High, 2: Mid, 3: Low
*/
#define DHT22_PIN 17
int ac_mode = 0;
int ac_fan_speed = 0;
int ac_temperature = 25;
#define AC_MAX_TEMPERATURE 30
#define AC_MIN_TEMPERATURE 18
char AC_SET_MODE_TOPIC[75] = MQTT_BASE_TOPIC "/ac/set/mode";
char AC_SET_FAN_TOPIC[75] = MQTT_BASE_TOPIC "/ac/set/fan_speed";
char AC_SET_TEMPERATURE_TOPIC[75] = MQTT_BASE_TOPIC "/ac/set/temperature";
char AC_MODE_TOPIC[75] = MQTT_BASE_TOPIC "/ac/mode";
char AC_FAN_TOPIC[75] = MQTT_BASE_TOPIC "/ac/fan_speed";
char AC_TEMPERATURE_TOPIC[75] = MQTT_BASE_TOPIC "/ac/temperature";
char AC_ROOM_TEMPERATURE_TOPIC[75] = MQTT_BASE_TOPIC "/ac/room_temperature";
char AC_HUMIDITY_TOPIC[75] = MQTT_BASE_TOPIC "/ac/humidity";
// Forward declaration // Forward declaration
void virtual_interrupt_loop(); void virtual_interrupt_loop();
void virtual_interrupt_callback(int pin, int state); void virtual_interrupt_callback(int pin, int state);
@ -68,6 +92,11 @@ void pwm_toggle(int id1, int id2);
void pwm_cycle_value(int id); void pwm_cycle_value(int id);
boolean pwm_group_state(int id1, int id2); boolean pwm_group_state(int id1, int id2);
void publish_ac_state();
void publish_env_state();
void ac_state_callback(String topic, String message);
void ac_set_state(int mode, int temperature, int fan_speed);
void publish_input_states(); void publish_input_states();
void publish_input_state(int id); void publish_input_state(int id);
void publish_input_state(int id, int state); void publish_input_state(int id, int state);
@ -80,8 +109,11 @@ WiFiClient eth;
PubSubClient mqtt_client(MQTT_SERVER, 1883, eth); PubSubClient mqtt_client(MQTT_SERVER, 1883, eth);
PubSubClientTools mqtt(mqtt_client); PubSubClientTools mqtt(mqtt_client);
DHTNEW env_sensor(DHT22_PIN);
Thread mqtt_reconnector = Thread(); Thread mqtt_reconnector = Thread();
StaticThreadController<1> thread_controller(&mqtt_reconnector); Thread environment_reporter = Thread();
StaticThreadController<2> thread_controller(&mqtt_reconnector, &environment_reporter);
void setup() void setup()
{ {
@ -90,8 +122,8 @@ void setup()
ESPMega_begin(); ESPMega_begin();
io_begin(); io_begin();
Serial.println("Initializing Infrared . . ."); Serial.println("Initializing Infrared . . .");
IrReceiver.begin(IR_RECIEVER_PIN); IrReceiver.begin(IR_RECIEVE_PIN);
IrSender.begin(IR_TRANSMITTER_PIN); IrSender.begin(IR_SEND_PIN);
network_begin(); network_begin();
Serial.println("Initializing MQTT . . ."); Serial.println("Initializing MQTT . . .");
mqtt_connect(); mqtt_connect();
@ -112,8 +144,11 @@ void loop()
void io_begin() void io_begin()
{ {
Serial.println("Initializing I/O . . ."); Serial.println("Initializing I/O . . .");
pinMode(IR_RECIEVE_PIN, INPUT_PULLUP);
pinMode(IR_SEND_PIN, OUTPUT);
memset(pwm_states, 0, PWM_COUNT); memset(pwm_states, 0, PWM_COUNT);
for(int i=0;i<PWM_COUNT;i++) { for (int i = 0; i < PWM_COUNT; i++)
{
pwm_values[i] = 4095; pwm_values[i] = 4095;
} }
} }
@ -148,6 +183,7 @@ void mqtt_connect()
Serial.print("MQTT connected\n"); Serial.print("MQTT connected\n");
publish_pwm_states(); publish_pwm_states();
publish_input_states(); publish_input_states();
publish_ac_state();
} }
else else
{ {
@ -158,9 +194,6 @@ void mqtt_connect()
void mqtt_subscribe() void mqtt_subscribe()
{ {
char PWM_SET_STATE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/state";
char PWM_SET_VALUE_TOPIC[75] = MQTT_BASE_TOPIC "/pwm/00/set/value";
char STATE_REQUEST_TOPIC[75] = MQTT_BASE_TOPIC "/requeststate";
for (int i = 0; i < PWM_COUNT; i++) for (int i = 0; i < PWM_COUNT; i++)
{ {
PWM_SET_VALUE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 4] = ((i - i % 10) / 10) + '0'; PWM_SET_VALUE_TOPIC[sizeof(MQTT_BASE_TOPIC) + 4] = ((i - i % 10) / 10) + '0';
@ -170,6 +203,9 @@ void mqtt_subscribe()
mqtt.subscribe(PWM_SET_STATE_TOPIC, pwm_state_callback); mqtt.subscribe(PWM_SET_STATE_TOPIC, pwm_state_callback);
mqtt.subscribe(PWM_SET_VALUE_TOPIC, pwm_value_callback); mqtt.subscribe(PWM_SET_VALUE_TOPIC, pwm_value_callback);
} }
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);
mqtt.subscribe(STATE_REQUEST_TOPIC, state_request_callback); mqtt.subscribe(STATE_REQUEST_TOPIC, state_request_callback);
} }
@ -179,6 +215,8 @@ void thread_initialization()
Serial.println("Initializing MQTT Thread . . ."); Serial.println("Initializing MQTT Thread . . .");
mqtt_reconnector.onRun(mqtt_connect); mqtt_reconnector.onRun(mqtt_connect);
mqtt_reconnector.setInterval(30000); mqtt_reconnector.setInterval(30000);
environment_reporter.onRun(publish_env_state);
environment_reporter.setInterval(5000);
} }
void pwm_state_callback(String topic, String message) void pwm_state_callback(String topic, String message)
@ -186,15 +224,15 @@ void pwm_state_callback(String topic, String message)
Serial.println("Recieved PWM State Message"); Serial.println("Recieved PWM State Message");
Serial.println(topic); Serial.println(topic);
Serial.println(message); Serial.println(message);
int a = topic.charAt(sizeof(MQTT_BASE_TOPIC)+4) - '0'; int a = topic.charAt(sizeof(MQTT_BASE_TOPIC) + 4) - '0';
int b = topic.charAt(sizeof(MQTT_BASE_TOPIC)+5) - '0'; int b = topic.charAt(sizeof(MQTT_BASE_TOPIC) + 5) - '0';
int id = 10 * a + b; int id = 10 * a + b;
if (message.compareTo("on")==0) if (message.compareTo("on") == 0)
{ {
Serial.printf("Setting pwm %d to on\n", id); Serial.printf("Setting pwm %d to on\n", id);
pwm_set_state(id, true); pwm_set_state(id, true);
} }
else if (message.compareTo("off")==0) else if (message.compareTo("off") == 0)
{ {
Serial.printf("Setting pwm %d to off\n", id); Serial.printf("Setting pwm %d to off\n", id);
pwm_set_state(id, false); pwm_set_state(id, false);
@ -206,8 +244,8 @@ void pwm_value_callback(String topic, String message)
Serial.println("Recieved PWM Value Message"); Serial.println("Recieved PWM Value Message");
Serial.println(topic); Serial.println(topic);
Serial.println(message); Serial.println(message);
int a = topic.charAt(sizeof(MQTT_BASE_TOPIC)+4) - '0'; int a = topic.charAt(sizeof(MQTT_BASE_TOPIC) + 4) - '0';
int b = topic.charAt(sizeof(MQTT_BASE_TOPIC)+5) - '0'; int b = topic.charAt(sizeof(MQTT_BASE_TOPIC) + 5) - '0';
int id = 10 * a + b; int id = 10 * a + b;
int value = message.toInt(); int value = message.toInt();
pwm_set_value(id, value); pwm_set_value(id, value);
@ -215,9 +253,10 @@ void pwm_value_callback(String topic, String message)
void virtual_interrupt_callback(int pin, int state) void virtual_interrupt_callback(int pin, int state)
{ {
publish_input_state(pin,state); publish_input_state(pin, state);
Serial.printf("Pin %d changed to %d\n", pin, state); Serial.printf("Pin %d changed to %d\n", pin, state);
if(pin==15) { if (pin == 15)
{
pwm_toggle(4); pwm_toggle(4);
} }
} }
@ -366,14 +405,142 @@ void state_request_callback(String topic, String message)
{ {
publish_input_states(); publish_input_states();
publish_pwm_states(); publish_pwm_states();
publish_ac_state();
} }
void ir_loop() { void ir_loop()
if (IrReceiver.decode()) { {
IrReceiver.printIRResultAsCVariables(&Serial); if (IrReceiver.decode())
{
Serial.println(); Serial.println();
IrReceiver.printIRResultRawFormatted(&Serial, true); IrReceiver.compensateAndPrintIRResultAsCArray(&Serial, false);
Serial.println(); Serial.println();
Serial.println(); Serial.println();
IrReceiver.resume();
}
}
void publish_ac_state()
{
String temp = "";
switch (ac_mode)
{
case 0:
temp = "off";
break;
case 1:
temp = "cool";
break;
case 2:
temp = "fan";
default:
break;
}
mqtt.publish(String(AC_MODE_TOPIC), temp);
mqtt.publish(String(AC_TEMPERATURE_TOPIC), String(ac_temperature));
switch (ac_fan_speed)
{
case 0:
temp = "auto";
break;
case 1:
temp = "high";
break;
case 2:
temp = "med";
break;
case 3:
temp = "low";
break;
}
mqtt.publish(String(AC_FAN_TOPIC), temp);
Serial.println("AC State Published.");
}
void ac_state_callback(String topic, String message)
{
if (topic.compareTo(String(AC_SET_TEMPERATURE_TOPIC)) == 0)
{
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 (topic.compareTo(String(AC_SET_MODE_TOPIC)) == 0)
{
if (message.compareTo("off") == 0)
{
ac_set_state(0, ac_temperature, ac_fan_speed);
}
else if (message.compareTo("cool") == 0)
{
ac_set_state(1, ac_temperature, ac_fan_speed);
}
else if (message.compareTo("fan") == 0)
{
ac_set_state(2, ac_temperature, ac_fan_speed);
}
}
else if (topic.compareTo(String(AC_SET_FAN_TOPIC)) == 0)
{
if (message.compareTo("auto") == 0)
{
ac_set_state(ac_mode, ac_temperature, 0);
}
else if (message.compareTo("low") == 0)
{
ac_set_state(ac_mode, ac_temperature, 1);
}
else if (message.compareTo("med") == 0)
{
ac_set_state(ac_mode, ac_temperature, 2);
}
else if (message.compareTo("high") == 0)
{
ac_set_state(ac_mode, ac_temperature, 3);
}
}
}
void ac_set_state(int mode, int temperature, int fan_speed)
{
ac_mode = mode;
ac_temperature = temperature;
ac_fan_speed = fan_speed;
temperature -= AC_MIN_TEMPERATURE;
publish_ac_state();
switch (mode)
{
case 0:
IrSender.sendRaw(ir_code_off, sizeof(ir_code_off) / sizeof(ir_code_off[0]), NEC_KHZ);
break;
case 1:
IrSender.sendRaw(ir_code_cool[fan_speed][temperature], sizeof(ir_code_cool[fan_speed][temperature]) / sizeof(ir_code_cool[fan_speed][0]), NEC_KHZ);
break;
case 2:
IrSender.sendRaw(ir_code_fan[fan_speed], sizeof(ir_code_fan[fan_speed]) / sizeof(ir_code_fan[fan_speed][0]), NEC_KHZ);
break;
}
Serial.println("IR SENT.");
}
void publish_env_state()
{
int errorCode = env_sensor.read();
yield();
switch (errorCode)
{
case DHTLIB_OK:
mqtt.publish(String(AC_ROOM_TEMPERATURE_TOPIC), String(env_sensor.getTemperature()));
mqtt_client.loop();
mqtt.publish(String(AC_HUMIDITY_TOPIC), String(env_sensor.getHumidity()));
mqtt_client.loop();
break;
default:
mqtt.publish(String(AC_ROOM_TEMPERATURE_TOPIC), "ERROR");
mqtt_client.loop();
mqtt.publish(String(AC_HUMIDITY_TOPIC), "ERROR");
mqtt_client.loop();
} }
} }