smart variable implementation

This commit is contained in:
Siwat Sirichai 2024-03-23 10:25:16 +07:00
parent aa28ec88fb
commit 7f55e3544d
3 changed files with 183 additions and 8 deletions

View File

@ -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);
}

View File

@ -2,9 +2,9 @@
#include <FRAM.h> #include <FRAM.h>
#include <ESPMegaIoT.hpp> #include <ESPMegaIoT.hpp>
#include <map> #include <map>
/** /**
* @brief SmartVariable is a local variable that can be accessed remotely and have FRAM support * @brief SmartVariable is a local variable that can be accessed remotely and have FRAM support
*
*/ */
class SmartVariable { class SmartVariable {
@ -18,14 +18,20 @@ public:
char* getValue(); char* getValue();
void enableSetValue(const char* setValueTopic); void enableSetValue(const char* setValueTopic);
void publishValue(); 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 loadValue();
void saveValue(); void saveValue();
void setValueAutoSave(bool autoSave); void setValueAutoSave(bool autoSave);
uint16_t registerCallback(void (*callback)(char*)); uint16_t registerCallback(void (*callback)(char*));
void unregisterCallback(uint16_t handlerId); void unregisterCallback(uint16_t handlerId);
int32_t getIntValue();
void setIntValue(int32_t value);
double getDoubleValue();
void setDoubleValue(double value);
protected: protected:
ESPMegaIoT* iot; ESPMegaIoT* iot;
bool iotEnabled;
const char* topic; const char* topic;
char* value; char* value;
size_t size; size_t size;
@ -34,9 +40,10 @@ protected:
bool setValueEnabled; bool setValueEnabled;
const char* setValueTopic; const char* setValueTopic;
bool autoSave; bool autoSave;
FRAM fram; FRAM *fram;
uint32_t framAddress; uint32_t framAddress;
void handleMqttCallback(char* topic, char* payload); void handleMqttCallback(char* topic, char* payload);
void subscribeMqtt();
// Value Change Callback // Value Change Callback
uint16_t currentHandlerId; uint16_t currentHandlerId;
std::map<uint16_t, void (*)(char*)> valueChangeCallbacks; std::map<uint16_t, void (*)(char*)> valueChangeCallbacks;

View File

@ -6,17 +6,19 @@
#include <RemoteVariable.hpp> #include <RemoteVariable.hpp>
#include <CurrentTransformerCard.hpp> #include <CurrentTransformerCard.hpp>
#include <AnalogCard.hpp> #include <AnalogCard.hpp>
#include <SmartVariable.hpp>
// #define FRAM_DEBUG // #define FRAM_DEBUG
// #define MQTT_DEBUG // #define MQTT_DEBUG
// #define WRITE_DEFAULT_NETCONF // #define WRITE_DEFAULT_NETCONF
//#define CLIMATE_CARD_ENABLE //#define CLIMATE_CARD_ENABLE
//#define MQTT_CARD_REGISTER //#define MQTT_CARD_REGISTER
#define DISPLAY_ENABLE //#define DISPLAY_ENABLE
#define WEB_SERVER_ENABLE //#define WEB_SERVER_ENABLE
#define LCD_OTA_ENABLE //#define LCD_OTA_ENABLE
#define REMOTE_VARIABLE_ENABLE //#define REMOTE_VARIABLE_ENABLE
#define CT_ENABLE //#define CT_ENABLE
#define SMART_VARIABLE_ENABLE
// Demo PLC firmware using the ESPMegaPRO OOP library // Demo PLC firmware using the ESPMegaPRO OOP library
@ -41,6 +43,10 @@ float voltage = 220.0;
CurrentTransformerCard ct = CurrentTransformerCard(&analogCard, 0, &voltage, adc2current, 1000); CurrentTransformerCard ct = CurrentTransformerCard(&analogCard, 0, &voltage, adc2current, 1000);
#endif #endif
#ifdef SMART_VARIABLE_ENABLE
SmartVariable smartVar = SmartVariable();
#endif
#ifdef CLIMATE_CARD_ENABLE #ifdef CLIMATE_CARD_ENABLE
// Climate Card // Climate Card
const char *mode_names[] = {"off", "fan_only", "cool"}; const char *mode_names[] = {"off", "fan_only", "cool"};
@ -226,6 +232,15 @@ void setup()
ct.bindFRAM(&espmega.fram, 7000); ct.bindFRAM(&espmega.fram, 7000);
ct.loadEnergy(); ct.loadEnergy();
ct.setEnergyAutoSave(true); 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 #endif
ESP_LOGI("Initializer", "Setup complete"); ESP_LOGI("Initializer", "Setup complete");
} }
@ -283,4 +298,13 @@ void loop()
Serial.println(ct.getCurrent()); Serial.println(ct.getCurrent());
} }
#endif #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
} }