diff --git a/ise-display/ise-display-prod.HMI b/ise-display/ise-display-prod.HMI index 75f51bd..ac9122b 100644 Binary files a/ise-display/ise-display-prod.HMI and b/ise-display/ise-display-prod.HMI differ diff --git a/src/codebook.txt b/src/codebook.txt index 419126f..c7c6996 100644 --- a/src/codebook.txt +++ b/src/codebook.txt @@ -31,9 +31,9 @@ object id: 3 s_light_toggle 4 s_ac_toggle 5 s_pm_toggle -6 s_time (txt) -7 s_date (txt) -8 s_outside_temp (txt) +6 s_time (txt) -> date +7 s_date (txt) -> time +8 s_outside_temp (txt) -> outside_temp 9 idle_timer (timer) // wait one min for inactivity then dim screen 10 s_weather_icon (pic) diff --git a/src/ise_display.cpp b/src/ise_display.cpp index af60c80..95e443f 100644 --- a/src/ise_display.cpp +++ b/src/ise_display.cpp @@ -5,7 +5,6 @@ ISEDisplay::ISEDisplay(HardwareSerial *adapter) : ESPMegaDisplay(adapter, 115200 // Work left // TODO : Implement // debug to work -// appdeamon send data / receive data void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCard, ClimateCard *climateCard) { @@ -24,7 +23,7 @@ void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCar 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); + this->jumpToPage(1); // change this back later to 2 delay(100); this->updateAirPurifierState(); this->updateACState(); @@ -50,6 +49,7 @@ void ISEDisplay::loop() 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); if (page == PAGE_STANDBY) { switch (component) @@ -68,7 +68,7 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type break; // TODO : So this does nothing? Shouldn't it turn on the lights? // should turn it on now - toggleLightGroupState(); + 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 @@ -106,7 +106,30 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type 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; @@ -169,21 +192,24 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type // 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 this->climateCard->setFanSpeed((fan_speed + 1) % 4); + 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; - this->outputCard->setState(5, !this->outputCard->getState(5)); + togglePM(); break; case COMPONENT_PM_FAN_SPEED_DECREASE: if (touch_type != TOUCH_TYPE_RELEASE) @@ -191,6 +217,7 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type pm_fan_speed = this->outputCard->getValue(6); if (pm_fan_speed >= 0 && pm_fan_speed <= 20) this->outputCard->setValue(5, (pm_fan_speed - 1)); + updateAirPurifierState(); break; case COMPONENT_PM_FAN_SPEED_INCREASE: if (touch_type != TOUCH_TYPE_RELEASE) @@ -198,6 +225,7 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type pm_fan_speed = this->outputCard->getValue(6); if (pm_fan_speed >= 0 && pm_fan_speed <= 20) this->outputCard->setValue(5, (pm_fan_speed + 1)); + updateAirPurifierState(); break; default: break; @@ -220,14 +248,13 @@ void ISEDisplay::handlePWMChange(uint8_t pin, bool state, uint16_t value) if (pin >= 1 && pin <= 4) { // Light - updateLightGroupStatePageDashboard(); updateLightGroupStatePageStandby(); time_since_last_screen_update = millis(); // update time since last activity } else if (pin == 4 || pin == 5) { // Air Purifier - updateAirPurifierState(); + updateAirPurifierStateStandby(); time_since_last_screen_update = millis(); // update time since last activity } } @@ -236,7 +263,7 @@ void ISEDisplay::handlePWMChange(uint8_t pin, bool state, uint16_t value) if (pin >= 1 && pin <= 4) { // Light - updateLightGroupStatePageStandby(); + updateLightGroupStatePageDashboard(); time_since_last_screen_update = millis(); // update time since last activity } else if (pin == 4 || pin == 5) @@ -256,16 +283,10 @@ void ISEDisplay::updateDateTimeText(rtctime_t time) this->takeSerialMutex(); // Send the time to the display - this->displayAdapter->printf("time.txt=%02d:%02d", time.hours, time.minutes); + 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->displayAdapter->printf("s_time.txt=%02d:%02d", time.hours, time.minutes); - this->sendStopBytes(); - - this->displayAdapter->printf("s_date.txt=%02d.%02d.%d", time.day, time.month, time.year); + this->displayAdapter->printf("date.txt=\"%02d.%02d.%d\"", time.day, time.month, time.year); this->sendStopBytes(); this->giveSerialMutex(); @@ -344,17 +365,17 @@ 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 + // change temp_outside to int then display u_int8_t temp_outside_int = (u_int8_t)temp_outside; this->takeSerialMutex(); - this->displayAdapter->printf("temp_outside.txt=%d", temp_outside_int); + this->displayAdapter->printf("temp_outside.txt=\"%d\"", temp_outside_int); this->sendStopBytes(); this->giveSerialMutex(); } void ISEDisplay::updatePMoutside(u_int16_t pm25_outside) { this->takeSerialMutex(); - this->displayAdapter->printf("pm_outside.txt=%d", pm25_outside); + this->displayAdapter->printf("pm_outside.txt=\"%d\"", pm25_outside); this->sendStopBytes(); this->giveSerialMutex(); // TODO : use remotevar to get PM2.5 data from appdaemon and update the display @@ -380,36 +401,73 @@ 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); } + updateLightGroupStatePageDashboard(); +} +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 = this->outputCard->getState(5); + ESP_LOGI("ISEDisplay", "Current PM state: %d", state); // Toggle the state state = !state; // Set the state this->outputCard->setState(5, state); + ESP_LOGI("ISEDisplay", "New PM state: %d", state); + updateAirPurifierState(); +} +void ISEDisplay::togglePMStandby() +{ + // Get the current group state + bool state = this->outputCard->getState(5); + ESP_LOGI("ISEDisplay", "Current PM state: %d", state); + // Toggle the state + state = !state; + // Set the state + this->outputCard->setState(5, state); + 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) { - this->climateCard->setMode(user_mode); + 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 - this->climateCard->setMode(0); + ESP_LOGI("ISEDisplay", "User mode AFTER: %d", user_mode); + setACstate(fan_speed, 0, temperature); } } void ISEDisplay::changeUserACmode() @@ -438,6 +496,7 @@ void ISEDisplay::setLightLevel(uint8_t row, uint8_t level) if (row == i) this->outputCard->setValue(row, level); } + updateLightGroupStatePageDashboard(); } void ISEDisplay::updateLightGroupStatePageStandby() @@ -540,6 +599,8 @@ void ISEDisplay::toggleLightIndividual(uint8_t row) } // Set the state setLightLevel(row, state); + updateLightGroupStatePageDashboard(); + updateLightGroupStatePageStandby(); } void ISEDisplay::toggleSliderLight(uint8_t row, uint8_t lightLevel) { @@ -569,12 +630,29 @@ void ISEDisplay::toggleSliderLight(uint8_t row, uint8_t lightLevel) // Set the state setLightLevel(row, state); } +void ISEDisplay::updateAirPurifierStateStandby() +{ + // Get the state + bool state = this->outputCard->getState(5); + // Send the state to the display + this->takeSerialMutex(); + + 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() { // Get the state bool state = this->outputCard->getState(5); - uint8_t fan_speed = this->outputCard->getState(5); + uint8_t fan_speed = this->outputCard->getState(6); // Send the state to the display this->takeSerialMutex(); diff --git a/src/ise_display.hpp b/src/ise_display.hpp index 5dbe09f..353efac 100644 --- a/src/ise_display.hpp +++ b/src/ise_display.hpp @@ -21,7 +21,7 @@ class ISEDisplay : public ESPMegaDisplay { public: ISEDisplay(HardwareSerial* adapter); void begin(DigitalInputCard* inputCard, DigitalOutputCard* outputCard, ClimateCard* climateCard); - + void updateLightGroupStatePageDashboard(); void updateDateTimeText(rtctime_t time); void updateWeather(char *weather_string); void updateTempOutside(float temp_outside); @@ -29,6 +29,8 @@ class ISEDisplay : public ESPMegaDisplay { void updatePMinside(u_int8_t pm25_inside); void loop(); + + private: void handleTouch(uint8_t page, uint8_t component, uint8_t touch_type); @@ -46,18 +48,22 @@ class ISEDisplay : public ESPMegaDisplay { uint8_t time_since_last_screen_update; - - void updateLightGroupStatePageDashboard(); + void updateuserACmode(); + void updateACfanSpeed(); void updateLightGroupStatePageStandby(); void updateAirPurifierState(); + void updateAirPurifierStateStandby(); void updateACState(); + bool calculateLightGroupState(); void toggleLightGroupState(); + void toggleLightGroupStateStandby(); void toggleLightIndividual(uint8_t row); void toggleSliderLight(uint8_t row,uint8_t lightLevel); void togglePM(); + void togglePMStandby(); void toggleAC(); + void toggleACStandby(); void changeUserACmode(); - void updateuserACmode(); - void updateACfanSpeed(); + }; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index fa296a7..9ce7193 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,7 +104,7 @@ void setup() auto bindedGetTime = std::bind(&ESPMegaPRO::getTime, &espmega); iseDisplay.begin(&espmega.inputs, &espmega.outputs, &climateCard); espmega.iot->registerRelativeMqttCallback(&handleMqttMessage); - + iseDisplay.registerPageChangeCallback(&handlePageChange); // placeholder // PM2.5 PPM Remote Variable // 12 bytes remote variable, 11 characters + null terminator @@ -122,10 +122,25 @@ void loop() iseDisplay.loop(); // Update the time every 15 seconds + //static bool run_when_init = false; // No static ? , this shit will reset to 0 every loop static uint32_t last_time_updated = 0; + //rtctime_t time = espmega.getTime(); + //when init update once then update every 15 seconds + // You don't need this, when it go from page 0 to 1 it call handlePageChange + // if(!run_when_init){ + // time = espmega.getTime(); + // iseDisplay.updateDateTimeText(time); + // last_time_updated = millis(); + // run_when_init = true; + // } + + if (millis() - last_time_updated > 15000) { rtctime_t time = espmega.getTime(); + // log time + ESP_LOGI("time", "Time: %d:%d:%d", time.hours, time.minutes, time.seconds); + ESP_LOGI("Date", "Date: %d/%d/%d", time.day, time.month, time.year); iseDisplay.updateDateTimeText(time); last_time_updated = millis(); } @@ -174,4 +189,24 @@ float get_temp_out() // Read temperature from sensor temp_out_value = atof(temp_out.getValue()); return temp_out_value; +} + +void handlePageChange(uint8_t page) { + + // Which already send the time + //printESP_LOGI the page have changed + ESP_LOGI("Page", "Page change to: %d", page); + rtctime_t time = espmega.getTime(); + iseDisplay.updateDateTimeText(time); + iseDisplay.updateLightGroupStatePageDashboard(); + //iseDisplay.updatePMinside(); + /* iseDisplay.updatePMoutside(get_pm25_out()); + iseDisplay.updateWeather(weather.getValue()); + iseDisplay.updateTempOutside(get_temp_out()); */ + /* iseDisplay.updateACState(); + iseDisplay.updateAirPurifierState(); + iseDisplay.updateLightGroupStatePageStandby(); + iseDisplay.updateLightGroupStatePageDashboard(); + iseDisplay.updateuserACmode(); + iseDisplay.updateAirPurifierStateStandby(); */ } \ No newline at end of file diff --git a/src/main.hpp b/src/main.hpp index df1e403..2100941 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -24,6 +24,7 @@ SET_LOOP_TASK_STACK_SIZE(32*1024); void handleMqttMessage(char *topic, char *payload); void subscribeToMqttTopics(); +void handlePageChange(uint8_t page); void sendStopBytes(); void sendExtStopBytes();