228 lines
15 KiB
C++
228 lines
15 KiB
C++
#include <ESPMegaProOS.hpp>
|
|
#include <InternalDisplay.hpp>
|
|
#include <ETH.h>
|
|
#include <ClimateCard.hpp>
|
|
#include <ESPMegaDisplayOTA.hpp>
|
|
|
|
// #define FRAM_DEBUG
|
|
// #define MQTT_DEBUG
|
|
#define WRITE_DEFAULT_NETCONF
|
|
#define CLIMATE_CARD_ENABLE
|
|
#define MQTT_CARD_REGISTER
|
|
#define DISPLAY_ENABLE
|
|
#define WEB_SERVER_ENABLE
|
|
#define LCD_OTA_ENABLE
|
|
|
|
// Demo PLC firmware using the ESPMegaPRO OOP library
|
|
|
|
ESPMegaPRO espmega = ESPMegaPRO();
|
|
|
|
#ifdef LCD_OTA_ENABLE
|
|
ESPMegaDisplayOTA internalDisplayOTA = ESPMegaDisplayOTA();
|
|
#endif
|
|
|
|
#ifdef CLIMATE_CARD_ENABLE
|
|
// Climate Card
|
|
const char *mode_names[] = {"off", "fan_only", "cool"};
|
|
const char *fan_speed_names[] = {"auto"};
|
|
|
|
const uint16_t code_off[] = {3478, 1717, 452, 418, 452, 1285, 452, 418, 452, 424, 452, 419, 451, 420, 452, 419, 451, 424, 451, 420, 451, 420, 452, 419, 451, 424, 451, 419, 451, 1285, 452, 419, 452, 424, 451, 419, 452, 419, 452, 419, 452, 423, 452, 418, 451, 1284, 452, 1284, 451, 1289, 452, 419, 452, 418, 452, 1285, 452, 423, 451, 420, 451, 420, 452, 419, 452, 423, 451, 420, 452, 420, 451, 419, 452, 423, 452, 419, 452, 419, 452, 419, 452, 423, 452, 420, 451, 420, 451, 420, 451, 423, 452, 419, 452, 419, 452, 420, 451, 423, 452, 419, 452, 420, 451, 419, 452, 423, 452, 419, 452, 419, 452, 420, 451, 423, 452, 418, 452, 1283, 452, 1285, 452, 424, 451, 420, 451, 420, 451, 420, 451, 419, 451, 9924, 3478, 1716, 452, 419, 451, 1284, 453, 420, 450, 425, 450, 420, 452, 419, 452, 419, 452, 423, 452, 420, 451, 420, 451, 420, 451, 423, 452, 418, 451, 1286, 451, 420, 451, 423, 452, 420, 451, 420, 451, 420, 451, 424, 451, 418, 451, 1285, 503, 1232, 451, 1289, 452, 420, 451, 418, 452, 1285, 451, 424, 451, 421, 450, 420, 451, 421, 450, 424, 451, 420, 451, 421, 450, 420, 451, 424, 451, 420, 451, 420, 451, 419, 452, 424, 451, 420, 451, 420, 451, 419, 450, 1290, 451, 419, 450, 1287, 504, 367, 451, 423, 451, 419, 450, 1285, 451, 1286, 450, 423, 451, 1284, 451, 1286, 506, 365, 506, 369, 451, 420, 451, 419, 506, 366, 505, 369, 505, 367, 450, 420, 506, 364, 506, 1236, 508, 1227, 506, 1230, 508, 1228, 506, 1234, 511, 358, 506, 1231, 505, 365, 504, 1235, 507, 1230, 505, 364, 508, 1228, 505, 1236, 507, 364, 505, 366, 506, 365, 507, 368, 506, 366, 505, 365, 451, 420, 506, 369, 506, 365, 506, 365, 506, 364, 507, 368, 506, 365, 505, 1229, 508, 1228, 451, 1289, 507, 364, 507, 365, 506, 365, 504, 370, 451, 421, 506, 366, 504, 366, 450, 425, 504, 365, 450, 1285, 451, 1285, 450, 1291, 504, 366, 505, 367, 504, 367, 450, 425, 506, 365, 450, 421, 450, 421, 510, 366, 449, 421, 450, 421, 506, 365, 504, 371, 506, 364, 506, 366, 505, 366, 506, 367, 451, 1286, 506, 366, 449, 422, 532, 342, 451, 420, 507, 364, 507, 363, 504, 1238, 506, 365, 504, 367, 505, 366, 506, 370, 508, 364, 450, 422, 449, 421, 506, 372, 506, 364, 506, 366, 450, 421, 450, 427, 450, 421, 450, 421, 532, 339, 450, 425, 507, 1229, 450, 1285, 506, 1229, 451, 1292, 507, 364, 507, 365, 535, 336, 450, 422, 506};
|
|
const uint16_t code_cool_auto[3][439] = {
|
|
{3477, 1718, 451, 419, 451, 1286, 450, 421, 451, 425, 449, 421, 451, 421, 450, 420, 451, 424, 451, 420, 451, 421, 450, 421, 450, 424, 451, 419, 451, 1286, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 419, 451, 1285, 450, 1285, 451, 1289, 452, 420, 450, 420, 450, 1287, 450, 424, 451, 421, 450, 420, 451, 420, 451, 424, 451, 421, 450, 421, 450, 421, 450, 425, 450, 421, 450, 421, 450, 421, 451, 424, 451, 420, 450, 421, 451, 420, 451, 424, 451, 420, 450, 421, 451, 421, 450, 424, 451, 421, 450, 420, 451, 421, 450, 424, 451, 421, 450, 421, 450, 421, 451, 423, 451, 419, 451, 1285, 450, 1286, 451, 424, 451, 420, 451, 420, 451, 421, 451, 418, 451, 9926, 3477, 1717, 451, 419, 451, 1286, 450, 421, 451, 423, 452, 421, 450, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 421, 450, 424, 451, 419, 451, 1285, 452, 420, 451, 424, 450, 421, 451, 420, 451, 420, 451, 424, 451, 419, 450, 1285, 451, 1285, 451, 1289, 451, 421, 450, 419, 451, 1286, 451, 424, 451, 420, 451, 420, 451, 420, 451, 425, 450, 421, 450, 420, 451, 421, 450, 424, 451, 420, 451, 421, 450, 421, 450, 425, 451, 420, 451, 420, 451, 418, 451, 1290, 451, 419, 450, 1286, 452, 420, 450, 425, 451, 420, 451, 420, 451, 420, 451, 422, 451, 1285, 451, 1286, 450, 420, 452, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 418, 451, 1292, 451, 1284, 452, 1285, 450, 1285, 451, 1290, 451, 419, 450, 1287, 450, 419, 451, 1289, 450, 1287, 450, 419, 451, 1284, 451, 1290, 451, 420, 451, 421, 450, 421, 450, 424, 451, 421, 450, 421, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 419, 450, 1284, 452, 1285, 451, 1289, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 452, 420, 450, 421, 450, 425, 451, 418, 451, 1285, 451, 1284, 451, 1290, 450, 421, 451, 420, 451, 421, 450, 424, 451, 421, 450, 420, 451, 421, 450, 424, 451, 420, 451, 421, 450, 421, 450, 424, 451, 420, 452, 419, 451, 421, 451, 423, 450, 1286, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 419, 451, 1290, 451, 420, 451, 421, 451, 420, 451, 426, 451, 420, 451, 420, 451, 420, 451, 426, 452, 420, 451, 419, 451, 421, 451, 425, 452, 420, 451, 420, 451, 420, 451, 425, 451, 1286, 450, 421, 451, 418, 451, 1292, 451, 420, 452, 419, 452, 420, 451, 420, 451}, // 24
|
|
{3478, 1717, 452, 417, 452, 1285, 452, 420, 451, 424, 451, 420, 451, 419, 452, 420, 451, 424, 451, 420, 452, 419, 451, 420, 452, 423, 452, 418, 451, 1286, 451, 420, 452, 423, 451, 420, 451, 419, 452, 420, 452, 423, 451, 419, 451, 1284, 452, 1283, 452, 1289, 452, 419, 452, 418, 452, 1285, 452, 423, 452, 419, 452, 419, 452, 420, 451, 423, 452, 418, 453, 419, 452, 419, 452, 423, 452, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 452, 423, 451, 420, 451, 420, 452, 419, 452, 423, 452, 419, 452, 420, 451, 419, 452, 423, 452, 419, 452, 419, 452, 420, 456, 419, 451, 418, 452, 1283, 452, 1286, 451, 423, 452, 420, 451, 419, 452, 420, 451, 418, 452, 9925, 3477, 1718, 451, 418, 451, 1286, 451, 420, 452, 423, 452, 419, 452, 419, 452, 420, 451, 423, 452, 419, 452, 420, 451, 420, 451, 423, 452, 418, 452, 1285, 452, 419, 452, 423, 451, 420, 452, 419, 452, 420, 502, 372, 452, 417, 452, 1284, 452, 1284, 451, 1289, 452, 420, 451, 418, 452, 1285, 452, 422, 453, 418, 453, 419, 452, 420, 451, 423, 452, 420, 451, 419, 452, 420, 452, 422, 452, 419, 452, 420, 452, 419, 452, 424, 450, 420, 452, 419, 452, 418, 451, 1289, 452, 418, 452, 1285, 452, 419, 452, 423, 451, 419, 451, 1285, 452, 419, 452, 422, 452, 1284, 451, 1285, 452, 420, 451, 424, 451, 420, 451, 420, 451, 419, 453, 423, 451, 420, 452, 419, 451, 419, 451, 1292, 451, 1284, 452, 1284, 451, 1284, 452, 1289, 452, 417, 452, 1285, 452, 418, 452, 1287, 452, 1285, 452, 418, 452, 1283, 452, 1290, 451, 419, 452, 419, 452, 420, 451, 423, 452, 419, 452, 420, 451, 420, 451, 423, 452, 420, 452, 419, 452, 419, 452, 423, 452, 417, 452, 1284, 452, 1283, 452, 1289, 452, 419, 452, 419, 452, 420, 451, 423, 452, 420, 451, 420, 451, 420, 452, 423, 452, 417, 452, 1284, 452, 1283, 452, 1289, 452, 420, 451, 419, 452, 420, 451, 423, 452, 419, 452, 420, 451, 420, 451, 423, 452, 419, 452, 420, 451, 420, 451, 424, 451, 419, 452, 420, 452, 419, 452, 422, 451, 1286, 451, 420, 451, 420, 451, 424, 451, 420, 452, 418, 453, 417, 452, 1291, 451, 419, 452, 419, 452, 422, 449, 426, 451, 420, 451, 420, 451, 420, 452, 425, 451, 420, 452, 419, 452, 420, 451, 424, 453, 419, 452, 419, 452, 420, 452, 424, 451, 1284, 451, 1285, 453, 418, 451, 1291, 452, 420, 451, 420, 451, 420, 451, 421, 451}, // 25
|
|
{3478, 1717, 451, 419, 451, 1286, 451, 420, 451, 424, 451, 421, 450, 421, 450, 421, 451, 423, 451, 420, 452, 420, 451, 420, 451, 424, 451, 418, 451, 1286, 451, 420, 452, 423, 451, 421, 450, 421, 451, 420, 451, 424, 450, 419, 451, 1285, 451, 1284, 451, 1290, 451, 420, 451, 419, 451, 1286, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 421, 450, 420, 451, 424, 451, 420, 451, 421, 450, 420, 451, 425, 450, 421, 450, 421, 450, 421, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 419, 451, 1285, 450, 1287, 451, 424, 450, 420, 451, 420, 452, 420, 451, 418, 451, 9926, 3477, 1717, 451, 419, 451, 1286, 451, 420, 451, 424, 451, 421, 450, 420, 451, 420, 451, 424, 451, 420, 451, 420, 452, 419, 452, 424, 450, 419, 451, 1286, 451, 420, 451, 424, 451, 420, 451, 420, 451, 421, 450, 424, 451, 419, 451, 1285, 450, 1285, 451, 1290, 450, 421, 451, 418, 451, 1287, 451, 423, 451, 420, 451, 421, 450, 421, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 424, 451, 421, 450, 420, 451, 419, 451, 1290, 450, 420, 450, 1286, 451, 421, 451, 423, 451, 421, 451, 418, 451, 1286, 451, 423, 451, 1284, 451, 1286, 451, 420, 451, 424, 451, 420, 451, 420, 451, 420, 451, 425, 450, 420, 451, 421, 450, 419, 451, 1292, 451, 1284, 451, 1286, 450, 1285, 451, 1290, 450, 419, 451, 1286, 451, 419, 451, 1288, 451, 1286, 456, 414, 450, 1285, 451, 1290, 450, 421, 451, 420, 451, 420, 451, 424, 451, 420, 451, 421, 450, 421, 450, 425, 450, 421, 450, 421, 451, 420, 451, 424, 451, 419, 450, 1285, 450, 1286, 450, 1290, 451, 420, 451, 420, 451, 420, 451, 424, 451, 420, 451, 421, 450, 421, 451, 424, 450, 419, 451, 1285, 450, 1285, 451, 1290, 450, 421, 451, 420, 451, 420, 451, 425, 450, 421, 450, 421, 450, 420, 451, 425, 450, 420, 451, 421, 451, 420, 451, 424, 450, 421, 450, 421, 451, 421, 450, 423, 450, 1286, 451, 421, 450, 421, 450, 425, 451, 419, 452, 420, 450, 420, 450, 1291, 451, 420, 451, 420, 451, 421, 450, 426, 451, 421, 450, 421, 451, 420, 451, 426, 451, 420, 451, 420, 451, 420, 451, 427, 450, 420, 452, 420, 450, 421, 451, 425, 450, 1287, 450, 419, 451, 1285, 450, 1293, 450, 421, 451, 420, 451, 420, 451, 421, 451} // 26
|
|
};
|
|
|
|
size_t getInfraredCode(uint8_t mode, uint8_t fan_speed, uint8_t temperature_index, const uint16_t **codePtr)
|
|
{
|
|
if (mode == 0)
|
|
{
|
|
// Off
|
|
*codePtr = &(code_off[0]);
|
|
return sizeof(code_off) / sizeof(uint16_t);
|
|
}
|
|
else if (mode == 1)
|
|
{
|
|
*codePtr = &(code_off[0]);
|
|
return sizeof(code_off) / sizeof(uint16_t);
|
|
}
|
|
else if (mode == 2)
|
|
{
|
|
// Cool
|
|
if (fan_speed == 0)
|
|
{
|
|
// Auto
|
|
Serial.printf("Returning cool auto code at temperature index %d\n", temperature_index);
|
|
*codePtr = &(code_cool_auto[temperature_index][0]);
|
|
return sizeof(code_cool_auto[temperature_index]) / sizeof(uint16_t);
|
|
}
|
|
else
|
|
{
|
|
// Didn't capture the other fan speeds yet
|
|
// Will do that later
|
|
*codePtr = &(code_off[0]);
|
|
return sizeof(code_off) / sizeof(uint16_t);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
AirConditioner ac = {
|
|
.max_temperature = 26,
|
|
.min_temperature = 24,
|
|
.modes = 3,
|
|
.mode_names = mode_names,
|
|
.fan_speeds = 4,
|
|
.fan_speed_names = fan_speed_names,
|
|
.getInfraredCode = &getInfraredCode};
|
|
|
|
ClimateCard climateCard = ClimateCard(4, ac, RMT_CHANNEL_1);
|
|
#endif
|
|
|
|
void input_change_callback(uint8_t pin, uint8_t value)
|
|
{
|
|
Serial.print("Input change callback: ");
|
|
Serial.print(pin);
|
|
Serial.print(" ");
|
|
Serial.println(value);
|
|
}
|
|
|
|
void mqtt_callback(char *topic, char *payload)
|
|
{
|
|
Serial.print("MQTT Callback: ");
|
|
Serial.print(topic);
|
|
Serial.print(" ");
|
|
Serial.println(payload);
|
|
}
|
|
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
|
void setNetworkConfig()
|
|
{
|
|
NetworkConfig config = {
|
|
.ip = {192, 168, 0, 10},
|
|
.gateway = {192, 168, 0, 1},
|
|
.subnet = {255, 255, 255, 0},
|
|
.dns1 = {10, 192, 1, 1},
|
|
.dns2 = {10, 192, 1, 1},
|
|
.useStaticIp = true,
|
|
.useWifi = false,
|
|
.wifiUseAuth = false,
|
|
};
|
|
strcpy(config.ssid, "ssid");
|
|
strcpy(config.password, "password");
|
|
strcpy(config.hostname, "espmega");
|
|
Serial.println("Setting network config");
|
|
espmega.iot->setNetworkConfig(config);
|
|
espmega.iot->saveNetworkConfig();
|
|
}
|
|
|
|
void setMqttConfig()
|
|
{
|
|
MqttConfig config = {
|
|
.mqtt_port = 1883,
|
|
.mqtt_useauth = false};
|
|
strcpy(config.mqtt_server, "192.168.0.26");
|
|
strcpy(config.base_topic, "/espmegaoop");
|
|
espmega.iot->setMqttConfig(config);
|
|
espmega.iot->saveMqttConfig();
|
|
}
|
|
#endif
|
|
|
|
void setup()
|
|
{
|
|
ESP_LOGI("Initializer", "Starting ESPMegaPRO OOP demo");
|
|
espmega.begin();
|
|
ESP_LOGI("Initializer", "Enabling IOT module");
|
|
espmega.enableIotModule();
|
|
ESP_LOGI("Initializer", "Enabling Ethernet");
|
|
ETH.begin();
|
|
ESP_LOGI("Initializer", "Binding Ethernet to IOT module");
|
|
espmega.iot->bindEthernetInterface(Ð);
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
|
setNetworkConfig();
|
|
#else
|
|
ESP_LOGI("Initializer", "Loading network config");
|
|
espmega.iot->loadNetworkConfig();
|
|
#endif
|
|
ESP_LOGI("Initializer", "Connecting to network");
|
|
espmega.iot->connectNetwork();
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
|
setMqttConfig();
|
|
#else
|
|
ESP_LOGI("Initializer", "Loading MQTT config");
|
|
espmega.iot->loadMqttConfig();
|
|
#endif
|
|
ESP_LOGI("Initializer", "Connecting to MQTT");
|
|
espmega.iot->connectToMqtt();
|
|
espmega.iot->registerMqttCallback(mqtt_callback);
|
|
#ifdef MQTT_CARD_REGISTER
|
|
ESP_LOGI("Initializer", "Registering cards 0");
|
|
espmega.iot->registerCard(0);
|
|
ESP_LOGI("Initializer", "Registering cards 1");
|
|
espmega.iot->registerCard(1);
|
|
#endif
|
|
ESP_LOGI("Initializer", "Registering Input change callback");
|
|
espmega.inputs.registerCallback(input_change_callback);
|
|
#ifdef CLIMATE_CARD_ENABLE
|
|
ESP_LOGI("Initializer", "Installing climate card");
|
|
espmega.installCard(2, &climateCard);
|
|
ESP_LOGI("Initializer", "Binding climate card to FRAM");
|
|
climateCard.bindFRAM(&espmega.fram, 1001);
|
|
ESP_LOGI("Initializer", "Loading climate card state from FRAM");
|
|
climateCard.loadStateFromFRAM();
|
|
ESP_LOGI("Initializer", "Enabling climate card FRAM autosave");
|
|
climateCard.setFRAMAutoSave(true);
|
|
ESP_LOGI("Initializer", "Registering cards 2");
|
|
espmega.iot->registerCard(2);
|
|
#endif
|
|
#ifdef DISPLAY_ENABLE
|
|
ESP_LOGI("Initializer", "Enabling internal display");
|
|
espmega.enableInternalDisplay(&Serial);
|
|
ESP_LOGI("Initializer", "Binding climate card to internal display");
|
|
espmega.display->bindClimateCard(&climateCard);
|
|
#endif
|
|
#ifdef WEB_SERVER_ENABLE
|
|
ESP_LOGI("Initializer", "Enabling web server");
|
|
espmega.enableWebServer(80);
|
|
espmega.webServer->setWebUsername("admin");
|
|
espmega.webServer->setWebPassword("Passw0rd");
|
|
espmega.webServer->saveCredentialsToFRAM();
|
|
#endif
|
|
#ifdef LCD_OTA_ENABLE
|
|
internalDisplayOTA.begin("/display", espmega.display, espmega.webServer);
|
|
#endif
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
espmega.loop();
|
|
#ifdef FRAM_DEBUG
|
|
// Every 20 seconds, dump FRAM 0-500 to serial
|
|
static uint32_t last_fram_dump = 0;
|
|
if (millis() - last_fram_dump >= 20000)
|
|
{
|
|
last_fram_dump = millis();
|
|
Serial.println("Dumping FRAM");
|
|
espmega.dumpFRAMtoSerial(0, 500);
|
|
Serial.println("Dumping FRAM ASCII");
|
|
espmega.dumpFRAMtoSerialASCII(0, 500);
|
|
}
|
|
#endif
|
|
|
|
// Every 5 seconds, publish "I'm alive" to MQTT
|
|
#ifdef MQTT_DEBUG
|
|
static uint32_t last_mqtt_publish = 0;
|
|
if (millis() - last_mqtt_publish >= 5000)
|
|
{
|
|
last_mqtt_publish = millis();
|
|
espmega.iot->publish("/espmegai/alive", "true");
|
|
}
|
|
static uint32_t last_mqtt_status = 0;
|
|
if (millis() - last_mqtt_status >= 1000)
|
|
{
|
|
last_mqtt_status = millis();
|
|
Serial.print("MQTT Status: ");
|
|
Serial.println(espmega.iot->mqttConnected() ? "Connected" : "Disconnected");
|
|
}
|
|
#endif
|
|
} |