debug_fram

This commit is contained in:
Siwat Sirichai 2023-12-31 02:18:57 +07:00
parent b4b7232937
commit 091dc183fe
7 changed files with 126 additions and 48 deletions

View File

@ -86,24 +86,37 @@ void ClimateCard::setFRAMAutoSave(bool autoSave)
void ClimateCard::saveStateToFRAM()
{
fram->writeObject(fram_address, this->state);
// fram->write8(fram_address, state.ac_temperature);
// fram->write8(fram_address + 1, state.ac_mode);
// fram->write8(fram_address + 2, state.ac_fan_speed);
fram->writeObject(fram_address, state);
Serial.println("Saved state to FRAM");
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
}
void ClimateCard::loadStateFromFRAM()
{
fram->readObject(fram_address, this->state);
// If temperature is out of range, set to its respective maximum or minimum
if (state.ac_temperature > ac.max_temperature)
state.ac_temperature = ac.max_temperature;
else if (state.ac_temperature < ac.min_temperature)
state.ac_temperature = ac.min_temperature;
// If mode is out of range, set to 0
if (state.ac_mode > ac.modes)
state.ac_mode = 0;
// If fan speed is out of range, set to 0
if (state.ac_fan_speed > ac.fan_speeds)
state.ac_fan_speed = 0;
// state.ac_temperature = fram->read8(fram_address);
// state.ac_mode = fram->read8(fram_address + 1);
// state.ac_fan_speed = fram->read8(fram_address + 2);
fram->readObject(fram_address, state);
// if (state.ac_temperature > ac.max_temperature)
// state.ac_temperature = ac.max_temperature;
// else if (state.ac_temperature < ac.min_temperature)
// state.ac_temperature = ac.min_temperature;
// // If mode is out of range, set to 0
// if (state.ac_mode > ac.modes)
// state.ac_mode = 0;
// // If fan speed is out of range, set to 0
// if (state.ac_fan_speed > ac.fan_speeds)
// state.ac_fan_speed = 0;
updateAirConditioner();
for (uint8_t i = 0; i < callbacks.size(); i++)
{
callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
}
}
void ClimateCard::setTemperature(uint8_t temperature)
@ -137,6 +150,10 @@ void ClimateCard::setFanSpeed(uint8_t fan_speed)
void ClimateCard::registerChangeCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback)
{
Serial.print("Registering callback");
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
callbacks.push_back(callback);
}
@ -199,10 +216,15 @@ void ClimateCard::updateAirConditioner()
// rmt_write_items(RMT_TX_CHANNEL, items, itemCount, true);
// rmt_wait_tx_done(RMT_TX_CHANNEL, portMAX_DELAY);
// // Publish state
// for (uint8_t i = 0; i < callbacks.size(); i++)
// {
// callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
// }
Serial.print("Callbacks: ");
Serial.println(callbacks.size());
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
for (uint8_t i = 0; i < callbacks.size(); i++)
{
callbacks[i](this->state.ac_mode, this->state.ac_fan_speed, this->state.ac_temperature);
}
}
uint8_t ClimateCard::getSensorType()

View File

