#include uint8_t user_acmode = 1; // Display Componets // Link with Dual state button object with id 2 on page 1 named bt0 NexButton light_toggle = NexButton(1, 2, "light_toggle"); NexButton row1_master = NexButton(1, 11, "row1_master"); NexButton row2_master = NexButton(1, 12, "row2_master"); NexButton row3_master = NexButton(1, 14, "row3_master"); NexButton row4_master = NexButton(1, 13, "row4_master"); NexButton row1_lv1 = NexButton(1, 3, "row1_lv1"); NexButton row1_lv2 = NexButton(1, 4, "row1_lv2"); NexButton row2_lv1 = NexButton(1, 5, "row2_lv1"); NexButton row2_lv2 = NexButton(1, 6, "row2_lv2"); NexButton row3_lv1 = NexButton(1, 10, "row3_lv1"); NexButton row3_lv2 = NexButton(1, 7, "row3_lv2"); NexButton row4_lv1 = NexButton(1, 9, "row4_lv1"); NexButton row4_lv2 = NexButton(1, 8, "row4_lv2"); NexButton temp_plus = NexButton(1, 18, "temp_plus"); NexButton temp_neg = NexButton(1, 17, "temp_neg"); NexButton fan = NexButton(1, 16, "fan"); NexButton mode = NexButton(1, 15, "mode"); NexButton air_toggle = NexButton(1, 1, "air_toggle"); NexText cur_temp = NexText(1, 19, "cur_temp"); // List of Component ID Message to listen to NexTouch *nex_listen_list[] = { &light_toggle, &row1_master, &row2_master, &row3_master, &row4_master, &row1_lv1, &row1_lv2, &row2_lv1, &row2_lv2, &row3_lv1, &row3_lv2, &row4_lv1, &row4_lv2, &temp_plus, &temp_neg, &fan, &mode, &air_toggle, NULL}; bool row_is_on(int light1_pin, int light2_pin) { return pwm_get_state(light1_pin) && pwm_get_state(light2_pin); } bool row_is_on_or(int light1_pin, int light2_pin) { return pwm_get_state(light1_pin) || pwm_get_state(light2_pin); } void light_toggle_pop_callback(void *ptr) { bool new_state = !row_is_on(ROW1_LIGHT1, ROW1_LIGHT2) && !row_is_on(ROW2_LIGHT1, ROW2_LIGHT2) && !row_is_on(ROW3_LIGHT1, ROW3_LIGHT2) && !row_is_on(ROW4_LIGHT1, ROW4_LIGHT2); pwm_set_state(ROW1_LIGHT1, new_state); pwm_set_state(ROW1_LIGHT2, new_state); pwm_set_state(ROW2_LIGHT1, new_state); pwm_set_state(ROW2_LIGHT2, new_state); pwm_set_state(ROW3_LIGHT1, new_state); pwm_set_state(ROW3_LIGHT2, new_state); pwm_set_state(ROW4_LIGHT1, new_state); pwm_set_state(ROW4_LIGHT2, new_state); } void row1_lv1_pop_callback(void *ptr) { pwm_toggle(ROW1_LIGHT1); } void row1_lv2_pop_callback(void *ptr) { pwm_toggle(ROW1_LIGHT2); } void row2_lv1_pop_callback(void *ptr) { pwm_toggle(ROW2_LIGHT1); } void row2_lv2_pop_callback(void *ptr) { pwm_toggle(ROW2_LIGHT2); } void row3_lv1_pop_callback(void *ptr) { pwm_toggle(ROW3_LIGHT1); } void row3_lv2_pop_callback(void *ptr) { pwm_toggle(ROW3_LIGHT2); } void row4_lv1_pop_callback(void *ptr) { pwm_toggle(ROW4_LIGHT1); } void row4_lv2_pop_callback(void *ptr) { pwm_toggle(ROW4_LIGHT2); } void increase_temp() { uint8_t current_temp = ac_get_temperature(); ac_set_state(ac_get_mode(), current_temp + 1, ac_get_fan_speed()); } void decrease_temp() { uint8_t current_temp = ac_get_temperature(); ac_set_state(ac_get_mode(), current_temp - 1, ac_get_fan_speed()); } void temp_plus_pop_callback(void *ptr) { increase_temp(); } void temp_neg_pop_callback(void *ptr) { decrease_temp(); } void fan_pop_callback(void *ptr) { uint8_t current_fan_speed = ac_get_fan_speed(); uint8_t new_fan_speed = (current_fan_speed + 1) % 4; // Loop back to 0 when reaching 3 ac_set_state(ac_get_mode(), ac_get_temperature(), new_fan_speed); } void mode_pop_callback(void *ptr) { uint8_t current_mode = ac_get_mode(); //user_acmode = ac_get_mode(); // uint8_t new_mode = (current_mode + 1) % 3; // Loop back to 1 when reaching 2 if (current_mode == 1) { user_acmode = 2; ac_set_state(2, ac_get_temperature(), ac_get_fan_speed()); } else if (current_mode == 2) { user_acmode = 1; ac_set_state(1, ac_get_temperature(), ac_get_fan_speed()); } else { if (user_acmode == 1) { user_acmode = 2; } else { user_acmode = 1; } update_lcd_ac(); } // ac_set_state(new_mode, ac_get_temperature(), ac_get_fan_speed()); } void air_toggle_pop_callback(void *ptr) { // this function should set the state of the AC to toggle between off (mode 0) and the same state as before store in variable acmode // val user_acmode already initialized to 1 (cool mode) if (ac_get_mode() == 0) { ac_set_state(user_acmode, ac_get_temperature(), ac_get_fan_speed()); } else { user_acmode = ac_get_mode(); ac_set_state(0, ac_get_temperature(), ac_get_fan_speed()); } /* if (ac_get_mode() == 0) { //ac_set_state(user_acmode, ac_get_temperature(), ac_get_fan_speed()); } else { user_acmode = ac_get_mode(); ac_set_state(0, ac_get_temperature(), ac_get_fan_speed()); } */ } void row1_master_pop_callback(void *ptr) { bool new_state = !row_is_on(ROW1_LIGHT1, ROW1_LIGHT2); pwm_set_state(ROW1_LIGHT1, new_state); pwm_set_state(ROW1_LIGHT2, new_state); } void row2_master_pop_callback(void *ptr) { bool new_state = !row_is_on(ROW2_LIGHT1, ROW2_LIGHT2); pwm_set_state(ROW2_LIGHT1, new_state); pwm_set_state(ROW2_LIGHT2, new_state); } void row3_master_pop_callback(void *ptr) { bool new_state = !row_is_on(ROW3_LIGHT1, ROW3_LIGHT2); pwm_set_state(ROW3_LIGHT1, new_state); pwm_set_state(ROW3_LIGHT2, new_state); } void row4_master_pop_callback(void *ptr) { bool new_state = !row_is_on(ROW4_LIGHT1, ROW4_LIGHT2); pwm_set_state(ROW4_LIGHT1, new_state); pwm_set_state(ROW4_LIGHT2, new_state); } /* This Code will run right after ESPMega PRO's Peripheral Initialization Routine */ void user_pre_init() { nexInit(); } /* This code will run after every component is initialized */ void user_init() { elcd.print("page main"); elcd_send_stop_bit(); light_toggle.attachPop(light_toggle_pop_callback, &light_toggle); row1_lv1.attachPop(row1_lv1_pop_callback, &row1_lv1); row1_lv2.attachPop(row1_lv2_pop_callback, &row1_lv2); row2_lv1.attachPop(row2_lv1_pop_callback, &row2_lv1); row2_lv2.attachPop(row2_lv2_pop_callback, &row2_lv2); row3_lv1.attachPop(row3_lv1_pop_callback, &row3_lv1); row3_lv2.attachPop(row3_lv2_pop_callback, &row3_lv2); row4_lv1.attachPop(row4_lv1_pop_callback, &row4_lv1); row4_lv2.attachPop(row4_lv2_pop_callback, &row4_lv2); row1_master.attachPop(row1_master_pop_callback, &row1_master); row2_master.attachPop(row2_master_pop_callback, &row2_master); row3_master.attachPop(row3_master_pop_callback, &row3_master); row4_master.attachPop(row4_master_pop_callback, &row4_master); temp_plus.attachPop(temp_plus_pop_callback, &temp_plus); temp_neg.attachPop(temp_neg_pop_callback, &temp_neg); fan.attachPop(fan_pop_callback, &fan); mode.attachPop(mode_pop_callback, &mode); air_toggle.attachPop(air_toggle_pop_callback, &air_toggle); update_lcd_row1(); update_lcd_row2(); update_lcd_row3(); update_lcd_row4(); update_toggle_button(); update_lcd_ac(); } /* This code will run once every event loop */ void user_loop() { nexLoop(nex_listen_list); } /* This code will run when an input pin changed state */ void virtual_interrupt_user_callback(int pin, int state) { } void update_lcd_row1() { bool master_state = row_is_on_or(ROW1_LIGHT1, ROW1_LIGHT2); // row1_master.Set_background_image_pic(master_state?10:9); elcd_send_stop_bit(); elcd.print("row1_master.pic="); elcd.print(master_state ? 10 : 9); elcd_send_stop_bit(); elcd.print("row1_master.pic2="); elcd.print(master_state ? 10 : 9); elcd_send_stop_bit(); bool lt1_state = pwm_get_state(ROW1_LIGHT1); bool lt2_state = pwm_get_state(ROW1_LIGHT2); // also update the light1 and light2 buttons background to reflect the current state // row1_lv1.Set_background_image_pic(lt1_state?6:5); // row1_lv2.Set_background_image_pic(lt2_state?8:7); elcd.print("row1_lv1.pic="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row1_lv2.pic="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); elcd.print("row1_lv1.pic2="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row1_lv2.pic2="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); } void update_lcd_row2() { bool master_state = row_is_on_or(ROW2_LIGHT1, ROW2_LIGHT2); // row2_master.Set_background_image_pic(master_state?12:11); elcd_send_stop_bit(); elcd.print("row2_master.pic="); elcd.print(master_state ? 12 : 11); elcd_send_stop_bit(); elcd.print("row2_master.pic2="); elcd.print(master_state ? 12 : 11); elcd_send_stop_bit(); bool lt1_state = pwm_get_state(ROW2_LIGHT1); bool lt2_state = pwm_get_state(ROW2_LIGHT2); // also update the light1 and light2 buttons background to reflect the current state // row2_lv1.Set_background_image_pic(lt1_state?6:5); // row2_lv2.Set_background_image_pic(lt2_state?8:7); elcd.print("row2_lv1.pic="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row2_lv2.pic="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); elcd.print("row2_lv1.pic2="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row2_lv2.pic2="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); } void update_lcd_row3() { bool master_state = row_is_on_or(ROW3_LIGHT1, ROW3_LIGHT2); // row3_master.Set_background_image_pic(master_state?14:13); elcd_send_stop_bit(); elcd.print("row3_master.pic="); elcd.print(master_state ? 14 : 13); elcd_send_stop_bit(); elcd.print("row3_master.pic2="); elcd.print(master_state ? 14 : 13); elcd_send_stop_bit(); bool lt1_state = pwm_get_state(ROW3_LIGHT1); bool lt2_state = pwm_get_state(ROW3_LIGHT2); // also update the light1 and light2 buttons background to reflect the current state // row3_lv1.Set_background_image_pic(lt1_state?6:5); // row3_lv2.Set_background_image_pic(lt2_state?8:7); elcd.print("row3_lv1.pic="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row3_lv2.pic="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); elcd.print("row3_lv1.pic2="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row3_lv2.pic2="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); } void update_lcd_row4() { bool master_state = row_is_on_or(ROW4_LIGHT1, ROW4_LIGHT2); // row4_master.Set_background_image_pic(master_state?16:15); elcd_send_stop_bit(); elcd.print("row4_master.pic="); elcd.print(master_state ? 16 : 15); elcd_send_stop_bit(); elcd.print("row4_master.pic2="); elcd.print(master_state ? 16 : 15); elcd_send_stop_bit(); bool lt1_state = pwm_get_state(ROW4_LIGHT1); bool lt2_state = pwm_get_state(ROW4_LIGHT2); // also update the light1 and light2 buttons background to reflect the current state // row4_lv1.Set_background_image_pic(lt1_state?6:5); // row4_lv2.Set_background_image_pic(lt2_state?8:7); elcd.print("row4_lv1.pic="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row4_lv2.pic="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); elcd.print("row4_lv1.pic2="); elcd.print(lt1_state ? 6 : 5); elcd_send_stop_bit(); elcd.print("row4_lv2.pic2="); elcd.print(lt2_state ? 8 : 7); elcd_send_stop_bit(); } void update_toggle_button() { // calcuate the current state of the toggle button bool current_state = row_is_on_or(ROW1_LIGHT1, ROW1_LIGHT2) || row_is_on_or(ROW2_LIGHT1, ROW2_LIGHT2) || row_is_on_or(ROW3_LIGHT1, ROW3_LIGHT2) || row_is_on_or(ROW4_LIGHT1, ROW4_LIGHT2); // light_toggle.Set_background_image_pic(current_state?4:3); elcd_send_stop_bit(); elcd.print("light_toggle.pic="); elcd.print(current_state ? 4 : 3); elcd_send_stop_bit(); elcd.print("light_toggle.pic2="); elcd.print(current_state ? 4 : 3); elcd_send_stop_bit(); } void update_lcd_ac() { // update the current temperature char temp_str[3]; sprintf(temp_str, "%d", ac_get_temperature()); cur_temp.setText(temp_str); // update the fan speed auto is 18, high 19, medium 21, low 20 // Fan Speed 0: Auto, 1: High, 2: Mid, 3: Low uint8_t fan_speed = ac_get_fan_speed(); if (fan_speed == 0) { // fan.Set_background_image_pic(18); elcd_send_stop_bit(); elcd.print("fan.pic=18"); elcd_send_stop_bit(); elcd.print("fan.pic2=18"); elcd_send_stop_bit(); } else if (fan_speed == 1) { // fan.Set_background_image_pic(19); elcd_send_stop_bit(); elcd.print("fan.pic=19"); elcd_send_stop_bit(); elcd.print("fan.pic2=19"); elcd_send_stop_bit(); } else if (fan_speed == 2) { // fan.Set_background_image_pic(21); elcd_send_stop_bit(); elcd.print("fan.pic=21"); elcd_send_stop_bit(); elcd.print("fan.pic2=21"); elcd_send_stop_bit(); } else if (fan_speed == 3) { // fan.Set_background_image_pic(20); elcd_send_stop_bit(); elcd.print("fan.pic=20"); elcd_send_stop_bit(); elcd.print("fan.pic2=20"); elcd_send_stop_bit(); } else { // fan.Set_background_image_pic(18); elcd_send_stop_bit(); elcd.print("fan.pic=18"); elcd_send_stop_bit(); elcd.print("fan.pic2=18"); elcd_send_stop_bit(); } // update the mode cool is 22, fan mode is 24, for off the toggle button act as indicator // Mode 0: Off, 1: Cool, 2: Fan //uint8_t mode_state = user_acmode; // mode.Set_background_image_pic(mode_state==1?22:24); elcd_send_stop_bit(); if (ac_get_mode() == 1) { elcd_send_stop_bit(); elcd.print("air_toggle.pic=2"); elcd_send_stop_bit(); elcd.print("air_toggle.pic2=2"); elcd_send_stop_bit(); elcd.print("mode.pic=22"); elcd_send_stop_bit(); elcd.print("mode.pic2=22"); elcd_send_stop_bit(); } else if (ac_get_mode() == 2) { elcd_send_stop_bit(); elcd.print("air_toggle.pic=2"); elcd_send_stop_bit(); elcd.print("air_toggle.pic2=2"); elcd_send_stop_bit(); elcd.print("mode.pic=24"); elcd_send_stop_bit(); elcd.print("mode.pic2=24"); elcd_send_stop_bit(); } else if (ac_get_mode() == 0) { elcd_send_stop_bit(); elcd.print("air_toggle.pic=1"); elcd_send_stop_bit(); elcd.print("air_toggle.pic2=1"); if (user_acmode == 1) { elcd_send_stop_bit(); elcd.print("mode.pic=22"); elcd_send_stop_bit(); elcd.print("mode.pic2=22"); elcd_send_stop_bit(); } else { elcd_send_stop_bit(); elcd.print("mode.pic=24"); elcd_send_stop_bit(); elcd.print("mode.pic2=24"); elcd_send_stop_bit(); } } /* elcd.print("mode.pic="); elcd.print(mode_state==1?22:24); elcd_send_stop_bit(); elcd.print("mode.pic2="); elcd.print(mode_state==1?22:24); elcd_send_stop_bit(); //update the ac toggle button //air_toggle.Set_background_image_pic(ac_get_mode()==0?1:2); elcd_send_stop_bit(); elcd.print("air_toggle.pic="); elcd.print(ac_get_mode()==0?2:1); elcd_send_stop_bit(); elcd.print("air_toggle.pic2="); elcd.print(ac_get_mode()==0?2:1); elcd_send_stop_bit(); */ } void pwm_changed_user_callback(int pin) { switch (pin) { case ROW1_LIGHT1: case ROW1_LIGHT2: update_lcd_row1(); update_toggle_button(); break; case ROW2_LIGHT1: case ROW2_LIGHT2: update_lcd_row2(); update_toggle_button(); break; case ROW3_LIGHT1: case ROW3_LIGHT2: update_lcd_row3(); update_toggle_button(); break; case ROW4_LIGHT1: case ROW4_LIGHT2: update_lcd_row4(); update_toggle_button(); break; default: break; } } /* This code will run every 15 seconds */ void timer_tick_callback() { if (standalone) { } } void ac_changed_user_callback(int mode, int temperature, int fan_speed) { update_lcd_ac(); } void mqtt_connected_user_callback() { } void user_state_request_callback() { } void user_mqtt_callback(char *topic, uint8_t topic_length, char *payload, unsigned int payload_length) { } void elcd_send_stop_bit() { elcd.write(0xFF); elcd.write(0xFF); elcd.write(0xFF); }