2023-12-28 13:20:49 +00:00
|
|
|
#include <ESPMegaPRO_OOP.hpp>
|
2023-12-29 14:41:19 +00:00
|
|
|
#include <InternalDisplay.hpp>
|
2023-12-28 16:28:21 +00:00
|
|
|
#include <ETH.h>
|
2023-12-30 08:39:16 +00:00
|
|
|
#include <ClimateCard.hpp>
|
2023-12-28 13:20:49 +00:00
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
// #define FRAM_DEBUG
|
2023-12-31 17:07:11 +00:00
|
|
|
// #define MQTT_DEBUG
|
2023-12-31 16:29:40 +00:00
|
|
|
// #define WRITE_DEFAULT_NETCONF
|
|
|
|
#define CLIMATE_CARD_ENABLE
|
|
|
|
#define MQTT_CARD_REGISTER
|
2023-12-31 17:31:28 +00:00
|
|
|
#define DISPLAY_ENABLE
|
2024-01-01 06:28:15 +00:00
|
|
|
#define WEB_SERVER_ENABLE
|
2023-12-30 11:47:52 +00:00
|
|
|
|
2023-12-30 11:27:39 +00:00
|
|
|
// Demo PLC firmware using the ESPMegaPRO OOP library
|
|
|
|
|
2023-12-28 13:20:49 +00:00
|
|
|
ESPMegaPRO espmega = ESPMegaPRO();
|
2023-12-31 16:29:40 +00:00
|
|
|
|
|
|
|
#ifdef CLIMATE_CARD_ENABLE
|
|
|
|
// Climate Card
|
2023-12-30 17:25:07 +00:00
|
|
|
const uint16_t irCode[15][4][4][1] = {0};
|
2023-12-31 17:31:28 +00:00
|
|
|
const char *mode_names[] = {"off", "fan_only", "cool"};
|
|
|
|
const char *fan_speed_names[] = {"auto", "low", "medium", "high"};
|
2023-12-30 17:25:07 +00:00
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
size_t getInfraredCode(uint8_t mode, uint8_t fan_speed, uint8_t temperature, const uint16_t **codePtr)
|
|
|
|
{
|
2023-12-30 17:25:07 +00:00
|
|
|
// Change the code pointer to point to the IR timing array
|
|
|
|
*codePtr = &(irCode[mode][fan_speed][temperature][0]);
|
|
|
|
return sizeof(irCode[mode][fan_speed][temperature]) / sizeof(uint16_t);
|
|
|
|
}
|
2023-12-31 08:53:39 +00:00
|
|
|
|
2023-12-30 17:25:07 +00:00
|
|
|
AirConditioner ac = {
|
|
|
|
.max_temperature = 30,
|
|
|
|
.min_temperature = 16,
|
|
|
|
.modes = 4,
|
|
|
|
.mode_names = mode_names,
|
|
|
|
.fan_speeds = 4,
|
|
|
|
.fan_speed_names = fan_speed_names,
|
2023-12-31 10:55:13 +00:00
|
|
|
.getInfraredCode = &getInfraredCode};
|
2023-12-31 08:53:39 +00:00
|
|
|
|
2023-12-30 17:25:07 +00:00
|
|
|
ClimateCard climateCard = ClimateCard(14, ac);
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2023-12-28 13:20:49 +00:00
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
void input_change_callback(uint8_t pin, uint8_t value)
|
|
|
|
{
|
2023-12-28 16:28:21 +00:00
|
|
|
Serial.print("Input change callback: ");
|
|
|
|
Serial.print(pin);
|
|
|
|
Serial.print(" ");
|
|
|
|
Serial.println(value);
|
|
|
|
}
|
|
|
|
|
2023-12-31 17:07:11 +00:00
|
|
|
void mqtt_callback(char *topic, char* payload)
|
|
|
|
{
|
|
|
|
Serial.print("MQTT Callback: ");
|
|
|
|
Serial.print(topic);
|
|
|
|
Serial.print(" ");
|
|
|
|
Serial.println(payload);
|
|
|
|
}
|
|
|
|
|
2023-12-31 16:29:40 +00:00
|
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
2023-12-31 10:55:13 +00:00
|
|
|
void setNetworkConfig()
|
|
|
|
{
|
2023-12-31 08:53:39 +00:00
|
|
|
NetworkConfig config = {
|
2023-12-31 16:29:40 +00:00
|
|
|
.ip = {10, 16, 6, 213},
|
|
|
|
.gateway = {10, 16, 6, 1},
|
2023-12-31 08:53:39 +00:00
|
|
|
.subnet = {255, 255, 255, 0},
|
2023-12-31 16:29:40 +00:00
|
|
|
.dns1 = {10, 192, 1, 1},
|
|
|
|
.dns2 = {10, 192, 1, 1},
|
2023-12-31 08:53:39 +00:00
|
|
|
.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();
|
|
|
|
}
|
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
void setMqttConfig()
|
|
|
|
{
|
2023-12-31 08:53:39 +00:00
|
|
|
MqttConfig config = {
|
|
|
|
.mqtt_port = 1883,
|
2023-12-31 10:55:13 +00:00
|
|
|
.mqtt_useauth = false};
|
2023-12-31 08:53:39 +00:00
|
|
|
strcpy(config.mqtt_server, "192.168.0.26");
|
|
|
|
strcpy(config.base_topic, "/espmegaoop");
|
|
|
|
espmega.iot->setMqttConfig(config);
|
|
|
|
espmega.iot->saveMqttConfig();
|
|
|
|
}
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2023-12-31 08:53:39 +00:00
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
void setup()
|
|
|
|
{
|
|
|
|
ESP_LOGI("Initializer", "Starting ESPMegaPRO OOP demo");
|
2023-12-28 13:20:49 +00:00
|
|
|
espmega.begin();
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Enabling IOT module");
|
2023-12-28 13:20:49 +00:00
|
|
|
espmega.enableIotModule();
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Enabling Ethernet");
|
2023-12-28 16:28:21 +00:00
|
|
|
ETH.begin();
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Binding Ethernet to IOT module");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.iot->bindEthernetInterface(Ð);
|
2023-12-31 16:29:40 +00:00
|
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
|
|
|
setNetworkConfig();
|
|
|
|
#else
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Loading network config");
|
2023-12-31 06:29:11 +00:00
|
|
|
espmega.iot->loadNetworkConfig();
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Connecting to network");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.iot->connectNetwork();
|
2023-12-31 16:29:40 +00:00
|
|
|
#ifdef WRITE_DEFAULT_NETCONF
|
|
|
|
setMqttConfig();
|
|
|
|
#else
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Loading MQTT config");
|
2023-12-31 06:29:11 +00:00
|
|
|
espmega.iot->loadMqttConfig();
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Connecting to MQTT");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.iot->connectToMqtt();
|
2023-12-31 17:07:11 +00:00
|
|
|
espmega.iot->registerMqttCallback(mqtt_callback);
|
2023-12-31 16:29:40 +00:00
|
|
|
#ifdef MQTT_CARD_REGISTER
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Registering cards 0");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.iot->registerCard(0);
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Registering cards 1");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.iot->registerCard(1);
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Registering Input change callback");
|
2023-12-29 17:49:09 +00:00
|
|
|
espmega.inputs.registerCallback(input_change_callback);
|
2023-12-31 16:29:40 +00:00
|
|
|
#ifdef CLIMATE_CARD_ENABLE
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Installing climate card");
|
2023-12-30 17:25:07 +00:00
|
|
|
espmega.installCard(2, &climateCard);
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Binding climate card to FRAM");
|
2024-01-01 13:30:17 +00:00
|
|
|
climateCard.bindFRAM(&espmega.fram, 1001);
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Loading climate card state from FRAM");
|
2023-12-30 17:37:50 +00:00
|
|
|
climateCard.loadStateFromFRAM();
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Enabling climate card FRAM autosave");
|
2023-12-30 17:37:50 +00:00
|
|
|
climateCard.setFRAMAutoSave(true);
|
2023-12-31 16:29:40 +00:00
|
|
|
ESP_LOGI("Initializer", "Registering cards 2");
|
|
|
|
espmega.iot->registerCard(2);
|
|
|
|
#endif
|
|
|
|
#ifdef DISPLAY_ENABLE
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Enabling internal display");
|
2023-12-30 08:56:05 +00:00
|
|
|
espmega.enableInternalDisplay(&Serial);
|
2023-12-31 10:55:13 +00:00
|
|
|
ESP_LOGI("Initializer", "Binding climate card to internal display");
|
2023-12-30 17:25:07 +00:00
|
|
|
espmega.display->bindClimateCard(&climateCard);
|
2023-12-31 16:29:40 +00:00
|
|
|
#endif
|
2024-01-01 06:28:15 +00:00
|
|
|
#ifdef WEB_SERVER_ENABLE
|
|
|
|
ESP_LOGI("Initializer", "Enabling web server");
|
|
|
|
espmega.enableWebServer(80);
|
2024-01-01 13:30:17 +00:00
|
|
|
espmega.webServer->setWebUsername("admin");
|
|
|
|
espmega.webServer->setWebPassword("Passw0rd");
|
|
|
|
espmega.webServer->saveCredentialsToFRAM();
|
2024-01-01 06:28:15 +00:00
|
|
|
#endif
|
2023-12-28 13:20:49 +00:00
|
|
|
}
|
|
|
|
|
2023-12-31 10:55:13 +00:00
|
|
|
void loop()
|
|
|
|
{
|
2023-12-28 13:20:49 +00:00
|
|
|
espmega.loop();
|
2023-12-31 10:55:13 +00:00
|
|
|
#ifdef FRAM_DEBUG
|
|
|
|
// Every 20 seconds, dump FRAM 0-500 to serial
|
2023-12-31 08:53:39 +00:00
|
|
|
static uint32_t last_fram_dump = 0;
|
2023-12-31 10:55:13 +00:00
|
|
|
if (millis() - last_fram_dump >= 20000)
|
|
|
|
{
|
2023-12-31 08:53:39 +00:00
|
|
|
last_fram_dump = millis();
|
|
|
|
Serial.println("Dumping FRAM");
|
|
|
|
espmega.dumpFRAMtoSerial(0, 500);
|
|
|
|
Serial.println("Dumping FRAM ASCII");
|
|
|
|
espmega.dumpFRAMtoSerialASCII(0, 500);
|
|
|
|
}
|
2023-12-31 10:55:13 +00:00
|
|
|
#endif
|
2023-12-31 13:49:22 +00:00
|
|
|
|
|
|
|
// 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();
|
2023-12-31 16:29:40 +00:00
|
|
|
espmega.iot->publish("/espmegai/alive", "true");
|
2023-12-31 13:49:22 +00:00
|
|
|
}
|
|
|
|
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
|
2023-12-28 13:20:49 +00:00
|
|
|
}
|