2023-12-29 13:04:25 +00:00
|
|
|
#include <InternalDisplay.hpp>
|
|
|
|
|
|
|
|
|
2023-12-29 17:49:09 +00:00
|
|
|
void InternalDisplay::begin(ESPMegaIoT *iot, std::function<rtctime_t()> getRtcTime) {
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Assigning IoT Module and RTC Time Getter");
|
2023-12-29 17:49:09 +00:00
|
|
|
this->iot = iot;
|
|
|
|
this->getRtcTime = getRtcTime;
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Acquiring Network and MQTT Configs");
|
2023-12-29 17:49:09 +00:00
|
|
|
this->mqttConfig = this->iot->getMqttConfig();
|
|
|
|
this->networkConfig = this->iot->getNetworkConfig();
|
|
|
|
// Register callbacks
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Registering Callbacks");
|
|
|
|
ESP_LOGD("InternalDisplay", "Binding Page Change Callback");
|
2023-12-30 11:27:39 +00:00
|
|
|
auto bindedInputStateChangeCallback = std::bind(&InternalDisplay::handleInputStateChange, this, std::placeholders::_1, std::placeholders::_2);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Binding Input State Change Callback");
|
2023-12-30 11:27:39 +00:00
|
|
|
auto bindedPwmStateChangeCallback = std::bind(&InternalDisplay::handlePwmStateChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Registering inputCard Callbacks");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->inputCard->registerCallback(bindedInputStateChangeCallback);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Registering outputCard Callbacks");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->outputCard->registerChangeCallback(bindedPwmStateChangeCallback);
|
|
|
|
// Initialize the display
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Initializing DisplayAdapter");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->displayAdapter->begin(115200);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Setting DisplayAdapter Timeout");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->displayAdapter->setTimeout(100);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Flushing DisplayAdapter");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->displayAdapter->flush();
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Resetting Display");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->reset();
|
|
|
|
delay(500);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Jumping to Page 1");
|
2023-12-30 11:27:39 +00:00
|
|
|
this->jumpToPage(1);
|
2023-12-30 11:47:52 +00:00
|
|
|
ESP_LOGD("InternalDisplay", "Display Initialization Complete");
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
2023-12-30 11:47:52 +00:00
|
|
|
|
2023-12-29 13:04:25 +00:00
|
|
|
void InternalDisplay::loop() {
|
2023-12-29 17:49:09 +00:00
|
|
|
// 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();
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
2023-12-29 17:49:09 +00:00
|
|
|
// Refresh the clock every 10 seconds
|
|
|
|
static uint32_t lastClockRefresh;
|
|
|
|
if (millis() - lastClockRefresh > INTERNAL_DISPLAY_CLOCK_REFRESH_INTERVAL) {
|
|
|
|
this->updateClock();
|
|
|
|
lastClockRefresh = millis();
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-29 17:49:09 +00:00
|
|
|
|
|
|
|
|
2023-12-29 13:04:25 +00:00
|
|
|
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
|
2023-12-29 17:49:09 +00:00
|
|
|
if (this->inputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_INPUT_PAGE) return;
|
2023-12-29 16:43:12 +00:00
|
|
|
// Update the input state
|
|
|
|
this->setInputMarker(pin, state);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
2023-12-29 16:43:12 +00:00
|
|
|
void InternalDisplay::handlePwmStateChange(uint8_t pin, bool state, uint16_t value) {
|
2023-12-29 13:04:25 +00:00
|
|
|
// If the output card is binded to the display and the current page is the output page
|
|
|
|
// then update the respective output component
|
2023-12-29 17:49:09 +00:00
|
|
|
if (this->outputCard!=nullptr || this->currentPage != INTERNAL_DISPLAY_OUTPUT_PAGE) return;
|
2023-12-29 16:43:12 +00:00
|
|
|
// Update the output state
|
|
|
|
this->setOutputBar(pin, value);
|
|
|
|
this->setOutputStateColor(pin, state);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::handlePageChange(uint8_t page) {
|
2023-12-29 16:43:12 +00:00
|
|
|
// Refresh the page
|
|
|
|
this->refreshPage(page);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::saveNetworkConfig() {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::saveMQTTConfig() {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
|
|
|
|
2023-12-29 16:43:12 +00:00
|
|
|
void InternalDisplay::updateStatusIcons(bool networkStatus, bool mqttStatus) {
|
|
|
|
this->setNumber("server.pic", mqttStatus ? PIC_MQTT_CONNECTED : PIC_MQTT_DISCONNECTED);
|
|
|
|
this->setNumber("lan.pic", networkStatus ? PIC_LAN_CONNECTED : PIC_LAN_DISCONNECTED);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::updateClock() {
|
2023-12-29 16:43:12 +00:00
|
|
|
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->sendStopBytes();
|
|
|
|
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshPage() {
|
2023-12-29 16:43:12 +00:00
|
|
|
this->refreshPage(this->currentPage);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshPage(uint8_t page) {
|
2023-12-29 16:43:12 +00:00
|
|
|
switch (page) {
|
|
|
|
case INTERNAL_DISPLAY_DASHBOARD_PAGE:
|
|
|
|
this->refreshDashboard();
|
|
|
|
break;
|
|
|
|
case INTERNAL_DISPLAY_INPUT_PAGE:
|
|
|
|
this->refreshInput();
|
|
|
|
break;
|
|
|
|
case INTERNAL_DISPLAY_OUTPUT_PAGE:
|
|
|
|
this->refreshOutput();
|
|
|
|
break;
|
|
|
|
case INTERNAL_DISPLAY_AC_PAGE:
|
|
|
|
this->refreshAC();
|
|
|
|
break;
|
|
|
|
}
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshDashboard() {
|
2023-12-29 16:43:12 +00:00
|
|
|
// The dashboard have the following components:
|
|
|
|
// 1. Hostname
|
|
|
|
// 2. IP Address
|
|
|
|
// 3. MQTT Server with port
|
|
|
|
// 4. MQTT Connection status
|
2023-12-29 17:49:09 +00:00
|
|
|
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);
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshInput() {
|
2023-12-29 17:49:09 +00:00
|
|
|
for (uint8_t i=0; i<16; i++) {
|
|
|
|
this->setInputMarker(i, this->inputCard->digitalRead(i));
|
|
|
|
}
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshOutput() {
|
2023-12-29 17:49:09 +00:00
|
|
|
for (uint8_t i=0; i<16; i++) {
|
|
|
|
this->setOutputBar(i, this->outputCard->getValue(i));
|
|
|
|
this->setOutputStateColor(i, this->outputCard->getState(i));
|
|
|
|
}
|
2023-12-29 13:04:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::refreshAC() {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void InternalDisplay::setPWMAdjustmentSlider(uint16_t value) {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::setPWMAdjustmentPin(uint8_t pin) {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::setPWMAdjustmentButton(bool state) {
|
|
|
|
// TODO: implementation
|
|
|
|
}
|
2023-12-29 14:41:19 +00:00
|
|
|
|
2023-12-29 17:49:09 +00:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-12-29 14:41:19 +00:00
|
|
|
void InternalDisplay::setOutputStateColor(uint8_t pin, bool state) {
|
2023-12-29 17:49:09 +00:00
|
|
|
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();
|
|
|
|
|
2023-12-29 14:41:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::setInputMarker(uint8_t pin, bool state) {
|
2023-12-29 17:49:09 +00:00
|
|
|
this->displayAdapter->print("I");
|
|
|
|
this->displayAdapter->print(pin);
|
|
|
|
this->displayAdapter->print(".val=");
|
|
|
|
this->displayAdapter->print(state ? 0:1);
|
|
|
|
this->sendStopBytes();
|
2023-12-29 14:41:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
InternalDisplay::InternalDisplay(HardwareSerial *displayAdapter) : ESPMegaDisplay(displayAdapter) {
|
|
|
|
this->currentPage = INTERNAL_DISPLAY_DASHBOARD_PAGE;
|
2023-12-30 11:27:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::bindInputCard(DigitalInputCard *inputCard) {
|
|
|
|
this->inputCard = inputCard;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InternalDisplay::bindOutputCard(DigitalOutputCard *outputCard) {
|
|
|
|
this->outputCard = outputCard;
|
2023-12-29 14:41:19 +00:00
|
|
|
}
|