ise-iot-oop-v2/src/main.cpp
2024-01-30 20:51:12 +07:00

180 lines
No EOL
5.3 KiB
C++

#include <main.hpp>
#include <cud_display.hpp>
/***********************************************
* Begin Configuration *
************************************************/
// Display Configuration
#define cudDisplayAdapter Serial2
#define CUD_DISPLAY_BAUD_RATE 115200
#define CUD_DISPLAY_TX_PIN 4
#define CUD_DISPLAY_RX_PIN 17
// Air Conditioner Configuration
#define AIR_CONDITIONER_LOCK_FRAM_ADDRESS 4900
#define AIR_CONDITIONER_LOCK_RELATIVE_TOPIC "ac_lock"
#define AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC "ac_lock/set"
#define AIR_CONDITIONER_SENSOR_TYPE AC_SENSOR_TYPE_DHT22
#define AIR_CONDITIONER_SENSOR_PIN 32
#define AIR_CONDITIONER_IR_PIN 5
#define AIR_CONDITIONER_RMT_CHANNEL RMT_CHANNEL_0
const char *mode_names[] = {"off", "fan_only", "cool"};
const char *fan_speed_names[] = {"auto", "high", "medium", "low"};
AirConditioner ac = {
.max_temperature = 30,
.min_temperature = 15,
.modes = 3,
.mode_names = mode_names,
.fan_speeds = 4,
.fan_speed_names = fan_speed_names,
.getInfraredCode = &getInfraredCode};
/***********************************************
* End Configuration *
***********************************************/
ESPMegaPRO espmega = ESPMegaPRO();
CUDDisplay cudDisplay = CUDDisplay(&cudDisplayAdapter);
ClimateCard climateCard = ClimateCard(AIR_CONDITIONER_IR_PIN, ac,
AIR_CONDITIONER_SENSOR_TYPE, AIR_CONDITIONER_SENSOR_PIN,
AIR_CONDITIONER_RMT_CHANNEL);
void handleMqttMessage(char *topic, char *payload)
{
char *temperature = (char*)calloc(16,sizeof(char));
strcpy(temperature, payload);
int temp_int;
temp_int = atoi(temperature);
Serial.printf("MQTT Message: %s %s\n", topic, payload);
if (!strcmp(topic, AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC))
{
if (!strcmp(payload, "lock"))
{
lockAC();
espmega.iot->publishRelative(AIR_CONDITIONER_LOCK_RELATIVE_TOPIC, "lock");
}
else if (!strcmp(payload, "unlock"))
{
unlockAC();
espmega.iot->publishRelative(AIR_CONDITIONER_LOCK_RELATIVE_TOPIC, "unlock");
}
}
free(temperature);
}
void lockAC()
{
espmega.fram.write8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS, 0);
cudDisplay.setACControlEnabled(false);
}
void unlockAC()
{
espmega.fram.write8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS, 1);
cudDisplay.setACControlEnabled(true);
}
void sendStopBytes()
{
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
}
void sendExtStopBytes()
{
cudDisplayAdapter.write(0xFF);
cudDisplayAdapter.write(0xFF);
cudDisplayAdapter.write(0xFF);
}
void setup()
{
gpio_config_t gpio_2_conf;
gpio_2_conf.intr_type = GPIO_INTR_DISABLE;
gpio_2_conf.mode = GPIO_MODE_INPUT;
gpio_2_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&gpio_2_conf);
// If GPIO 2 is pulled low, clear the FRAM then reboot (Reset the device to factory defaults)
bool clear_fram = !gpio_get_level(GPIO_NUM_2);
Serial.begin(115200);
cudDisplayAdapter.begin(CUD_DISPLAY_BAUD_RATE, SERIAL_8N1, CUD_DISPLAY_RX_PIN, CUD_DISPLAY_TX_PIN);
sendExtStopBytes();
cudDisplayAdapter.print("rest");
sendExtStopBytes();
sendStopBytes();
Serial.print("rest");
sendStopBytes();
Serial.print("boot_state.txt=\"Core Initializing . . .\"");
sendStopBytes();
espmega.begin();
// if (clear_fram)
// {
// Serial.print("boot_state.txt=\"Factory Resetting . . .\"");
// sendStopBytes();
// for (uint16_t i = 0; i < 32768; i++)
// {
// espmega.fram.write8(i, 0);
// }
// esp_restart();
// }
Serial.print("boot_state.txt=\"IoT Initializing . . .\"");
sendStopBytes();
espmega.enableIotModule();
ETH.begin();
espmega.iot->bindEthernetInterface(&ETH);
Serial.print("boot_state.txt=\"Network Initializing . . .\"");
sendStopBytes();
espmega.iot->loadNetworkConfig();
espmega.iot->connectNetwork();
Serial.print("boot_state.txt=\"MQTT Initializing . . .\"");
sendStopBytes();
espmega.iot->loadMqttConfig();
espmega.iot->connectToMqtt();
Serial.print("boot_state.txt=\"Display Initializing . . .\"");
espmega.enableInternalDisplay(&Serial);
espmega.enableWebServer(80);
espmega.inputs.registerCallback(on_pin_change);
espmega.outputs.setAutoSaveToFRAM(true);
espmega.installCard(2, &climateCard);
climateCard.bindFRAM(&espmega.fram, 5000);
climateCard.loadStateFromFRAM();
climateCard.setFRAMAutoSave(true);
espmega.display->bindClimateCard(&climateCard);
espmega.iot->registerCard(0); // Register the Input Card
espmega.iot->registerCard(1); // Register the Output Card
espmega.iot->registerCard(2); // Register the Climate Card
auto bindedGetTime = std::bind(&ESPMegaPRO::getTime, &espmega);
cudDisplay.begin(bindedGetTime, &espmega.inputs, &espmega.outputs, &climateCard);
if (espmega.fram.read8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS))
{
lockAC();
}
else
{
// AC is unlocked
unlockAC();
}
espmega.iot->subscribeRelative(AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC);
espmega.iot->registerRelativeMqttCallback(&handleMqttMessage);
}
void loop()
{
espmega.loop();
cudDisplay.loop();
}
void on_pin_change(uint8_t pin, uint8_t value)
{
// For pin 0-6, when the pin value changes, toggle the corresponding PWM pin
if (pin < 7)
{
bool new_value = !espmega.outputs.getState(pin);
espmega.outputs.digitalWrite(pin, new_value);
}
}