From 2eb06c1c25508853e3f0b1e0256fd7c2f8b3d852 Mon Sep 17 00:00:00 2001 From: reaw55 <58457329+reaw55@users.noreply.github.com> Date: Sat, 6 Apr 2024 04:06:17 +0700 Subject: [PATCH] complied now --- .../main/light/light-button-off-prressed.png | Bin 4635 -> 5785 bytes .../images/main/light/light-button-off.png | Bin 3305 -> 4045 bytes .../main/light/light-button-on-pressed.png | Bin 4979 -> 6117 bytes .../images/main/light/light-button-on.png | Bin 4094 -> 5327 bytes .../master-light-button-off-pressed.png | Bin 2312 -> 2350 bytes .../master-light/master-light-button-off.png | Bin 2528 -> 2552 bytes .../master-light/master-light-button-on.png | Bin 4444 -> 4485 bytes .../master-light-button-pressed.png | Bin 1579 -> 1601 bytes .../toggle-all/toggle-all-off-pressed.png | Bin 12253 -> 13029 bytes .../main/toggle-all/toggle-all-on-pressed.png | Bin 12857 -> 13767 bytes src/ise_display.cpp | 967 +++++++++++------- src/ise_display.hpp | 21 +- src/ise_display_definitions.hpp | 524 +++++++--- src/main.cpp | 89 +- src/main.hpp | 6 + 15 files changed, 1091 insertions(+), 516 deletions(-) diff --git a/ise-display/images/main/light/light-button-off-prressed.png b/ise-display/images/main/light/light-button-off-prressed.png index ac98521492a0133b6cd9f181ee0310a559cbfdf6..a41755a740aaa300241e7e2b482a9077afe3bbfd 100644 GIT binary patch literal 5785 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 Jt&(Nv{{WGRAkP2* delta 4627 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 JPDHLkV1f;b@^AnE diff --git a/ise-display/images/main/light/light-button-off.png b/ise-display/images/main/light/light-button-off.png index 14c703589582d750f40f3c91cdbac4f90be89bd4..1e9ac7347ad3c2f7a511a852b7eaddbe06829b58 100644 GIT binary patch delta 4033 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 diff --git a/ise-display/images/main/light/light-button-on.png b/ise-display/images/main/light/light-button-on.png index 34703c8b39e44e163f5abf2fc40b8d58c70ca84d..31cc05119a55bc5429b6c5752753b7bbaebe221a 100644 GIT binary patch literal 5327 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 Y7=}HPR-J;O|N2J&NZUxOM#C=ZKih?Ur~m)} delta 4082 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 diff --git a/ise-display/images/main/master-light/master-light-button-off-pressed.png b/ise-display/images/main/master-light/master-light-button-off-pressed.png index 47d7b600c24865e0c8227ed73a27db977daed124..fc2f69e8a527974472613c96a7251aabe52dca3c 100644 GIT binary patch delta 2323 zcmai0X*?4S16C%-&|>Z|gb~WbT;-e`QIUISvneJ+|z`c@hLF1Y{C#*j(k~5$9oJW8T3sa+8p(p;3to#KX!QDg2_rwbe_=+H!@~2;Nn8ykz-?dEyf518BPeWLM zf?P;dNrST6gAqo9uk!;RES(gQoQio0RF& zy(_Bg)imF)z3{0X$Nt52SuBYPJb5N7JLhV|v_V2PI28umd^&&0hDxOlL!&VcX-p=& zd~K9>QbKFq+B>ncIRjp6$Y$wSRmISmZR8l=>qb8t1H{C}q34gmS88@~Jp>Y@0fd?l zUkHNrGM+Mdk%?0)oK&ro!D5+2!u_bnmXdEg)qoS<=DP=` zcPYB!M=mSn+Fx`6>m%0g$^-1X!}h~yYGra!F-%#Irzm=O<+?zsAlWe4cve%$)rV+j z@Qe&C2L6Lp2RA@F(SH6euPn1|<2rYB`q6BEXmPVHvuGs_TOqF z%EJX~JD&V3Y)b0&Ys}ddKad;`>|&6D+nCsN?Y-rxt(6T8O!_Uf`6WL{`JW)I8uzrY zw}Odi`4Fic8t-~>oyt+BwMlYS`3m7O5W9Eoh4uB$bM9L5)=mq)RR_vza?nRv zy(b-10hz9ubF`1d^z>IxQdgC>zY--Idxi0?wdEZpkaC#rSm7^lwk&*m=3iX*CU-|m zJ{fT#T5dRP?O5kb^S8JrM+^e6@^7&6iJk-4n!ca%`UFRI3oyn5pULftQxUI^_2Q6y40K!JE* z%LF+PjJZ7#X%6&4a0`sW&rdq9!j631Yz|!M$y=MKCwMtFaav7$xRZR1yZjt4!(yzi zjO%^VWa}o$sl5_^{xYpnluysV;Ofd^U*?2i4^(10qJKOX0eBmKx;gq8!~rmCR5v3# z-@%{%{-z%?_q6yZm@8~$sm*GrTI$x>-o;IV4vJYNYmPga6L4qH0Oj-RX7sufDSe*OX<#3~t<5<^AuA{-#xwH+Jq{d)5*0qbAsi%m`C#V7w?N2n9 zj^x&g7m`cA99MEyb1-rLsfWOupCqTCp7W-VyqvxKWC{QVZv`e!h5Jiu;--2Z?a>2_ zjjEiw0Lj6obYYl`CizVK&PQAB!7q%uq`{4F;HsvQigUt!p{sVl6Az046<&CJ%rzsr zC55QHC>rb^QHiw#osZhwUh31n;^9*J=!Vu9OV5nYnkP!M#jRggn82%O5@WT{Mh<6f zA@gt+WmII@h)@6bTE5KPw)hd-OM-sWEf%Zm%eR9fAv~!G9LoWplm`%#do$6jCy<+K z%^I20DF-S;*`0ff21mQBa7z$Q(u637)%qde#X{BQaYLc#vnHw1_{*VhG!g)81wvSB zb6mPYd*^Jm0}N02Ik)H3+1GP=LBvuNXJ^sQp)*B4x3r!o+h`@>2tOgLegIF^R(n45 zJ*tsb^|o-Uspaxd?*fM(+r$*>!>)J%aal%FnUvZ|#&<$%sLJ7IR`{)Q2Xr=bwq$*e z4-jHsOuAyq?HRm%(Ao;Q<2ne2{ezdx)d2}x)l)#Y6;(?-$4F z50EuF)i#vnleZ>TEnFM&_6D^ZFWmMnhDkI`1N#G~RnEp{Dad`p-m*rW*X_ z2_GyMhlsw&?cX%0XBAM7njNg)AmU%QgWi}R<|`D1D?4Vk;)4E{AVF8{zk8 z#MH{IF}nphbF7b{9%!Zg76AqQQ+iuv_13ZN`qckRZR~}}Ii9%KTz#hZcIa!5He)gV*2wZ2XglpHZgThO^Q!KGV`W9& oaUli@~ delta 2285 zcmVSXSxo;NW0^ zVo27uF3YxU@40O!#IMLYe~#Px`0+rN zVnl3&5C!lX-66+u@Y}LRuNGe%+Y=;_SRzV+J-Twa{<{{Q{+r{2myQ~D&khZoC#DHH}n;ho?I8M=XKf2)G105iWANUj3 z8XFs@$H)J9N;RS;7J)!Ke>Yd|Va;*_zr+1N0M!<-9ruO^NQLm@fhR&UL?{*)BDaFofC#D7S3GtU zEUS1WN--i6BF-XkL^0Co#F?l%gEmD36XCZwivWakYlaJjE2RjCe?*A3wr~1)Oo*!p zoTcaJwto8LbW;RqPhZ>HJ386n$IT!@5cFfv3AAmi{m`Mq?_a$d8zhZrjS<1PP%3?{ zd3Ll>kV&EQhaw{D^qtWeytTR}c2{*n1iz!UxkLc`yjkpSaNX2x(ug)8E?nri#x9_f z_hdIKfsSV8+__5`f6_#fG{I89n<&;n1YL3Az=0+@cKjrjibWb38K&2-$4E7P@v&6t zfqO;CENMWCMWB+(Q&pYT(9&|;^Wk;rdOCLOB$T!9^Ccd@z4NG zO}(x9vtOS$>pgEddYqm=e?o8GOpq+F3fuPTQ5kgdRQI@*TZHSDuHqOrHtgNI-)l%N z0yuE6sp`+e8aS|))-!FMII{3jLNGg9xV<>kv^PrxACckGmQQ2`<7<45N*DMYCd zY=p}@xiGN-DQS?`ug1Ivl?4L6nVeYjJ2nE36N!X4f2S%ON`SqYE%d7g7?#s8-W$w$4V7fSwvAktP_7$BXDg6Qiy7c z2vw1s66!(P58C3Yt52ElnPN_pUC34xP)rspnNU*Z;aB(6zVWcx{@_aNKP{F zf0u&!O}2GwLg`uxr8E5sg~I%yLx(f$gq!)2D;eItouq?oG%mRQ4Fy5?di0RjOIHzB zPMtdM2@wRJdz5=1-RD?b{^e#LK78;qDMWdPj>U;AGusSi$zgV%3@G$r96^i^a4~qG z6NkW#o;SB1q^C%C;mYt>Dab#6_9Rphe=%@l+#$s%pK|FhL~*86%ymVD^n@^OEdwlI z_%AlXHz7ao32tf2mb%LG;t|!;FSX2lZENee#|{}ZK-hUrb*wmd?))X`vF4c%?(J~vnv9XC|PgW-~3=Erw0b-)2gdhvold7^Pf7u;>(d(ilpy@Ae}Y(HTo@EwSG zj6yEge}pukaqg?z%Y(McHPdKdm5sa}!tMoKqzP@+*TF$=i-jy-Lc3YPx#JqJFka^_ z1zOACmX-J(i#!nMgzXnL1^%*MfA72t*qwkhqP2C##|zV}gSWt*eybvIM+vL|S(0xJ z<*r=r&-cj~)&DM4E|Ygf5*<^!h9Mmt0^hS$d9E zp2dYowuFd82uxv5r|l~k!HcsP%Xc66e4Qe~YynZB)>}YCI(cAlFv~8`f3u7)ZYmDh z6tbhBJHplv|LILpg0P*R?NFaHKL||ffdj4jg3d{G7*s8wqo?luj%Nq48L!X@*Z3S zR8wuc^j$9Z$L~}_Vw1Wse^+&tolakHFIRtWzw(zIE@j}uwpfVBcfRy-v#gTZGc?q% zwWC%ovCAPZUhKGBF1tPK)H1=>xgh@0+c{>%?MD5hU1@ZCh4J%v3BZYM&kCt7vxuv# zJ+FzPY#a>VQntQ6c`L5FBFDFj8vw(v3k%L^$8j@QAi@G`LuD;SL$mPK0&DbXOmt%< z_&iGlunXD!&9Ei4!C){L3fhR-m(77J<00000NkvXX Hu0mjf*3VL# diff --git a/ise-display/images/main/master-light/master-light-button-off.png b/ise-display/images/main/master-light/master-light-button-off.png index 59130a93c2dda730f068425eac6989620c52756d..e3528e005b0afc1f11a62ce992093507cefd25f0 100644 GIT binary patch delta 2527 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 delta 2503 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 Z{|8}&w+Jm(2%Z1{002ovPDHLkV1hBpiXZ?0 diff --git a/ise-display/images/main/master-light/master-light-button-pressed.png b/ise-display/images/main/master-light/master-light-button-pressed.png index 9fe992085b92b6e439af77a6b665e6e530de6472..5cce401c67328a72e4b36553becdff280240ed5c 100644 GIT binary patch delta 1568 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 literal 12857 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 = row; this->column = column; } -// Work left -// TODO : Implement -// debug to work -void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCard, ClimateCard *climateCard_daikin, ClimateCard *climateCard_york, RemoteVariable* pm_switch, RemoteVariable* pm_fan_speed) +void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCard, ClimateCard *climateCard_daikin, ClimateCard *climateCard_york, RemoteVariable *pm_switch, RemoteVariable *pm_fan_speed, RemoteVariable *ac_lock, RemoteVariable *pm_lock) { this->inputCard = inputCard; this->outputCard = outputCard; this->climateCard_daikin = climateCard_daikin; this->climateCard_york = climateCard_york; this->pm_switch = pm_switch; + this->pm_lock = pm_lock; + this->ac_lock = ac_lock; 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_daikin->registerChangeCallback(bindedHandleACChange); - //this->climateCallbackHandle = this->climateCard_york->registerChangeCallback(bindedHandleACChange); - this->user_mode = 2; // initialized to cool by default + // this->climateCallbackHandle = this->climateCard_york->registerChangeCallback(bindedHandleACChange); + this->user_mode = 2; // initialized to cool by default + this->ac_lock_state = strcmp(ac_lock->getValue(), "on") == 0;// initialized to get value + this->pm_lock_state = strcmp(pm_lock->getValue(), "on") == 0; // initialized to get value this->pm_fan_speed = 10; - //remote_pm_fan_speed->setValue(pm_fan_speed); + // remote_pm_fan_speed->setValue(pm_fan_speed); this->ac_fan_speed = 0; this->ac_mode = 0; this->ac_temperature = 25; @@ -33,31 +34,24 @@ void ISEDisplay::begin(DigitalInputCard *inputCard, DigitalOutputCard *outputCar this->lightLevelRow2 = 0; this->lightLevelRow3 = 0; this->lightLevelRow4 = 0; + this->time_since_last_ac_change = 0; + this->ac_press_pending = false; // 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->updateSystemtoggle(); 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_daikin->setState(ac_mode, ac_fan_speed, ac_temperature); - if(ac_mode == 3){ - this->climateCard_york->setState(0, ac_fan_speed, ac_temperature); - } - else{ - this->climateCard_york->setState(ac_mode, ac_fan_speed, ac_temperature); + // intialize AC state + if(ac_lock_state == false) + { + setACstate(ac_fan_speed, ac_mode, ac_temperature); // default to off with temp 25 and fan on Auto } } @@ -67,55 +61,82 @@ void ISEDisplay::loop() // If there is data, process the data recieveSerialCommand(); - // Update the time since the last screen update using millis() + // Check if the AC state has been changed + if (ac_press_pending && (millis() - time_since_last_ac_change) > 5000) + { + sendACIRcode(); + ac_press_pending = false; + } - // u_int32_t current_time = millis(); + // Check if the MQTT connection has been lost + static uint32_t last_mqtt_connected_check = 0; + if (last_mqtt_connected_check == 0) + { + last_mqtt_connected_check = millis() + 15000; // Wait 15 seconds before checking + } + static bool first_disconnect = true; + if (millis() - last_mqtt_connected_check > 3000) + { + ESP_LOGD("ISE Display", "Checking MQTT Connection, Connection is %s", this->cards.iot->mqttConnected() ? "true" : "false"); + if (!this->iot->mqttConnected()) + + { + + if (first_disconnect) + { + // When MQTT is disconnected, enter standalone mode + // A/C lock is lifted + // PM lock are lifted + this->ac_lock_state = false; + this->pm_lock_state = false; + first_disconnect = false; + } + } + else + { + if (first_disconnect == false) + { + // When MQTT is connected, exit standalone mode + // In standalone mode, socket contactor is turned off + // A/C lock is set - // 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"); - // } - // } + first_disconnect = true; + this->ac_lock_state = strcmp(ac_lock->getValue(), "on") == 0; + this->pm_lock_state = strcmp(pm_lock->getValue(), "on") == 0; + updateACState(); + updateAirPurifierState(); + } + } + last_mqtt_connected_check = millis(); + } } 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: + case COMPONENT_OBJ_STANDBY_BTN_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(); + allOn(); this->jumpToPage(2); // the function of the button is to open the dashboard from standby break; - case COMPONENT_STANDBY_LIGHT_TOGGLE: + case COMPONENT_OBJ_STANDBY_BTN_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? + case COMPONENT_OBJ_STANDBY_BTN_AC_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleAC(); - break; - case COMPONENT_STANDBY_PM_TOGGLE: + case COMPONENT_OBJ_STANDBY_BTN_PM_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; togglePMStandby(); @@ -124,151 +145,226 @@ void ISEDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t touch_type 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. + case COMPONENT_OBJ_DASHBOARD_NUM_AC_TEMP: + break; + case COMPONENT_OBJ_DASHBOARD_BTN_AC_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; - toggleLightGroupState(); + //if ac_lock is true do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + break; + toggleAC(); break; - // TODOlater : can't this be done better with array lookup? - case COMPONENT_LIGHT_MASTER_LEVEL1_TOUCHPOINT: + case COMPONENT_OBJ_DASHBOARD_BTN_AC_MODE: if (touch_type != TOUCH_TYPE_RELEASE) break; - for (uint8_t i = 1; i <= 4; i++) - { - setLightLevel(i, 1); - } + //if ac_lock is true do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + break; + changeUserACmode(); break; - case COMPONENT_LIGHT_MASTER_LEVEL2_TOUCHPOINT: + case COMPONENT_OBJ_DASHBOARD_BTN_AC_FAN_SPEED: if (touch_type != TOUCH_TYPE_RELEASE) break; - for (uint8_t i = 1; i <= 4; i++) - { - setLightLevel(i, 2); - } + //if ac_lock is true do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + break; + ac_fan_speed = this->climateCard_daikin->getFanSpeed(); + // mode= auto, high, mid, low + 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); + setACstate(ac_fan_speed, ac_mode, ac_temperature); break; - case COMPONENT_LIGHT_MASTER_LEVEL3_TOUCHPOINT: + case COMPONENT_OBJ_DASHBOARD_BTN_AC_TEMP_MINUS: if (touch_type != TOUCH_TYPE_RELEASE) break; - for (uint8_t i = 1; i <= 4; i++) - { - setLightLevel(i, 3); - } + //if ac_lock is true do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + break; + ac_temperature = this->climateCard_daikin->getTemperature() - 1; + setACstate(ac_fan_speed, ac_mode, ac_temperature); break; - case COMPONENT_LIGHT_ROW1_SLIDER: + case COMPONENT_OBJ_DASHBOARD_BTN_AC_TEMP_PLUS: if (touch_type != TOUCH_TYPE_RELEASE) break; - lightLevelRow1 = this->getNumber("light_r1_slide.val"); - toggleSliderLight(1, lightLevelRow1); + //if ac_lock is true do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + break; + ac_temperature = this->climateCard_daikin->getTemperature() + 1; + setACstate(ac_fan_speed, ac_mode, ac_temperature); break; - case COMPONENT_LIGHT_ROW2_SLIDER: + case COMPONENT_OBJ_DASHBOARD_BTN_PM_TOGGLE: 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) + //if pm_lock is true do nothing + if (strcmp(pm_lock->getValue(), "on") == 0) + ESP_LOGI("ISEDisplay", "PM lock is on, do nothing"); break; - lightLevelRow3 = this->getNumber("light_r3_slide.val"); - toggleSliderLight(3, lightLevelRow3); + togglePM(); break; - case COMPONENT_LIGHT_ROW4_SLIDER: - if (touch_type != TOUCH_TYPE_RELEASE) - break; - lightLevelRow4 = this->getNumber("light_r4_slide.val"); - toggleSliderLight(4, lightLevelRow4); + case COMPONENT_OBJ_DASHBOARD_TXT_PM_INSIDE: break; - case COMPONENT_LIGHT_ROW1_SWITCH: + case COMPONENT_OBJ_DASHBOARD_TXT_PM_OUTSIDE: + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW1: + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW2: + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW3: + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW4: + break; + case COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW1: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(1); break; - case COMPONENT_LIGHT_ROW2_SWITCH: + case COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW2: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(2); break; - case COMPONENT_LIGHT_ROW3_SWITCH: + case COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW3: if (touch_type != TOUCH_TYPE_RELEASE) break; toggleLightIndividual(3); break; - case COMPONENT_LIGHT_ROW4_SWITCH: + case COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW4: 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(); + case COMPONENT_OBJ_DASHBOARD_TIMER_TEN_SEC: break; - case COMPONENT_AC_MODE: - if (touch_type != TOUCH_TYPE_RELEASE) - break; - changeUserACmode(); + case COMPONENT_OBJ_DASHBOARD_VAL_TIME_PAST: break; - case COMPONENT_AC_FAN_SPEED: - if (touch_type != TOUCH_TYPE_RELEASE) - break; - ac_fan_speed = this->climateCard_daikin->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_daikin->setFanSpeed(ac_fan_speed); - this->climateCard_york->setFanSpeed(ac_fan_speed); - // updateACState(); + case COMPONENT_OBJ_DASHBOARD_TIMER_INACTIVE_CHECK: break; - case COMPONENT_AC_TEMP_DOWN_BUTTON: + case COMPONENT_OBJ_DASHBOARD_BTN_SYSTEM_TOGGLE: if (touch_type != TOUCH_TYPE_RELEASE) break; - this->climateCard_daikin->setTemperature(this->climateCard_daikin->getTemperature() - 1); - this->climateCard_york->setTemperature(this->climateCard_daikin->getTemperature()); - // updateACState(); + // implement system toggle + // check light on or off + // check ac on or off + // check pm on or off + toggleSystem(); break; - case COMPONENT_AC_TEMP_UP_BUTTON: + case COMPONENT_OBJ_DASHBOARD_BTN_PM_SPEED: if (touch_type != TOUCH_TYPE_RELEASE) break; - this->climateCard_daikin->setTemperature(this->climateCard_daikin->getTemperature() + 1); - this->climateCard_york->setTemperature(this->climateCard_daikin->getTemperature()); - // updateACState(); + // implement pm speed change break; - case COMPONENT_PM_TOGGLE_BUTTON: + case COMPONENT_OBJ_DASHBOARD_BTN_PM_MODE: if (touch_type != TOUCH_TYPE_RELEASE) break; - togglePM(); + // implement pm mode change 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(); + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_MASTER_LIGHT: break; - case COMPONENT_PM_FAN_SPEED_INCREASE: + case COMPONENT_OBJ_DASHBOARD_LOGO: + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_PM_LOCK: 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(); + // toggle_pm_lock(); + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_AC_LOCK: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + // toggle_ac_lock(); + break; + case COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_MASTER: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + toggleLightGroupState(); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV1: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightGroupState(1); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV2: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightGroupState(2); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV3: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightGroupState(3); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV1: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(1, 1); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV2: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(1, 2); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV3: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(1, 3); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV1: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(2, 1); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV2: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(2, 2); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV3: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(2, 3); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV1: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(3, 1); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV2: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(3, 2); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV3: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(3, 3); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV1: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(4, 1); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV2: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(4, 2); + break; + case COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV3: + if (touch_type != TOUCH_TYPE_RELEASE) + break; + setLightLevel(4, 3); + break; + case COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_C_DEGREE: break; default: break; @@ -286,13 +382,13 @@ void ISEDisplay::handlePWMChange(uint8_t pin, bool state, uint16_t value) // NEED to switch case for different page uint8_t current_page = this->currentPage; - - //uint8_t first_pin = *(light_array); - //uint8_t last_pin = *(light_array + 7); + + // uint8_t first_pin = *(light_array); + // uint8_t last_pin = *(light_array + 7); if (current_page == PAGE_STANDBY) { - if (LIGHT_ROW1_COLUMN1 || LIGHT_ROW1_COLUMN2 || LIGHT_ROW2_COLUMN1 || LIGHT_ROW2_COLUMN2 || LIGHT_ROW3_COLUMN1 || LIGHT_ROW3_COLUMN2 || LIGHT_ROW4_COLUMN1 || LIGHT_ROW4_COLUMN2) //change + if (LIGHT_ROW1_COLUMN1 || LIGHT_ROW1_COLUMN2 || LIGHT_ROW2_COLUMN1 || LIGHT_ROW2_COLUMN2 || LIGHT_ROW3_COLUMN1 || LIGHT_ROW3_COLUMN2 || LIGHT_ROW4_COLUMN1 || LIGHT_ROW4_COLUMN2) // change { // Light updateLightGroupStatePageStandby(); @@ -301,7 +397,7 @@ void ISEDisplay::handlePWMChange(uint8_t pin, bool state, uint16_t value) } else if (current_page == PAGE_DASHBOARD) { - if (LIGHT_ROW1_COLUMN1 || LIGHT_ROW1_COLUMN2 || LIGHT_ROW2_COLUMN1 || LIGHT_ROW2_COLUMN2 || LIGHT_ROW3_COLUMN1 || LIGHT_ROW3_COLUMN2 || LIGHT_ROW4_COLUMN1 || LIGHT_ROW4_COLUMN2) //change + if (LIGHT_ROW1_COLUMN1 || LIGHT_ROW1_COLUMN2 || LIGHT_ROW2_COLUMN1 || LIGHT_ROW2_COLUMN2 || LIGHT_ROW3_COLUMN1 || LIGHT_ROW3_COLUMN2 || LIGHT_ROW4_COLUMN1 || LIGHT_ROW4_COLUMN2) // change { // Light updateLightGroupStatePageDashboard(); @@ -330,100 +426,20 @@ void ISEDisplay::updateDateTimeText(rtctime_t time) // 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); +// void ISEDisplay::updateTempOutside(float temp_outside) +// { +// // TODO : use remotevar to get PM2.5 data from appdaemon and update the display - 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(); -} +// // 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); @@ -459,28 +475,65 @@ void ISEDisplay::setPMstate(bool is_pm_on, uint8_t 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"); + pm_switch->setValue(is_pm_on ? "on" : "off"); +} + +void ISEDisplay::setPMlockstate(bool is_pm_lock_on) +{ + ESP_LOGI("ISEDisplay", "Setting PM lock state: %d", is_pm_lock_on); + pm_lock->setValue(is_pm_lock_on ? "on" : "off"); +} + +void ISEDisplay::setAClockstate(bool is_ac_lock_on) +{ + ESP_LOGI("ISEDisplay", "Setting AC lock state: %d", is_ac_lock_on); + ac_lock->setValue(is_ac_lock_on ? "on" : "off"); } 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); + ESP_LOGI("ISEDisplay", "Setting AC state in memory to: = 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_daikin->setState(ac_mode, ac_fan_speed, ac_temperature); - if(ac_mode == 3){ - this->climateCard_york->setState(0, ac_fan_speed, ac_temperature); - } - else{ - this->climateCard_york->setState(ac_mode, ac_fan_speed, ac_temperature); - } - // updateACState(); + this->ac_fan_speed = ac_fan_speed; + this->ac_mode = ac_mode; + this->ac_temperature = ac_temperature; + this->time_since_last_ac_change = millis(); + this->ac_press_pending = true; + + updateACState(); } +void ISEDisplay::sendACIRcode() +{ + uint8_t cur_ac_fan_speed = this->ac_fan_speed; + uint8_t cur_ac_mode = this->ac_mode; + uint8_t cur_ac_temperature = this->ac_temperature; + uint8_t york_temp = cur_ac_temperature; + // this->climateCard->setFanSpeed(ac_fan_speed); + ESP_LOGI("ISEDisplay", "AC fan speed set to: %d", cur_ac_fan_speed); + // this->climateCard->setMode(ac_mode); + ESP_LOGI("ISEDisplay", "AC mode set to: %d", cur_ac_mode); + // this->climateCard->setTemperature(ac_temperature); + ESP_LOGI("ISEDisplay", "AC temperature set to: %d", cur_ac_temperature); + // check if temp is within range of min and max for york if not set an min or max for only york + this->climateCard_daikin->setState(cur_ac_mode, cur_ac_fan_speed, cur_ac_temperature); + if (cur_ac_temperature < YORK_MIN_TEMP) + { + york_temp = YORK_MIN_TEMP; + } + else if (cur_ac_temperature > YORK_MAX_TEMP) + { + york_temp = YORK_MAX_TEMP; + } + if (ac_mode == 3) + { + this->climateCard_york->setState(0, cur_ac_fan_speed, york_temp); + } + else + { + this->climateCard_york->setState(cur_ac_mode, cur_ac_fan_speed, york_temp); + } +} + void ISEDisplay::toggleLightGroupState() { // Get the current group state @@ -492,6 +545,16 @@ void ISEDisplay::toggleLightGroupState() setLightLevel(i, state ? 0 : 3); } } +void ISEDisplay::setLightGroupState(uint8_t level) +{ + // Get the current group state + ESP_LOGI("ISEDisplay", "Current light group state: %d", level); + // Toggle light + for (uint8_t i = 1; i <= 4; i++) + { + setLightLevel(i, level); + } +} void ISEDisplay::toggleLightGroupStateStandby() { // Get the current group state @@ -512,7 +575,27 @@ void ISEDisplay::togglePM() // Toggle the state pm_switch->setValue(state ? "off" : "on"); ESP_LOGI("ISEDisplay", "New PM state: %d", state); - //updateAirPurifierState(); + // updateAirPurifierState(); +} +void ISEDisplay::toggleACLock() +{ + // Get the current group state + bool state = strcmp(ac_lock->getValue(), "on") == 0; + ESP_LOGI("ISEDisplay", "Current AC lock state: %d", state); + // Toggle the state + ac_lock->setValue(state ? "off" : "on"); + ESP_LOGI("ISEDisplay", "New AC lock state: %d", state); + // updateAirPurifierStateStandby(); +} +void ISEDisplay::togglePMLock() +{ + // Get the current group state + bool state = strcmp(pm_lock->getValue(), "on") == 0; + ESP_LOGI("ISEDisplay", "Current PM lock state: %d", state); + // Toggle the state + pm_lock->setValue(state ? "off" : "on"); + ESP_LOGI("ISEDisplay", "New PM lock state: %d", state); + // updateAirPurifierStateStandby(); } void ISEDisplay::togglePMStandby() { @@ -522,7 +605,7 @@ void ISEDisplay::togglePMStandby() // Toggle the state pm_switch->setValue(state ? "off" : "on"); ESP_LOGI("ISEDisplay", "New PM state: %d", state); - //updateAirPurifierStateStandby(); + // updateAirPurifierStateStandby(); } void ISEDisplay::toggleAC() { @@ -548,7 +631,7 @@ void ISEDisplay::toggleAC() ESP_LOGI("ISEDisplay", "User mode AFTER: %d", user_mode); setACstate(fan_speed, 0, temperature); } -} +} void ISEDisplay::changeUserACmode() { // Get the current group state @@ -577,8 +660,14 @@ 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); + + // only value between 1 and 4 is valid + ESP_LOGI("ISEDisplay", "Setting light level for row %d to %d", row, level); + + uint8_t primary_pin = *(light_array + 2 * (row - 1)); + uint8_t secondary_pin = *(light_array + 2 * (row - 1) + 1); + + ESP_LOGI("ISEDisplay", "Primary pin: %d, Secondary pin: %d", primary_pin, secondary_pin); bool primary = false; bool secondary = false; @@ -588,36 +677,45 @@ void ISEDisplay::setLightLevel(uint8_t row, uint8_t level) case 0: primary = false; secondary = false; + ESP_LOGI("ISEDisplay", "Primary pin is %d, Secondary pin is %d", primary, secondary); break; case 1: primary = false; secondary = true; + ESP_LOGI("ISEDisplay", "Primary pin is %d, Secondary pin is %d", primary, secondary); break; case 2: primary = true; secondary = false; + ESP_LOGI("ISEDisplay", "Primary pin is %d, Secondary pin is %d", primary, secondary); break; case 3: primary = true; secondary = true; + ESP_LOGI("ISEDisplay", "Primary pin is %d, Secondary pin is %d", primary, secondary); break; default: + ESP_LOGE("ISEDisplay", "Invalid light level: %d", level); break; } this->outputCard->setState(primary_pin, primary); this->outputCard->setState(secondary_pin, secondary); + ESP_LOGI("ISEDisplay", "Light level set for row %d", row); } 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); + ESP_LOGI("ISEDisplay", "Getting light level for row %d", row); + // lightLevel = this->outputCard->getValue(row); + // row can only be between 1 and 4 + uint8_t primary_pin = *(light_array + 2 * (row - 1)); + uint8_t secondary_pin = *(light_array + 2 * (row - 1) + 1); + ESP_LOGI("ISEDisplay", "Primary pin: %d, Secondary pin: %d", primary_pin, secondary_pin); bool primary = this->outputCard->getState(primary_pin); bool secondary = this->outputCard->getState(secondary_pin); + ESP_LOGI("ISEDisplay", "Primary pin state: %d, Secondary pin state: %d", primary, secondary); if (primary && secondary) { lightLevel = 3; @@ -634,19 +732,20 @@ u_int8_t ISEDisplay::getLightLevel(uint8_t row) { lightLevel = 0; } - + ESP_LOGI("ISEDisplay", "Light level for row %d is %d", row, lightLevel); return lightLevel; } -//change to light with the assignment +// change to light with the assignment -lightPosition ISEDisplay::getRowCol(uint8_t pin){ +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 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) @@ -659,7 +758,6 @@ lightPosition ISEDisplay::getRowCol(uint8_t pin){ return position; } - void ISEDisplay::updateLightGroupStatePageStandby() { // Calculate the state @@ -669,11 +767,11 @@ void ISEDisplay::updateLightGroupStatePageStandby() return; this->displayAdapter->print("s_light_toggle.pic="); - this->displayAdapter->print(state ? COMPONENT_STANDBY_LIGHT_PIC_ON : COMPONENT_STANDBY_LIGHT_PIC_OFF); + this->displayAdapter->print(state ? COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_ON : COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_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->displayAdapter->print(state ? COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_ON_PRESSED : COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); @@ -686,12 +784,12 @@ void ISEDisplay::updateLightGroupStatePageDashboard() if (!this->takeSerialMutex()) return; - this->displayAdapter->print("light_master.pic="); - this->displayAdapter->print(state ? COMPONENT_LIGHT_MASTER_ON : COMPONENT_LIGHT_MASTER_OFF); + this->displayAdapter->print("light_m_sw.pic="); + this->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_ON : COMPONENT_DASHBOARD_PIC_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->displayAdapter->print("light_m_sw.pic2="); + this->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_ON_PRESSED : COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_OFF_PRESSED); this->sendStopBytes(); for (uint8_t i = 1; i <= 4; i++) @@ -703,28 +801,28 @@ void ISEDisplay::updateLightGroupStatePageDashboard() this->displayAdapter->print("light_row"); this->displayAdapter->print(i); this->displayAdapter->print(".pic="); - this->displayAdapter->print(COMPONENT_LIGHT_LEVEL_0); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_LIGHT_ROW_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->displayAdapter->print(COMPONENT_DASHBOARD_PIC_LIGHT_ROW_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->displayAdapter->print(COMPONENT_DASHBOARD_PIC_LIGHT_ROW_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->displayAdapter->print(COMPONENT_DASHBOARD_PIC_LIGHT_ROW_LEVEL_3); this->sendStopBytes(); break; default: @@ -750,6 +848,44 @@ bool ISEDisplay::calculateLightGroupState() } return lightOn; } +bool ISEDisplay::calculateAllState() +{ + bool lightState = calculateLightGroupState(); + bool pmState = strcmp(pm_switch->getValue(), "on") == 0; + bool acState = false; + if (ac_mode != 0) + { + acState = true; + } + return lightState || pmState || acState; +} +void ISEDisplay::toggleSystem() +{ + toggleLightGroupState(); + //check for ac lock and pm lock, if lock is on do nothing + if (strcmp(ac_lock->getValue(), "on") == 0) + { + ESP_LOGI("ISEDisplay", "AC lock is on, do nothing"); + } + else + { + toggleAC(); + } + if (strcmp(pm_lock->getValue(), "on") == 0) + { + ESP_LOGI("ISEDisplay", "PM lock is on, do nothing"); + } + else + { + togglePM(); + } +} +void ISEDisplay::allOn() +{ + setLightGroupState(3); + setPMstate(true, pm_fan_speed); + setACstate(ac_mode, ac_fan_speed, ac_temperature); +} void ISEDisplay::toggleLightIndividual(uint8_t row) { @@ -766,48 +902,36 @@ void ISEDisplay::toggleLightIndividual(uint8_t row) // Set the state setLightLevel(row, state); } -void ISEDisplay::toggleSliderLight(uint8_t row, uint8_t lightLevel) +void ISEDisplay::updateSystemtoggle() { - // Get the current state - uint8_t state = 0; + bool state = calculateAllState(); + if (!this->takeSerialMutex()) + return; + this->displayAdapter->print("system_toggle.pic="); + this->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_ON : COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_OFF); + this->sendStopBytes(); - 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); + this->displayAdapter->print("system_toggle.pic2="); + this->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_ON_PRESSED : COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_OFF_PRESSED); + this->sendStopBytes(); + + this->giveSerialMutex(); } void ISEDisplay::updateAirPurifierStateStandby() { // Get the state bool state = strcmp(pm_switch->getValue(), "on") == 0; + this->pm_lock_state = strcmp(pm_lock->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->displayAdapter->print(state ? COMPONENT_STANDBY_PIC_AC_TOGGLE_ON : COMPONENT_STANDBY_PIC_AC_TOGGLE_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->displayAdapter->print(state ? COMPONENT_STANDBY_PIC_AC_TOGGLE_ON_PRESSED : COMPONENT_STANDBY_PIC_AC_TOGGLE_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); @@ -815,40 +939,47 @@ void ISEDisplay::updateAirPurifierStateStandby() void ISEDisplay::updateAirPurifierState() { - //check for page - if(currentPage == PAGE_DASHBOARD){ + // check for page + if (currentPage == PAGE_DASHBOARD) + { ESP_LOGI("ISEDisplay", "Updating dashboard"); // Get the state bool state = strcmp(pm_switch->getValue(), "on") == 0; + this->pm_lock_state = strcmp(pm_lock->getValue(), "on") == 0; ESP_LOGI("ISEDisplay", "Updating air purifier state to: %d", state); - pm_fan_speed = (int) atof(remote_pm_fan_speed->getValue()); + pm_fan_speed = (int)atof(remote_pm_fan_speed->getValue()); // Send the state to the display if (!this->takeSerialMutex()) - return; + return; this->displayAdapter->print("pm_sw.pic="); - this->displayAdapter->print(state ? COMPONENT_PM_TOGGLE_PIC_ON : COMPONENT_PM_TOGGLE_PIC_OFF); + this->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_PM_TOGGLE_ON : COMPONENT_DASHBOARD_PIC_PM_TOGGLE_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->displayAdapter->print(state ? COMPONENT_DASHBOARD_PIC_PM_TOGGLE_ON_PRESSED : COMPONENT_DASHBOARD_PIC_PM_TOGGLE_OFF_PRESSED); this->sendStopBytes(); - this->displayAdapter->print("pm_speed.val="); - this->displayAdapter->print(pm_fan_speed); - // this->displayAdapter->print("\""); + this->displayAdapter->print("pm_lock.pic="); + this->displayAdapter->print(this->pm_lock_state ? COMPONENT_DASHBOARD_PIC_LOCK : COMPONENT_DASHBOARD_PIC_UNLOCK); this->sendStopBytes(); - this->displayAdapter->print("pm_speed.pco="); - this->displayAdapter->print(state ? 34486 : 33841); - 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){ + + else if (currentPage == PAGE_STANDBY) + { ESP_LOGI("ISEDisplay", "Updating standby"); - updateAirPurifierStateStandby(); + updateAirPurifierStateStandby(); } } void ISEDisplay::handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature) @@ -858,26 +989,72 @@ void ISEDisplay::handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t tempera } void ISEDisplay::updateuserACmode() { + uint8_t mode = this->climateCard_daikin->getMode(); 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_FAN_PIC); - this->sendStopBytes(); - this->displayAdapter->print("ac_mode.pic2="); - this->displayAdapter->print(COMPONENT_AC_MODE_FAN_PIC_PRESSED); - this->sendStopBytes(); + if (mode == 0) + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_ON_PRESSED); + this->sendStopBytes(); + } break; case 2: - 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(); + if (mode == 0) + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_ON_PRESSED); + this->sendStopBytes(); + } + break; + + case 3: + if (mode == 0) + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_mode.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_mode.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_ON_PRESSED); + this->sendStopBytes(); + } break; default: break; @@ -887,42 +1064,93 @@ void ISEDisplay::updateuserACmode() void ISEDisplay::updateACfanSpeed() { uint8_t fan_speed = this->climateCard_daikin->getFanSpeed(); + uint8_t mode = this->climateCard_daikin->getMode(); + this->ac_lock_state = strcmp(ac_lock->getValue(), "on") == 0; + 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(); + if (mode == 0) + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_ON_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(); + if (mode == 0) + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_ON_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(); + if (mode == 0) + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_MID_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_MID_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_MID_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_MID_ON_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(); + if (mode == 0) + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_OFF); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_OFF_PRESSED); + this->sendStopBytes(); + } + else + { + this->displayAdapter->print("ac_speed.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_ON); + this->sendStopBytes(); + this->displayAdapter->print("ac_speed.pic2="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_ON_PRESSED); + this->sendStopBytes(); + } break; default: break; @@ -936,7 +1164,10 @@ void ISEDisplay::updateACState() // Get the state uint8_t mode = this->climateCard_daikin->getMode(); uint8_t temperature = this->climateCard_daikin->getTemperature(); - if(currentPage != 1){ + this->ac_lock_state = strcmp(ac_lock->getValue(), "on") == 0; + + if (currentPage != 1) + { if (!this->takeSerialMutex()) return; @@ -944,40 +1175,43 @@ void ISEDisplay::updateACState() if (mode == 0) { this->displayAdapter->print("ac_temp.pco="); - this->displayAdapter->print(33841); + this->displayAdapter->print(COMPONENT_COLOR_INACTIVE_GREY); this->sendStopBytes(); - this->displayAdapter->print("ac_temp.pic="); - this->displayAdapter->print(COMPONENT_AC_STATUS_OFF); + this->displayAdapter->print("c_degree.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_DEGREE_C_OFF); this->sendStopBytes(); } else { this->displayAdapter->print("ac_temp.pco="); - this->displayAdapter->print(34486); + this->displayAdapter->print(COMPONENT_COLOR_ACTIVE_BLUE); this->sendStopBytes(); - this->displayAdapter->print("ac_temp.pic="); - this->displayAdapter->print(COMPONENT_AC_STATUS_ON); + this->displayAdapter->print("c_degree.pic="); + this->displayAdapter->print(COMPONENT_DASHBOARD_PIC_DEGREE_C_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->displayAdapter->print(mode != 0 ? COMPONENT_DASHBOARD_PIC_AC_TOGGLE_ON : COMPONENT_DASHBOARD_PIC_AC_TOGGLE_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->displayAdapter->print(mode != 0 ? COMPONENT_DASHBOARD_PIC_AC_TOGGLE_ON_PRESSED : COMPONENT_DASHBOARD_PIC_AC_TOGGLE_OFF_PRESSED); + this->sendStopBytes(); + this->displayAdapter->print("ac_lock.pic="); + this->displayAdapter->print(this->ac_lock_state ? COMPONENT_DASHBOARD_PIC_LOCK : COMPONENT_DASHBOARD_PIC_UNLOCK); this->sendStopBytes(); this->giveSerialMutex(); updateuserACmode(); updateACfanSpeed(); - + if (!this->takeSerialMutex()) return; - + this->displayAdapter->print("ac_temp.val="); this->displayAdapter->print(temperature); // this->displayAdapter->print("\""); @@ -990,16 +1224,15 @@ void ISEDisplay::updateACState() return; this->displayAdapter->print("s_ac_toggle.pic="); - this->displayAdapter->print(mode != 0 ? COMPONENT_STANDBY_AC_PIC_ON : COMPONENT_STANDBY_AC_PIC_OFF); + this->displayAdapter->print(mode != 0 ? COMPONENT_STANDBY_PIC_AC_TOGGLE_ON : COMPONENT_STANDBY_PIC_AC_TOGGLE_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->displayAdapter->print(mode != 0 ? COMPONENT_STANDBY_PIC_AC_TOGGLE_ON_PRESSED : COMPONENT_STANDBY_PIC_AC_TOGGLE_OFF_PRESSED); this->sendStopBytes(); this->giveSerialMutex(); } - ESP_LOGI("ISEDisplay", "display AC state updated"); } diff --git a/src/ise_display.hpp b/src/ise_display.hpp index 74a86fc..4a615b4 100644 --- a/src/ise_display.hpp +++ b/src/ise_display.hpp @@ -2,6 +2,7 @@ #include "ise_display_definitions.hpp" #include +#include #include #include #include @@ -24,11 +25,12 @@ struct lightPosition { class ISEDisplay : public ESPMegaDisplay { public: ISEDisplay(HardwareSerial* adapter, const uint8_t *light_array, uint8_t row, uint8_t column); - void begin(DigitalInputCard* inputCard, DigitalOutputCard* outputCard, ClimateCard* climateCard_daikin, ClimateCard* climateCard_york, RemoteVariable* pm_switch, RemoteVariable* pm_fan_speed); + void begin(DigitalInputCard* inputCard, DigitalOutputCard* outputCard, ClimateCard* climateCard_daikin, ClimateCard* climateCard_york, RemoteVariable* pm_switch, RemoteVariable* pm_fan_speed, RemoteVariable* ac_lock, RemoteVariable* pm_lock); void updateLightGroupStatePageDashboard(); void updateLightGroupStatePageStandby(); void updateAirPurifierState(); void updateAirPurifierStateStandby(); + void updateSystemtoggle(); void updateDateTimeText(rtctime_t time); void updateWeather(char *weather_string); void updateTempOutside(float temp_outside); @@ -54,6 +56,7 @@ class ISEDisplay : public ESPMegaDisplay { DigitalOutputCard *outputCard; ClimateCard *climateCard_daikin; ClimateCard *climateCard_york; + ESPMegaIoT *iot; const uint8_t *light_array; uint8_t row; @@ -61,12 +64,18 @@ class ISEDisplay : public ESPMegaDisplay { RemoteVariable *pm_switch; RemoteVariable *remote_pm_fan_speed; + RemoteVariable *ac_lock; + RemoteVariable *pm_lock; uint8_t outputCallbackHandle; uint8_t climateCallbackHandle; + uint8_t time_since_last_ac_change; uint8_t user_mode; + uint8_t ac_lock_state; + uint8_t pm_lock_state; uint8_t ac_mode; uint8_t ac_fan_speed; uint8_t ac_temperature; + bool ac_press_pending; uint8_t pm_fan_speed; uint8_t time_since_last_screen_update; u_int8_t lightLevelRow1; @@ -78,13 +87,21 @@ class ISEDisplay : public ESPMegaDisplay { void updateuserACmode(); void updateACfanSpeed(); bool calculateLightGroupState(); + bool calculateAllState(); + void toggleSystem(); + void sendACIRcode(); + void setPMlockstate(bool is_pm_lock_on); + void setAClockstate(bool is_ac_lock_on); + void toggleACLock(); + void togglePMLock(); + void allOn(); void toggleLightGroupState(); void toggleLightGroupStateStandby(); void toggleLightIndividual(uint8_t row); - void toggleSliderLight(uint8_t row,uint8_t lightLevel); void togglePM(); void togglePMStandby(); void toggleAC(); + void setLightGroupState(uint8_t level); void toggleACStandby(); void changeUserACmode(); diff --git a/src/ise_display_definitions.hpp b/src/ise_display_definitions.hpp index 4f7783d..f277d47 100644 --- a/src/ise_display_definitions.hpp +++ b/src/ise_display_definitions.hpp @@ -23,6 +23,13 @@ change light assignment 8: row 4 column 2 */ +#define DAIKIN_MAX_TEMP 32 +#define DAIKIN_MIN_TEMP 16 + +#define YORK_MAX_TEMP 30 +#define YORK_MIN_TEMP 18 + + #define LIGHT_ROW1_COLUMN1 10 #define LIGHT_ROW1_COLUMN2 11 #define LIGHT_ROW2_COLUMN1 9 @@ -72,178 +79,457 @@ lights have 4 states #define PAGE_STANDBY 1 #define PAGE_DASHBOARD 2 +//gmov logo size +#define COMPONENT_LOGO_500X500 0 //original size +#define COMPONENT_LOGO_260X260 1 //use for boot page loading +#define COMPONENT_LOGO_140X140 2 //use for standby page logo +#define COMPONENT_LOGO_62X62 3 //use for dashboard page top left logo + +//font +#define COMPONENT_FONT_K2D_SB_24 0 //use for date +#define COMPONENT_FONT_BAIJ_B_32 1 //use for PM +#define COMPONENT_FONT_BAIJ_B_48 2 //use for time +#define COMPONENT_FONT_BAIJ_SB_80 3 //use for AC temperature +#define COMPONENT_FONT_BAIJ_B_40 4 //use for PM + +//color (PCO) +#define COMPONENT_COLOR_ACTIVE_BLUE 7775 +#define COMPONENT_COLOR_INACTIVE_GREY 44405 +#define COMPONENT_COLOR_WHITE 65535 +#define COMPONENT_COLOR_BLACK 0 + + +//-------------BOOT PAGE---------------- +//logo gmov boot +#define COMPONENT_OBJ_BOOT_LOGO 1 + +//boot background +#define COMPONENT_BOOT_BACKGROUND_PIC 0 +#define COMPONENT_BOOT_BACKGROUND_PIC_REFERENCE 1 + +//-------------STANDBY PAGE---------------- +//standby page object id and object name +#define COMPONENT_OBJ_STANDBY_LOGO 1 //logo +#define COMPONENT_OBJ_STANDBY_BTN_OPEN_ALL_TOGGLE 2 //s_open_all +#define COMPONENT_OBJ_STANDBY_BTN_LIGHT_TOGGLE 3 //s_light_toggle +#define COMPONENT_OBJ_STANDBY_BTN_AC_TOGGLE 4 //s_ac_toggle +#define COMPONENT_OBJ_STANDBY_BTN_PM_TOGGLE 5 //s_pm_toggle +#define COMPONENT_OBJ_STANDBY_TXT_TIME 6 //time +#define COMPONENT_OBJ_STANDBY_TXT_DATE 7 //date +#define COMPONENT_OBJ_STANDBY_TIMER_IDLE 8 //idle_timer +#define COMPONENT_OBJ_STANDBY_TXT_PM_OUTSIDE 9 //pm_out +#define COMPONENT_OBJ_STANDBY_TXT_PM_INSIDE 10 //pm_in + +//---------standby page picture id and picture name------------ + +//Standby background +#define COMPONENT_STANDBY_PIC_BACKGROUND 2 +#define COMPONENT_STANDBY_PIC_BACKGROUND_REFERENCE 3 + +//Standby open all toggle +#define COMPONENT_STANDBY_PIC_OPEN_ALL_TOGGLE_OFF 4 +#define COMPONENT_STANDBY_PIC_OPEN_ALL_TOGGLE_OFF_PRESSED 5 +#define COMPONENT_STANDBY_PIC_OPEN_ALL_TOGGLE_ON 6 +#define COMPONENT_STANDBY_PIC_OPEN_ALL_TOGGLE_ON_PRESSED 7 + +//Standby light toggle +#define COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_OFF 8 +#define COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_OFF_PRESSED 9 +#define COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_ON 10 +#define COMPONENT_STANDBY_PIC_LIGHT_TOGGLE_ON_PRESSED 11 + +//Standby AC toggle +#define COMPONENT_STANDBY_PIC_AC_TOGGLE_OFF 12 +#define COMPONENT_STANDBY_PIC_AC_TOGGLE_OFF_PRESSED 13 +#define COMPONENT_STANDBY_PIC_AC_TOGGLE_ON 14 +#define COMPONENT_STANDBY_PIC_AC_TOGGLE_ON_PRESSED 15 + +//Standby PM toggle +#define COMPONENT_STANDBY_PIC_PM_TOGGLE_OFF 16 +#define COMPONENT_STANDBY_PIC_PM_TOGGLE_OFF_PRESSED 17 +#define COMPONENT_STANDBY_PIC_PM_TOGGLE_ON 18 +#define COMPONENT_STANDBY_PIC_PM_TOGGLE_ON_PRESSED 19 + +//-------------DASHBOARD PAGE---------------- +//dashboard page object id and object name + +//AC +#define COMPONENT_OBJ_DASHBOARD_NUM_AC_TEMP 1 //ac_temp +#define COMPONENT_OBJ_DASHBOARD_BTN_AC_TOGGLE 2 //ac_sw +#define COMPONENT_OBJ_DASHBOARD_BTN_AC_MODE 3 //ac_mode +#define COMPONENT_OBJ_DASHBOARD_BTN_AC_FAN_SPEED 4 //ac_speed +#define COMPONENT_OBJ_DASHBOARD_BTN_AC_TEMP_MINUS 5 //ac_minus +#define COMPONENT_OBJ_DASHBOARD_BTN_AC_TEMP_PLUS 6 //ac_plus + +//PM +#define COMPONENT_OBJ_DASHBOARD_BTN_PM_TOGGLE 7 //pm_sw +#define COMPONENT_OBJ_DASHBOARD_TXT_PM_INSIDE 8 //pm_in +#define COMPONENT_OBJ_DASHBOARD_TXT_PM_OUTSIDE 9 //pm_out + +//DECAPRICATED +#define DONTUSE_COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_MASTER 10 //DONT USE THIS D_light_master + +//Light Pic Holder +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW1 11 //light_row1 +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW2 12 //light_row2 +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW3 13 //light_row3 +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_LIGHT_ROW4 14 //light_row4 + +//Light Button +#define COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW1 15 //light_row1_sw +#define COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW2 16 //light_row2_sw +#define COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW3 17 //light_row3_sw +#define COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_ROW4 18 //light_row4_sw + +//Timer +#define COMPONENT_OBJ_DASHBOARD_TIMER_TEN_SEC 19 //time_10sec +#define COMPONENT_OBJ_DASHBOARD_VAL_TIME_PAST 20 //time_past +#define COMPONENT_OBJ_DASHBOARD_TIMER_INACTIVE_CHECK 21 //inactive_check + +//System toggle +#define COMPONENT_OBJ_DASHBOARD_BTN_SYSTEM_TOGGLE 22 //system_toggle + +//PM Button +#define COMPONENT_OBJ_DASHBOARD_BTN_PM_SPEED 23 //pm_speed +#define COMPONENT_OBJ_DASHBOARD_BTN_PM_MODE 24 //pm_mode + +//Light Master Pic Holder +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_MASTER_LIGHT 25 //master_light + +//Logo +#define COMPONENT_OBJ_DASHBOARD_LOGO 26 //small_ise_logo + +//Lock Pic Holder +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_PM_LOCK 27 //pm_lock +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_AC_LOCK 28 //ac_lock + +//Light Master Button +#define COMPONENT_OBJ_DASHBOARD_BTN_LIGHT_MASTER 29 //light_m_sw + +//Light Master Hotspot +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV1 30 //light_m_lv1 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV2 31 //light_m_lv2 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_MASTER_LV3 32 //light_m_lv3 + +//Light Row1 Hotspot +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV1 33 //light_row1_lv1 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV2 34 //light_row1_lv2 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW1_LV3 35 //light_row1_lv3 + +//Light Row2 Hotspot +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV1 36 //light_row2_lv1 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV2 37 //light_row2_lv2 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW2_LV3 38 //light_row2_lv3 + +//Light Row3 Hotspot +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV1 39 //light_row3_lv1 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV2 40 //light_row3_lv2 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW3_LV3 41 //light_row3_lv3 + +//Light Row4 Hotspot +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV1 42 //light_row4_lv1 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV2 43 //light_row4_lv2 +#define COMPONENT_OBJ_DASHBOARD_HOTSPOT_LIGHT_ROW4_LV3 44 //light_row4_lv3 + +//Degree Pic Holder +#define COMPONENT_OBJ_DASHBOARD_HOLDER_PIC_C_DEGREE 45 //c_degree + +//-----------------dashboard page picture id and picture name---------------- + +//Dashboard Background +#define COMPONENT_DASHBOARD_PIC_BACKGROUND_WITH_C 20 +#define COMPONENT_DASHBOARD_PIC_BACKGROUND 21 //use this +#define COMPONENT_DASHBOARD_PIC_BACKGROUND_REFERENCE 22 + +//System Toggle Button +#define COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_OFF 23 +#define COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_OFF_PRESSED 24 +#define COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_ON 25 +#define COMPONENT_DASHBOARD_PIC_SYSTEM_TOGGLE_ON_PRESSED 26 + +//AC Temperature Minus +#define COMPONENT_DASHBOARD_PIC_AC_TEMP_MINUS 27 +#define COMPONENT_DASHBOARD_PIC_AC_TEMP_MINUS_PRESSED 28 + +//AC Temperature Plus +#define COMPONENT_DASHBOARD_PIC_AC_TEMP_PLUS 29 +#define COMPONENT_DASHBOARD_PIC_AC_TEMP_PLUS_PRESSED 30 + +//AC Mode Cool +#define COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_OFF 31 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_OFF_PRESSED 32 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_ON 33 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_COOL_ON_PRESSED 34 + +//AC Mode Dry +#define COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_OFF 35 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_OFF_PRESSED 36 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_ON 37 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_DRY_ON_PRESSED 38 + +//AC Mode Fan +#define COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_OFF 39 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_OFF_PRESSED 40 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_ON 41 +#define COMPONENT_DASHBOARD_PIC_AC_MODE_FAN_ON_PRESSED 42 + +//AC Fan Speed Auto +#define COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_OFF 43 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_OFF_PRESSED 44 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_ON 45 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_AUTO_ON_PRESSED 46 + +//AC Fan Speed High +#define COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_OFF 47 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_OFF_PRESSED 48 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_ON 49 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_HIGH_ON_PRESSED 50 + +//AC Fan Speed Mid +#define COMPONENT_DASHBOARD_PIC_AC_FAN_MID_OFF 51 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_MID_OFF_PRESSED 52 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_MID_ON 53 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_MID_ON_PRESSED 54 + +//AC Fan Speed Low +#define COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_OFF 55 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_OFF_PRESSED 56 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_ON 57 +#define COMPONENT_DASHBOARD_PIC_AC_FAN_LOW_ON_PRESSED 58 + +//AC Toggle Button +#define COMPONENT_DASHBOARD_PIC_AC_TOGGLE_OFF 59 +#define COMPONENT_DASHBOARD_PIC_AC_TOGGLE_OFF_PRESSED 60 +#define COMPONENT_DASHBOARD_PIC_AC_TOGGLE_ON 61 +#define COMPONENT_DASHBOARD_PIC_AC_TOGGLE_ON_PRESSED 62 + +//PM Toggle Button +#define COMPONENT_DASHBOARD_PIC_PM_TOGGLE_OFF 63 +#define COMPONENT_DASHBOARD_PIC_PM_TOGGLE_OFF_PRESSED 64 +#define COMPONENT_DASHBOARD_PIC_PM_TOGGLE_ON 65 +#define COMPONENT_DASHBOARD_PIC_PM_TOGGLE_ON_PRESSED 66 + +//Light Switch Button +#define COMPONENT_DASHBOARD_PIC_LIGHT_SWITCH_OFF 67 +#define COMPONENT_DASHBOARD_PIC_LIGHT_SWITCH_OFF_PRESSED 68 +#define COMPONENT_DASHBOARD_PIC_LIGHT_SWITCH_ON 69 +#define COMPONENT_DASHBOARD_PIC_LIGHT_SWITCH_ON_PRESSED 70 + +//Light Row Level +#define COMPONENT_DASHBOARD_PIC_LIGHT_ROW_LEVEL_0 71 +#define COMPONENT_DASHBOARD_PIC_LIGHT_ROW_LEVEL_1 72 +#define COMPONENT_DASHBOARD_PIC_LIGHT_ROW_LEVEL_2 73 +#define COMPONENT_DASHBOARD_PIC_LIGHT_ROW_LEVEL_3 74 + +//Light Master Switch Button +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_OFF 75 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_OFF_PRESSED 76 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_ON 77 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_ON_PRESSED 78 + +//Light Master Level +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_LEVEL_D 79 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_LEVEL_0 80 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_LEVEL_1 81 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_LEVEL_2 82 +#define COMPONENT_DASHBOARD_PIC_LIGHT_MASTER_LEVEL_3 83 + +//Lock Pic +#define COMPONENT_DASHBOARD_PIC_LOCK 84 +#define COMPONENT_DASHBOARD_PIC_UNLOCK 85 + +//Degree Pic +#define COMPONENT_DASHBOARD_PIC_DEGREE_C_OFF 86 +#define COMPONENT_DASHBOARD_PIC_DEGREE_C_ON 87 + + + + + + + + + + + + + + + +//-----------------DECAPRICATED---------------- + //boot page //logo gmov boot -#define COMPONENT_LOGO_BOOT 1 -#define COMPONENT_LOGO_BOOT_VID 1 +#define OLD_COMP_LOGO_BOOT 1 +#define OLD_COMP_LOGO_BOOT_VID 1 //boot background -#define COMPONENT_BACKGROUND_BOOT_PIC 43 +#define OLD_COMP_BACKGROUND_BOOT_PIC 43 //standby page object id -#define COMPONENT_LOGO_STANDBY 1 -#define COMPONENT_LOGO_STANDBY_VID 2 +#define OLD_COMP_LOGO_STANDBY 1 +#define OLD_COMP_LOGO_STANDBY_VID 2 -#define COMPONENT_STANDBY_OPEN_ALL_TOGGLE 2 -#define COMPONENT_STANDBY_LIGHT_TOGGLE 3 -#define COMPONENT_STANDBY_AC_TOGGLE 4 -#define COMPONENT_STANDBY_PM_TOGGLE 5 +#define OLD_COMP_STANDBY_OPEN_ALL_TOGGLE 2 +#define OLD_COMP_STANDBY_LIGHT_TOGGLE 3 +#define OLD_COMP_STANDBY_AC_TOGGLE 4 +#define OLD_COMP_STANDBY_PM_TOGGLE 5 //text -#define COMPONENT_STANDBY_TIME_TXT 6 -#define COMPONENT_STANDBY_DATE_TXT 7 -#define COMPONENT_STANDBY_OUTSIDE_TEMP_TXT 8 +#define OLD_COMP_STANDBY_TIME_TXT 6 +#define OLD_COMP_STANDBY_DATE_TXT 7 +#define OLD_COMP_STANDBY_OUTSIDE_TEMP_TXT 8 -#define COMPONENT_STANDBY_TIMER 9 -#define COMPONENT_STANDBY_WEATHER_ICON 10 +#define OLD_COMP_STANDBY_TIMER 9 +#define OLD_COMP_STANDBY_WEATHER_ICON 10 //standby page picture id -#define COMPONENT_BACKGROUND_PIC 44 -#define COMPONENT_BACKGROUND_REFERENCE_PIC 45 +#define OLD_COMP_BACKGROUND_PIC 44 +#define OLD_COMP_BACKGROUND_REFERENCE_PIC 45 -#define COMPONENT_STANDBY_OPEN_ALL_TOGGLE_PIC_OFF 46 -#define COMPONENT_STANDBY_OPEN_ALL_TOGGLE_PIC_OFF_PRESSED 47 -#define COMPONENT_STANDBY_OPEN_ALL_TOGGLE_PIC_ON 48 -#define COMPONENT_STANDBY_OPEN_ALL_TOGGLE_PIC_ON_PRESSED 49 +#define OLD_COMP_STANDBY_OPEN_ALL_TOGGLE_PIC_OFF 46 +#define OLD_COMP_STANDBY_OPEN_ALL_TOGGLE_PIC_OFF_PRESSED 47 +#define OLD_COMP_STANDBY_OPEN_ALL_TOGGLE_PIC_ON 48 +#define OLD_COMP_STANDBY_OPEN_ALL_TOGGLE_PIC_ON_PRESSED 49 -#define COMPONENT_STANDBY_AC_PIC_OFF 50 -#define COMPONENT_STANDBY_AC_PIC_OFF_PRESSED 51 -#define COMPONENT_STANDBY_AC_PIC_ON 52 -#define COMPONENT_STANDBY_AC_PIC_ON_PRESSED 53 +#define OLD_COMP_STANDBY_AC_PIC_OFF 50 +#define OLD_COMP_STANDBY_AC_PIC_OFF_PRESSED 51 +#define OLD_COMP_STANDBY_AC_PIC_ON 52 +#define OLD_COMP_STANDBY_AC_PIC_ON_PRESSED 53 -#define COMPONENT_STANDBY_LIGHT_PIC_OFF 54 -#define COMPONENT_STANDBY_LIGHT_PIC_OFF_PRESSED 55 -#define COMPONENT_STANDBY_LIGHT_PIC_ON 56 -#define COMPONENT_STANDBY_LIGHT_PIC_ON_PRESSED 57 +#define OLD_COMP_STANDBY_LIGHT_PIC_OFF 54 +#define OLD_COMP_STANDBY_LIGHT_PIC_OFF_PRESSED 55 +#define OLD_COMP_STANDBY_LIGHT_PIC_ON 56 +#define OLD_COMP_STANDBY_LIGHT_PIC_ON_PRESSED 57 -#define COMPONENT_STANDBY_PM_PIC_OFF 58 -#define COMPONENT_STANDBY_PM_PIC_OFF_PRESSED 59 -#define COMPONENT_STANDBY_PM_PIC_ON 60 -#define COMPONENT_STANDBY_PM_PIC_ON_PRESSED 61 +#define OLD_COMP_STANDBY_PM_PIC_OFF 58 +#define OLD_COMP_STANDBY_PM_PIC_OFF_PRESSED 59 +#define OLD_COMP_STANDBY_PM_PIC_ON 60 +#define OLD_COMP_STANDBY_PM_PIC_ON_PRESSED 61 -#define COMPONENT_REFERENCE_BACKGROUND_PIC 62 +#define OLD_COMP_REFERENCE_BACKGROUND_PIC 62 //dashboard page //dashboard page object id -#define COMPONENT_AC_TOGGLE_BUTTON 3 -#define COMPONENT_AC_MODE 4 -#define COMPONENT_AC_FAN_SPEED 5 -#define COMPONENT_AC_TEMP_DOWN_BUTTON 6 -#define COMPONENT_AC_TEMP_UP_BUTTON 7 +#define OLD_COMP_AC_TOGGLE_BUTTON 3 +#define OLD_COMP_AC_MODE 4 +#define OLD_COMP_AC_FAN_SPEED 5 +#define OLD_COMP_AC_TEMP_DOWN_BUTTON 6 +#define OLD_COMP_AC_TEMP_UP_BUTTON 7 -#define COMPONENT_PM_TOGGLE_BUTTON 8 -#define COMPONENT_PM_FAN_SPEED_DECREASE 9 -#define COMPONENT_PM_FAN_SPEED_INCREASE 10 +#define OLD_COMP_PM_TOGGLE_BUTTON 8 +#define OLD_COMP_PM_FAN_SPEED_DECREASE 9 +#define OLD_COMP_PM_FAN_SPEED_INCREASE 10 -#define COMPONENT_PM_INSIDE_TXT 11 -#define COMPONENT_PM_OUTSIDE_TXT 12 +#define OLD_COMP_PM_INSIDE_TXT 11 +#define OLD_COMP_PM_OUTSIDE_TXT 12 -#define COMPONENT_LIGHT_MASTER_BUTTON 13 -#define COMPONENT_LIGHT_ROW1_PIC_PLACEHOLDER 14 -#define COMPONENT_LIGHT_ROW2_PIC_PLACEHOLDER 15 -#define COMPONENT_LIGHT_ROW3_PIC_PLACEHOLDER 16 -#define COMPONENT_LIGHT_ROW4_PIC_PLACEHOLDER 17 +#define OLD_COMP_LIGHT_MASTER_BUTTON 13 +#define OLD_COMP_LIGHT_ROW1_PIC_PLACEHOLDER 14 +#define OLD_COMP_LIGHT_ROW2_PIC_PLACEHOLDER 15 +#define OLD_COMP_LIGHT_ROW3_PIC_PLACEHOLDER 16 +#define OLD_COMP_LIGHT_ROW4_PIC_PLACEHOLDER 17 -#define COMPONENT_LIGHT_MASTER_LEVEL1_TOUCHPOINT 18 -#define COMPONENT_LIGHT_MASTER_LEVEL2_TOUCHPOINT 19 -#define COMPONENT_LIGHT_MASTER_LEVEL3_TOUCHPOINT 20 +#define OLD_COMP_LIGHT_MASTER_LEVEL1_TOUCHPOINT 18 +#define OLD_COMP_LIGHT_MASTER_LEVEL2_TOUCHPOINT 19 +#define OLD_COMP_LIGHT_MASTER_LEVEL3_TOUCHPOINT 20 -#define COMPONENT_DASHBOARD_TIME_TXT 21 -#define COMPONENT_DASHBOARD_DATE_TXT 22 -#define COMPONENT_DASHBOARD_OUTSIDE_TEMP_TXT 23 +#define OLD_COMP_DASHBOARD_TIME_TXT 21 +#define OLD_COMP_DASHBOARD_DATE_TXT 22 +#define OLD_COMP_DASHBOARD_OUTSIDE_TEMP_TXT 23 -#define COMPONENT_LIGHT_ROW1_SLIDER 24 -#define COMPONENT_LIGHT_ROW2_SLIDER 25 -#define COMPONENT_LIGHT_ROW3_SLIDER 26 -#define COMPONENT_LIGHT_ROW4_SLIDER 27 +#define OLD_COMP_LIGHT_ROW1_SLIDER 24 +#define OLD_COMP_LIGHT_ROW2_SLIDER 25 +#define OLD_COMP_LIGHT_ROW3_SLIDER 26 +#define OLD_COMP_LIGHT_ROW4_SLIDER 27 -#define COMPONENT_LIGHT_ROW1_SWITCH 28 -#define COMPONENT_LIGHT_ROW2_SWITCH 29 -#define COMPONENT_LIGHT_ROW3_SWITCH 30 -#define COMPONENT_LIGHT_ROW4_SWITCH 31 +#define OLD_COMP_LIGHT_ROW1_SWITCH 28 +#define OLD_COMP_LIGHT_ROW2_SWITCH 29 +#define OLD_COMP_LIGHT_ROW3_SWITCH 30 +#define OLD_COMP_LIGHT_ROW4_SWITCH 31 -#define COMPONENT_DASHBOARD_WEATHER_ICON 32 +#define OLD_COMP_DASHBOARD_WEATHER_ICON 32 //dashboard page picture id -#define COMPONENT_DASHBOARD_REFERENCE_BACKGROUND_PIC 0 -#define COMPONENT_DASHBOARD_BACKGROUND_PIC 1 -#define COMPONENT_DASHBOARD_BACKGROUND_VARIANT_PIC 2 +#define OLD_COMP_DASHBOARD_REFERENCE_BACKGROUND_PIC 0 +#define OLD_COMP_DASHBOARD_BACKGROUND_PIC 1 +#define OLD_COMP_DASHBOARD_BACKGROUND_VARIANT_PIC 2 //AC on/off -#define COMPONENT_AC_TOGGLE_PIC_OFF 3 -#define COMPONENT_AC_TOGGLE_PIC_OFF_PRESSED 4 -#define COMPONENT_AC_TOGGLE_PIC_ON 5 -#define COMPONENT_AC_TOGGLE_PIC_ON_PRESSED 6 -#define COMPONENT_AC_TEMP_DOWN_PIC 7 -#define COMPONENT_AC_TEMP_DOWN_PIC_PRESSED 8 -#define COMPONENT_AC_TEMP_UP_PIC 9 -#define COMPONENT_AC_TEMP_UP_PIC_PRESSED 10 +#define OLD_COMP_AC_TOGGLE_PIC_OFF 3 +#define OLD_COMP_AC_TOGGLE_PIC_OFF_PRESSED 4 +#define OLD_COMP_AC_TOGGLE_PIC_ON 5 +#define OLD_COMP_AC_TOGGLE_PIC_ON_PRESSED 6 +#define OLD_COMP_AC_TEMP_DOWN_PIC 7 +#define OLD_COMP_AC_TEMP_DOWN_PIC_PRESSED 8 +#define OLD_COMP_AC_TEMP_UP_PIC 9 +#define OLD_COMP_AC_TEMP_UP_PIC_PRESSED 10 -#define COMPONENT_AC_FAN_MODE_AUTO_PIC 11 -#define COMPONENT_AC_FAN_MODE_AUTO_PIC_PRESSED 12 -#define COMPONENT_AC_FAN_MODE_HIGH_PIC 13 -#define COMPONENT_AC_FAN_MODE_HIGH_PIC_PRESSED 14 -#define COMPONENT_AC_FAN_MODE_MID_PIC 15 -#define COMPONENT_AC_FAN_MODE_MID_PIC_PRESSED 16 -#define COMPONENT_AC_FAN_MODE_LOW_PIC 17 -#define COMPONENT_AC_FAN_MODE_LOW_PIC_PRESSED 18 +#define OLD_COMP_AC_FAN_MODE_AUTO_PIC 11 +#define OLD_COMP_AC_FAN_MODE_AUTO_PIC_PRESSED 12 +#define OLD_COMP_AC_FAN_MODE_HIGH_PIC 13 +#define OLD_COMP_AC_FAN_MODE_HIGH_PIC_PRESSED 14 +#define OLD_COMP_AC_FAN_MODE_MID_PIC 15 +#define OLD_COMP_AC_FAN_MODE_MID_PIC_PRESSED 16 +#define OLD_COMP_AC_FAN_MODE_LOW_PIC 17 +#define OLD_COMP_AC_FAN_MODE_LOW_PIC_PRESSED 18 -#define COMPONENT_AC_MODE_DRY_PIC 19 -#define COMPONENT_AC_MODE_DRY_PIC_PRESSED 20 -#define COMPONENT_AC_MODE_COOL_PIC 21 -#define COMPONENT_AC_MODE_COOL_PIC_PRESSED 22 -#define COMPONENT_AC_MODE_FAN_PIC 23 -#define COMPONENT_AC_MODE_FAN_PIC_PRESSED 24 +#define OLD_COMP_AC_MODE_DRY_PIC 19 +#define OLD_COMP_AC_MODE_DRY_PIC_PRESSED 20 +#define OLD_COMP_AC_MODE_COOL_PIC 21 +#define OLD_COMP_AC_MODE_COOL_PIC_PRESSED 22 +#define OLD_COMP_AC_MODE_FAN_PIC 23 +#define OLD_COMP_AC_MODE_FAN_PIC_PRESSED 24 //pm; air purifier -#define COMPONENT_PM_TOGGLE_PIC_OFF 25 -#define COMPONENT_PM_TOGGLE_PIC_OFF_PRESSED 26 -#define COMPONENT_PM_TOGGLE_PIC_ON 27 -#define COMPONENT_PM_TOGGLE_PIC_ON_PRESSED 28 +#define OLD_COMP_PM_TOGGLE_PIC_OFF 25 +#define OLD_COMP_PM_TOGGLE_PIC_OFF_PRESSED 26 +#define OLD_COMP_PM_TOGGLE_PIC_ON 27 +#define OLD_COMP_PM_TOGGLE_PIC_ON_PRESSED 28 -#define COMPONENT_PM_FAN_SPEED_DECREASE_PIC 29 -#define COMPONENT_PM_FAN_SPEED_DECREASE_PIC_PRESSED 30 -#define COMPONENT_PM_FAN_SPEED_INCREASE_PIC 31 -#define COMPONENT_PM_FAN_SPEED_INCREASE_PIC_PRESSED 32 +#define OLD_COMP_PM_FAN_SPEED_DECREASE_PIC 29 +#define OLD_COMP_PM_FAN_SPEED_DECREASE_PIC_PRESSED 30 +#define OLD_COMP_PM_FAN_SPEED_INCREASE_PIC 31 +#define OLD_COMP_PM_FAN_SPEED_INCREASE_PIC_PRESSED 32 //AC status indicator -#define COMPONENT_AC_STATUS_OFF 33 -#define COMPONENT_AC_STATUS_ON 34 +#define OLD_COMP_AC_STATUS_OFF 33 +#define OLD_COMP_AC_STATUS_ON 34 //light master -#define COMPONENT_LIGHT_MASTER_OFF 35 -#define COMPONENT_LIGHT_MASTER_OFF_PRESSED 36 -#define COMPONENT_LIGHT_MASTER_ON 37 -#define COMPONENT_LIGHT_MASTER_ON_PRESSED 38 +#define OLD_COMP_LIGHT_MASTER_OFF 35 +#define OLD_COMP_LIGHT_MASTER_OFF_PRESSED 36 +#define OLD_COMP_LIGHT_MASTER_ON 37 +#define OLD_COMP_LIGHT_MASTER_ON_PRESSED 38 //light level component -#define COMPONENT_LIGHT_LEVEL_0 39 -#define COMPONENT_LIGHT_LEVEL_1 40 -#define COMPONENT_LIGHT_LEVEL_2 41 -#define COMPONENT_LIGHT_LEVEL_3 42 +#define OLD_COMP_LIGHT_LEVEL_0 39 +#define OLD_COMP_LIGHT_LEVEL_1 40 +#define OLD_COMP_LIGHT_LEVEL_2 41 +#define OLD_COMP_LIGHT_LEVEL_3 42 //weather icon legend -#define COMPONENT_WEATHER_ICON_FAIR_DAY 63 -#define COMPONENT_WEATHER_ICON_FAIR_NIGHT 64 -#define COMPONENT_WEATHER_ICON_CLOUDY 65 -#define COMPONENT_WEATHER_ICON_CLEARSKY_DAY 66 -#define COMPONENT_WEATHER_ICON_CLEARSKY_NIGHT 67 -#define COMPONENT_WEATHER_ICON_PARTLYCLOUDY_DAY 68 -#define COMPONENT_WEATHER_ICON_PARTLYCLOUDY_NIGHT 69 -#define COMPONENT_WEATHER_ICON_HEAVY_RAIN 70 -#define COMPONENT_WEATHER_ICON_HEAVY_RAIN_AND_THUNDER 71 -#define COMPONENT_WEATHER_ICON_RAIN_AND_THUNDER 72 -#define COMPONENT_WEATHER_ICON_RAIN 73 -#define COMPONENT_WEATHER_ICON_LIGHT_RAIN 74 -#define COMPONENT_WEATHER_ICON_FOG 75 +#define OLD_COMP_WEATHER_ICON_FAIR_DAY 63 +#define OLD_COMP_WEATHER_ICON_FAIR_NIGHT 64 +#define OLD_COMP_WEATHER_ICON_CLOUDY 65 +#define OLD_COMP_WEATHER_ICON_CLEARSKY_DAY 66 +#define OLD_COMP_WEATHER_ICON_CLEARSKY_NIGHT 67 +#define OLD_COMP_WEATHER_ICON_PARTLYCLOUDY_DAY 68 +#define OLD_COMP_WEATHER_ICON_PARTLYCLOUDY_NIGHT 69 +#define OLD_COMP_WEATHER_ICON_HEAVY_RAIN 70 +#define OLD_COMP_WEATHER_ICON_HEAVY_RAIN_AND_THUNDER 71 +#define OLD_COMP_WEATHER_ICON_RAIN_AND_THUNDER 72 +#define OLD_COMP_WEATHER_ICON_RAIN 73 +#define OLD_COMP_WEATHER_ICON_LIGHT_RAIN 74 +#define OLD_COMP_WEATHER_ICON_FOG 75 //need to toggle 4 row of light independently and have one master switch that can control all diff --git a/src/main.cpp b/src/main.cpp index 769d5b0..9915a48 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,6 +23,8 @@ RemoteVariable temp_out = RemoteVariable(); RemoteVariable weather = RemoteVariable(); RemoteVariable pm_switch = RemoteVariable(); RemoteVariable pm_fan_speed = RemoteVariable(); +RemoteVariable pm_lock = RemoteVariable(); +RemoteVariable ac_lock = RemoteVariable(); float adc2current(uint16_t adc_val) { return adc_val * 1.0; @@ -45,8 +47,8 @@ const char *mode_names_york[] = {"off", "cool", "fan_only"}; const char *fan_speed_names[] = {"auto", "high", "medium", "low"}; AirConditioner ac_daikin = { - .max_temperature = 30, - .min_temperature = 18, + .max_temperature = DAIKIN_MAX_TEMP, + .min_temperature = DAIKIN_MIN_TEMP, .modes = 4, .mode_names = mode_names_daikin, .fan_speeds = 4, @@ -54,8 +56,8 @@ AirConditioner ac_daikin = { .getInfraredCode = &getInfraredCode_daikin}; AirConditioner ac_york = { - .max_temperature = 30, - .min_temperature = 18, + .max_temperature = YORK_MAX_TEMP, + .min_temperature = YORK_MIN_TEMP, .modes = 3, .mode_names = mode_names_york, .fan_speeds = 4, @@ -121,17 +123,6 @@ void setup() espmega.inputs.setDebounceTime(i,200); } - - // if (clear_fram) - // { - // Serial.print("boot_state.txt=\"Factory Resetting . . .\""); - // sendStopBytes(); - // for (uint16_t i = 0; i < 32768; i++) - // { - // espmega.fram.write8(i, 0); - // } - // esp_restart(); - // } // // ------------ End Factory Reset Routine ------------ @@ -198,14 +189,6 @@ void setup() ct6.bindFRAM(&espmega.fram, 6500); espmega.iot->registerCard(10); - // auto binded_display_update_on_pm25_out = std::bind(&display_update,0,std::placeholders::_1); - // auto binded_display_update_on_pm25_in = std::bind(&display_update,1,std::placeholders::_1); - // auto binded_display_update_on_temp_out = std::bind(&display_update,2,std::placeholders::_1); - // auto binded_display_update_on_weather = std::bind(&display_update,3,std::placeholders::_1); - // auto binded_display_update_on_pm_switch = std::bind(&display_update,4,std::placeholders::_1); - // auto binded_display_update_on_pm_fan_speed = std::bind(&display_update,5,std::placeholders::_1); - - // ------------ Climate Cards Initialization Routine ------------ ESP_LOGD("ISE OS", "Setting up climate cards"); @@ -271,6 +254,9 @@ void setup() weather.registerCallback(&weatherupdatedisplay); pm_switch.registerCallback(&pmswitchupdatedisplay); pm_fan_speed.registerCallback(&pmfanspeedupdatedisplay); + pm_lock.registerCallback(&pmlockupdatedisplay); + ac_lock.registerCallback(&aclockupdatedisplay); + // PM2.5 PPM Remote Variable pm25_out.begin(6, "/aqi/value", espmega.iot, true, "/aqi/request_value"); @@ -286,6 +272,12 @@ void setup() // Air Purifier Fan Speed Remote Variable pm_fan_speed.begin(6, "/pm/fan_speed", espmega.iot, true, "/pm/request_fan_speed"); pm_fan_speed.enableSetValue("/pm/set_fan_speed"); + // Air Purifier Lock Remote Variable + pm_lock.begin(6, "/pm/lock_state", espmega.iot, true, "/pm/request_lock_pm_state"); + pm_lock.enableSetValue("/pm/set_lock_pm_state"); + // Air Conditioner Lock Remote Variable + ac_lock.begin(6, "/ac/lock_state", espmega.iot, true, "/ac/request_lock_ac_state"); + ac_lock.enableSetValue("/ac/set_lock_ac_state"); // ------------ End Remote Variables Initialization Routine ------------ @@ -299,7 +291,7 @@ void setup() // ------------ External Display Initialization Routine ------------ auto bindedGetTime = std::bind(&ESPMegaPRO::getTime, &espmega); - iseDisplay.begin(&espmega.inputs, &espmega.outputs, &climateCard_daikin, &climateCard_york, &pm_switch, &pm_fan_speed); + iseDisplay.begin(&espmega.inputs, &espmega.outputs, &climateCard_daikin, &climateCard_york, &pm_switch, &pm_fan_speed, &pm_lock, &ac_lock); espmega.iot->registerRelativeMqttCallback(&handleMqttMessage); iseDisplay.registerPageChangeCallback(&handlePageChange); // ------------ End External Display Initialization Routine ------------ @@ -315,11 +307,11 @@ void pm25inupdatedisplay(char *value) } void tempoutupdatedisplay(char *value) { - iseDisplay.updateTempOutside(get_temp_out()); + //iseDisplay.updateTempOutside(get_temp_out()); } void weatherupdatedisplay(char *value) { - iseDisplay.updateWeather(weather.getValue()); + //iseDisplay.updateWeather(weather.getValue()); } void pmfanspeedupdatedisplay(char *value) { @@ -331,6 +323,18 @@ void pmswitchupdatedisplay(char *value) iseDisplay.updateAirPurifierState(); ESP_LOGI("PM switch", "toggling PM switch state from: %d to %d", pm_switch.getValue(), !pm_switch.getValue()); } +void pmlockupdatedisplay(char *value) +{ + ESP_LOGI("PM lock", "getting PM lock state from MQTT: %d", pm_lock.getValue()); + iseDisplay.updateAirPurifierState(); + ESP_LOGI("PM lock", "toggling PM lock state from: %d to %d", pm_lock.getValue(), !pm_lock.getValue()); +} +void aclockupdatedisplay(char *value) +{ + ESP_LOGI("AC lock", "getting AC lock state from MQTT: %d", ac_lock.getValue()); + iseDisplay.updateACState(); + ESP_LOGI("AC lock", "toggling AC lock state from: %d to %d", ac_lock.getValue(), !ac_lock.getValue()); +} void loop() { @@ -418,6 +422,20 @@ uint8_t get_pm_fanspeed() return pm_fan_speed_value; } +bool get_pm_lock() +{ + ESP_LOGI("PM lock", "getting PM lock state from MQTT: %d", pm_lock.getValue()); + bool is_pm_lock_on = strcmp(pm_lock.getValue(), "on") == 0; + return is_pm_lock_on; +} + +bool get_ac_lock() +{ + ESP_LOGI("AC lock", "getting AC lock state from MQTT: %d", ac_lock.getValue()); + bool is_ac_lock_on = strcmp(ac_lock.getValue(), "on") == 0; + return is_ac_lock_on; +} + /** * @brief Get the PM switch state from home assistant * @return true if the PM switch is on, false if the PM switch is off @@ -436,6 +454,20 @@ void toggle_pm_switch() pm_switch.setValue(is_pm_switch_on ? "0" : "1"); } +void toggle_ac_lock() +{ + bool is_ac_lock_on = get_ac_lock(); + ESP_LOGI("AC lock", "toggling AC lock state from: %d to %d", is_ac_lock_on, !is_ac_lock_on); + ac_lock.setValue(is_ac_lock_on ? "0" : "1"); +} + +void toggle_pm_lock() +{ + bool is_pm_lock_on = get_pm_lock(); + ESP_LOGI("PM lock", "toggling PM lock state from: %d to %d", is_pm_lock_on, !is_pm_lock_on); + pm_lock.setValue(is_pm_lock_on ? "0" : "1"); +} + void set_pm_fanspeed(uint8_t speed) { ESP_LOGI("PM fan speed", "setting PM fan speed to: %d", speed); @@ -458,6 +490,7 @@ void handlePageChange(uint8_t page) case PAGE_DASHBOARD: iseDisplay.updateLightGroupStatePageDashboard(); iseDisplay.updateAirPurifierState(); + iseDisplay.updateSystemtoggle(); break; default: break; @@ -465,8 +498,8 @@ void handlePageChange(uint8_t page) iseDisplay.updatePMoutside(get_pm25_out()); iseDisplay.updatePMinside(get_pm25_in()); - iseDisplay.updateWeather(weather.getValue()); - iseDisplay.updateTempOutside(get_temp_out()); + //iseDisplay.updateWeather(weather.getValue()); + //iseDisplay.updateTempOutside(get_temp_out()); iseDisplay.updateACState(); } diff --git a/src/main.hpp b/src/main.hpp index 99824e8..580d03f 100644 --- a/src/main.hpp +++ b/src/main.hpp @@ -51,6 +51,10 @@ void on_pin_change(uint8_t pin, uint8_t value); uint16_t get_pm25_out(); uint16_t get_pm25_in(); float get_temp_out(); +bool get_pm_lock(); +bool get_ac_lock(); +void toggle_ac_lock(); +void toggle_pm_lock(); void toggle_pm_switch(); void set_pm_fanspeed(uint8_t speed); void display_update(); @@ -59,5 +63,7 @@ void pm25inupdatedisplay(char* value); void tempoutupdatedisplay(char* value); void weatherupdatedisplay(char* value); void pmfanspeedupdatedisplay(char* value); +void pmlockupdatedisplay(char* value); +void aclockupdatedisplay(char* value); void pmswitchupdatedisplay(char* value); float adc2current(uint16_t adc_val); \ No newline at end of file