diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.cpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.cpp new file mode 100644 index 0000000..229709e --- /dev/null +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.cpp @@ -0,0 +1,144 @@ +#include "SmartVariable.hpp" +SmartVariable::SmartVariable() +{ +} + +SmartVariable::~SmartVariable() +{ + if (this->value != nullptr) + free(this->value); +} + +void SmartVariable::begin(size_t size) +{ + this->value = (char *)calloc(size, sizeof(char)); + this->size = size; +} + +void SmartVariable::enableIoT(ESPMegaIoT *iot, const char *topic) +{ + bool iotEnabled = true; + auto bindedMqttCallback = std::bind(&SmartVariable::handleMqttCallback, this, std::placeholders::_1, std::placeholders::_2); + this->iot->registerRelativeMqttCallback(bindedMqttCallback); + this->subscribeMqtt(); +} + +void SmartVariable::enableValueRequest(const char *valueRequestTopic) +{ + this->useValueRequest = true; + this->valueRequestTopic = valueRequestTopic; + this->subscribeMqtt(); +} + +void SmartVariable::setValue(const char *value) +{ + strncpy(this->value, value, this->size - 1); + this->value[this->size - 1] = '\0'; + if (this->autoSave) + this->saveValue(); + if (this->iotEnabled) + this->publishValue(); +} + +char *SmartVariable::getValue() +{ + return this->value; +} + +void SmartVariable::enableSetValue(const char *setValueTopic) +{ + this->setValueEnabled = true; + this->setValueTopic = setValueTopic; + this->subscribeMqtt(); +} + +void SmartVariable::publishValue() +{ + if (this->iotEnabled) + this->iot->publish(this->topic, this->value); +} + +void SmartVariable::bindFRAM(FRAM fram, uint32_t framAddress) +{ + this->bindFRAM(fram, framAddress, true); +} + +void SmartVariable::bindFRAM(FRAM *fram, uint32_t framAddress, bool loadValue) +{ + this->framAddress = framAddress; + this->fram = fram; + if (loadValue) + this->loadValue(); +} + +void SmartVariable::loadValue() +{ + this->fram.read(this->framAddress, (uint8_t *)this->value, this->size); + this->setValue(this->value); +} + +void SmartVariable::saveValue() +{ + this->fram.write(this->framAddress, (uint8_t *)this->value, this->size); +} + +void SmartVariable::setValueAutoSave(bool autoSave) +{ + this->autoSave = autoSave; +} + +uint16_t SmartVariable::registerCallback(void (*callback)(char *)) +{ + this->valueChangeCallbacks[this->currentHandlerId] = callback; + return this->currentHandlerId++; +} + +void SmartVariable::unregisterCallback(uint16_t handlerId) +{ + this->valueChangeCallbacks.erase(handlerId); +} + +void SmartVariable::handleMqttCallback(char *topic, char *payload) +{ + if (!strcmp(topic, this->valueRequestTopic)) + { + this->publishValue(); + } + else if (!strcmp(topic, this->setValueTopic)) + { + this->setValue(payload); + } +} + +void SmartVariable::subscribeMqtt() +{ + if (this->iotEnabled) + { + if (this->useValueRequest) + this->iot->subscribe(this->valueRequestTopic); + if (this->setValueEnabled) + this->iot->subscribe(this->setValueTopic); + } +} + +int32_t SmartVariable::getIntValue() +{ + return atoi(this->value); +} + +void SmartVariable::setIntValue(int32_t value) +{ + itoa(value, this->value, 10); + this->setValue(this->value); +} + +double SmartVariable::getDoubleValue() +{ + return atof(this->value); +} + +void SmartVariable::setDoubleValue(double value) +{ + dtostrf(value, 0, 2, this->value); + this->setValue(this->value); +} diff --git a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.hpp b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.hpp index 3af1eb8..1550b50 100644 --- a/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.hpp +++ b/ESPMegaPRO-OS-SDK/lib/ESPMegaPRO/SmartVariable.hpp @@ -2,9 +2,9 @@ #include #include #include + /** * @brief SmartVariable is a local variable that can be accessed remotely and have FRAM support - * */ class SmartVariable { @@ -18,14 +18,20 @@ public: char* getValue(); void enableSetValue(const char* setValueTopic); void publishValue(); - void bindFRAM(uint32_t framAddress); + void bindFRAM(FRAM *fram, uint32_t framAddress); + void bindFRAM(FRAM *fram, uint32_t framAddress, bool loadValue); void loadValue(); void saveValue(); void setValueAutoSave(bool autoSave); uint16_t registerCallback(void (*callback)(char*)); void unregisterCallback(uint16_t handlerId); + int32_t getIntValue(); + void setIntValue(int32_t value); + double getDoubleValue(); + void setDoubleValue(double value); protected: ESPMegaIoT* iot; + bool iotEnabled; const char* topic; char* value; size_t size; @@ -34,9 +40,10 @@ protected: bool setValueEnabled; const char* setValueTopic; bool autoSave; - FRAM fram; + FRAM *fram; uint32_t framAddress; void handleMqttCallback(char* topic, char* payload); + void subscribeMqtt(); // Value Change Callback uint16_t currentHandlerId; std::map valueChangeCallbacks; diff --git a/ESPMegaPRO-OS-SDK/src/main.cpp b/ESPMegaPRO-OS-SDK/src/main.cpp index c154233..20e0f47 100644 --- a/ESPMegaPRO-OS-SDK/src/main.cpp +++ b/ESPMegaPRO-OS-SDK/src/main.cpp @@ -6,17 +6,19 @@ #include #include #include +#include // #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 -#define REMOTE_VARIABLE_ENABLE -#define CT_ENABLE +//#define DISPLAY_ENABLE +//#define WEB_SERVER_ENABLE +//#define LCD_OTA_ENABLE +//#define REMOTE_VARIABLE_ENABLE +//#define CT_ENABLE +#define SMART_VARIABLE_ENABLE // Demo PLC firmware using the ESPMegaPRO OOP library @@ -41,6 +43,10 @@ float voltage = 220.0; CurrentTransformerCard ct = CurrentTransformerCard(&analogCard, 0, &voltage, adc2current, 1000); #endif +#ifdef SMART_VARIABLE_ENABLE +SmartVariable smartVar = SmartVariable(); +#endif + #ifdef CLIMATE_CARD_ENABLE // Climate Card const char *mode_names[] = {"off", "fan_only", "cool"}; @@ -226,6 +232,15 @@ void setup() ct.bindFRAM(&espmega.fram, 7000); ct.loadEnergy(); ct.setEnergyAutoSave(true); +#endif +#ifdef SMART_VARIABLE_ENABLE + ESP_LOGI("Initializer", "Initializing smart variable"); + smartVar.begin(16); + smartVar.bindFRAM(&espmega.fram, 8000); + smartVar.setValueAutoSave(true); + smartVar.enableIoT(espmega.iot, "/smartvar"); + smartVar.enableSetValue("/smartvar/set"); + smartVar.enableValueRequest("/smartvar/request"); #endif ESP_LOGI("Initializer", "Setup complete"); } @@ -283,4 +298,13 @@ void loop() Serial.println(ct.getCurrent()); } #endif +#ifdef SMART_VARIABLE_ENABLE + static uint32_t last_smartvar_print = 0; + if (millis() - last_smartvar_print >= 1000) + { + last_smartvar_print = millis(); + Serial.print("SmartVar: "); + Serial.println(smartVar.getValue()); + } +#endif } \ No newline at end of file