2023-09-29 16:18:21 +00:00
# include <espmega_iot_core.hpp>
2023-09-28 07:55:02 +00:00
// OS Configuration
2023-09-30 14:09:45 +00:00
// #define FASTBOOT
# define ESPMEGA_REV "ESPMega PRO R3.3b"
2023-09-28 07:55:02 +00:00
2023-08-25 18:38:17 +00:00
// Network Connectivity
2023-09-11 17:37:33 +00:00
char HOSTNAME [ 15 ] ;
IPAddress IP ( 0 , 0 , 0 , 0 ) ;
IPAddress SUBNET ( 0 , 0 , 0 , 0 ) ;
IPAddress GATEWAY ( 0 , 0 , 0 , 0 ) ;
IPAddress DNS ( 0 , 0 , 0 , 0 ) ;
IPAddress MQTT_SERVER ( 0 , 0 , 0 , 0 ) ;
uint16_t MQTT_PORT = 0 ;
2023-09-29 19:54:38 +00:00
WebServer otaserver ( 80 ) ;
2023-09-03 09:28:01 +00:00
bool standalone = true ;
2023-09-11 18:11:49 +00:00
// #define MQTT_BASE_TOPIC "/espmega/ProR3"
char MQTT_BASE_TOPIC [ 20 ] ;
uint8_t base_topic_length = 0 ;
char STATE_REQUEST_TOPIC [ 40 ] ;
2023-11-07 05:19:35 +00:00
bool MQTT_USE_AUTH = false ;
char MQTT_USERNAME [ 32 ] ;
char MQTT_PASSWORD [ 32 ] ;
2023-09-16 18:12:29 +00:00
uint8_t utc_offset = 7 ;
2023-10-03 20:14:33 +00:00
float current_room_temp = 0 ;
float current_room_humid = 0 ;
2023-08-25 18:38:17 +00:00
// Inputs
2023-08-26 08:22:59 +00:00
# define VINT_COUNT 16
2023-08-25 18:38:17 +00:00
const int DEBOUNCE_TIME_MS = 50 ;
2023-08-26 08:22:59 +00:00
const int virtual_interrupt_pins [ VINT_COUNT ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 } ;
int virtual_interupt_state [ VINT_COUNT ] ;
unsigned long virtual_interupt_timer [ VINT_COUNT ] ;
2023-08-25 18:38:17 +00:00
// Outputs
# define PWM_COUNT 16
2023-09-11 09:13:09 +00:00
const uint8_t pwm_pins [ PWM_COUNT ] = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 , 11 , 12 , 13 , 14 , 15 } ;
bool pwm_states [ PWM_COUNT ] ;
uint8_t pwm_states_eeprom [ PWM_COUNT ] ;
uint16_t pwm_values [ PWM_COUNT ] ;
2023-09-11 17:37:33 +00:00
uint8_t pwm_values_eeprom [ PWM_COUNT * 2 ] ;
2023-09-10 07:24:27 +00:00
// output = m*input+c
const float pwm_linear_scaling_m [ PWM_COUNT ] = { 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 } ;
const float pwm_linear_scaling_c [ PWM_COUNT ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
2023-08-25 18:38:17 +00:00
# define PWM_CYCLE_VALUES_COUNT 3
const int PWM_CYCLE_VALUES [ PWM_CYCLE_VALUES_COUNT ] = { 50 , 125 , 255 } ;
2023-09-11 18:11:49 +00:00
char PWM_SET_STATE_TOPIC [ 70 ] ;
char PWM_SET_VALUE_TOPIC [ 70 ] ;
2023-08-25 18:38:17 +00:00
2023-09-03 09:28:01 +00:00
// LCD
int lcd_current_page = 1 ;
2023-09-03 10:41:31 +00:00
int lcd_pwmAdj_id = 0 ;
2023-09-03 09:28:01 +00:00
EasyNex panel ( Serial ) ;
2023-08-28 17:49:11 +00:00
// Air Conditioner Control
/*
Mode 0 : Off , 1 : Cool , 2 : Fan
Fan Speed 0 : Auto , 1 : High , 2 : Mid , 3 : Low
*/
2023-09-29 17:06:49 +00:00
# define DHT22_PIN 32
2023-09-11 09:13:09 +00:00
uint8_t ac_mode = 0 ;
uint8_t ac_fan_speed = 0 ;
uint8_t ac_temperature = 25 ;
2023-09-11 18:11:49 +00:00
char AC_SET_MODE_TOPIC [ 75 ] ;
char AC_SET_FAN_TOPIC [ 75 ] ;
char AC_SET_TEMPERATURE_TOPIC [ 75 ] ;
char AC_MODE_TOPIC [ 75 ] ;
char AC_FAN_TOPIC [ 75 ] ;
char AC_TEMPERATURE_TOPIC [ 75 ] ;
char AC_ROOM_TEMPERATURE_TOPIC [ 75 ] ;
char AC_HUMIDITY_TOPIC [ 75 ] ;
2023-08-27 19:07:04 +00:00
2023-09-11 17:37:33 +00:00
// EEPROM ADDRESS
2023-11-07 08:49:11 +00:00
# define EEPROM_ADDRESS_AC_MODE 0 // 01bytes
# define EEPROM_ADDRESS_AC_TEMPERATURE 1 // 01bytes
# define EEPROM_ADDRESS_AC_FAN_SPEED 2 // 01bytes
# define EEPROM_ADDRESS_PWM_STATE 3 // 16bytes, thru 18
# define EEPROM_ADDRESS_PWM_VALUE 19 // 32bytes, thru 50
# define EEPROM_ADDRESS_HOSTNAME 65 // 15bytes, thru 79
# define EEPROM_ADDRESS_TOPIC 80 // 20bytes, thru 99
# define EEPROM_ADDRESS_IP 100 // 04bytes, thru 103
# define EEPROM_ADDRESS_SUBNET 104 // 04bytes, thru 107
# define EEPROM_ADDRESS_GATEWAY 108 // 04bytes, thru 111
# define EEPROM_ADDRESS_DNS 112 // 04bytes, thru 115
# define EEPROM_ADDRESS_MQTT_SERVER 116 // 04bytes, thru 119
# define EEPROM_ADDRESS_MQTT_PORT 120 // 02bytes, thru 121
# define EEPROM_ADDRESS_MQTT_USERNAME 122 // 32bytes, thru 153
# define EEPROM_ADDRESS_MQTT_PASSWORD 154 // 32bytes, thru 185
# define EEPROM_ADDRESS_MQTT_USEAUTH 186 // 1bytes
2023-09-11 17:37:33 +00:00
2023-09-11 18:11:49 +00:00
char PWM_STATE_TOPIC [ 75 ] ;
char PWM_VALUE_TOPIC [ 75 ] ;
char INPUTS_TOPIC [ 75 ] ;
2023-08-26 08:22:59 +00:00
2023-08-25 18:38:17 +00:00
WiFiClient eth ;
PubSubClient mqtt_client ( MQTT_SERVER , 1883 , eth ) ;
PubSubClientTools mqtt ( mqtt_client ) ;
2023-08-28 17:49:11 +00:00
DHTNEW env_sensor ( DHT22_PIN ) ;
2023-08-25 18:38:17 +00:00
Thread mqtt_reconnector = Thread ( ) ;
2023-08-28 17:49:11 +00:00
Thread environment_reporter = Thread ( ) ;
2023-09-11 09:13:09 +00:00
Thread eeprom_pwm_updater = Thread ( ) ;
2023-09-29 17:06:49 +00:00
Thread user_timer_tick = Thread ( ) ;
StaticThreadController < 4 > thread_controller ( & mqtt_reconnector , & environment_reporter , & eeprom_pwm_updater , & user_timer_tick ) ;
2023-08-25 18:38:17 +00:00
2023-09-03 09:28:01 +00:00
Thread top_bar_updater = Thread ( ) ;
Thread page_updater = Thread ( ) ;
StaticThreadController < 2 > lcd_thread_controller ( & top_bar_updater , & page_updater ) ;
2023-08-25 18:38:17 +00:00
void setup ( )
{
Serial . begin ( 115200 ) ;
2023-09-30 14:09:45 +00:00
# ifdef ENABLE_EXTERNAL_LCD
Serial2 . begin ( 115200 , SERIAL_8N1 , RXD2 , TXD2 ) ;
# endif
2023-09-03 09:28:01 +00:00
panel . begin ( 115200 ) ;
2023-09-11 17:37:33 +00:00
Serial . println ( " ESPMega R3 Initializing " ) ;
2023-08-26 05:53:25 +00:00
ESPMega_begin ( ) ;
2023-08-26 10:28:21 +00:00
io_begin ( ) ;
2023-09-11 09:13:09 +00:00
eeprom_retrieve_init ( ) ;
2023-10-02 20:47:12 +00:00
user_pre_init ( ) ;
2023-09-11 17:37:33 +00:00
lcd_send_stop_bit ( ) ;
lcd_init ( ) ;
lcd_begin ( ) ;
2023-09-30 14:09:45 +00:00
# ifdef ENABLE_EXTERNAL_LCD
2023-09-30 07:28:21 +00:00
Serial2 . print ( " rest " ) ;
Serial2 . write ( 0xFF ) ;
Serial2 . write ( 0xFF ) ;
Serial2 . write ( 0xFF ) ;
2023-09-30 14:09:45 +00:00
# endif
2023-09-11 17:37:33 +00:00
lcd_send_command ( " boot_state.txt= \" Core Initializing . . . \" " ) ;
2023-08-27 19:07:04 +00:00
Serial . println ( " Initializing Infrared . . . " ) ;
2023-09-03 09:28:01 +00:00
lcd_send_command ( " boot_state.txt= \" Infrared Initializing . . . \" " ) ;
2023-08-28 17:49:11 +00:00
IrReceiver . begin ( IR_RECIEVE_PIN ) ;
IrSender . begin ( IR_SEND_PIN ) ;
2023-09-03 09:28:01 +00:00
lcd_send_command ( " boot_state.txt= \" Network Initializing . . . \" " ) ;
2023-08-25 18:38:17 +00:00
network_begin ( ) ;
2023-09-03 09:28:01 +00:00
lcd_send_command ( " boot_state.txt= \" IoT Core Initializing . . . \" " ) ;
2023-08-25 18:38:17 +00:00
mqtt_connect ( ) ;
2023-09-03 09:28:01 +00:00
lcd_send_command ( " boot_state.txt= \" Threads Initializing . . . \" " ) ;
2023-08-25 18:38:17 +00:00
thread_initialization ( ) ;
2023-09-29 19:54:38 +00:00
ota_begin ( ) ;
2023-08-26 08:22:59 +00:00
Serial . println ( " Initialization Completed. " ) ;
Serial . println ( " Jumping to User Code. " ) ;
2023-09-29 16:18:21 +00:00
user_init ( ) ;
2023-09-03 09:28:01 +00:00
lcd_send_command ( " page dashboard " ) ;
2023-08-25 18:38:17 +00:00
}
void loop ( )
{
virtual_interrupt_loop ( ) ;
mqtt_client . loop ( ) ;
ESPMega_loop ( ) ;
2023-08-27 19:07:04 +00:00
ir_loop ( ) ;
2023-08-26 05:53:25 +00:00
thread_controller . run ( ) ;
2023-09-03 09:28:01 +00:00
lcd_loop ( ) ;
2023-09-29 16:18:21 +00:00
user_loop ( ) ;
2023-09-29 19:54:38 +00:00
otaserver . handleClient ( ) ;
2023-08-26 05:53:25 +00:00
}
2023-09-11 09:13:09 +00:00
void eeprom_retrieve_init ( )
{
// EEPROM Data Retrival
2023-09-28 07:55:02 +00:00
ac_mode = ESPMega_FRAM . read8 ( EEPROM_ADDRESS_AC_MODE ) ;
ac_temperature = ESPMega_FRAM . read8 ( EEPROM_ADDRESS_AC_TEMPERATURE ) ;
ac_fan_speed = ESPMega_FRAM . read8 ( EEPROM_ADDRESS_AC_FAN_SPEED ) ;
2023-09-11 09:13:09 +00:00
// EEPROM Data Retrival Validation
if ( ac_mode > 2 )
{
ac_mode = 0 ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write8 ( EEPROM_ADDRESS_AC_MODE , ac_mode ) ;
2023-09-11 09:13:09 +00:00
}
if ( ac_temperature > AC_MAX_TEMPERATURE | | ac_temperature < AC_MIN_TEMPERATURE )
{
ac_temperature = AC_MAX_TEMPERATURE ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write8 ( EEPROM_ADDRESS_AC_TEMPERATURE , ac_temperature ) ;
2023-09-11 09:13:09 +00:00
}
if ( ac_fan_speed > 3 )
{
ac_fan_speed = 0 ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write8 ( EEPROM_ADDRESS_AC_TEMPERATURE , ac_fan_speed ) ;
2023-09-11 09:13:09 +00:00
}
2023-09-11 17:37:33 +00:00
ac_set_state ( ac_mode , ac_temperature , ac_fan_speed ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_PWM_STATE , pwm_states_eeprom , 16 ) ;
2023-09-11 09:13:09 +00:00
memcpy ( pwm_states , pwm_states_eeprom , 16 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_PWM_VALUE , pwm_values_eeprom , 32 ) ;
2023-09-11 09:13:09 +00:00
memcpy ( pwm_values , pwm_values_eeprom , 32 ) ;
2023-09-11 17:37:33 +00:00
for ( int i = 0 ; i < 15 ; i + + )
{
if ( pwm_states [ i ] < = 1 )
pwm_set_state ( i , pwm_states [ i ] ) ;
else
pwm_set_state ( i , 0 ) ;
if ( pwm_values [ i ] < = 4095 )
pwm_set_value ( i , pwm_values [ i ] ) ;
else
pwm_set_value ( i , 0 ) ;
2023-09-11 09:13:09 +00:00
}
2023-09-11 17:37:33 +00:00
IP = eeprom_ip_retrieve ( EEPROM_ADDRESS_IP ) ;
SUBNET = eeprom_ip_retrieve ( EEPROM_ADDRESS_SUBNET ) ;
GATEWAY = eeprom_ip_retrieve ( EEPROM_ADDRESS_GATEWAY ) ;
DNS = eeprom_ip_retrieve ( EEPROM_ADDRESS_DNS ) ;
MQTT_SERVER = eeprom_ip_retrieve ( EEPROM_ADDRESS_MQTT_SERVER ) ;
eeprom_hostname_retrieve ( ) ;
eeprom_mqtt_port_retrieve ( ) ;
2023-11-07 05:19:35 +00:00
eeprom_mqtt_useauth_retrieve ( ) ;
eeprom_mqtt_username_retrieve ( ) ;
eeprom_mqtt_password_retrieve ( ) ;
2023-09-11 17:37:33 +00:00
mqtt_client . setServer ( MQTT_SERVER , MQTT_PORT ) ;
2023-09-11 18:11:49 +00:00
eeprom_basetopic_retrieve ( ) ;
2023-09-30 14:09:45 +00:00
base_topic_length = strlen ( MQTT_BASE_TOPIC ) + 1 ;
2023-09-11 18:11:49 +00:00
memcpy ( STATE_REQUEST_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( STATE_REQUEST_TOPIC , " /requeststate " ) ;
memcpy ( PWM_SET_STATE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( PWM_SET_STATE_TOPIC , " /pwm/00/set/state " ) ;
memcpy ( PWM_SET_VALUE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( PWM_SET_VALUE_TOPIC , " /pwm/00/set/value " ) ;
memcpy ( AC_SET_MODE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_SET_MODE_TOPIC , " /ac/set/mode " ) ;
memcpy ( AC_SET_FAN_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_SET_FAN_TOPIC , " /ac/set/fan_speed " ) ;
memcpy ( AC_SET_TEMPERATURE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_SET_TEMPERATURE_TOPIC , " /ac/set/temperature " ) ;
memcpy ( AC_MODE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_MODE_TOPIC , " /ac/mode " ) ;
memcpy ( AC_FAN_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_FAN_TOPIC , " /ac/fan_speed " ) ;
memcpy ( AC_TEMPERATURE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_TEMPERATURE_TOPIC , " /ac/temperature " ) ;
memcpy ( AC_ROOM_TEMPERATURE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_ROOM_TEMPERATURE_TOPIC , " /ac/room_temperature " ) ;
memcpy ( AC_HUMIDITY_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( AC_HUMIDITY_TOPIC , " /ac/humidity " ) ;
memcpy ( PWM_STATE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( PWM_STATE_TOPIC , " /pwm/00/state " ) ;
memcpy ( PWM_VALUE_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( PWM_VALUE_TOPIC , " /pwm/00/value " ) ;
memcpy ( INPUTS_TOPIC , MQTT_BASE_TOPIC , 20 ) ;
strcat ( INPUTS_TOPIC , " /input/00 " ) ;
2023-09-11 09:13:09 +00:00
}
2023-09-30 14:09:45 +00:00
void ota_begin ( )
{
otaserver . on ( " / " , HTTP_GET , [ ] ( )
{
2023-09-29 19:54:38 +00:00
otaserver . sendHeader ( " Connection " , " close " ) ;
2023-11-07 09:03:46 +00:00
String otabuffer = ota_part1 ;
otabuffer + = ota_part2_1 + " Hostname " + ota_part2_2 + String ( HOSTNAME ) + ota_part2_3 ;
otabuffer + = ota_part2_1 + " IP Address " + ota_part2_2 + IP . toString ( ) + ota_part2_3 ;
otabuffer + = ota_part2_1 + " MAC Address " + ota_part2_2 + ETH . macAddress ( ) + ota_part2_3 ;
otabuffer + = ota_part2_1 + " Device " + ota_part2_2 + ESPMEGA_REV + ota_part2_3 ;
otabuffer + = ota_part2_1 + " BMS Server " + ota_part2_2 + MQTT_SERVER . toString ( ) + ota_part2_3 ;
otabuffer + = ota_part2_1 + " BMS Endpoint " + ota_part2_2 + String ( MQTT_BASE_TOPIC ) + ota_part2_3 ;
otabuffer + = ota_part2_1 + " Centrally Managed " + ota_part2_2 ;
2023-09-30 14:09:45 +00:00
if ( standalone )
otabuffer + = String ( " No " ) ;
else
otabuffer + = String ( " Yes " ) ;
2023-11-07 09:03:46 +00:00
otabuffer + = ota_part2_3 + ota_part3 ;
2023-09-30 14:09:45 +00:00
otaserver . send ( 200 , " text/html " , otabuffer ) ; } ) ;
2023-11-07 09:46:47 +00:00
otaserver . on ( " /config " , HTTP_GET , [ ] ( )
{
otaserver . sendHeader ( " Connection " , " close " ) ;
String configbuffer = config_part1 ;
configbuffer + = config_part1 ;
configbuffer + = config_txt_part1 + " IP Address " + config_txt_part2 + " text " + config_txt_part3 + " dev_ip " + config_txt_part4 + " dev_ip " + config_txt_part5 + IP . toString ( ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " Network Mask " + config_txt_part2 + " text " + config_txt_part3 + " netmask " + config_txt_part4 + " netmask " + config_txt_part5 + IP . toString ( ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " Gateway " + config_txt_part2 + " text " + config_txt_part3 + " gateway " + config_txt_part4 + " gateway " + config_txt_part5 + GATEWAY . toString ( ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " DNS Server " + config_txt_part2 + " text " + config_txt_part3 + " dns " + config_txt_part4 + " dns " + config_txt_part5 + DNS . toString ( ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " Hostname " + config_txt_part2 + " text " + config_txt_part3 + " hostname " + config_txt_part4 + " hostname " + config_txt_part5 + String ( HOSTNAME ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " BMS Server - IP Address " + config_txt_part2 + " text " + config_txt_part3 + " bms_ip " + config_txt_part4 + " bms_ip " + config_txt_part5 + MQTT_SERVER . toString ( ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " BMS Server - Port " + config_txt_part2 + " text " + config_txt_part3 + " bms_port " + config_txt_part4 + " bms_port " + config_txt_part5 + String ( MQTT_PORT ) + config_txt_part6 ;
configbuffer + = config_auth_part1 + ( MQTT_USE_AUTH ? " yes " : " no " ) + config_auth_part2 ;
configbuffer + = config_txt_part1 + " BMS Server - Username " + config_txt_part2 + " text " + config_txt_part3 + " bms_username " + config_txt_part4 + " bms_username " + config_txt_part5 + String ( MQTT_USERNAME ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " BMS Server - Password " + config_txt_part2 + " password " + config_txt_part3 + " bms_password " + config_txt_part4 + " bms_password " + config_txt_part5 + String ( MQTT_PASSWORD ) + config_txt_part6 ;
configbuffer + = config_txt_part1 + " BMS Server - Endpoint " + config_txt_part2 + " text " + config_txt_part3 + " bms_endpoint " + config_txt_part4 + " bms_endpoint " + config_txt_part5 + String ( MQTT_BASE_TOPIC ) + config_txt_part6 ;
configbuffer + = config_part2 ;
otaserver . send ( 200 , " text/html " , configbuffer ) ; } ) ;
2023-09-30 14:09:45 +00:00
otaserver . on (
" /update " , HTTP_POST , [ ] ( )
{
2023-09-29 19:54:38 +00:00
otaserver . sendHeader ( " Connection " , " close " ) ;
otaserver . send ( 200 , " text/plain " , ( Update . hasError ( ) ) ? " FAIL " : " OK " ) ;
2023-09-30 14:09:45 +00:00
ESP . restart ( ) ; } ,
[ ] ( )
{
HTTPUpload & upload = otaserver . upload ( ) ;
if ( upload . status = = UPLOAD_FILE_START )
{
2023-10-01 05:32:12 +00:00
lcd_send_command ( " page ota " ) ;
2023-10-01 06:48:02 +00:00
Serial . println ( upload . currentSize ) ;
2023-10-01 05:32:12 +00:00
String otafiletxt = " Downloading File : " + upload . filename ;
2023-10-01 06:48:02 +00:00
lcd_send_stop_bit ( ) ;
panel . writeStr ( " otatxt.txt " , otafiletxt ) ;
2023-09-30 14:09:45 +00:00
Serial . printf ( " Update: %s \n " , upload . filename . c_str ( ) ) ;
if ( ! Update . begin ( UPDATE_SIZE_UNKNOWN ) )
{
2023-10-01 06:48:02 +00:00
panel . writeStr ( " otatxt.txt " , " Update Failed, Rebooting . . . " ) ;
2023-09-30 14:09:45 +00:00
Update . printError ( Serial ) ;
}
}
else if ( upload . status = = UPLOAD_FILE_WRITE )
{
if ( Update . write ( upload . buf , upload . currentSize ) ! = upload . currentSize )
{
2023-10-01 06:48:02 +00:00
panel . writeStr ( " otatxt.txt " , " Update Failed, Rebooting . . . " ) ;
2023-09-30 14:09:45 +00:00
Update . printError ( Serial ) ;
}
2023-10-01 06:48:02 +00:00
if ( upload . currentSize ! = 0 & & upload . totalSize ! = 0 )
{
lcd_send_stop_bit ( ) ;
uint32_t totalsize_kb = upload . totalSize / 1000 ;
2023-10-02 11:02:17 +00:00
uint32_t upload_pct = 100 * upload . totalSize / 1000000 ;
String otafiletxt = " Downloading File : " + upload . filename + " ( " + String ( totalsize_kb ) + " KB) " ;
2023-10-01 06:48:02 +00:00
panel . writeNum ( " prog.val " , upload_pct ) ;
panel . writeStr ( " otatxt.txt " , otafiletxt ) ;
}
2023-09-30 14:09:45 +00:00
}
else if ( upload . status = = UPLOAD_FILE_END )
{
if ( Update . end ( true ) )
{
2023-10-01 06:48:02 +00:00
panel . writeStr ( " otatxt.txt " , " Update Completed, Rebooting . . . " ) ;
2023-09-30 14:09:45 +00:00
Serial . printf ( " Update Success: %u \n Rebooting... \n " , upload . totalSize ) ;
}
else
{
2023-10-01 06:48:02 +00:00
panel . writeStr ( " otatxt.txt " , " Update Failed, Rebooting . . . " ) ;
2023-09-30 14:09:45 +00:00
Update . printError ( Serial ) ;
}
}
} ) ;
2023-09-29 19:54:38 +00:00
otaserver . begin ( ) ;
}
2023-08-26 05:53:25 +00:00
void io_begin ( )
{
Serial . println ( " Initializing I/O . . . " ) ;
2023-08-28 17:49:11 +00:00
pinMode ( IR_RECIEVE_PIN , INPUT_PULLUP ) ;
pinMode ( IR_SEND_PIN , OUTPUT ) ;
2023-08-25 18:38:17 +00:00
}
void network_begin ( )
{
2023-08-26 05:53:25 +00:00
Serial . print ( " Initializing Network " ) ;
2023-08-25 18:38:17 +00:00
ETH . begin ( ) ;
2023-08-26 05:53:25 +00:00
ETH . setHostname ( HOSTNAME ) ;
ETH . config ( IP , GATEWAY , SUBNET , DNS , DNS ) ;
2023-09-30 14:09:45 +00:00
# ifndef FASTBOOT
2023-09-16 08:55:34 +00:00
delay ( 1000 ) ;
2023-09-16 18:12:29 +00:00
lcd_send_command ( " boot_state.txt= \" Ethernet Core Initializing \" " ) ;
delay ( 500 ) ;
lcd_send_command ( " boot_state.txt= \" Ethernet Core Initializing . \" " ) ;
delay ( 500 ) ;
lcd_send_command ( " boot_state.txt= \" Ethernet Core Initializing . . \" " ) ;
delay ( 500 ) ;
2023-09-16 08:55:34 +00:00
lcd_send_command ( " boot_state.txt= \" Ethernet Core Initializing . . . \" " ) ;
delay ( 500 ) ;
2023-09-16 18:12:29 +00:00
lcd_send_command ( " boot_state.txt= \" NTP Core Initializing . . . \" " ) ;
2023-09-16 08:55:34 +00:00
delay ( 500 ) ;
2023-09-30 14:09:45 +00:00
# endif
2023-09-16 18:12:29 +00:00
char ntp [ 19 ] ;
2023-09-30 14:09:45 +00:00
MQTT_SERVER . toString ( ) . toCharArray ( ntp , 19 ) ;
ESPMega_configNTP ( utc_offset * 3600 , 0 , ntp ) ;
2023-09-16 18:12:29 +00:00
ESPMega_updateTimeFromNTP ( ) ;
2023-08-26 05:53:25 +00:00
Serial . println ( ) ;
2023-08-25 18:38:17 +00:00
}
void mqtt_connect ( )
{
if ( ! mqtt_client . connected ( ) )
{
Serial . print ( " MQTT not connected, connecting . . . \n " ) ;
2023-09-03 09:28:01 +00:00
lcd_send_stop_bit ( ) ;
2023-11-07 08:49:11 +00:00
if ( MQTT_USE_AUTH )
mqtt_client . connect ( HOSTNAME , MQTT_USERNAME , MQTT_PASSWORD ) ;
else
mqtt_client . connect ( HOSTNAME ) ;
2023-08-25 18:38:17 +00:00
if ( mqtt_client . connected ( ) )
{
mqtt_subscribe ( ) ;
Serial . print ( " MQTT connected \n " ) ;
2023-09-03 09:28:01 +00:00
lcd_send_stop_bit ( ) ;
2023-08-26 08:22:59 +00:00
publish_pwm_states ( ) ;
publish_input_states ( ) ;
2023-08-28 17:49:11 +00:00
publish_ac_state ( ) ;
2023-10-02 19:34:56 +00:00
mqtt_connected_user_callback ( ) ;
2023-09-03 09:28:01 +00:00
standalone = false ;
2023-08-25 18:38:17 +00:00
}
else
{
2023-09-03 09:28:01 +00:00
standalone = true ;
2023-08-25 18:38:17 +00:00
Serial . print ( " MQTT not connected, continuing in standalone mode \n " ) ;
2023-09-03 09:28:01 +00:00
lcd_send_stop_bit ( ) ;
2023-08-25 18:38:17 +00:00
}
2023-09-03 09:28:01 +00:00
lcd_send_stop_bit ( ) ;
lcd_refresh ( ) ;
lcd_top_bar_update ( ) ;
2023-08-25 18:38:17 +00:00
}
}
void mqtt_subscribe ( )
{
2023-08-26 08:22:59 +00:00
for ( int i = 0 ; i < PWM_COUNT ; i + + )
{
2023-09-11 18:11:49 +00:00
PWM_SET_VALUE_TOPIC [ base_topic_length + 4 ] = ( ( i - i % 10 ) / 10 ) + ' 0 ' ;
PWM_SET_VALUE_TOPIC [ base_topic_length + 5 ] = ( i % 10 ) + ' 0 ' ;
PWM_SET_STATE_TOPIC [ base_topic_length + 4 ] = ( ( i - i % 10 ) / 10 ) + ' 0 ' ;
PWM_SET_STATE_TOPIC [ base_topic_length + 5 ] = ( i % 10 ) + ' 0 ' ;
2023-08-26 08:22:59 +00:00
mqtt . subscribe ( PWM_SET_STATE_TOPIC , pwm_state_callback ) ;
mqtt . subscribe ( PWM_SET_VALUE_TOPIC , pwm_value_callback ) ;
}
2023-08-28 17:49:11 +00:00
mqtt . subscribe ( AC_SET_FAN_TOPIC , ac_state_callback ) ;
mqtt . subscribe ( AC_SET_TEMPERATURE_TOPIC , ac_state_callback ) ;
mqtt . subscribe ( AC_SET_MODE_TOPIC , ac_state_callback ) ;
2023-08-26 08:22:59 +00:00
mqtt . subscribe ( STATE_REQUEST_TOPIC , state_request_callback ) ;
2023-08-25 18:38:17 +00:00
}
void thread_initialization ( )
{
2023-08-26 05:53:25 +00:00
Serial . println ( " Initializing Threads . . . " ) ;
Serial . println ( " Initializing MQTT Thread . . . " ) ;
2023-08-25 18:38:17 +00:00
mqtt_reconnector . onRun ( mqtt_connect ) ;
2023-09-03 09:28:01 +00:00
mqtt_reconnector . setInterval ( 15000 ) ;
2023-08-28 17:49:11 +00:00
environment_reporter . onRun ( publish_env_state ) ;
environment_reporter . setInterval ( 5000 ) ;
2023-09-11 09:13:09 +00:00
eeprom_pwm_updater . onRun ( eeprom_pwm_update ) ;
2023-09-28 07:55:02 +00:00
eeprom_pwm_updater . setInterval ( 1000 ) ;
2023-09-29 17:06:49 +00:00
user_timer_tick . onRun ( timer_tick_callback ) ;
2023-09-29 17:37:31 +00:00
user_timer_tick . setInterval ( 15000 ) ;
2023-08-25 18:38:17 +00:00
}
2023-08-26 08:22:59 +00:00
void pwm_state_callback ( String topic , String message )
2023-08-25 18:38:17 +00:00
{
2023-09-11 18:11:49 +00:00
int a = topic . charAt ( base_topic_length + 4 ) - ' 0 ' ;
int b = topic . charAt ( base_topic_length + 5 ) - ' 0 ' ;
2023-08-26 08:22:59 +00:00
int id = 10 * a + b ;
2023-08-28 17:49:11 +00:00
if ( message . compareTo ( " on " ) = = 0 )
2023-08-26 08:22:59 +00:00
{
pwm_set_state ( id , true ) ;
}
2023-08-28 17:49:11 +00:00
else if ( message . compareTo ( " off " ) = = 0 )
2023-08-26 08:22:59 +00:00
{
pwm_set_state ( id , false ) ;
}
}
void pwm_value_callback ( String topic , String message )
{
2023-09-11 18:11:49 +00:00
int a = topic . charAt ( base_topic_length + 4 ) - ' 0 ' ;
int b = topic . charAt ( base_topic_length + 5 ) - ' 0 ' ;
2023-08-26 08:22:59 +00:00
int id = 10 * a + b ;
int value = message . toInt ( ) ;
pwm_set_value ( id , value ) ;
2023-08-25 18:38:17 +00:00
}
void virtual_interrupt_callback ( int pin , int state )
{
2023-09-03 09:28:01 +00:00
2023-08-28 17:49:11 +00:00
publish_input_state ( pin , state ) ;
2023-09-03 09:28:01 +00:00
// Serial.printf("Pin %d changed to %d\n", pin, state);
if ( lcd_current_page = = 2 )
panel . writeNum ( " I " + String ( pin ) + " .val " , state ) ;
2023-09-29 16:18:21 +00:00
virtual_interrupt_user_callback ( pin , state ) ;
2023-08-25 18:38:17 +00:00
}
void virtual_interrupt_loop ( )
{
for ( int i = 0 ; i < 16 ; i + + )
{
int current_pin_value = ESPMega_digitalRead ( virtual_interrupt_pins [ i ] ) ;
if ( virtual_interupt_state [ i ] ! = current_pin_value )
{
if ( millis ( ) - virtual_interupt_timer [ i ] > DEBOUNCE_TIME_MS )
{
virtual_interupt_state [ i ] = current_pin_value ;
virtual_interrupt_callback ( i , current_pin_value ) ;
}
}
else
{
virtual_interupt_timer [ i ] = millis ( ) ;
}
yield ( ) ;
}
}
void publish_pwm_states ( )
{
for ( int i = 0 ; i < PWM_COUNT ; i + + )
{
publish_pwm_state ( i ) ;
}
}
void publish_pwm_state ( int id )
{
2023-08-26 08:22:59 +00:00
int state = pwm_states [ id ] ;
int value = pwm_values [ id ] ;
2023-09-11 18:11:49 +00:00
PWM_STATE_TOPIC [ base_topic_length + 4 ] = ( ( id - id % 10 ) / 10 ) + ' 0 ' ;
PWM_STATE_TOPIC [ base_topic_length + 5 ] = ( id % 10 ) + ' 0 ' ;
PWM_VALUE_TOPIC [ base_topic_length + 4 ] = ( ( id - id % 10 ) / 10 ) + ' 0 ' ;
PWM_VALUE_TOPIC [ base_topic_length + 5 ] = ( id % 10 ) + ' 0 ' ;
2023-08-25 18:38:17 +00:00
if ( state = = 1 )
{
2023-08-26 08:22:59 +00:00
mqtt_client . publish ( PWM_STATE_TOPIC , " on " ) ;
2023-08-25 18:38:17 +00:00
}
else if ( state = = 0 )
{
2023-08-26 08:22:59 +00:00
mqtt_client . publish ( PWM_STATE_TOPIC , " off " ) ;
2023-08-25 18:38:17 +00:00
}
2023-08-26 08:22:59 +00:00
mqtt . publish ( String ( PWM_VALUE_TOPIC ) , String ( value ) ) ;
2023-08-25 18:38:17 +00:00
}
void pwm_set_state ( int id , int state )
{
2023-08-26 08:22:59 +00:00
if ( state ! = pwm_states [ id ] )
2023-08-25 18:38:17 +00:00
{
2023-08-26 08:22:59 +00:00
pwm_states [ id ] = state ;
int pwm_value = pwm_values [ id ] ;
ESPMega_analogWrite ( pwm_pins [ id ] , state * ( int ) ( pwm_linear_scaling_m [ id ] * pwm_value + pwm_linear_scaling_c [ id ] ) ) ;
2023-09-03 09:28:01 +00:00
if ( lcd_current_page = = 3 )
2023-10-03 19:36:27 +00:00
panel . writeNum ( " j " + String ( id ) + " .ppic " , pwm_states [ id ] ? 33 : 48 ) ;
2023-09-03 10:41:31 +00:00
else if ( lcd_current_page = = 5 & & id = = lcd_pwmAdj_id )
panel . writeStr ( " pwm_state.txt " , pwm_states [ lcd_pwmAdj_id ] ? " ON " : " OFF " ) ;
2023-08-25 18:38:17 +00:00
publish_pwm_state ( id ) ;
2023-09-30 08:42:44 +00:00
pwm_changed_user_callback ( id ) ;
2023-08-25 18:38:17 +00:00
}
}
void pwm_set_value ( int id , int value )
{
2023-08-26 08:22:59 +00:00
pwm_values [ id ] = value ;
int pwm_state = pwm_states [ id ] ;
ESPMega_analogWrite ( pwm_pins [ id ] , pwm_state * ( int ) ( pwm_linear_scaling_m [ id ] * value + pwm_linear_scaling_c [ id ] ) ) ;
2023-09-03 09:28:01 +00:00
if ( lcd_current_page = = 3 )
panel . writeNum ( " j " + String ( id ) + " .val " , int ( value / 4095.0 * 100.0 ) ) ;
2023-09-03 10:41:31 +00:00
else if ( lcd_current_page = = 5 & & id = = lcd_pwmAdj_id )
panel . writeNum ( " pwm_value.val " , pwm_values [ lcd_pwmAdj_id ] ) ;
2023-08-25 18:38:17 +00:00
publish_pwm_state ( id ) ;
2023-09-30 08:42:44 +00:00
pwm_changed_user_callback ( id ) ;
2023-08-25 18:38:17 +00:00
}
void pwm_toggle ( int id )
{
2023-08-26 08:22:59 +00:00
int state = ! pwm_states [ id ] ;
2023-08-25 18:38:17 +00:00
pwm_set_state ( id , state ) ;
}
void pwm_toggle ( int id1 , int id2 )
{
boolean state = pwm_group_state ( id1 , id2 ) ;
if ( state )
{
pwm_set_state ( id1 , 0 ) ;
pwm_set_state ( id2 , 0 ) ;
}
else
{
pwm_set_state ( id1 , 1 ) ;
pwm_set_state ( id2 , 1 ) ;
}
}
boolean pwm_group_state ( int id1 , int id2 )
{
int state1 = pwm_states [ id1 - 1 ] , state2 = pwm_states [ id2 - 1 ] ;
if ( state1 | | state2 )
return true ;
return false ;
}
void pwm_cycle_value ( int id )
{
2023-08-26 08:22:59 +00:00
int state = pwm_states [ id ] ;
int value = pwm_values [ id ] ;
2023-08-25 18:38:17 +00:00
if ( state = = 1 )
for ( int i = 0 ; i < PWM_CYCLE_VALUES_COUNT ; i + + )
{
if ( PWM_CYCLE_VALUES [ i ] = = value )
{
if ( i > 0 )
{
pwm_set_value ( id , PWM_CYCLE_VALUES [ i - 1 ] ) ;
return ;
}
else
{
pwm_set_state ( id , 0 ) ;
return ;
}
}
}
pwm_set_state ( id , 1 ) ;
pwm_set_value ( id , PWM_CYCLE_VALUES [ PWM_CYCLE_VALUES_COUNT - 1 ] ) ;
2023-08-26 08:22:59 +00:00
}
void publish_input_states ( )
{
for ( int i = 0 ; i < VINT_COUNT ; i + + )
{
publish_input_state ( i ) ;
}
}
void publish_input_state ( int id )
{
int state = ESPMega_digitalRead ( virtual_interrupt_pins [ id ] ) ;
publish_input_state ( id , state ) ;
}
void publish_input_state ( int id , int state )
{
2023-09-11 18:11:49 +00:00
INPUTS_TOPIC [ base_topic_length + 6 ] = ( ( id - id % 10 ) / 10 ) + ' 0 ' ;
INPUTS_TOPIC [ base_topic_length + 7 ] = ( id % 10 ) + ' 0 ' ;
2023-08-26 08:22:59 +00:00
mqtt . publish ( String ( INPUTS_TOPIC ) , state ? " 1 " : " 0 " ) ;
}
void state_request_callback ( String topic , String message )
{
publish_input_states ( ) ;
publish_pwm_states ( ) ;
2023-08-28 17:49:11 +00:00
publish_ac_state ( ) ;
2023-10-02 19:24:30 +00:00
user_state_request_callback ( ) ;
2023-08-27 19:07:04 +00:00
}
2023-08-28 17:49:11 +00:00
void ir_loop ( )
{
if ( IrReceiver . decode ( ) )
{
2023-09-03 09:28:01 +00:00
// Serial.println();
// IrReceiver.compensateAndPrintIRResultAsCArray(&Serial, false);
// Serial.println();
// Serial.println();
2023-08-28 17:49:11 +00:00
IrReceiver . resume ( ) ;
}
}
void publish_ac_state ( )
{
String temp = " " ;
switch ( ac_mode )
{
case 0 :
temp = " off " ;
break ;
case 1 :
temp = " cool " ;
break ;
case 2 :
2023-09-13 05:03:35 +00:00
temp = " fan_only " ;
2023-08-28 17:49:11 +00:00
default :
break ;
}
mqtt . publish ( String ( AC_MODE_TOPIC ) , temp ) ;
mqtt . publish ( String ( AC_TEMPERATURE_TOPIC ) , String ( ac_temperature ) ) ;
switch ( ac_fan_speed )
{
case 0 :
temp = " auto " ;
break ;
case 1 :
temp = " high " ;
break ;
case 2 :
temp = " med " ;
break ;
case 3 :
temp = " low " ;
break ;
}
mqtt . publish ( String ( AC_FAN_TOPIC ) , temp ) ;
}
void ac_state_callback ( String topic , String message )
{
if ( topic . compareTo ( String ( AC_SET_TEMPERATURE_TOPIC ) ) = = 0 )
{
int new_temp = message . toInt ( ) ;
if ( new_temp > = AC_MIN_TEMPERATURE & & new_temp < = AC_MAX_TEMPERATURE )
{
ac_set_state ( ac_mode , new_temp , ac_fan_speed ) ;
}
}
else if ( topic . compareTo ( String ( AC_SET_MODE_TOPIC ) ) = = 0 )
{
if ( message . compareTo ( " off " ) = = 0 )
{
ac_set_state ( 0 , ac_temperature , ac_fan_speed ) ;
2023-08-27 19:07:04 +00:00
}
2023-08-28 17:49:11 +00:00
else if ( message . compareTo ( " cool " ) = = 0 )
{
ac_set_state ( 1 , ac_temperature , ac_fan_speed ) ;
}
2023-09-13 05:03:35 +00:00
else if ( message . compareTo ( " fan_only " ) = = 0 )
2023-08-28 17:49:11 +00:00
{
ac_set_state ( 2 , ac_temperature , ac_fan_speed ) ;
}
}
else if ( topic . compareTo ( String ( AC_SET_FAN_TOPIC ) ) = = 0 )
{
if ( message . compareTo ( " auto " ) = = 0 )
{
ac_set_state ( ac_mode , ac_temperature , 0 ) ;
}
else if ( message . compareTo ( " low " ) = = 0 )
{
ac_set_state ( ac_mode , ac_temperature , 1 ) ;
}
else if ( message . compareTo ( " med " ) = = 0 )
{
ac_set_state ( ac_mode , ac_temperature , 2 ) ;
}
else if ( message . compareTo ( " high " ) = = 0 )
{
ac_set_state ( ac_mode , ac_temperature , 3 ) ;
}
}
}
void ac_set_state ( int mode , int temperature , int fan_speed )
{
ac_mode = mode ;
ac_temperature = temperature ;
2023-10-02 11:47:51 +00:00
if ( ac_temperature < AC_MIN_TEMPERATURE )
ac_temperature = AC_MIN_TEMPERATURE ;
else if ( ac_temperature > AC_MAX_TEMPERATURE )
ac_temperature = AC_MAX_TEMPERATURE ;
2023-08-28 17:49:11 +00:00
ac_fan_speed = fan_speed ;
temperature - = AC_MIN_TEMPERATURE ;
2023-09-03 15:55:07 +00:00
if ( lcd_current_page = = 4 )
{
lcd_ac_refresh_fan ( ) ;
lcd_ac_refresh_mode ( ) ;
if ( ac_mode ! = 2 )
panel . writeStr ( " temp.txt " , String ( ac_temperature ) + " C " ) ;
else
panel . writeStr ( " temp.txt " , " --C " ) ;
}
2023-08-28 17:49:11 +00:00
publish_ac_state ( ) ;
2023-09-11 09:13:09 +00:00
uint8_t ac_datablock [ 3 ] = { ac_mode , ac_temperature , ac_fan_speed } ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( 0 , ac_datablock , 3 ) ;
2023-08-28 17:49:11 +00:00
switch ( mode )
{
case 0 :
IrSender . sendRaw ( ir_code_off , sizeof ( ir_code_off ) / sizeof ( ir_code_off [ 0 ] ) , NEC_KHZ ) ;
break ;
case 1 :
IrSender . sendRaw ( ir_code_cool [ fan_speed ] [ temperature ] , sizeof ( ir_code_cool [ fan_speed ] [ temperature ] ) / sizeof ( ir_code_cool [ fan_speed ] [ 0 ] ) , NEC_KHZ ) ;
break ;
case 2 :
IrSender . sendRaw ( ir_code_fan [ fan_speed ] , sizeof ( ir_code_fan [ fan_speed ] ) / sizeof ( ir_code_fan [ fan_speed ] [ 0 ] ) , NEC_KHZ ) ;
break ;
}
2023-10-02 16:20:06 +00:00
ac_changed_user_callback ( mode , ac_temperature , fan_speed ) ;
2023-08-28 17:49:11 +00:00
}
void publish_env_state ( )
{
int errorCode = env_sensor . read ( ) ;
yield ( ) ;
switch ( errorCode )
{
case DHTLIB_OK :
2023-10-03 20:14:33 +00:00
current_room_humid = env_sensor . getHumidity ( ) ;
current_room_temp = env_sensor . getTemperature ( ) ;
mqtt . publish ( String ( AC_ROOM_TEMPERATURE_TOPIC ) , String ( current_room_temp ) ) ;
2023-08-28 17:49:11 +00:00
mqtt_client . loop ( ) ;
2023-10-03 20:14:33 +00:00
mqtt . publish ( String ( AC_HUMIDITY_TOPIC ) , String ( current_room_humid ) ) ;
2023-08-28 17:49:11 +00:00
mqtt_client . loop ( ) ;
2023-10-03 20:14:33 +00:00
if ( lcd_current_page = = 4 )
{
2023-10-04 06:47:24 +00:00
Serial . printf ( " roomtemp.txt= \" %.01fC \" " , current_room_temp ) ;
2023-10-03 20:06:44 +00:00
lcd_send_stop_bit ( ) ;
2023-10-04 06:47:24 +00:00
Serial . printf ( " roomhumid.txt= \" %d%% \" " , ( int ) current_room_humid ) ;
2023-10-03 20:06:44 +00:00
lcd_send_stop_bit ( ) ;
}
2023-08-28 17:49:11 +00:00
break ;
default :
mqtt . publish ( String ( AC_ROOM_TEMPERATURE_TOPIC ) , " ERROR " ) ;
mqtt_client . loop ( ) ;
mqtt . publish ( String ( AC_HUMIDITY_TOPIC ) , " ERROR " ) ;
mqtt_client . loop ( ) ;
}
2023-09-03 09:28:01 +00:00
}
void lcd_begin ( )
{
top_bar_updater . onRun ( lcd_top_bar_update ) ;
top_bar_updater . setInterval ( 10000 ) ;
page_updater . onRun ( lcd_refresh_pd ) ;
page_updater . setInterval ( 5000 ) ;
lcd_refresh ( ) ;
}
void lcd_loop ( )
{
lcd_thread_controller . run ( ) ;
panel . NextionListen ( ) ;
if ( panel . currentPageId ! = lcd_current_page )
{
lcd_current_page = panel . currentPageId ;
lcd_refresh ( ) ;
lcd_top_bar_update ( ) ;
}
}
void lcd_refresh_pd ( )
{
if ( lcd_current_page = = 1 )
{
lcd_refresh ( ) ;
}
}
void lcd_refresh ( )
{
switch ( lcd_current_page )
{
case 1 :
panel . writeStr ( " hostname.txt " , HOSTNAME ) ;
panel . writeStr ( " server_address.txt " , MQTT_SERVER . toString ( ) ) ;
panel . writeStr ( " ip_address.txt " , IP . toString ( ) ) ;
panel . writeStr ( " status_txt.txt " , standalone ? " Standalone " : " BMS Managed " ) ;
break ;
case 2 :
for ( int i = 0 ; i < = 15 ; i + + )
{
panel . writeNum ( " I " + String ( i ) + " .val " , virtual_interupt_state [ i ] ) ;
}
break ;
case 3 :
for ( int i = 0 ; i < = 15 ; i + + )
{
panel . writeNum ( " j " + String ( i ) + " .val " , int ( pwm_values [ i ] / 4095.0 * 100.0 ) ) ;
2023-10-03 19:28:09 +00:00
panel . writeNum ( " j " + String ( i ) + " .ppic " , pwm_states [ i ] ? 33 : 48 ) ;
2023-09-03 09:28:01 +00:00
}
break ;
2023-09-03 15:55:07 +00:00
case 4 :
2023-10-04 06:47:24 +00:00
Serial . printf ( " roomtemp.txt= \" %.01fC \" " , current_room_temp ) ;
lcd_send_stop_bit ( ) ;
Serial . printf ( " roomhumid.txt= \" %d%% \" " , ( int ) current_room_humid ) ;
lcd_send_stop_bit ( ) ;
2023-09-03 15:55:07 +00:00
if ( ac_mode ! = 2 )
panel . writeStr ( " temp.txt " , String ( ac_temperature ) + " C " ) ;
else
panel . writeStr ( " temp.txt " , " --C " ) ;
lcd_ac_refresh_fan ( ) ;
lcd_ac_refresh_mode ( ) ;
2023-09-03 10:41:31 +00:00
case 5 :
panel . writeStr ( " pwm_id.txt " , String ( " P " ) + String ( lcd_pwmAdj_id ) ) ;
panel . writeStr ( " pwm_state.txt " , pwm_states [ lcd_pwmAdj_id ] ? " ON " : " OFF " ) ;
panel . writeNum ( " pwm_value.val " , pwm_values [ lcd_pwmAdj_id ] ) ;
break ;
2023-09-11 17:37:33 +00:00
case 6 :
panel . writeStr ( " ip_set.txt " , IP . toString ( ) ) ;
panel . writeStr ( " netmask_set.txt " , SUBNET . toString ( ) ) ;
panel . writeStr ( " gateway_set.txt " , GATEWAY . toString ( ) ) ;
panel . writeStr ( " dns_set.txt " , DNS . toString ( ) ) ;
panel . writeStr ( " host_set.txt " , HOSTNAME ) ;
2023-11-07 08:49:11 +00:00
break ;
case 11 :
panel . writeStr ( " mqttsv_set.txt " , MQTT_SERVER . toString ( ) ) ;
2023-09-11 17:37:33 +00:00
panel . writeNum ( " port_set.val " , MQTT_PORT ) ;
2023-09-11 18:11:49 +00:00
panel . writeStr ( " topic_set.txt " , MQTT_BASE_TOPIC ) ;
2023-11-07 08:49:11 +00:00
panel . writeStr ( " user_set.txt " , MQTT_USERNAME ) ;
panel . writeStr ( " password_set.txt " , MQTT_PASSWORD ) ;
panel . writeNum ( " use_auth.val " , MQTT_USE_AUTH ) ;
2023-09-11 17:37:33 +00:00
break ;
2023-09-03 09:28:01 +00:00
default :
break ;
}
}
void lcd_top_bar_update ( )
{
2023-09-16 11:02:44 +00:00
char time_buffer [ 15 ] ;
2023-09-16 17:06:00 +00:00
rtctime_t time = ESPMega_getTime ( ) ;
2023-09-30 14:09:45 +00:00
sprintf ( time_buffer , " %02d:%02d " , time . hours , time . minutes ) ;
2023-09-16 17:06:00 +00:00
panel . writeStr ( " time.txt " , time_buffer ) ;
2023-09-03 09:28:01 +00:00
panel . writeNum ( " server.pic " , standalone ? 4 : 5 ) ;
panel . writeNum ( " lan.pic " , ETH . linkUp ( ) ? 3 : 2 ) ;
2023-09-03 10:41:31 +00:00
}
2023-09-03 15:55:07 +00:00
void lcd_ac_refresh_mode ( )
{
// auto high mid low
panel . writeNum ( " mode_cool.pic " , ac_mode = = 1 ? 12 : 13 ) ;
panel . writeNum ( " mode_fan.pic " , ac_mode = = 2 ? 22 : 23 ) ;
2023-09-28 07:55:02 +00:00
panel . writeNum ( " mode_off.pic " , ac_mode = = 0 ? 24 : 25 ) ;
2023-09-03 15:55:07 +00:00
}
void lcd_ac_refresh_fan ( )
{
panel . writeNum ( " fan_auto.pic " , ac_fan_speed = = 0 ? 14 : 15 ) ;
panel . writeNum ( " fan_low.pic " , ac_fan_speed = = 3 ? 18 : 19 ) ;
panel . writeNum ( " fan_mid.pic " , ac_fan_speed = = 2 ? 20 : 21 ) ;
panel . writeNum ( " fan_high.pic " , ac_fan_speed = = 1 ? 16 : 17 ) ;
}
2023-09-03 10:41:31 +00:00
void trigger0 ( )
{
if ( lcd_pwmAdj_id > = 15 )
lcd_pwmAdj_id = 0 ;
else
lcd_pwmAdj_id + + ;
lcd_refresh ( ) ;
}
void trigger1 ( )
{
if ( lcd_pwmAdj_id < = 0 )
lcd_pwmAdj_id = 15 ;
else
lcd_pwmAdj_id - - ;
lcd_refresh ( ) ;
}
void trigger2 ( )
{
pwm_toggle ( lcd_pwmAdj_id ) ;
}
void trigger3 ( )
{
int value = panel . readNumber ( " pwm_value.val " ) ;
lcd_send_stop_bit ( ) ;
2023-09-03 15:55:07 +00:00
pwm_set_value ( lcd_pwmAdj_id , value ) ;
}
void trigger4 ( )
{
if ( ac_temperature < AC_MAX_TEMPERATURE & & ac_mode ! = 2 )
ac_set_state ( ac_mode , ac_temperature + 1 , ac_fan_speed ) ;
}
void trigger5 ( )
{
if ( ac_temperature > AC_MIN_TEMPERATURE & & ac_mode ! = 2 )
ac_set_state ( ac_mode , ac_temperature - 1 , ac_fan_speed ) ;
}
void trigger6 ( )
{
ac_set_state ( ac_mode , ac_temperature , 0 ) ;
}
void trigger7 ( )
{
ac_set_state ( ac_mode , ac_temperature , 3 ) ;
}
void trigger8 ( )
{
ac_set_state ( ac_mode , ac_temperature , 2 ) ;
}
void trigger9 ( )
{
ac_set_state ( ac_mode , ac_temperature , 1 ) ;
}
void trigger10 ( )
{
ac_set_state ( 1 , ac_temperature , ac_fan_speed ) ;
}
void trigger11 ( )
{
ac_set_state ( 2 , ac_temperature , ac_fan_speed ) ;
}
void trigger12 ( )
{
ac_set_state ( 0 , ac_temperature , ac_fan_speed ) ;
}
void trigger13 ( )
{
2023-09-11 17:37:33 +00:00
set_ip ( panel . readStr ( " ip_set.txt " ) ) ;
set_netmask ( panel . readStr ( " netmask_set.txt " ) ) ;
set_gw ( panel . readStr ( " gateway_set.txt " ) ) ;
set_dns ( panel . readStr ( " dns_set.txt " ) ) ;
set_hostname ( panel . readStr ( " host_set.txt " ) ) ;
delay ( 100 ) ;
ESP . restart ( ) ;
2023-09-11 09:13:09 +00:00
}
2023-11-07 08:49:11 +00:00
void trigger14 ( )
{
2023-11-06 16:24:06 +00:00
Serial . print ( " page dashboard " ) ;
lcd_send_stop_bit ( ) ;
}
2023-11-07 08:49:11 +00:00
void trigger15 ( )
{
set_mqtt_server ( panel . readStr ( " mqttsv_set.txt " ) ) ;
set_basetopic ( panel . readStr ( " topic_set.txt " ) ) ;
uint16_t port = panel . readNumber ( " port_set.val " ) ;
mqtt_port_set ( port ) ;
set_mqtt_useauth ( panel . readNumber ( " use_auth.val " ) ) ;
set_mqtt_username ( panel . readStr ( " user_set.txt " ) ) ;
set_mqtt_password ( panel . readStr ( " password_set.txt " ) ) ;
delay ( 100 ) ;
ESP . restart ( ) ;
}
2023-09-11 09:13:09 +00:00
void eeprom_pwm_update ( )
{
if ( memcmp ( pwm_states , pwm_states_eeprom , 16 ) )
{
memcpy ( pwm_states_eeprom , pwm_states , 16 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( 3 , pwm_states_eeprom , 16 ) ;
2023-09-11 09:13:09 +00:00
lcd_send_stop_bit ( ) ;
}
if ( memcmp ( pwm_values , pwm_values_eeprom , 32 ) )
{
memcpy ( pwm_values_eeprom , pwm_values , 32 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( 19 , pwm_values_eeprom , 32 ) ;
2023-09-11 09:13:09 +00:00
lcd_send_stop_bit ( ) ;
}
2023-09-11 17:37:33 +00:00
}
void set_ip ( String address )
{
IP . fromString ( address ) ;
eeprom_ip_update ( EEPROM_ADDRESS_IP , IP [ 0 ] , IP [ 1 ] , IP [ 2 ] , IP [ 3 ] ) ;
}
void set_netmask ( String address )
{
SUBNET . fromString ( address ) ;
eeprom_ip_update ( EEPROM_ADDRESS_SUBNET , SUBNET [ 0 ] , SUBNET [ 1 ] , SUBNET [ 2 ] , SUBNET [ 3 ] ) ;
}
void set_dns ( String address )
{
DNS . fromString ( address ) ;
eeprom_ip_update ( EEPROM_ADDRESS_DNS , DNS [ 0 ] , DNS [ 1 ] , DNS [ 2 ] , DNS [ 3 ] ) ;
}
void set_gw ( String address )
{
GATEWAY . fromString ( address ) ;
eeprom_ip_update ( EEPROM_ADDRESS_GATEWAY , GATEWAY [ 0 ] , GATEWAY [ 1 ] , GATEWAY [ 2 ] , GATEWAY [ 3 ] ) ;
}
void set_mqtt_server ( String address )
{
MQTT_SERVER . fromString ( address ) ;
eeprom_ip_update ( EEPROM_ADDRESS_MQTT_SERVER , MQTT_SERVER [ 0 ] , MQTT_SERVER [ 1 ] , MQTT_SERVER [ 2 ] , MQTT_SERVER [ 3 ] ) ;
}
void eeprom_ip_update ( uint16_t rom_address , uint8_t byte1 , uint8_t byte2 , uint8_t byte3 , uint8_t byte4 )
{
uint8_t addressblock [ 4 ] = { byte1 , byte2 , byte3 , byte4 } ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( rom_address , addressblock , 4 ) ;
2023-09-11 17:37:33 +00:00
}
IPAddress eeprom_ip_retrieve ( uint16_t rom_address )
{
uint8_t addressblock [ 4 ] ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( rom_address , addressblock , 4 ) ;
2023-09-11 17:37:33 +00:00
return IPAddress ( addressblock [ 0 ] , addressblock [ 1 ] , addressblock [ 2 ] , addressblock [ 3 ] ) ;
}
void set_hostname ( String hostname )
{
hostname . toCharArray ( HOSTNAME , 15 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( EEPROM_ADDRESS_HOSTNAME , ( uint8_t * ) HOSTNAME , 15 ) ;
2023-09-11 17:37:33 +00:00
}
void eeprom_hostname_retrieve ( )
{
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_HOSTNAME , ( uint8_t * ) HOSTNAME , 15 ) ;
2023-09-11 18:11:49 +00:00
}
void set_basetopic ( String topic )
{
topic . toCharArray ( MQTT_BASE_TOPIC , 20 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( EEPROM_ADDRESS_TOPIC , ( uint8_t * ) MQTT_BASE_TOPIC , 20 ) ;
2023-09-11 18:11:49 +00:00
}
void eeprom_basetopic_retrieve ( )
{
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_TOPIC , ( uint8_t * ) MQTT_BASE_TOPIC , 20 ) ;
2023-09-11 17:37:33 +00:00
}
void mqtt_port_set ( uint16_t port )
{
uint8_t port_arr [ 2 ] ;
memcpy ( port_arr , & port , 2 ) ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . write ( EEPROM_ADDRESS_MQTT_PORT , port_arr , 2 ) ;
2023-09-11 17:37:33 +00:00
}
void eeprom_mqtt_port_retrieve ( )
{
uint8_t port_arr [ 2 ] ;
2023-09-28 07:55:02 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_MQTT_PORT , port_arr , 2 ) ;
2023-09-11 17:37:33 +00:00
memcpy ( & MQTT_PORT , port_arr , 2 ) ;
2023-09-29 17:06:49 +00:00
}
2023-09-30 14:09:45 +00:00
boolean pwm_get_state ( int id )
{
2023-09-29 17:06:49 +00:00
return pwm_states [ id ] ;
}
2023-09-30 14:09:45 +00:00
uint16_t pwm_get_value ( int id )
{
2023-09-29 17:06:49 +00:00
return pwm_values [ id ] ;
}
2023-09-30 14:09:45 +00:00
boolean input_get_state ( int id )
{
2023-09-29 17:06:49 +00:00
return virtual_interupt_state [ id ] ;
}
2023-09-30 14:09:45 +00:00
uint8_t ac_get_temperature ( )
{
2023-09-29 17:06:49 +00:00
return ac_temperature ;
}
2023-09-30 14:09:45 +00:00
uint8_t ac_get_mode ( )
{
2023-09-29 17:06:49 +00:00
return ac_mode ;
}
2023-09-30 14:09:45 +00:00
uint8_t ac_get_fan_speed ( )
{
2023-09-29 17:06:49 +00:00
return ac_fan_speed ;
2023-11-07 05:19:35 +00:00
}
2023-11-07 08:49:11 +00:00
void eeprom_mqtt_username_retrieve ( )
{
ESPMega_FRAM . read ( EEPROM_ADDRESS_MQTT_USERNAME , ( uint8_t * ) MQTT_USERNAME , 32 ) ;
2023-11-07 05:19:35 +00:00
}
2023-11-07 08:49:11 +00:00
void eeprom_mqtt_password_retrieve ( )
{
2023-11-07 05:19:35 +00:00
ESPMega_FRAM . read ( EEPROM_ADDRESS_MQTT_PASSWORD , ( uint8_t * ) MQTT_PASSWORD , 32 ) ;
}
2023-11-07 08:49:11 +00:00
void set_mqtt_username ( String username )
{
username . toCharArray ( MQTT_USERNAME , 32 ) ;
2023-11-07 05:19:35 +00:00
ESPMega_FRAM . write ( EEPROM_ADDRESS_MQTT_USERNAME , ( uint8_t * ) MQTT_USERNAME , 20 ) ;
}
2023-11-07 08:49:11 +00:00
void set_mqtt_password ( String password )
{
password . toCharArray ( MQTT_PASSWORD , 32 ) ;
ESPMega_FRAM . write ( EEPROM_ADDRESS_MQTT_PASSWORD , ( uint8_t * ) MQTT_PASSWORD , 20 ) ;
2023-11-07 05:19:35 +00:00
}
2023-11-07 08:49:11 +00:00
void eeprom_mqtt_useauth_retrieve ( )
{
2023-11-07 05:19:35 +00:00
MQTT_USE_AUTH = ESPMega_FRAM . read8 ( EEPROM_ADDRESS_MQTT_USEAUTH ) ;
}
2023-11-07 08:49:11 +00:00
void set_mqtt_useauth ( bool use_auth )
{
2023-11-07 05:19:35 +00:00
MQTT_USE_AUTH = use_auth ;
ESPMega_FRAM . write8 ( EEPROM_ADDRESS_MQTT_USEAUTH , MQTT_USE_AUTH ) ;
2023-08-25 18:38:17 +00:00
}