#include ISEDisplay::ISEDisplay(HardwareSerial *adapter, const uint8_t *light_array, uint8_t row, uint8_t column) : ESPMegaDisplay(adapter, 115200, 912600, 4, 17) { this->light_array = light_array; this->row = row; this->column = column; } // Work left // TODO : Implement // debug to work void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCard, ClimateCard *climateCard, RemoteVariable* pm_switch, RemoteVariable* pm_fan_speed) { this->inputCard = inputCard; this->outputCard = outputCard; this->climateCard = climateCard; this->pm_switch = pm_switch; this->remote_pm_fan_speed = pm_fan_speed; auto bindedHandlePWMChange = std::bind(&ISEDisplay::handlePWMChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedHandleACChange = std::bind(&ISEDisplay::handleACChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedHandleTouch = std::bind(&ISEDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); this->outputCallbackHandle = this->outputCard->registerChangeCallback(bindedHandlePWMChange); this->climateCallbackHandle = this->climateCard->registerChangeCallback(bindedHandleACChange); this->user_mode = 1; // initialized to cool by default this->pm_fan_speed = 10; //remote_pm_fan_speed->setValue(pm_fan_speed); this->ac_fan_speed = 0; this->ac_mode = 0; this->ac_temperature = 25; this->lightLevelRow1 = 0; this->lightLevelRow2 = 0; this->lightLevelRow3 = 0; this->lightLevelRow4 = 0; // this->time_since_last_screen_update = 0; this->registerTouchCallback(bindedHandleTouch); this->reset(); delay(1000); // TODO : Will the light be on or off when the system is started?, You need to jump to its respective page // first jump to main then if no activity jump to standby this->jumpToPage(2); // change this back later to 2 delay(100); this->updateAirPurifierState(); this->updateACState(); this->updateLightGroupStatePageDashboard(); // this->outputCard->setValue(1, 0); // this->outputCard->setValue(2, 0); // this->outputCard->setValue(3, 0); // this->outputCard->setValue(4, 0); // this->climateCard->setTemperature(ac_temperature); // this->climateCard->setFanSpeed(ac_fan_speed); // this->climateCard->setMode(ac_mode); this->climateCard->setState(ac_mode, ac_fan_speed, ac_temperature); } void ISEDisplay::loop() { // Check if there is data in the serial buffer // If there is data, process the data recieveSerialCommand(); // Update the time since the last screen update using millis() // u_int32_t current_time = millis(); // if (current_time - this->time_since_last_screen_update > 120000) // { // // jump to standby page if there is no activity for 2 minutes // if(this->currentPage != 1){ // this->jumpToPage(1); // ESP_LOGI("ISEDisplay", "Jumping to standby page"); // } // } } void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type) { ESP_LOGD("ISEDisplay", "Touch detected on page %d, component %d, touch type %d", page, component, touch_type); // time_since_last_screen_update = millis(); // update time since last activity char buffer[4]; if (page == PAGE_STANDBY) { switch (component) { case COMPONENT_STANDBY_OPEN_ALL_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; // TODO : Should you really jump to page 2 here? should't page jumping be handled reactivly? // EX. if atleast one light is on, then jump to active page, else jump to standby page // This will allow page to change correctly when the system is started and when controlled remotely which won't call handleTouch // time_since_last_screen_update = millis(); this->jumpToPage(2); // the function of the button is to open the dashboard from standby break; case COMPONENT_STANDBY_LIGHT_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; // TODO : So this does nothing? Shouldn't it turn on the lights? // should turn it on now toggleLightGroupStateStandby(); break; case COMPONENT_STANDBY_AC_TOGGLE: // TODO : What's the expexted behavior of standby? Does it enter standby when the lights are all off and ignore the AC // or does it only enter standby when ac is also off and purifier is off, or is it a timed thing? if (touch_type != TOUCH_TYPE_RELEASE) break; toggleAC(); break; case COMPONENT_STANDBY_PM_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; togglePMStandby(); break; default: break; } } else if (page == PAGE_DASHBOARD) { switch (component) { case COMPONENT_LIGHT_MASTER_BUTTON: // TODO : this only update the display to match the light, it doesn't toggle the light. if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightGroupState(); break; // TODOlater : can't this be done better with array lookup? case COMPONENT_LIGHT_MASTER_LEVEL1_TOUCHPOINT: if (touch_type != TOUCH_TYPE_RELEASE) break; for (uint8_t i = 1; i <= 4; i++) { setLightLevel(i, 1); } break; case COMPONENT_LIGHT_MASTER_LEVEL2_TOUCHPOINT: if (touch_type != TOUCH_TYPE_RELEASE) break; for (uint8_t i = 1; i <= 4; i++) { setLightLevel(i, 2); } break; case COMPONENT_LIGHT_MASTER_LEVEL3_TOUCHPOINT: if (touch_type != TOUCH_TYPE_RELEASE) break; for (uint8_t i = 1; i <= 4; i++) { setLightLevel(i, 3); } break; case COMPONENT_LIGHT_ROW1_SLIDER: if (touch_type != TOUCH_TYPE_RELEASE) break; lightLevelRow1 = this->getNumber("light_r1_slide.val"); toggleSliderLight(1, lightLevelRow1); break; case COMPONENT_LIGHT_ROW2_SLIDER: if (touch_type != TOUCH_TYPE_RELEASE) break; lightLevelRow2 = this->getNumber("light_r2_slide.val"); toggleSliderLight(2, lightLevelRow2); break; case COMPONENT_LIGHT_ROW3_SLIDER: if (touch_type != TOUCH_TYPE_RELEASE) break; lightLevelRow3 = this->getNumber("light_r3_slide.val"); toggleSliderLight(3, lightLevelRow3); break; case COMPONENT_LIGHT_ROW4_SLIDER: if (touch_type != TOUCH_TYPE_RELEASE) break; lightLevelRow4 = this->getNumber("light_r4_slide.val"); toggleSliderLight(4, lightLevelRow4); break; case COMPONENT_LIGHT_ROW1_SWITCH: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(1); break; case COMPONENT_LIGHT_ROW2_SWITCH: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(2); break; case COMPONENT_LIGHT_ROW3_SWITCH: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(3); break; case COMPONENT_LIGHT_ROW4_SWITCH: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(4); break; // TODO : Don't we have fan only mode too? can you really just switch between 0 and 1? case COMPONENT_AC_TOGGLE_BUTTON: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleAC(); break; case COMPONENT_AC_MODE: if (touch_type != TOUCH_TYPE_RELEASE) break; changeUserACmode(); break; case COMPONENT_AC_FAN_SPEED: if (touch_type != TOUCH_TYPE_RELEASE) break; ac_fan_speed = this->climateCard->getFanSpeed(); // We have auto, low, mid, high right?, that's 0,1,2,3 a modulo operation of 3 only gives 0,1,2 // mod 4 should fixed it ESP_LOGI("ISEDisplay", "Current AC fan speed: %d", ac_fan_speed); ac_fan_speed = (ac_fan_speed + 1) % 4; ESP_LOGI("ISEDisplay", "New AC fan speed: %d", ac_fan_speed); this->climateCard->setFanSpeed(ac_fan_speed); // updateACState(); break; case COMPONENT_AC_TEMP_DOWN_BUTTON: if (touch_type != TOUCH_TYPE_RELEASE) break; this->climateCard->setTemperature(this->climateCard->getTemperature() - 1); // updateACState(); break; case COMPONENT_AC_TEMP_UP_BUTTON: if (touch_type != TOUCH_TYPE_RELEASE) break; this->climateCard->setTemperature(this->climateCard->getTemperature() + 1); // updateACState(); break; case COMPONENT_PM_TOGGLE_BUTTON: if (touch_type != TOUCH_TYPE_RELEASE) break; togglePM(); break; case COMPONENT_PM_FAN_SPEED_DECREASE: if (touch_type != TOUCH_TYPE_RELEASE) break; pm_fan_speed = (int) atof(remote_pm_fan_speed->getValue()); ESP_LOGI("ISEDisplay", "Current PM fan speed: %d", pm_fan_speed); if (pm_fan_speed >= 1 && pm_fan_speed <= 20) itoa(pm_fan_speed - 1, buffer, DEC); remote_pm_fan_speed->setValue(buffer); ESP_LOGI("ISEDisplay", "New PM fan speed: %d", pm_fan_speed); //updateAirPurifierState(); break; case COMPONENT_PM_FAN_SPEED_INCREASE: if (touch_type != TOUCH_TYPE_RELEASE) break; pm_fan_speed = (int) atof(remote_pm_fan_speed->getValue()); ESP_LOGI("ISEDisplay", "Current PM fan speed: %d", pm_fan_speed); if (pm_fan_speed >= 0 && pm_fan_speed <= 19) itoa(pm_fan_speed + 1, buffer, DEC); remote_pm_fan_speed->setValue(buffer); ESP_LOGI("ISEDisplay", "New PM fan speed: %d", pm_fan_speed); //updateAirPurifierState(); break; default: break; } } else { return; } } void ISEDisplay::handlePWMChange(uint8_t pin, bool state, uint16_t value) { // NEED to switch case for different page uint8_t current_page = this->currentPage; if (current_page == PAGE_STANDBY) { if ((pin >= 0 && pin <= 3) ||(pin >= 8 && pin <= 11)) { // Light updateLightGroupStatePageStandby(); // time_since_last_screen_update = millis(); // update time since last activity } } else if (current_page == PAGE_DASHBOARD) { if ((pin >= 0 && pin <= 3) ||(pin >= 8 && pin <= 11)) { // Light updateLightGroupStatePageDashboard(); // time_since_last_screen_update = millis(); // update time since last activity } } else { return; } } void ISEDisplay::updateDateTimeText(rtctime_t time) { if (!this->takeSerialMutex()) return; // Send the time to the display this->displayAdapter->printf("time.txt=\"%02d:%02d\"", time.hours, time.minutes); this->sendStopBytes(); this->displayAdapter->printf("date.txt=\"%02d.%02d.%d\"", time.day, time.month, time.year); this->sendStopBytes(); this->giveSerialMutex(); } // TODO : Implement // user remote var // appdeamon void ISEDisplay::updateWeather(char *weather_string) { // TODO : use remotevar to get weather data from appdaemon and update the display u_int8_t weather_code = 68; if (strcmp(weather_string, "fair_day") == 0) { weather_code = 63; } else if (strcmp(weather_string, "sunny") == 0) { weather_code = 63; } else if (strcmp(weather_string, "fair_night") == 0) { weather_code = 64; } else if (strcmp(weather_string, "cloudy") == 0) { weather_code = 65; } else if (strcmp(weather_string, "clear-day") == 0) { weather_code = 66; } else if (strcmp(weather_string, "clear-night") == 0) { weather_code = 67; } else if (strcmp(weather_string, "partlycloudy_day") == 0) { weather_code = 68; } else if (strcmp(weather_string, "partlycloudy") == 0) { weather_code = 68; } else if (strcmp(weather_string, "partlycloudy_night") == 0) { weather_code = 69; } else if (strcmp(weather_string, "heavyrain") == 0) { weather_code = 70; } else if (strcmp(weather_string, "heavyrainandthunder") == 0) { weather_code = 71; } else if (strcmp(weather_string, "rainandthunder") == 0) { weather_code = 72; } else if (strcmp(weather_string, "rain") == 0) { weather_code = 73; } else if (strcmp(weather_string, "rainy") == 0) { weather_code = 73; } else if (strcmp(weather_string, "lightrain") == 0) { weather_code = 74; } else if (strcmp(weather_string, "fog") == 0) { weather_code = 75; } else { weather_code = 68; } ESP_LOGI("ISEDisplay", "Updating weather to: %s (%d)", weather_string, weather_code); if (!this->takeSerialMutex()) return; this->displayAdapter->printf("weather_icon.pic=%d", weather_code); this->sendStopBytes(); this->giveSerialMutex(); } void ISEDisplay::updateTempOutside(float temp_outside) { // TODO : use remotevar to get PM2.5 data from appdaemon and update the display // change temp_outside to int then display u_int8_t temp_outside_int = (u_int8_t)temp_outside; ESP_LOGI("ISEDisplay", "Updating temperature outside to: %d", temp_outside_int); if (!this->takeSerialMutex()) return; this->displayAdapter->printf("outside_temp.txt=\"%d\"", temp_outside_int); this->sendStopBytes(); this->giveSerialMutex(); } void ISEDisplay::updatePMoutside(u_int16_t pm25_outside) { ESP_LOGI("ISEDisplay", "Updating PM2.5 outside to: %d", pm25_outside); u_int16_t curPage = this->currentPage; if (curPage == 2) { if (!this->takeSerialMutex()) return; this->displayAdapter->printf("pm_out.txt=\"%d\"", pm25_outside); this->sendStopBytes(); this->giveSerialMutex(); } // TODO : use remotevar to get PM2.5 data from appdaemon and update the display } void ISEDisplay::updatePMinside(u_int16_t pm25_inside) { // TODO : get data from HA's Xiaomi air purifier sensor ESP_LOGI("ISEDisplay", "Updating PM2.5 inside to: %d", pm25_inside); u_int16_t curPage = this->currentPage; if (curPage == 2) { if (!this->takeSerialMutex()) return; this->displayAdapter->printf("pm_in.txt=\"%d\"", pm25_inside); this->sendStopBytes(); this->giveSerialMutex(); } } void ISEDisplay::setPMstate(bool is_pm_on, uint8_t pm_fan_speed) { ESP_LOGI("ISEDisplay", "Setting PM state: %d, fan speed: %d", is_pm_on, pm_fan_speed); char buffer[4]; itoa(pm_fan_speed, buffer, DEC); remote_pm_fan_speed->setValue(buffer); pm_switch->setValue(is_pm_on ? "1" : "0"); } void ISEDisplay::setACstate(uint8_t ac_fan_speed, uint8_t ac_mode, uint8_t ac_temperature) { ESP_LOGI("ISEDisplay", "Setting AC state: = fan speed: %d, mode: %d, temperature: %d", ac_fan_speed, ac_mode, ac_temperature); //this->climateCard->setFanSpeed(ac_fan_speed); ESP_LOGI("ISEDisplay", "AC fan speed set to: %d", ac_fan_speed); //this->climateCard->setMode(ac_mode); ESP_LOGI("ISEDisplay", "AC mode set to: %d", ac_mode); //this->climateCard->setTemperature(ac_temperature); ESP_LOGI("ISEDisplay", "AC temperature set to: %d", ac_temperature); this->climateCard->setState(ac_mode, ac_fan_speed, ac_temperature); // updateACState(); } void ISEDisplay::toggleLightGroupState() { // Get the current group state bool state = calculateLightGroupState(); ESP_LOGI("ISEDisplay", "Current light group state: %d", state); // Toggle light for (uint8_t i = 1; i <= 4; i++) { setLightLevel(i, state ? 0 : 3); } } void ISEDisplay::toggleLightGroupStateStandby() { // Get the current group state bool state = calculateLightGroupState(); ESP_LOGI("ISEDisplay", "Current light group state: %d", state); // Toggle light for (uint8_t i = 1; i <= 4; i++) { setLightLevel(i, state ? 0 : 3); } // updateLightGroupStatePageStandby(); } void ISEDisplay::togglePM() { // Get the current group state bool state = strcmp(pm_switch->getValue(), "on") == 0; ESP_LOGI("ISEDisplay", "Current PM state: %d", state); // Toggle the state pm_switch->setValue(state ? "off" : "on"); ESP_LOGI("ISEDisplay", "New PM state: %d", state); //updateAirPurifierState(); } void ISEDisplay::togglePMStandby() { // Get the current group state bool state = strcmp(pm_switch->getValue(), "on") == 0; ESP_LOGI("ISEDisplay", "Current PM state: %d", state); // Toggle the state pm_switch->setValue(state ? "off" : "on"); ESP_LOGI("ISEDisplay", "New PM state: %d", state); //updateAirPurifierStateStandby(); } void ISEDisplay::toggleAC() { // Get the current group state uint8_t mode = this->climateCard->getMode(); // get fan speed and temperature uint8_t fan_speed = this->climateCard->getFanSpeed(); uint8_t temperature = this->climateCard->getTemperature(); ESP_LOGI("ISEDisplay", "Current AC mode: %d", mode); // Toggle the state if (mode == 0) { ESP_LOGI("ISEDisplay", " User mode: %d", user_mode); setACstate(fan_speed, user_mode, temperature); } else { ESP_LOGI("ISEDisplay", "User mode BEFORE: %d", user_mode); // update user mode to new mode user_mode = mode; // change actual mode to off ESP_LOGI("ISEDisplay", "User mode AFTER: %d", user_mode); setACstate(fan_speed, 0, temperature); } } void ISEDisplay::changeUserACmode() { // Get the current group state uint8_t mode = this->climateCard->getMode(); ESP_LOGI("ISEDisplay", "Current actual AC mode: %d", mode); // Toggle the state // user mode alternate between 1 and 2 ESP_LOGI("ISEDisplay", "User mode BEFORE: %d", user_mode); user_mode = (user_mode) % 2 + 1; ESP_LOGI("ISEDisplay", "User mode AFTER: %d", user_mode); if (mode != 0) { // update mode to new mode mode = user_mode; ESP_LOGI("ISEDisplay", "change actual AC mode to user mode: %d", mode); } else { // ie mode is off // do nothing as the state is keep in user_mode // the mode will change to user_mode when turn on by toggleAC() ESP_LOGI("ISEDisplay", "do nothing; user mode: %d , actual mode: %d", user_mode, mode); } updateuserACmode(); // call to update mode part of the display seperately } void ISEDisplay::setLightLevel(uint8_t row, uint8_t level) { // Set the light level // this->outputCard->setValue(row, level); uint8_t primary_pin = *(light_array + 2*(row - 1)); uint8_t secondary_pin = *(light_array + 2*(row - 1) + 1); bool primary = false; bool secondary = false; switch (level) { case 0: primary = false; secondary = false; break; case 1: primary = false; secondary = true; break; case 2: primary = true; secondary = false; break; case 3: primary = true; secondary = true; break; default: break; } this->outputCard->setState(primary_pin, primary); this->outputCard->setState(secondary_pin, secondary); } u_int8_t ISEDisplay::getLightLevel(uint8_t row) { u_int8_t lightLevel = 0; //lightLevel = this->outputCard->getValue(row); uint8_t primary_pin = *(light_array + 2*(row - 1)); uint8_t secondary_pin = *(light_array + 2*(row - 1) + 1); bool primary = this->outputCard->getState(primary_pin); bool secondary = this->outputCard->getState(secondary_pin); if (primary && secondary) { lightLevel = 3; } else if (primary) { lightLevel = 2; } else if (secondary) { lightLevel = 1; } else { lightLevel = 0; } return lightLevel; } //change to light with the assignment lightPosition ISEDisplay::getRowCol(uint8_t pin){ lightPosition position; //uint8_t row = this->row; //uint8_t column = this->column; //const uint8_t *light_array = this->light_array; // should return the row and column of the light from pin in a row by column array pointer pass from main using pointer arithmetic for (uint8_t i = 0; i < row*column; i++) { uint8_t value = *(light_array + i); if (value == pin) { position.row = i / column; position.column = i % column; return position; } } return position; } void ISEDisplay::updateLightGroupStatePageStandby() { // Calculate the state bool state = calculateLightGroupState(); // Send the state to the display if (!this->takeSerialMutex()) return; this->displayAdapter->print("s_light_toggle.pic="); this->displayAdapter->print(state ? COMPONENT_STANDBY_LIGHT_PIC_ON : COMPONENT_STANDBY_LIGHT_PIC_OFF); this->sendStopBytes(); this->displayAdapter->print("s_light_toggle.pic2="); this->displayAdapter->print(state ? COMPONENT_STANDBY_LIGHT_PIC_ON_PRESSED : COMPONENT_STANDBY_LIGHT_PIC_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); } void ISEDisplay::updateLightGroupStatePageDashboard() { // Calculate the state bool state = calculateLightGroupState(); // Send the state to the display if (!this->takeSerialMutex()) return; this->displayAdapter->print("light_master.pic="); this->displayAdapter->print(state ? COMPONENT_LIGHT_MASTER_ON : COMPONENT_LIGHT_MASTER_OFF); this->sendStopBytes(); this->displayAdapter->print("light_master.pic2="); this->displayAdapter->print(state ? COMPONENT_LIGHT_MASTER_ON_PRESSED : COMPONENT_LIGHT_MASTER_OFF_PRESSED); this->sendStopBytes(); for (uint8_t i = 1; i <= 4; i++) { u_int8_t state = getLightLevel(i); switch (state) { case 0: this->displayAdapter->print("light_row"); this->displayAdapter->print(i); this->displayAdapter->print(".pic="); this->displayAdapter->print(COMPONENT_LIGHT_LEVEL_0); this->sendStopBytes(); break; case 1: this->displayAdapter->print("light_row"); this->displayAdapter->print(i); this->displayAdapter->print(".pic="); this->displayAdapter->print(COMPONENT_LIGHT_LEVEL_1); this->sendStopBytes(); break; case 2: this->displayAdapter->print("light_row"); this->displayAdapter->print(i); this->displayAdapter->print(".pic="); this->displayAdapter->print(COMPONENT_LIGHT_LEVEL_2); this->sendStopBytes(); break; case 3: this->displayAdapter->print("light_row"); this->displayAdapter->print(i); this->displayAdapter->print(".pic="); this->displayAdapter->print(COMPONENT_LIGHT_LEVEL_3); this->sendStopBytes(); break; default: break; } } this->giveSerialMutex(); } bool ISEDisplay::calculateLightGroupState() { // Check if all lights are on bool lightOn = false; for (uint8_t i = 1; i <= 4; i++) { if (getLightLevel(i) != 0) { lightOn = true; break; } } return lightOn; } void ISEDisplay::toggleLightIndividual(uint8_t row) { // Get the current state uint8_t state = getLightLevel(row); if (state != 0) { state = 0; } else { state = 3; } // Set the state setLightLevel(row, state); } void ISEDisplay::toggleSliderLight(uint8_t row, uint8_t lightLevel) { // Get the current state uint8_t state = 0; if (lightLevel < 10) { state = 0; } else if (lightLevel < 33) { state = 1; } else if (lightLevel <= 66) { state = 2; } else if (lightLevel > 66) { state = 3; } else { state = 0; } // Set the state setLightLevel(row, state); } void ISEDisplay::updateAirPurifierStateStandby() { // Get the state bool state = strcmp(pm_switch->getValue(), "on") == 0; // Send the state to the display if (!this->takeSerialMutex()) return; this->displayAdapter->print("s_pm_toggle.pic="); this->displayAdapter->print(state ? COMPONENT_STANDBY_PM_PIC_ON : COMPONENT_STANDBY_PM_PIC_OFF); this->sendStopBytes(); this->displayAdapter->print("s_pm_toggle.pic2="); this->displayAdapter->print(state ? COMPONENT_STANDBY_PM_PIC_ON_PRESSED : COMPONENT_STANDBY_PM_PIC_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); } void ISEDisplay::updateAirPurifierState() { //check for page if(currentPage == PAGE_DASHBOARD){ ESP_LOGI("ISEDisplay", "Updating dashboard"); // Get the state bool state = strcmp(pm_switch->getValue(), "on") == 0; ESP_LOGI("ISEDisplay", "Updating air purifier state to: %d", state); pm_fan_speed = (int) atof(remote_pm_fan_speed->getValue()); // Send the state to the display if (!this->takeSerialMutex()) return; this->displayAdapter->print("pm_sw.pic="); this->displayAdapter->print(state ? COMPONENT_PM_TOGGLE_PIC_ON : COMPONENT_PM_TOGGLE_PIC_OFF); this->sendStopBytes(); this->displayAdapter->print("pm_sw.pic2="); this->displayAdapter->print(state ? COMPONENT_PM_TOGGLE_PIC_ON_PRESSED : COMPONENT_PM_TOGGLE_PIC_OFF_PRESSED); this->sendStopBytes(); this->displayAdapter->print("pm_speed.val="); this->displayAdapter->print(pm_fan_speed); // this->displayAdapter->print("\""); this->sendStopBytes(); this->displayAdapter->print("pm_speed.pco="); this->displayAdapter->print(state ? 34486 : 33841); this->sendStopBytes(); this->giveSerialMutex(); } else if(currentPage == PAGE_STANDBY){ ESP_LOGI("ISEDisplay", "Updating standby"); updateAirPurifierStateStandby(); } } void ISEDisplay::handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature) { ESP_LOGI("ISEDisplay", "AC state changed: mode: %d, fan speed: %d, temperature: %d", mode, fan_speed, temperature); updateACState(); } void ISEDisplay::updateuserACmode() { if (!this->takeSerialMutex()) return; ESP_LOGI("ISEDisplay", "updating display user AC mode to: %d", user_mode); switch (user_mode) { case 1: this->displayAdapter->print("ac_mode.pic="); this->displayAdapter->print(COMPONENT_AC_MODE_COOL_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_mode.pic2="); this->displayAdapter->print(COMPONENT_AC_MODE_COOL_PIC_PRESSED); this->sendStopBytes(); break; case 2: this->displayAdapter->print("ac_mode.pic="); this->displayAdapter->print(COMPONENT_AC_MODE_FAN_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_mode.pic2="); this->displayAdapter->print(COMPONENT_AC_MODE_FAN_PIC_PRESSED); this->sendStopBytes(); break; default: break; } this->giveSerialMutex(); } void ISEDisplay::updateACfanSpeed() { uint8_t fan_speed = this->climateCard->getFanSpeed(); ESP_LOGI("ISEDisplay", "updating display AC fan speed to: %d", fan_speed); if (!this->takeSerialMutex()) return; switch (fan_speed) { case 0: this->displayAdapter->print("ac_speed.pic="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_AUTO_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_speed.pic2="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_AUTO_PIC_PRESSED); this->sendStopBytes(); break; case 1: this->displayAdapter->print("ac_speed.pic="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_HIGH_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_speed.pic2="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_HIGH_PIC_PRESSED); this->sendStopBytes(); break; case 2: this->displayAdapter->print("ac_speed.pic="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_MID_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_speed.pic2="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_MID_PIC_PRESSED); this->sendStopBytes(); break; case 3: this->displayAdapter->print("ac_speed.pic="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_LOW_PIC); this->sendStopBytes(); this->displayAdapter->print("ac_speed.pic2="); this->displayAdapter->print(COMPONENT_AC_FAN_MODE_LOW_PIC_PRESSED); this->sendStopBytes(); break; default: break; } this->giveSerialMutex(); } void ISEDisplay::updateACState() { // TODOlater : The cognitive complexity here is so high, maybe break up the method a bit? // Get the state uint8_t mode = this->climateCard->getMode(); uint8_t temperature = this->climateCard->getTemperature(); if(currentPage != 1){ if (!this->takeSerialMutex()) return; // Send the state to the display if (mode == 0) { this->displayAdapter->print("ac_temp.pco="); this->displayAdapter->print(33841); this->sendStopBytes(); this->displayAdapter->print("ac_temp.pic="); this->displayAdapter->print(COMPONENT_AC_STATUS_OFF); this->sendStopBytes(); } else { this->displayAdapter->print("ac_temp.pco="); this->displayAdapter->print(34486); this->sendStopBytes(); this->displayAdapter->print("ac_temp.pic="); this->displayAdapter->print(COMPONENT_AC_STATUS_ON); this->sendStopBytes(); user_mode = mode; } this->displayAdapter->print("ac_sw.pic="); this->displayAdapter->print(mode != 0 ? COMPONENT_AC_TOGGLE_PIC_ON : COMPONENT_AC_TOGGLE_PIC_OFF); this->sendStopBytes(); this->displayAdapter->print("ac_sw.pic2="); this->displayAdapter->print(mode != 0 ? COMPONENT_AC_TOGGLE_PIC_ON_PRESSED : COMPONENT_AC_TOGGLE_PIC_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); updateuserACmode(); updateACfanSpeed(); if (!this->takeSerialMutex()) return; this->displayAdapter->print("ac_temp.val="); this->displayAdapter->print(temperature); // this->displayAdapter->print("\""); this->sendStopBytes(); this->giveSerialMutex(); } else if (currentPage == 1) { if (!this->takeSerialMutex()) return; this->displayAdapter->print("s_ac_toggle.pic="); this->displayAdapter->print(mode != 0 ? COMPONENT_STANDBY_AC_PIC_ON : COMPONENT_STANDBY_AC_PIC_OFF); this->sendStopBytes(); this->displayAdapter->print("s_ac_toggle.pic2="); this->displayAdapter->print(mode != 0 ? COMPONENT_STANDBY_AC_PIC_ON_PRESSED : COMPONENT_STANDBY_AC_PIC_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); } ESP_LOGI("ISEDisplay", "display AC state updated"); }