card rebinding support

This commit is contained in:
Siwat Sirichai 2023-12-31 13:41:48 +07:00
parent 724f8f42e9
commit e8804864b8
14 changed files with 270 additions and 176 deletions

View File

@ -132,7 +132,7 @@ uint8_t AnalogCard::registerDACChangeCallback(std::function<void(uint8_t, bool,
return this->handler_count++; return this->handler_count++;
} }
void AnalogCard::deregisterDACChangeCallback(uint8_t handler) void AnalogCard::unregisterDACChangeCallback(uint8_t handler)
{ {
this->dac_change_callbacks.erase(handler); this->dac_change_callbacks.erase(handler);
} }

View File

@ -27,7 +27,7 @@ class AnalogCard : public ExpansionCard {
void setDACState(uint8_t pin, bool state); void setDACState(uint8_t pin, bool state);
void setDACValue(uint8_t pin, uint16_t value); void setDACValue(uint8_t pin, uint16_t value);
uint8_t registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); uint8_t registerDACChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
void deregisterDACChangeCallback(uint8_t handler); void unregisterDACChangeCallback(uint8_t handler);
uint8_t getType(); uint8_t getType();
private: private:
uint8_t handler_count; uint8_t handler_count;

View File

@ -69,7 +69,7 @@ uint8_t AnalogIoT::registerADCConversionCallback(std::function<void(uint8_t, uin
this->adc_conversion_callbacks[this->adc_conversion_callback_index] = callback; this->adc_conversion_callbacks[this->adc_conversion_callback_index] = callback;
return this->adc_conversion_callback_index++; return this->adc_conversion_callback_index++;
} }
void AnalogIoT::deregisterADCConversionCallback(uint8_t handler) { void AnalogIoT::unregisterADCConversionCallback(uint8_t handler) {
this->adc_conversion_callbacks.erase(handler); this->adc_conversion_callbacks.erase(handler);
} }
void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) { void AnalogIoT::setADCConversionInterval(uint8_t pin, uint16_t interval) {

View File

@ -26,7 +26,7 @@ class AnalogIoT : public IoTComponent {
void setADCsPublishInterval(uint32_t interval); void setADCsPublishInterval(uint32_t interval);
void setADCsPublishEnabled(bool enabled); void setADCsPublishEnabled(bool enabled);
uint8_t registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback); uint8_t registerADCConversionCallback(std::function<void(uint8_t, uint16_t)> callback);
void deregisterADCConversionCallback(uint8_t handler); void unregisterADCConversionCallback(uint8_t handler);
void setADCConversionInterval(uint8_t pin, uint16_t interval); void setADCConversionInterval(uint8_t pin, uint16_t interval);
void setADCConversionEnabled(uint8_t pin, bool enabled); void setADCConversionEnabled(uint8_t pin, bool enabled);
bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length); bool processADCSetConversionIntervalMessage(char *topic, char *payload, uint8_t topic_length);

View File

@ -107,7 +107,7 @@ uint8_t DigitalOutputCard::registerChangeCallback(std::function<void(uint8_t, bo
return this->callbacks_handler_index++; return this->callbacks_handler_index++;
} }
void DigitalOutputCard::deregisterChangeCallback(uint8_t handler) { void DigitalOutputCard::unregisterChangeCallback(uint8_t handler) {
this->change_callbacks.erase(handler); this->change_callbacks.erase(handler);
} }

View File

@ -49,8 +49,8 @@ public:
uint16_t getValue(uint8_t pin); uint16_t getValue(uint8_t pin);
// Register a callback function that will be called when the state of a pin changes // Register a callback function that will be called when the state of a pin changes
uint8_t registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); uint8_t registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
// Deregister the callback function // Unregister the callback function
void deregisterChangeCallback(uint8_t handler); void unregisterChangeCallback(uint8_t handler);
// Load a new pin map // Load a new pin map
void loadPinMap(uint8_t pinMap[16]); void loadPinMap(uint8_t pinMap[16]);
// Bind the fram object to the card // Bind the fram object to the card

View File

@ -166,7 +166,7 @@ void DigitalOutputIoT::registerChangeCallback(std::function<void(uint8_t, bool,
value_change_callback = callback; value_change_callback = callback;
} }
void DigitalOutputIoT::deregisterChangeCallback() { void DigitalOutputIoT::unregisterChangeCallback() {
value_change_callback = NULL; value_change_callback = NULL;
} }

View File