@ -1,7 +1,5 @@
#include <ESPMegaIoT.hpp>
#include <ETH.h>
#define NETWORK_CONFIG_ADDRESS 34
#define MQTT_CONFIG_ADDRESS 34 + sizeof(NetworkConfig)
ESPMegaIoT::ESPMegaIoT() : mqtt(tcpClient)
{
@ -316,13 +314,34 @@ void ESPMegaIoT::setNetworkConfig(NetworkConfig network_config)
void ESPMegaIoT::loadNetworkConfig()
{
// Load the network config from FRAM
fram->read(0, (uint8_t *)&network_config, sizeof(NetworkConfig));
network_config.ip = fram->read32(FRAM_ADDRESS);
network_config.gateway = fram->read32(FRAM_ADDRESS + 4);
network_config.subnet = fram->read32(FRAM_ADDRESS + 8);
network_config.dns1 = fram->read32(FRAM_ADDRESS + 12);
network_config.dns2 = fram->read32(FRAM_ADDRESS + 16);
fram->read(FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32);
network_config.useStaticIp = fram->read8(FRAM_ADDRESS + 52);
network_config.useWifi = fram->read8(FRAM_ADDRESS + 53);
network_config.wifiUseAuth = fram->read8(FRAM_ADDRESS + 54);
fram->read(FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32);
fram->read(FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32);
}
void ESPMegaIoT::saveNetworkConfig()
{
// Save the network config to FRAM
fram->write(NETWORK_CONFIG_ADDRESS, (uint8_t *)&network_config, sizeof(NetworkConfig));
fram->write32(FRAM_ADDRESS, network_config.ip);
fram->write32(FRAM_ADDRESS + 4, network_config.gateway);
fram->write32(FRAM_ADDRESS + 8, network_config.subnet);
fram->write32(FRAM_ADDRESS + 12, network_config.dns1);
fram->write32(FRAM_ADDRESS + 16, network_config.dns2);
fram->write(FRAM_ADDRESS + 20, (uint8_t*)network_config.hostname, 32);
fram->write8(FRAM_ADDRESS + 52, network_config.useStaticIp);
fram->write8(FRAM_ADDRESS + 53, network_config.useWifi);
fram->write8(FRAM_ADDRESS + 54, network_config.wifiUseAuth);
fram->write(FRAM_ADDRESS + 55, (uint8_t*)network_config.ssid, 32);
fram->write(FRAM_ADDRESS + 87, (uint8_t*)network_config.password, 32);
}
void ESPMegaIoT::ethernetBegin()
@ -333,13 +352,23 @@ void ESPMegaIoT::ethernetBegin()
void ESPMegaIoT::loadMqttConfig()
{
// Load the mqtt config from FRAM
fram->read(sizeof(NetworkConfig), (uint8_t *)&this->mqtt_config, sizeof(MqttConfig));
// Populate the mqtt connection parameters
// We skip bytes 119-127 because they are reserved for the network config
mqtt_config.mqtt_port = fram->read16(FRAM_ADDRESS + 128);
fram->read(FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32);
fram->read(FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32);
fram->read(FRAM_ADDRESS + 194, (uint8_t*)mqtt_config.mqtt_password, 32);
mqtt_config.mqtt_useauth = fram->read8(FRAM_ADDRESS + 226);
fram->read(FRAM_ADDRESS + 227, (uint8_t*)mqtt_config.base_topic, 32);
}
void ESPMegaIoT::saveMqttConfig()
{
fram->write(MQTT_CONFIG_ADDRESS, (uint8_t *)&mqtt_config, sizeof(MqttConfig));
fram->write16(FRAM_ADDRESS + 128, mqtt_config.mqtt_port);
fram->write(FRAM_ADDRESS + 130, (uint8_t*)mqtt_config.mqtt_server, 32);
fram->write(FRAM_ADDRESS + 162, (uint8_t*)mqtt_config.mqtt_user, 32);
fram->write(FRAM_ADDRESS + 194, (uint8_t*)mqtt_config.mqtt_password, 32);
fram->write8(FRAM_ADDRESS + 226, mqtt_config.mqtt_useauth);
fram->write(FRAM_ADDRESS + 227, (uint8_t*)mqtt_config.base_topic, 32);
}
void ESPMegaIoT::connectToMqtt()
@ -408,3 +437,8 @@ bool ESPMegaIoT::networkConnected()
else
return ethernetIface->linkUp();
}
void ESPMegaIoT::bindFRAM(FRAM *fram)
{
this->fram = fram;
}

View File

