diff --git a/Template Project/lib/ESPMegaPRO/AnalogCard.cpp b/Template Project/lib/ESPMegaPRO/AnalogCard.cpp index e4accba..aeec23a 100644 --- a/Template Project/lib/ESPMegaPRO/AnalogCard.cpp +++ b/Template Project/lib/ESPMegaPRO/AnalogCard.cpp @@ -19,9 +19,9 @@ void AnalogCard::setDACState(uint8_t pin, bool state) { this->dac_state[pin] = state; this->sendDataToDAC(pin, this->dac_value[pin]*state); - if (this->dac_change_callback != NULL) + for (int i = 0; i < this->dac_change_callbacks.size(); i++) { - this->dac_change_callback(pin, state, this->dac_value[pin]); + this->dac_change_callbacks[i](pin, state, this->dac_value[pin]); } } @@ -29,9 +29,9 @@ void AnalogCard::setDACValue(uint8_t pin, uint16_t value) { this->dac_value[pin] = value; this->sendDataToDAC(pin, value*this->dac_state[pin]); - if (this->dac_change_callback != NULL) + for (int i = 0; i < this->dac_change_callbacks.size(); i++) { - this->dac_change_callback(pin, this->dac_state[pin], value); + this->dac_change_callbacks[i](pin, this->dac_state[pin], value); } } @@ -121,10 +121,18 @@ uint8_t AnalogCard::getType() void AnalogCard::registerDACChangeCallback(std::function callback) { - this->dac_change_callback = callback; + this->dac_change_callbacks.push_back(callback); } -void AnalogCard::deregisterDACChangeCallback() -{ - this->dac_change_callback = NULL; -} \ No newline at end of file +// void AnalogCard::deregisterDACChangeCallback(std::function callback) +// { +// for (int i = 0; i < this->dac_change_callbacks.size(); i++) +// { +// if (this->dac_change_callbacks[i].target() == callback.target()) +// { +// this->dac_change_callbacks.erase(this->dac_change_callbacks.begin() + i); +// break; +// } +// } + +// } \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/AnalogCard.hpp b/Template Project/lib/ESPMegaPRO/AnalogCard.hpp index 6c38a35..83aeda7 100644 --- a/Template Project/lib/ESPMegaPRO/AnalogCard.hpp +++ b/Template Project/lib/ESPMegaPRO/AnalogCard.hpp @@ -2,6 +2,7 @@ #include #include #include +#include #define CARD_TYPE_ANALOG 0x02 @@ -25,10 +26,10 @@ class AnalogCard : public ExpansionCard { void setDACState(uint8_t pin, bool state); void setDACValue(uint8_t pin, uint16_t value); void registerDACChangeCallback(std::function callback); - void deregisterDACChangeCallback(); + //void deregisterDACChangeCallback(std::function callback); uint8_t getType(); private: - std::function dac_change_callback; + std::vector> dac_change_callbacks; bool dac_state[4]; uint16_t dac_value[4]; MCP4725 dac0; diff --git a/Template Project/lib/ESPMegaPRO/AnalogIoT.cpp b/Template Project/lib/ESPMegaPRO/AnalogIoT.cpp index b809874..358bb3e 100644 --- a/Template Project/lib/ESPMegaPRO/AnalogIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/AnalogIoT.cpp @@ -48,6 +48,10 @@ void AnalogIoT::publishADC(uint8_t pin) { this->publishRelative(topic, payload); delete[] topic; delete[] payload; + // Call all callbacks + for (int i = 0; i < this->adc_conversion_callbacks.size(); i++) { + this->adc_conversion_callbacks[i](pin, value); + } } } void AnalogIoT::setADCsPublishInterval(uint32_t interval) { @@ -60,18 +64,17 @@ void AnalogIoT::setADCsPublishEnabled(bool enabled) { adc_publish_enabled[i] = enabled; } } -void AnalogIoT::registerDACChangeCallback(std::function callback) { - dac_change_callback = callback; -} -void AnalogIoT::deregisterDACChangeCallback() { - dac_change_callback = NULL; -} void AnalogIoT::registerADCConversionCallback(std::function callback) { - adc_conversion_callback = callback; -} -void AnalogIoT::deregisterADCConversionCallback() { - adc_conversion_callback = NULL; + this->adc_conversion_callbacks.push_back(callback); } +// void AnalogIoT::deregisterADCConversionCallback(std::function callback) { +// for (int i = 0; i < this->adc_conversion_callbacks.size(); i++) { +// if (this->adc_conversion_callbacks[i].target() == callback.target()) { +// this->adc_conversion_callbacks.erase(this->adc_conversion_callbacks.begin() + i); +// break; +// } +// } +// } void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) { adc_conversion_interval[pin] = interval; } diff --git a/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp b/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp index 85de6f9..0cc757c 100644 --- a/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/AnalogIoT.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #define DAC_SET_STATE_TOPIC "/set/state" #define DAC_SET_VALUE_TOPIC "/set/value" @@ -24,10 +25,8 @@ class AnalogIoT : public IoTComponent { void publishDACValue(uint8_t pin); void setADCsPublishInterval(uint32_t interval); void setADCsPublishEnabled(bool enabled); - void registerDACChangeCallback(std::function callback); - void deregisterDACChangeCallback(); void registerADCConversionCallback(std::function callback); - void deregisterADCConversionCallback(); + // void deregisterADCConversionCallback(std::function callback); void setADCConversionInterval(uint8_t pin, uint16_t interval); void setADCConversionEnabled(uint8_t pin, bool enabled); bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length); @@ -51,6 +50,5 @@ class AnalogIoT : public IoTComponent { bool adc_publish_enabled[8]; uint16_t adc_conversion_interval[8]; uint32_t last_adc_conversion[8]; - std::function dac_change_callback; - std::function adc_conversion_callback; + std::vector> adc_conversion_callbacks; }; \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp b/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp index fcc5e92..d736a41 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputCard.cpp @@ -96,8 +96,8 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t { lastDebounceTime[pin] = millis(); previousBuffer ^= (-((currentBuffer >> (7 - pin)) & 1) ^ previousBuffer) & (1UL << (7 - pin)); - if (callback != NULL) - callback(virtualPin, ((currentBuffer >> (7 - pin)) & 1)); + for (int i = 0; i < callbacks.size(); i++) + callbacks[i](virtualPin, ((currentBuffer >> (7 - pin)) & 1)); } } // Handle Bank B @@ -107,12 +107,13 @@ void DigitalInputCard::handlePinChange(int pin, uint8_t ¤tBuffer, uint8_t { lastDebounceTime[pin] = millis(); previousBuffer ^= (-((currentBuffer >> (15 - pin)) & 1) ^ previousBuffer) & (1UL << (15 - pin)); - if (callback != NULL) - callback(virtualPin, ((currentBuffer >> (15 - pin)) & 1)); + for (int i = 0; i < callbacks.size(); i++) + callbacks[i](virtualPin, ((currentBuffer >> (15 - pin)) & 1)); } } } + // Preform a loop to refresh the input buffers void DigitalInputCard::loop() { @@ -158,7 +159,7 @@ uint8_t DigitalInputCard::getInputBufferB() // Register a callback function to be called when a pin changes void DigitalInputCard::registerCallback(std::function callback) { - this->callback = callback; + callbacks.push_back(callback); } // Refresh the input buffer for bank A @@ -178,10 +179,17 @@ void DigitalInputCard::setDebounceTime(uint8_t pin, uint32_t debounceTime) this->debounceTime[pin] = debounceTime; } -void DigitalInputCard::unregisterCallback() -{ - this->callback = NULL; -} +// void DigitalInputCard::unregisterCallback(std::function callback) +// { +// for (int i = 0; i < callbacks.size(); i++) +// { +// if (callbacks[i].target() == callback.target()) +// { +// callbacks.erase(callbacks.begin() + i); +// break; +// } +// } +// } void DigitalInputCard::loadPinMap(uint8_t pinMap[16]) { diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp b/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp index 54caf91..db6b129 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputCard.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include #define CARD_TYPE_DIGITAL_INPUT 0x01 @@ -27,7 +28,7 @@ class DigitalInputCard : public ExpansionCard { // Register a callback function to be called when a pin changes void registerCallback(std::function callback); // Unregister the callback function - void unregisterCallback(); + //void unregisterCallback(std::function callback); // Load a new pin map void loadPinMap(uint8_t pinMap[16]); // Get type of card @@ -47,7 +48,7 @@ class DigitalInputCard : public ExpansionCard { uint8_t pinMap[16]; // A map of the virtual pin to the physical pin uint8_t virtualPinMap[16]; - std::function callback; + std::vector> callbacks; void refreshInputBankA(); void refreshInputBankB(); void handlePinChange(int pin, uint8_t& currentBuffer, uint8_t& previousBuffer); diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.cpp b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.cpp index ea5666a..6349803 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.cpp @@ -46,13 +46,6 @@ void DigitalInputIoT::handleValueChange(uint8_t pin, uint8_t value) { if (this->digital_inputs_publish_enabled) { this->publishDigitalInput(pin); } - if (this->change_callback != NULL) { - this->change_callback(pin, value); - } - -} -void DigitalInputIoT::registerChangeCallback(std::function callback) { - this->change_callback = callback; } void DigitalInputIoT::publishReport() { diff --git a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp index f2bf4ce..7eeb100 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalInputIoT.hpp @@ -14,12 +14,10 @@ class DigitalInputIoT : public IoTComponent { void publishDigitalInput(uint8_t pin); void setDigitalInputsPublishEnabled(bool enabled); void handleValueChange(uint8_t pin, uint8_t value); - void registerChangeCallback(std::function callback); void publishReport(); void subscribe(); uint8_t getType(); private: - std::function change_callback; bool digital_inputs_publish_enabled = false; DigitalInputCard *card; }; \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp index eb938ff..fabf1ec 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.cpp @@ -36,8 +36,8 @@ void DigitalOutputCard::digitalWrite(uint8_t pin, bool state) { this->saveStateToFRAM(); this->savePinValueToFRAM(pin); } - if(change_callback != NULL) { - change_callback(pin, state, state ? 4095 : 0); + for (int i = 0; i < change_callbacks.size(); i++) { + change_callbacks[i](pin, state, state ? 4095 : 0); } } // Set the output to the specified pwm value @@ -52,8 +52,8 @@ void DigitalOutputCard::analogWrite(uint8_t pin, uint16_t value) { } this->state_buffer[pin] = value > 0; this->value_buffer[pin] = value; - if(change_callback != NULL) { - change_callback(pin, value > 0, value); + for (int i = 0; i < change_callbacks.size(); i++) { + change_callbacks[i](pin, value > 0, value); } } @@ -82,8 +82,8 @@ void DigitalOutputCard::setState(uint8_t pin, bool state) { if(this->framAutoSave) { this->saveStateToFRAM(); } - if (change_callback != NULL) { - change_callback(pin, state, value_buffer[pin]); + for(int i = 0; i < change_callbacks.size(); i++) { + change_callbacks[i](pin, state, value_buffer[pin]); } } @@ -95,18 +95,23 @@ void DigitalOutputCard::setValue(uint8_t pin, uint16_t value) { if (this->framAutoSave) { this->savePinValueToFRAM(pin); } - if (change_callback != NULL) { - change_callback(pin, state_buffer[pin], value); + for (int i = 0; i < change_callbacks.size(); i++) { + change_callbacks[i](pin, state_buffer[pin], value); } } void DigitalOutputCard::registerChangeCallback(std::function callback) { - this->change_callback = callback; + this->change_callbacks.push_back(callback); } -void DigitalOutputCard::deregisterChangeCallback() { - this->change_callback = NULL; -} +// void DigitalOutputCard::deregisterChangeCallback(std::function callback) { +// for(int i = 0; i < change_callbacks.size(); i++) { +// if(change_callbacks[i].target() == callback.target()) { +// change_callbacks.erase(change_callbacks.begin()+i); +// break; +// } +// } +// } void DigitalOutputCard::loadPinMap(uint8_t pinMap[16]) { for(int i = 0; i < 16; i++) { diff --git a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp index 9c869ca..d17fdb4 100644 --- a/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp +++ b/Template Project/lib/ESPMegaPRO/DigitalOutputCard.hpp @@ -2,6 +2,7 @@ #include #include #include +#include // Protocol for digital output card // Note that pin is always 2 characters long and padded with 0 if necessary @@ -49,7 +50,7 @@ public: // Register a callback function that will be called when the state of a pin changes void registerChangeCallback(std::function callback); // Deregister the callback function - void deregisterChangeCallback(); + // void deregisterChangeCallback(std::function callback); // Load a new pin map void loadPinMap(uint8_t pinMap[16]); // Bind the fram object to the card @@ -89,7 +90,7 @@ private: // The pwm value of the card uint16_t value_buffer[16]; // The callback function - std::function change_callback; + std::vector> change_callbacks; // Physical pin to virtual pin map uint8_t pinMap[16]; // Return 16 bit value representing all 16 channels diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.cpp b/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.cpp index d7f4f0f..39d981d 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.cpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.cpp @@ -109,7 +109,7 @@ void ESPMegaDisplay::jumpToPage(int page) { * @param component The component name. * @param value The value to set. */ -void ESPMegaDisplay::setNumber(char* component, int value) { +void ESPMegaDisplay::setNumber(const char* component, int value) { this->displayAdapter->print(component); this->displayAdapter->print("="); this->displayAdapter->print(value); @@ -121,7 +121,7 @@ void ESPMegaDisplay::setNumber(char* component, int value) { * @param component The component name. * @param value The value to set. */ -void ESPMegaDisplay::setString(char* component, char* value) { +void ESPMegaDisplay::setString(const char* component, const char* value) { this->displayAdapter->print(component); this->displayAdapter->print("=\""); this->displayAdapter->print(value); @@ -134,7 +134,7 @@ void ESPMegaDisplay::setString(char* component, char* value) { * @param component The component name. * @return The value of the number component. */ -uint32_t ESPMegaDisplay::getNumber(char* component) { +uint32_t ESPMegaDisplay::getNumber(const char* component) { uint32_t start = millis(); // Send the get command this->displayAdapter->print("get "); @@ -162,7 +162,7 @@ uint32_t ESPMegaDisplay::getNumber(char* component) { * @return The value of the string component. * @note The returned char array must be freed after use. */ -char* ESPMegaDisplay::getString(char* component) { +char* ESPMegaDisplay::getString(const char* component) { uint32_t start = millis(); // Send the get command this->displayAdapter->print("get "); @@ -186,7 +186,7 @@ char* ESPMegaDisplay::getString(char* component) { return value; } -bool ESPMegaDisplay::getStringToBuffer(char* component, char* buffer, uint8_t buffer_size) { +bool ESPMegaDisplay::getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size) { uint32_t start = millis(); // Send the get command this->displayAdapter->print("get "); diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.hpp b/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.hpp index 49bd331..d6e025d 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.hpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaDisplay.hpp @@ -13,11 +13,11 @@ class ESPMegaDisplay void setBrightness(int value); void setVolume(int value); void jumpToPage(int page); - void setString(char* component, char* value); - void setNumber(char* component, int value); - char* getString(char* component); - bool getStringToBuffer(char* component, char* buffer, uint8_t buffer_size); - uint32_t getNumber(char* component); + void setString(const char* component, const char* value); + void setNumber(const char* component, int value); + char* getString(const char* component); + bool getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size); + uint32_t getNumber(const char* component); void handlePwmStateChange(uint8_t pin, uint16_t value); void handleInputStateChange(uint8_t pin, bool state); void registerPushCallback(std::function callback); diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp index b535b17..8e8a93e 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.cpp @@ -369,4 +369,27 @@ void ESPMegaIoT::bindEthernetInterface(ETHClass *ethernetIface) IoTComponent *ESPMegaIoT::getComponent(uint8_t card_id) { return components[card_id]; +} + +NetworkConfig* ESPMegaIoT::getNetworkConfig() +{ + return &network_config; +} + +MqttConfig* ESPMegaIoT::getMqttConfig() +{ + return &mqtt_config; +} + +bool ESPMegaIoT::mqttConnected() +{ + return mqtt_connected; +} + +bool ESPMegaIoT::networkConnected() +{ + if (network_config.useWifi) + return WiFi.status() == WL_CONNECTED; + else + return ethernetIface->linkUp(); } \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp index 96be8ea..4c7a971 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaIoT.hpp @@ -1,3 +1,4 @@ +#pragma once #include #include #include @@ -59,6 +60,8 @@ public: void ethernetBegin(); void loadNetworkConfig(); void saveNetworkConfig(); + NetworkConfig* getNetworkConfig(); + MqttConfig* getMqttConfig(); void setMqttConfig(MqttConfig mqtt_config); void saveMqttConfig(); void loadMqttConfig(); @@ -67,6 +70,7 @@ public: void connectToMqtt(); bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port, char *mqtt_user, char *mqtt_password); bool connectToMqtt(char *client_id, char *mqtt_server, uint16_t mqtt_port); + bool mqttConnected(); void disconnectFromMqtt(); void publishToTopic(char *topic, char *payload); void registerMqttCallback(void (*callback)(char *, char *)); @@ -74,6 +78,7 @@ public: void registerSubscribeCallback(void (*callback)(void)); void setBaseTopic(char *base_topic); void bindEthernetInterface(ETHClass *ethernetIface); + bool networkConnected(); IoTComponent* getComponent(uint8_t card_id); IPAddress getETHIp(); diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp b/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp index ac06492..a70d3ef 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.cpp @@ -89,4 +89,10 @@ void ESPMegaPRO::setTime(int hours, int minutes, int seconds, int day, int month void ESPMegaPRO::enableIotModule() { iot.intr_begin(cards); +} + +ExpansionCard* ESPMegaPRO::getCard(uint8_t slot) { + if (slot > 255) return nullptr; + if (!cardInstalled[slot]) return nullptr; + return cards[slot]; } \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.hpp b/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.hpp index cab86ec..584c4e2 100644 --- a/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.hpp +++ b/Template Project/lib/ESPMegaPRO/ESPMegaPRO_OOP.hpp @@ -27,6 +27,7 @@ class ESPMegaPRO { void enableIotModule(); rtctime_t getTime(); void setTime(int hours, int minutes, int seconds, int day, int month, int year); + ExpansionCard* getCard(uint8_t slot); FRAM fram; DigitalInputCard inputs = DigitalInputCard(INPUT_BANK_A_ADDRESS, INPUT_BANK_B_ADDRESS); DigitalOutputCard outputs = DigitalOutputCard(PWM_BANK_ADDRESS); diff --git a/Template Project/lib/ESPMegaPRO/InternalDisplay.cpp b/Template Project/lib/ESPMegaPRO/InternalDisplay.cpp index 71ec1cc..0254d19 100644 --- a/Template Project/lib/ESPMegaPRO/InternalDisplay.cpp +++ b/Template Project/lib/ESPMegaPRO/InternalDisplay.cpp @@ -1,31 +1,39 @@ #include -void InternalDisplay::begin() { +void InternalDisplay::begin(ESPMegaIoT *iot, std::function getRtcTime) { + this->iot = iot; + this->getRtcTime = getRtcTime; + this->mqttConfig = this->iot->getMqttConfig(); + this->networkConfig = this->iot->getNetworkConfig(); + // Register callbacks + this->inputCard->registerCallback(std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2)); + this->outputCard->registerChangeCallback(std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } void InternalDisplay::loop() { - // TODO: implementation -} - -void InternalDisplay::bindInputCard(uint8_t card_id) { - this->bindedInputCard = card_id; - if(currentPage == INTERNAL_DISPLAY_INPUT_PAGE) { - refreshInput(); + // Keep reading the Serial Adapter + this->recieveSerialCommand(); + // Refresh the top bar every 5 seconds + static uint32_t lastTopBarRefresh; + if (millis() - lastTopBarRefresh > INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL) { + this->updateStatusIcons(this->iot->networkConnected(), this->iot->mqttConnected()); + lastTopBarRefresh = millis(); + } + // Refresh the clock every 10 seconds + static uint32_t lastClockRefresh; + if (millis() - lastClockRefresh > INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL) { + this->updateClock(); + lastClockRefresh = millis(); } } -void InternalDisplay::bindOutputCard(uint8_t card_id) { - this->bindedOutputCard = card_id; - if(currentPage == INTERNAL_DISPLAY_OUTPUT_PAGE) { - refreshOutput(); - } -} + void InternalDisplay::handleInputStateChange(uint8_t pin, bool state) { // If the input card is binded to the display and the current page is the input page // then update the respective input component - if (!this->bindedInputCard || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return; + if (this->inputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return; // Update the input state this->setInputMarker(pin, state); } @@ -33,7 +41,7 @@ void InternalDisplay::handleInputStateChange(uint8_t pin, bool state) { void InternalDisplay::handlePwmStateChange(uint8_t pin, bool state, uint16_t value) { // If the output card is binded to the display and the current page is the output page // then update the respective output component - if (!this->bindedOutputCard || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return; + if (this->outputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return; // Update the output state this->setOutputBar(pin, value); this->setOutputStateColor(pin, state); @@ -96,29 +104,38 @@ void InternalDisplay::refreshDashboard() { // 2. IP Address // 3. MQTT Server with port // 4. MQTT Connection status - this->iot-> + this->setString("hostname.txt", this->networkConfig->hostname); + // Construct the IP address string + static char ip_address[25]; + sprintf(ip_address, "%d.%d.%d.%d", this->networkConfig->ip[0], this->networkConfig->ip[1], this->networkConfig->ip[2], this->networkConfig->ip[3]); + this->setString("ip_address.txt", ip_address); + // Send the MQTT server and port + this->displayAdapter->print("server_address.txt="); + this->displayAdapter->print(this->mqttConfig->mqtt_server); + this->displayAdapter->print(":"); + this->displayAdapter->print(this->mqttConfig->mqtt_port); + this->sendStopBytes(); + // Send the MQTT connection status + this->setString("status_txt.txt", this->iot->mqttConnected() ? MSG_MQTT_CONNECTED : MSG_MQTT_DISCONNECTED); } void InternalDisplay::refreshInput() { - // TODO: implementation + for (uint8_t i=0; i<16; i++) { + this->setInputMarker(i, this->inputCard->digitalRead(i)); + } } void InternalDisplay::refreshOutput() { - // TODO: implementation + for (uint8_t i=0; i<16; i++) { + this->setOutputBar(i, this->outputCard->getValue(i)); + this->setOutputStateColor(i, this->outputCard->getState(i)); + } } void InternalDisplay::refreshAC() { // TODO: implementation } -void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value) { - // Write the value to the output bar - this->displayAdapter->print("j"); - this->displayAdapter->print(pin); - this->displayAdapter->print(".val="); - this->displayAdapter->print(value); - this->sendStopBytes(); -} void InternalDisplay::setPWMAdjustmentSlider(uint16_t value) { // TODO: implementation @@ -132,16 +149,32 @@ void InternalDisplay::setPWMAdjustmentButton(bool state) { // TODO: implementation } +void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value) { + // Write the value to the output bar + this->displayAdapter->print("j"); + this->displayAdapter->print(pin); + this->displayAdapter->print(".val="); + this->displayAdapter->print((int)(value*100/4095)); + this->sendStopBytes(); +} + void InternalDisplay::setOutputStateColor(uint8_t pin, bool state) { - // TODO: implementation + this->displayAdapter->print("j"); + this->displayAdapter->print(pin); + this->displayAdapter->print(".ppic="); + this->displayAdapter->print(state ? PIC_PWM_BAR_ON : PIC_PWM_BAR_OFF); + this->sendStopBytes(); + } void InternalDisplay::setInputMarker(uint8_t pin, bool state) { - // TODO: implementation + this->displayAdapter->print("I"); + this->displayAdapter->print(pin); + this->displayAdapter->print(".val="); + this->displayAdapter->print(state ? 0:1); + this->sendStopBytes(); } InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter) { this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE; - this->bindedInputCard = 0; - this->bindedOutputCard = 0; } \ No newline at end of file diff --git a/Template Project/lib/ESPMegaPRO/InternalDisplay.hpp b/Template Project/lib/ESPMegaPRO/InternalDisplay.hpp index e2efe9c..503c5bb 100644 --- a/Template Project/lib/ESPMegaPRO/InternalDisplay.hpp +++ b/Template Project/lib/ESPMegaPRO/InternalDisplay.hpp @@ -1,7 +1,10 @@ #include #include #include +#include +#include +// Page IDs #define INTERNAL_DISPLAY_DASHBOARD_PAGE 0 #define INTERNAL_DISPLAY_INPUT_PAGE 1 #define INTERNAL_DISPLAY_OUTPUT_PAGE 2 @@ -12,19 +15,31 @@ #define PIC_LAN_CONNECTED 3 #define PIC_MQTT_DISCONNECTED 4 #define PIC_MQTT_CONNECTED 5 +#define PIC_PWM_BAR_ON 33 +#define PIC_PWM_BAR_OFF 48 +// Messages +#define MSG_MQTT_CONNECTED "BMS Managed" +#define MSG_MQTT_DISCONNECTED "Standalone" + +// Refresh Interval +#define INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL 15000 +#define INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL 5000 class InternalDisplay : public ESPMegaDisplay { public: InternalDisplay(HardwareSerial *displayAdapter); void begin(ESPMegaIoT *iot, std::function getRtcTime); void loop(); - void bindInputCard(uint8_t card_id); - void bindOutputCard(uint8_t card_id); + void bindInputCard(DigitalInputCard *inputCard); + void bindOutputCard(DigitalOutputCard *outputCard); private: - uint8_t bindedInputCard; - uint8_t bindedOutputCard; + DigitalInputCard *inputCard; + DigitalOutputCard *outputCard; + // Previously registered callbacks of input and output cards + // We need to call them when the respective card is binded to the display + // Because we will replace the callbacks with the display's own callbacks void handleInputStateChange(uint8_t pin, bool state); void handlePwmStateChange(uint8_t pin, bool state, uint16_t value); void handlePageChange(uint8_t page); @@ -44,6 +59,8 @@ class InternalDisplay : public ESPMegaDisplay { void refreshInput(); void refreshOutput(); void refreshAC(); + MqttConfig *mqttConfig; + NetworkConfig *networkConfig; // Pointers to various data ESPMegaIoT *iot; std::function getRtcTime; diff --git a/Template Project/src/iot_framdemo.cpp b/Template Project/src/iot_framdemo.cpp index 8544cc0..b85da59 100644 --- a/Template Project/src/iot_framdemo.cpp +++ b/Template Project/src/iot_framdemo.cpp @@ -50,10 +50,7 @@ void setup() { espmega.iot.registerCard(0); espmega.iot.registerCard(1); Serial.println("Initialization Routine Complete"); - ((DigitalInputIoT*)espmega.iot.getComponent(0)) -> registerChangeCallback(input_change_callback); - - - + espmega.inputs.registerCallback(input_change_callback); } void loop() {