@ -16,7 +16,7 @@ class DigitalOutputIoT : public IoTComponent {
void setDigitalOutputsPublishEnabled(bool enabled); void setDigitalOutputsPublishEnabled(bool enabled);
void handleValueChange(uint8_t pin, bool state, uint16_t value); void handleValueChange(uint8_t pin, bool state, uint16_t value);
void registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback); void registerChangeCallback(std::function<void(uint8_t, bool, uint16_t)> callback);
void deregisterChangeCallback(); void unregisterChangeCallback();
void publishReport(); void publishReport();
void subscribe(); void subscribe();
void loop(); void loop();

View File

@ -409,10 +409,10 @@ uint16_t ESPMegaDisplay::registerTouchCallback(std::function<void(uint8_t, uint8
} }
/** /**
* @brief Deregisters a callback function for touch events. * @brief Unregisters a callback function for touch events.
* @param handle The handle of the callback function. * @param handle The handle of the callback function.
*/ */
void ESPMegaDisplay::deregisterTouchCallback(uint16_t handle) void ESPMegaDisplay::unregisterTouchCallback(uint16_t handle)
{ {
touch_callbacks.erase(handle); touch_callbacks.erase(handle);
} }
@ -430,10 +430,10 @@ uint16_t ESPMegaDisplay::registerPageChangeCallback(std::function<void(uint8_t)>
} }
/** /**
* @brief Deregisters a callback function for page change events. * @brief Unregisters a callback function for page change events.
* @param handle The handle of the callback function. * @param handle The handle of the callback function.
*/ */
void ESPMegaDisplay::deregisterPageChangeCallback(uint16_t handle) void ESPMegaDisplay::unregisterPageChangeCallback(uint16_t handle)
{ {
page_change_callbacks.erase(handle); page_change_callbacks.erase(handle);
} }

View File

@ -21,9 +21,9 @@ class ESPMegaDisplay
bool getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size); bool getStringToBuffer(const char* component, char* buffer, uint8_t buffer_size);
uint32_t getNumber(const char* component); uint32_t getNumber(const char* component);
uint16_t registerTouchCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback); uint16_t registerTouchCallback(std::function<void(uint8_t, uint8_t, uint8_t)> callback);
void deregisterTouchCallback(uint16_t handle); void unregisterTouchCallback(uint16_t handle);
uint16_t registerPageChangeCallback(std::function<void(uint8_t)> callback); uint16_t registerPageChangeCallback(std::function<void(uint8_t)> callback);
void deregisterPageChangeCallback(uint16_t handle); void unregisterPageChangeCallback(uint16_t handle);
protected: protected:
uint8_t currentPage; uint8_t currentPage;

View File