@ -14,6 +14,12 @@
#include <WiFi.h>
#include <FRAM.h>
// FRAM Address for ESPMegaPROIoT
// Starts from 34
// Ends at 300 (inclusive)
// Total of 267 bytes
#define FRAM_ADDRESS 34
struct NetworkConfig
{
IPAddress ip;
@ -81,6 +87,7 @@ public:
void setBaseTopic(char *base_topic);
void bindEthernetInterface(ETHClass *ethernetIface);
bool networkConnected();
void bindFRAM(FRAM *fram);
IoTComponent* getComponent(uint8_t card_id);
IPAddress getETHIp();

View File

@ -1,4 +1,9 @@
#include <ESPMegaPRO_OOP.hpp>
// Reserve FRAM address 0 - 1000 for ESPMegaPRO Internal Use
// (34 Bytes) Address 0-33 for Built-in Digital Output Card
// () Address 34-300 for ESPMegaPRO IoT Module
ESPMegaPRO::ESPMegaPRO() {
}
@ -95,6 +100,7 @@ void ESPMegaPRO::setTime(int hours, int minutes, int seconds, int day, int month
void ESPMegaPRO::enableIotModule() {
if (iotEnabled) return;
this->iot = new ESPMegaIoT();
this->iot->bindFRAM(&fram);
this->iot->intr_begin(cards);
iotEnabled = true;
}

View File

@ -2,39 +2,26 @@
void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime) {
ESP_LOGD("InternalDisplay", "Assigning IoT Module and RTC Time Getter");
this->iot = iot;
this->getRtcTime = getRtcTime;
ESP_LOGD("InternalDisplay", "Acquiring Network and MQTT Configs");
this->mqttConfig = this->iot->getMqttConfig();
this->networkConfig = this->iot->getNetworkConfig();
// Register callbacks
ESP_LOGD("InternalDisplay", "Registering Callbacks");
auto bindedPageChangeCallback = std::bind(&InternalDisplay::handlePageChange, this, std::placeholders::_1);
this->registerPageChangeCallback(bindedPageChangeCallback);
auto bindedTouchCallback = std::bind(&InternalDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->registerTouchCallback(bindedTouchCallback);
ESP_LOGD("InternalDisplay", "Binding Page Change Callback");
auto bindedInputStateChangeCallback = std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2);
ESP_LOGD("InternalDisplay", "Binding Input State Change Callback");
auto bindedPwmStateChangeCallback = std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
ESP_LOGD("InternalDisplay", "Registering inputCard Callbacks");
this->inputCard->registerCallback(bindedInputStateChangeCallback);
ESP_LOGD("InternalDisplay", "Registering outputCard Callbacks");
this->outputCard->registerChangeCallback(bindedPwmStateChangeCallback);
// Initialize the display
ESP_LOGD("InternalDisplay", "Initializing DisplayAdapter");
this->displayAdapter->begin(115200);
ESP_LOGD("InternalDisplay", "Setting DisplayAdapter Timeout");
this->displayAdapter->setTimeout(100);
ESP_LOGD("InternalDisplay", "Flushing DisplayAdapter");
this->displayAdapter->flush();
ESP_LOGD("InternalDisplay", "Resetting Display");
this->reset();
delay(500);
ESP_LOGD("InternalDisplay", "Jumping to Page 1");
this->jumpToPage(1);
ESP_LOGD("InternalDisplay", "Display Initialization Complete");
}
@ -99,12 +86,7 @@ void InternalDisplay::updateStatusIcons(bool networkStatus, bool mqttStatus) {
void InternalDisplay::updateClock() {
rtctime_t time = this->getRtcTime();
this->displayAdapter->print("time.txt=");
this->displayAdapter->print(time.hours%12);
this->displayAdapter->print(":");
this->displayAdapter->print(time.minutes);
this->displayAdapter->print(" ");
this->displayAdapter->print(time.hours/12 ? "PM" : "AM");
this->displayAdapter->printf("time.txt=\"%02d:%02d %s\"", time.hours%12, time.minutes, time.hours/12 ? "PM" : "AM");
this->sendStopBytes();
}
@ -134,6 +116,12 @@ void InternalDisplay::refreshPage(uint8_t page) {
case INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE:
this->refreshPWMAdjustment();
break;
case INTERNAL_DISPLAY_NETWORK_CONFIG_PAGE:
this->refreshNetworkConfig();
break;
case INTERNAL_DISPLAY_MQTT_CONFIG_PAGE:
this->refreshMQTTConfig();
break;
default:
break;
}
@ -269,6 +257,8 @@ void InternalDisplay::bindOutputCard(DigitalOutputCard *outputCard) {
// fan_speed: [auto, low, medium, high]
void InternalDisplay::bindClimateCard(ClimateCard *climateCard) {
this->climateCard = climateCard;
auto bindedACStateChangeCallback = std::bind(&InternalDisplay::handleACStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->climateCard->registerChangeCallback(bindedACStateChangeCallback);
}
void InternalDisplay::refreshPWMAdjustment() {
@ -379,8 +369,6 @@ void InternalDisplay::handleACTouch(uint8_t type, uint8_t component) {
default:
break;
}
// Refresh the AC page
this->refreshAC();
}
void InternalDisplay::handlePWMAdjustmentTouch(uint8_t type, uint8_t component) {
@ -468,9 +456,8 @@ void InternalDisplay::refreshMQTTConfig() {
this->displayAdapter->print("\"");
this->sendStopBytes();
// Refresh the mqtt port
this->displayAdapter->print("port_set.txt=\"");
this->displayAdapter->print("port_set.val=");
this->displayAdapter->print(this->mqttConfig->mqtt_port);
this->displayAdapter->print("\"");
this->sendStopBytes();
// Refresh the mqtt username
this->displayAdapter->print("user_set.txt=\"");
@ -487,6 +474,10 @@ void InternalDisplay::refreshMQTTConfig() {
this->displayAdapter->print(this->mqttConfig->base_topic);
this->displayAdapter->print("\"");
this->sendStopBytes();
// Refresh the mqtt use auth
this->displayAdapter->print("use_auth.val=");
this->displayAdapter->print(this->mqttConfig->mqtt_useauth ? 1 : 0);
this->sendStopBytes();
}
void InternalDisplay::sendIpToDisplay(IPAddress ip) {
@ -499,3 +490,13 @@ void InternalDisplay::sendIpToDisplay(IPAddress ip) {
this->displayAdapter->print(".");
this->displayAdapter->print(ip[3]);
}
void InternalDisplay::handleACStateChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature) {
// If the climate card is binded to the display and the current page is the AC page
// then update the respective AC component
Serial.println("AC state changed");
if (this->climateCard==nullptr || this->currentPage != INTERNAL_DISPLAY_AC_PAGE) return;
this->sendStopBytes();
// Update the AC state
this->refreshAC();
}

View File

@ -84,6 +84,7 @@ class InternalDisplay : public ESPMegaDisplay {
void setOutputBar(uint8_t pin, uint16_t value);
void setOutputStateColor(uint8_t pin, bool state);
void setInputMarker(uint8_t pin, bool state);
void handleACStateChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature);
void saveNetworkConfig();
void saveMQTTConfig();
void updateStatusIcons(bool networkStatus, bool mqttStatus);

View File

@ -68,6 +68,7 @@ void setup() {
Serial.println("Setting network config");
espmega.iot->setNetworkConfig(config);
espmega.iot->saveNetworkConfig();
// espmega.iot->loadNetworkConfig();
Serial.println("Connecting to network");
espmega.iot->connectNetwork();
Serial.println("Begin MQTT Modules");
@ -81,6 +82,7 @@ void setup() {
Serial.println("Loading MQTT Config Struct to IoT Module");
espmega.iot->setMqttConfig(mqtt_config);
espmega.iot->saveMqttConfig();
// espmega.iot->loadMqttConfig();
Serial.println("Connecting to MQTT");
espmega.iot->connectToMqtt();
Serial.println("Registering Output Card");
@ -91,13 +93,18 @@ void setup() {
espmega.inputs.registerCallback(input_change_callback);
Serial.println("Installing Climate Card");
espmega.installCard(2, &climateCard);
climateCard.bindFRAM(&espmega.fram, 2000);
climateCard.bindFRAM(&espmega.fram, 301);
climateCard.loadStateFromFRAM();
climateCard.setFRAMAutoSave(true);
Serial.println("Enabling Internal Display");
espmega.enableInternalDisplay(&Serial);
espmega.display->bindClimateCard(&climateCard);
Serial.println("Initialization Routine Complete");
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
Serial.println(sizeof(MqttConfig));
Serial.println(sizeof(NetworkConfig));
}
void loop() {