@ -127,7 +127,7 @@ void ESPMegaIoT::registerCard(uint8_t card_id)
return; return;
} }
} }
void ESPMegaIoT::deregisterCard(uint8_t card_id) void ESPMegaIoT::unregisterCard(uint8_t card_id)
{ {
// Check if the card is registered // Check if the card is registered
if (components[card_id] == NULL) if (components[card_id] == NULL)

View File

@ -53,7 +53,7 @@ public:
void intr_begin(ExpansionCard *cards[]); void intr_begin(ExpansionCard *cards[]);
void loop(); void loop();
void registerCard(uint8_t card_id); void registerCard(uint8_t card_id);
void deregisterCard(uint8_t card_id); void unregisterCard(uint8_t card_id);
void publishCard(uint8_t card_id); void publishCard(uint8_t card_id);
// Publish topic appended with base topic // Publish topic appended with base topic
void publishRelative(char *topic, char *payload); void publishRelative(char *topic, char *payload);

View File

@ -1,7 +1,7 @@
#include <InternalDisplay.hpp> #include <InternalDisplay.hpp>
void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime)
void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime) { {
this->iot = iot; this->iot = iot;
this->getRtcTime = getRtcTime; this->getRtcTime = getRtcTime;
this->mqttConfig = this->iot->getMqttConfig(); this->mqttConfig = this->iot->getMqttConfig();
@ -11,10 +11,6 @@ void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTi
this->registerPageChangeCallback(bindedPageChangeCallback); this->registerPageChangeCallback(bindedPageChangeCallback);
auto bindedTouchCallback = std::bind(&InternalDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedTouchCallback = std::bind(&InternalDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->registerTouchCallback(bindedTouchCallback); this->registerTouchCallback(bindedTouchCallback);
auto bindedInputStateChangeCallback = std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2);
auto bindedPwmStateChangeCallback = std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->inputCard->registerCallback(bindedInputStateChangeCallback);
this->outputCard->registerChangeCallback(bindedPwmStateChangeCallback);
// Initialize the display // Initialize the display
this->displayAdapter->begin(115200); this->displayAdapter->begin(115200);
this->displayAdapter->setTimeout(100); this->displayAdapter->setTimeout(100);
@ -24,110 +20,124 @@ void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTi
this->jumpToPage(1); this->jumpToPage(1);
} }
void InternalDisplay::loop()
void InternalDisplay::loop() { {
// Keep reading the Serial Adapter // Keep reading the Serial Adapter
this->recieveSerialCommand(); this->recieveSerialCommand();
// Refresh the top bar every 5 seconds // Refresh the top bar every 5 seconds
static uint32_t lastTopBarRefresh; static uint32_t lastTopBarRefresh;
if (millis() - lastTopBarRefresh > INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL) { if (millis() - lastTopBarRefresh > INTERNAL_DISPLAY_TOP_BAR_REFRESH_INTERVAL)
{
this->updateStatusIcons(this->iot->networkConnected(), this->iot->mqttConnected()); this->updateStatusIcons(this->iot->networkConnected(), this->iot->mqttConnected());
lastTopBarRefresh = millis(); lastTopBarRefresh = millis();
} }
// Refresh the clock every 10 seconds // Refresh the clock every 10 seconds
static uint32_t lastClockRefresh; static uint32_t lastClockRefresh;
if (millis() - lastClockRefresh > INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL) { if (millis() - lastClockRefresh > INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL)
{
this->updateClock(); this->updateClock();
lastClockRefresh = millis(); lastClockRefresh = millis();
} }
} }
void InternalDisplay::handleInputStateChange(uint8_t pin, bool state)
{
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 // If the input card is binded to the display and the current page is the input page
// then update the respective input component // then update the respective input component
if (this->inputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return; if (this->inputCard != nullptr || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE)
return;
// Update the input state // Update the input state
this->setInputMarker(pin, state); this->setInputMarker(pin, state);
} }
void InternalDisplay::handlePwmStateChange(uint8_t pin, bool state, uint16_t value) { 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 // If the output card is binded to the display and the current page is the output page
// then update the respective output component // then update the respective output component
if (this->outputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return; if (this->outputCard != nullptr || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE)
return;
// Update the output state // Update the output state
this->setOutputBar(pin, value); this->setOutputBar(pin, value);
this->setOutputStateColor(pin, state); this->setOutputStateColor(pin, state);
// Refresh the PWM Adjustment page if the current page is the PWM Adjustment page and the pin is the same // Refresh the PWM Adjustment page if the current page is the PWM Adjustment page and the pin is the same
if (this->currentPage == INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE && this->pmwAdjustmentPin == pin) { if (this->currentPage == INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE && this->pmwAdjustmentPin == pin)
{
this->refreshPWMAdjustment(); this->refreshPWMAdjustment();
} }
} }
void InternalDisplay::handlePageChange(uint8_t page) { void InternalDisplay::handlePageChange(uint8_t page)
{
// Refresh the page // Refresh the page
this->refreshPage(page); this->refreshPage(page);
} }
void InternalDisplay::saveNetworkConfig() { void InternalDisplay::saveNetworkConfig()
{
// TODO: implementation // TODO: implementation
} }
void InternalDisplay::saveMQTTConfig() { void InternalDisplay::saveMQTTConfig()
{
// TODO: implementation // TODO: implementation
} }
void InternalDisplay::updateStatusIcons(bool networkStatus, bool mqttStatus) { void InternalDisplay::updateStatusIcons(bool networkStatus, bool mqttStatus)
{
this->setNumber("server.pic", mqttStatus ? PIC_MQTT_CONNECTED : PIC_MQTT_DISCONNECTED); this->setNumber("server.pic", mqttStatus ? PIC_MQTT_CONNECTED : PIC_MQTT_DISCONNECTED);
this->setNumber("lan.pic", networkStatus ? PIC_LAN_CONNECTED : PIC_LAN_DISCONNECTED); this->setNumber("lan.pic", networkStatus ? PIC_LAN_CONNECTED : PIC_LAN_DISCONNECTED);
} }
void InternalDisplay::updateClock() { void InternalDisplay::updateClock()
{
rtctime_t time = this->getRtcTime(); rtctime_t time = this->getRtcTime();
this->displayAdapter->printf("time.txt=\"%02d:%02d %s\"", time.hours%12, time.minutes, 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(); this->sendStopBytes();
} }
void InternalDisplay::refreshPage() { void InternalDisplay::refreshPage()
{
this->refreshPage(this->currentPage); this->refreshPage(this->currentPage);
} }
void InternalDisplay::refreshPage(uint8_t page) { void InternalDisplay::refreshPage(uint8_t page)
switch (page) { {
case INTERNAL_DISPLAY_DASHBOARD_PAGE: switch (page)
this->refreshDashboard(); {
break; case INTERNAL_DISPLAY_DASHBOARD_PAGE:
case INTERNAL_DISPLAY_INPUT_PAGE: this->refreshDashboard();
this->refreshInput(); break;
break; case INTERNAL_DISPLAY_INPUT_PAGE:
case INTERNAL_DISPLAY_OUTPUT_PAGE: this->refreshInput();
this->refreshOutput(); break;
break; case INTERNAL_DISPLAY_OUTPUT_PAGE:
case INTERNAL_DISPLAY_AC_PAGE: this->refreshOutput();
if (this->climateCard == nullptr) { break;
this->jumpToPage(INTERNAL_DISPLAY_CLIMATE_NULL_PTR_PAGE); case INTERNAL_DISPLAY_AC_PAGE:
break; if (this->climateCard == nullptr)
} {
this->refreshAC(); this->jumpToPage(INTERNAL_DISPLAY_CLIMATE_NULL_PTR_PAGE);
break;
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; break;
}
this->refreshAC();
break;
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;
} }
} }
void InternalDisplay::refreshDashboard() { void InternalDisplay::refreshDashboard()
{
// The dashboard have the following components: // The dashboard have the following components:
// 1. Hostname // 1. Hostname
// 2. IP Address // 2. IP Address
@ -147,20 +157,25 @@ void InternalDisplay::refreshDashboard() {
this->setString("status_txt.txt", this->iot->mqttConnected() ? MSG_MQTT_CONNECTED : MSG_MQTT_DISCONNECTED); this->setString("status_txt.txt", this->iot->mqttConnected() ? MSG_MQTT_CONNECTED : MSG_MQTT_DISCONNECTED);
} }
void InternalDisplay::refreshInput() { void InternalDisplay::refreshInput()
for (uint8_t i=0; i<16; i++) { {
for (uint8_t i = 0; i < 16; i++)
{
this->setInputMarker(i, this->inputCard->digitalRead(i, false)); this->setInputMarker(i, this->inputCard->digitalRead(i, false));
} }
} }
void InternalDisplay::refreshOutput() { void InternalDisplay::refreshOutput()
for (uint8_t i=0; i<16; i++) { {
for (uint8_t i = 0; i < 16; i++)
{
this->setOutputBar(i, this->outputCard->getValue(i)); this->setOutputBar(i, this->outputCard->getValue(i));
this->setOutputStateColor(i, this->outputCard->getState(i)); this->setOutputStateColor(i, this->outputCard->getState(i));
} }
} }
void InternalDisplay::refreshAC() { void InternalDisplay::refreshAC()
{
this->displayAdapter->print("temp.txt=\""); this->displayAdapter->print("temp.txt=\"");
this->displayAdapter->print(this->climateCard->getTemperature()); this->displayAdapter->print(this->climateCard->getTemperature());
this->displayAdapter->print("C\""); this->displayAdapter->print("C\"");
@ -186,7 +201,8 @@ void InternalDisplay::refreshAC() {
this->displayAdapter->print("mode_cool.pic="); this->displayAdapter->print("mode_cool.pic=");
this->displayAdapter->print(this->climateCard->getMode() == AC_MODE_COOL ? PIC_AC_MODE_COOL_ACTIVE : PIC_AC_MODE_COOL_INACTIVE); this->displayAdapter->print(this->climateCard->getMode() == AC_MODE_COOL ? PIC_AC_MODE_COOL_ACTIVE : PIC_AC_MODE_COOL_INACTIVE);
this->sendStopBytes(); this->sendStopBytes();
if (this->climateCard->getSensorType() == AC_SENSOR_TYPE_DHT22) { if (this->climateCard->getSensorType() == AC_SENSOR_TYPE_DHT22)
{
this->displayAdapter->print("roomtemp.txt=\""); this->displayAdapter->print("roomtemp.txt=\"");
this->displayAdapter->print(this->climateCard->getRoomTemperature()); this->displayAdapter->print(this->climateCard->getRoomTemperature());
this->displayAdapter->print("C\""); this->displayAdapter->print("C\"");
@ -196,46 +212,51 @@ void InternalDisplay::refreshAC() {
this->displayAdapter->print("%\""); this->displayAdapter->print("%\"");
this->sendStopBytes(); this->sendStopBytes();
} }
else if(this->climateCard->getSensorType() == AC_SENSOR_TYPE_DS18B20) { else if (this->climateCard->getSensorType() == AC_SENSOR_TYPE_DS18B20)
{
this->displayAdapter->print("roomtemp.txt=\""); this->displayAdapter->print("roomtemp.txt=\"");
this->displayAdapter->print(this->climateCard->getRoomTemperature()); this->displayAdapter->print(this->climateCard->getRoomTemperature());
this->displayAdapter->print("C\""); this->displayAdapter->print("C\"");
this->sendStopBytes(); this->sendStopBytes();
this->setString("roomhumid.txt", "N/A"); this->setString("roomhumid.txt", "N/A");
} }
else { else
{
this->setString("roomtemp.txt", "N/A"); this->setString("roomtemp.txt", "N/A");
this->setString("roomhumid.txt", "N/A"); this->setString("roomhumid.txt", "N/A");
} }
} }
void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value) { void InternalDisplay::setOutputBar(uint8_t pin, uint16_t value)
{
// Write the value to the output bar // Write the value to the output bar
this->displayAdapter->print("j"); this->displayAdapter->print("j");
this->displayAdapter->print(pin); this->displayAdapter->print(pin);
this->displayAdapter->print(".val="); this->displayAdapter->print(".val=");
this->displayAdapter->print((int)(value*100/4095)); this->displayAdapter->print((int)(value * 100 / 4095));
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::setOutputStateColor(uint8_t pin, bool state) { void InternalDisplay::setOutputStateColor(uint8_t pin, bool state)
{
this->displayAdapter->print("j"); this->displayAdapter->print("j");
this->displayAdapter->print(pin); this->displayAdapter->print(pin);
this->displayAdapter->print(".ppic="); this->displayAdapter->print(".ppic=");
this->displayAdapter->print(state ? PIC_PWM_BAR_ON : PIC_PWM_BAR_OFF); this->displayAdapter->print(state ? PIC_PWM_BAR_ON : PIC_PWM_BAR_OFF);
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::setInputMarker(uint8_t pin, bool state) { void InternalDisplay::setInputMarker(uint8_t pin, bool state)
{
this->displayAdapter->print("I"); this->displayAdapter->print("I");
this->displayAdapter->print(pin); this->displayAdapter->print(pin);
this->displayAdapter->print(".val="); this->displayAdapter->print(".val=");
this->displayAdapter->print(state ? 0:1); this->displayAdapter->print(state ? 0 : 1);
this->sendStopBytes(); this->sendStopBytes();
} }
InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter) { InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter)
{
this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE; this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE;
this->iot = nullptr; this->iot = nullptr;
this->inputCard = nullptr; this->inputCard = nullptr;
@ -244,24 +265,73 @@ InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDispla
this->pmwAdjustmentPin = 0; this->pmwAdjustmentPin = 0;
} }
void InternalDisplay::bindInputCard(DigitalInputCard *inputCard) { void InternalDisplay::bindInputCard(DigitalInputCard *inputCard)
{
// Check if the input card is already binded
// If it is, then unbind it first
if (this->inputCard != nullptr)
this->unbindInputCard();
this->inputCard = inputCard; this->inputCard = inputCard;
auto bindedInputStateChangeCallback =
std::bind(&InternalDisplay::handleInputStateChange, this,
std::placeholders::_1, std::placeholders::_2);
this->bindedInputCardCallbackHandler =
this->inputCard->registerCallback(bindedInputStateChangeCallback);
} }
void InternalDisplay::bindOutputCard(DigitalOutputCard *outputCard) { void InternalDisplay::unbindInputCard()
{
if (this->inputCard == nullptr)
return;
this->inputCard->unregisterCallback(this->bindedInputCardCallbackHandler);
this->inputCard = nullptr;
}
void InternalDisplay::bindOutputCard(DigitalOutputCard *outputCard)
{
// Check if the output card is already binded
// If it is, then unbind it first
if (this->outputCard != nullptr)
this->unbindOutputCard();
this->outputCard = outputCard; this->outputCard = outputCard;
auto bindedPwmStateChangeCallback = std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->bindedOutputCardCallbackHandler =
this->outputCard->registerChangeCallback(bindedPwmStateChangeCallback);
}
void InternalDisplay::unbindOutputCard()
{
if (this->outputCard == nullptr)
return;
this->outputCard->unregisterChangeCallback(this->bindedOutputCardCallbackHandler);
this->outputCard = nullptr;
} }
// This assume that your ClimeateCard has the mode and fan speed names in the following order: // This assume that your ClimeateCard has the mode and fan speed names in the following order:
// mode: [off, fan_only, cool] // mode: [off, fan_only, cool]
// fan_speed: [auto, low, medium, high] // fan_speed: [auto, low, medium, high]
void InternalDisplay::bindClimateCard(ClimateCard *climateCard) { void InternalDisplay::bindClimateCard(ClimateCard *climateCard)
{
// Check if the climate card is already binded
// If it is, then unbind it first
if (this->climateCard != nullptr)
this->unbindClimateCard();
this->climateCard = climateCard; this->climateCard = climateCard;
auto bindedACStateChangeCallback = std::bind(&InternalDisplay::handleACStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedACStateChangeCallback = std::bind(&InternalDisplay::handleACStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->climateCard->registerChangeCallback(bindedACStateChangeCallback); this->bindedClimateCardCallbackHandler =
this->climateCard->registerChangeCallback(bindedACStateChangeCallback);
} }
void InternalDisplay::refreshPWMAdjustment() { void InternalDisplay::unbindClimateCard()
{
if (this->climateCard == nullptr)
return;
this->climateCard->unregisterChangeCallback(this->bindedClimateCardCallbackHandler);
this->climateCard = nullptr;
}
void InternalDisplay::refreshPWMAdjustment()
{
// The PWM Adjustment page have the following components: // The PWM Adjustment page have the following components:
// pwm_value -> a slider to adjust the PWM value // pwm_value -> a slider to adjust the PWM value
// pwm_state -> a button to toggle the PWM state // pwm_state -> a button to toggle the PWM state
@ -275,7 +345,8 @@ void InternalDisplay::refreshPWMAdjustment() {
this->refreshPWMAdjustmentState(); this->refreshPWMAdjustmentState();
} }
void InternalDisplay::refreshPWMAdjustmentId() { void InternalDisplay::refreshPWMAdjustmentId()
{
// Send the PWM pin // Send the PWM pin
this->displayAdapter->print("pwm_id.txt=\"P"); this->displayAdapter->print("pwm_id.txt=\"P");
this->displayAdapter->print(pmwAdjustmentPin); this->displayAdapter->print(pmwAdjustmentPin);
@ -283,14 +354,16 @@ void InternalDisplay::refreshPWMAdjustmentId() {
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::refreshPWMAdjustmentSlider() { void InternalDisplay::refreshPWMAdjustmentSlider()
{
// Send the PWM value // Send the PWM value
this->displayAdapter->print("pwm_value.val="); this->displayAdapter->print("pwm_value.val=");
this->displayAdapter->print(this->outputCard->getValue(this->pmwAdjustmentPin)); this->displayAdapter->print(this->outputCard->getValue(this->pmwAdjustmentPin));
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::refreshPWMAdjustmentState() { void InternalDisplay::refreshPWMAdjustmentState()
{
// Send the PWM state // Send the PWM state
this->displayAdapter->print("pwm_state.txt=\""); this->displayAdapter->print("pwm_state.txt=\"");
this->displayAdapter->print(this->outputCard->getState(this->pmwAdjustmentPin) ? MSG_PWM_ADJUSTMENT_STATE_ON : MSG_PWM_ADJUSTMENT_STATE_OFF); this->displayAdapter->print(this->outputCard->getState(this->pmwAdjustmentPin) ? MSG_PWM_ADJUSTMENT_STATE_ON : MSG_PWM_ADJUSTMENT_STATE_OFF);
@ -298,21 +371,24 @@ void InternalDisplay::refreshPWMAdjustmentState() {
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t type) { void InternalDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t type)
{
// Switch based on the page // Switch based on the page
switch (page) { switch (page)
case INTERNAL_DISPLAY_AC_PAGE: {
this->handleACTouch(type, component); case INTERNAL_DISPLAY_AC_PAGE:
break; this->handleACTouch(type, component);
case INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE: break;
this->handlePWMAdjustmentTouch(type, component); case INTERNAL_DISPLAY_PWM_ADJUSTMENT_PAGE:
break; this->handlePWMAdjustmentTouch(type, component);
default: break;
break; default:
break;
} }
} }
void InternalDisplay::handleACTouch(uint8_t type, uint8_t component) { void InternalDisplay::handleACTouch(uint8_t type, uint8_t component)
{
// b1 [component 18] -> inclement AC temperature by 1 // b1 [component 18] -> inclement AC temperature by 1
// b0 [component 17] -> declement AC temperature by 1 // b0 [component 17] -> declement AC temperature by 1
// fan_auto [component 4] -> set the fan speed to auto // fan_auto [component 4] -> set the fan speed to auto
@ -325,88 +401,95 @@ void InternalDisplay::handleACTouch(uint8_t type, uint8_t component) {
// For b0 and b1, if the type is not release then return // For b0 and b1, if the type is not release then return
// For other components, if the type is not press then return // For other components, if the type is not press then return
if ((component == 17 || component == 18) && type != TOUCH_TYPE_RELEASE) return; if ((component == 17 || component == 18) && type != TOUCH_TYPE_RELEASE)
if ((component != 17 && component != 18) && type != TOUCH_TYPE_PRESS) return; return;
if ((component != 17 && component != 18) && type != TOUCH_TYPE_PRESS)
return;
// Switch based on the component // Switch based on the component
switch (component) { switch (component)
case 17: {
// Decrement the temperature case 17:
this->climateCard->setTemperature(this->climateCard->getTemperature() - 1); // Decrement the temperature
break; this->climateCard->setTemperature(this->climateCard->getTemperature() - 1);
case 18: break;
// Increment the temperature case 18:
this->climateCard->setTemperature(this->climateCard->getTemperature() + 1); // Increment the temperature
break; this->climateCard->setTemperature(this->climateCard->getTemperature() + 1);
case 4: break;
// Set the fan speed to auto case 4:
this->climateCard->setFanSpeed(AC_FAN_SPEED_AUTO); // Set the fan speed to auto
break; this->climateCard->setFanSpeed(AC_FAN_SPEED_AUTO);
case 5: break;
// Set the fan speed to low case 5:
this->climateCard->setFanSpeed(AC_FAN_SPEED_LOW); // Set the fan speed to low
break; this->climateCard->setFanSpeed(AC_FAN_SPEED_LOW);
case 6: break;
// Set the fan speed to medium case 6:
this->climateCard->setFanSpeed(AC_FAN_SPEED_MEDIUM); // Set the fan speed to medium
break; this->climateCard->setFanSpeed(AC_FAN_SPEED_MEDIUM);
case 7: break;
// Set the fan speed to high case 7:
this->climateCard->setFanSpeed(AC_FAN_SPEED_HIGH); // Set the fan speed to high
break; this->climateCard->setFanSpeed(AC_FAN_SPEED_HIGH);
case 10: break;
// Set the mode to off case 10:
this->climateCard->setMode(AC_MODE_OFF); // Set the mode to off
break; this->climateCard->setMode(AC_MODE_OFF);
case 9: break;
// Set the mode to fan only case 9:
this->climateCard->setMode(AC_MODE_FAN_ONLY); // Set the mode to fan only
break; this->climateCard->setMode(AC_MODE_FAN_ONLY);
case 8: break;
// Set the mode to cool case 8:
this->climateCard->setMode(AC_MODE_COOL); // Set the mode to cool
break; this->climateCard->setMode(AC_MODE_COOL);
default: break;
break; default:
break;
} }
} }
void InternalDisplay::handlePWMAdjustmentTouch(uint8_t type, uint8_t component) { void InternalDisplay::handlePWMAdjustmentTouch(uint8_t type, uint8_t component)
{
// b0 [component 5] -> decrement the PWM id if its greater than 0, else set it to 15 // b0 [component 5] -> decrement the PWM id if its greater than 0, else set it to 15
// b1 [component 6] -> increment the PWM id if its less than 15, else set it to 0 // b1 [component 6] -> increment the PWM id if its less than 15, else set it to 0
// pwm_state [component 4] -> toggle the PWM state // pwm_state [component 4] -> toggle the PWM state
// pwm_value [component 1] -> set the PWM value based on the slider value // pwm_value [component 1] -> set the PWM value based on the slider value
// If the type is not release then return // If the type is not release then return
if (type != TOUCH_TYPE_RELEASE) return; if (type != TOUCH_TYPE_RELEASE)
return;
uint16_t val = 0; uint16_t val = 0;
// switch based on the component // switch based on the component
switch (component) { switch (component)
case 5: {
// Decrement the PWM id case 5:
this->pmwAdjustmentPin = this->pmwAdjustmentPin > 0 ? this->pmwAdjustmentPin - 1 : 15; // Decrement the PWM id
this->refreshPWMAdjustment(); this->pmwAdjustmentPin = this->pmwAdjustmentPin > 0 ? this->pmwAdjustmentPin - 1 : 15;
break; this->refreshPWMAdjustment();
case 6: break;
// Increment the PWM id case 6:
this->pmwAdjustmentPin = this->pmwAdjustmentPin < 15 ? this->pmwAdjustmentPin + 1 : 0; // Increment the PWM id
this->refreshPWMAdjustment(); this->pmwAdjustmentPin = this->pmwAdjustmentPin < 15 ? this->pmwAdjustmentPin + 1 : 0;
break; this->refreshPWMAdjustment();
case 4: break;
// Toggle the PWM state case 4:
this->outputCard->setState(this->pmwAdjustmentPin, !this->outputCard->getState(this->pmwAdjustmentPin)); // Toggle the PWM state
this->refreshPWMAdjustmentState(); this->outputCard->setState(this->pmwAdjustmentPin, !this->outputCard->getState(this->pmwAdjustmentPin));
break; this->refreshPWMAdjustmentState();
case 1: break;
// Set the PWM value case 1:
val = (uint16_t)this -> getNumber("pwm_value.val"); // Set the PWM value
this->outputCard->setValue(this->pmwAdjustmentPin, val); val = (uint16_t)this->getNumber("pwm_value.val");
break; this->outputCard->setValue(this->pmwAdjustmentPin, val);
default: break;
break; default:
break;
} }
} }
void InternalDisplay::refreshNetworkConfig() { void InternalDisplay::refreshNetworkConfig()
{
// The network config page have the following components: // The network config page have the following components:
// ip_set -> a text input to set the ip address // ip_set -> a text input to set the ip address
// netmask_set -> a text input to set the netmask // netmask_set -> a text input to set the netmask
@ -441,7 +524,8 @@ void InternalDisplay::refreshNetworkConfig() {
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::refreshMQTTConfig() { void InternalDisplay::refreshMQTTConfig()
{
// The MQTT config page have the following components: // The MQTT config page have the following components:
// mqttsv_set -> a text input to set the mqtt server // mqttsv_set -> a text input to set the mqtt server
// port_set -> a text input to set the mqtt port // port_set -> a text input to set the mqtt port
@ -480,7 +564,8 @@ void InternalDisplay::refreshMQTTConfig() {
this->sendStopBytes(); this->sendStopBytes();
} }
void InternalDisplay::sendIpToDisplay(IPAddress ip) { void InternalDisplay::sendIpToDisplay(IPAddress ip)
{
// Send the ip address // Send the ip address
this->displayAdapter->print(ip[0]); this->displayAdapter->print(ip[0]);
this->displayAdapter->print("."); this->displayAdapter->print(".");
@ -491,11 +576,13 @@ void InternalDisplay::sendIpToDisplay(IPAddress ip) {
this->displayAdapter->print(ip[3]); this->displayAdapter->print(ip[3]);
} }
void InternalDisplay::handleACStateChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature) { 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 // If the climate card is binded to the display and the current page is the AC page
// then update the respective AC component // then update the respective AC component
Serial.println("AC state changed"); Serial.println("AC state changed");
if (this->climateCard==nullptr || this->currentPage != INTERNAL_DISPLAY_AC_PAGE) return; if (this->climateCard == nullptr || this->currentPage != INTERNAL_DISPLAY_AC_PAGE)
return;
this->sendStopBytes(); this->sendStopBytes();
// Update the AC state // Update the AC state
this->refreshAC(); this->refreshAC();

View File

@ -73,8 +73,15 @@ class InternalDisplay : public ESPMegaDisplay {
void bindInputCard(DigitalInputCard *inputCard); void bindInputCard(DigitalInputCard *inputCard);
void bindOutputCard(DigitalOutputCard *outputCard); void bindOutputCard(DigitalOutputCard *outputCard);
void bindClimateCard(ClimateCard *climateCard); void bindClimateCard(ClimateCard *climateCard);
void unbindInputCard();
void unbindOutputCard();
void unbindClimateCard();
private: private:
uint8_t bindedInputCardCallbackHandler;
uint8_t bindedOutputCardCallbackHandler;
uint8_t bindedClimateCardCallbackHandler;
uint8_t bindedClimateCardSensorCallbackHandler;
DigitalInputCard *inputCard; DigitalInputCard *inputCard;
DigitalOutputCard *outputCard; DigitalOutputCard *outputCard;
ClimateCard *climateCard; ClimateCard *climateCard;