diff --git a/src/main.cpp b/src/main.cpp index 15f608f..b8d6c3f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,76 +1,59 @@ -#include - /* - Device Title: MK-BlindsControl - Device Description: MQTT Blinds Control - Device Explanation: The device recieves an MQTT message from the server and - changes the position of the servo motor - Device information: https://www.MK-SmartHouse.com/blinds-control + Device Title: MK-BlindsControl + Device Description: MQTT Blinds Control + Device Explanation: The device recieves an MQTT message from the server and + changes the position of the servo motor + Device information: https://www.MK-SmartHouse.com/blinds-control - Author: Matt Kaczynski - Website: http://www.MK-SmartHouse.com - Version 1 and 2 + Author: Matt Kaczynski + Website: http://www.MK-SmartHouse.com + Version 1 and 2 - Original software modified by Mountain-Eagle Pitt - Website: www.mountaineagle-technologies.com.au V6 and above + Original software modified by Mountain-Eagle Pitt + Website: www.mountaineagle-technologies.com.au V6 and above - Added to github + Added to github - +!!!!!!!!!! DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING !!!!!!!!!! */ -/* ---------- DO NOT EDIT ANYTHING IN THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING---------- */ - -#include //this needs to be first, or it all crashes and burns... +#include +#include // this needs to be first, or it all crashes and burns... #include #include -Servo myservo[2]; ///allow for 2 servo's to be connected - - #include - - -#include //https://github.com/256dpi/arduino-mqtt +#include // https://github.com/256dpi/arduino-mqtt #include - -#include //https://github.com/tzapu/WiFiManager -#include //https://github.com/bblanchon/ArduinoJson V6 and above only +#include // https://github.com/tzapu/WiFiManager +#include // https://github.com/bblanchon/ArduinoJson V6 and above only #include #include - #include #include - - - #include // Built-in #include // Built-in - -ESP8266WebServer httpServer(80); - -ESP8266HTTPUpdateServer httpUpdater; #include - -#include //HA implementation - - +#include // HA implementation +#include #define ServerVersion "8" String webpage = ""; -#include "PageIndex.h" //--> Include the contents of the User Interface Web page, stored in the same folder as the .ino file -bool SPIFFS_present = false; #include "CSS.h" -#include - - +#include "PageIndex.h" //--> Include the contents of the User Interface Web page, stored in the same folder as the .ino file #include "user_interface.h" -//wifi_set_sleep_type(MODEM_SLEEP_T); -//define your default values here, if there are different values in config.json, they are overwritten. + +Servo myservo[2]; // allow for 2 servo's to be connected +ESP8266WebServer httpServer(80); +ESP8266HTTPUpdateServer httpUpdater; +bool SPIFFS_present = false; + +// wifi_set_sleep_type(MODEM_SLEEP_T); +// define your default values here, if there are different values in config.json, they are overwritten. char host[34]; char mqtt_server[40]; char mqtt_port[6] = "1883"; -char mqtt_topic[50]; ///MQTT Device ID +char mqtt_topic[50]; // MQTT Device ID char mqtt_isAuthentication[7] = "FALSE"; char mqtt_username[40]; char mqtt_password[40]; @@ -78,19 +61,19 @@ char update_username[40] = "admin"; char update_password[40] = "password"; char auto_discovery[20] = "DISABLED"; char remote_switch[6] = "NO"; -char update_path[34] = "/firmware"; //Default -char blinds_speed[7] = "FAST"; //Default -char blinds_swing_direction[7] = "DOWN"; //Default -char blinds_servo_install[7] = "LEFT"; //Default -char blinds_trim_adjust[3] = "0"; //Default -char blinds_slip_correction[5] = "ON"; //Default -char OTAAuto_path[90] = "http://mountaineagle-technologies.com.au/tasmota/mk-blindcontrol.bin"; //updtate OTA_url server path and file -char tele_battery_set[4] = "60"; ////in seconds +char update_path[34] = "/firmware"; // Default +char blinds_speed[7] = "FAST"; // Default +char blinds_swing_direction[7] = "DOWN"; // Default +char blinds_servo_install[7] = "LEFT"; // Default +char blinds_trim_adjust[3] = "0"; // Default +char blinds_slip_correction[5] = "ON"; // Default +char OTAAuto_path[90] = "http://mountaineagle-technologies.com.au/tasmota/mk-blindcontrol.bin"; // updtate OTA_url server path and file +char tele_battery_set[4] = "60"; // in seconds char tele_update_set[4] = "60"; -char open_limit_set[5] = ""; ///open limit set, set by user and program can be inverter -char close_limit_set[5] = ""; ////close limit set, set by user and program can be inverter -char open_limit_default[5] = ""; ///open limit default position -char close_limit_default[5] = ""; ////closeed limit default position +char open_limit_set[5] = ""; // open limit set, set by user and program can be inverter +char close_limit_set[5] = ""; // close limit set, set by user and program can be inverter +char open_limit_default[5] = ""; // open limit default position +char close_limit_default[5] = ""; // closeed limit default position int openVal; int openTemp = 20; @@ -98,58 +81,55 @@ int closedVal; int closedTemp; String BufferPos = "0"; - -//Unique Software ID and Version Information +// Unique Software ID and Version Information char software_name[40] = "MK-BlindsControl"; -char software_version_old[7] = "V7"; ///previous software version -char software_version[7] = "V8"; //changing this value will cause WiFiManager to Reload and will have to re-configure Device eg if size of json changes then change this -char software_variant[7] = "00"; //change this for minor changes only to program...will not cause re configure options +char software_version_old[7] = "V7"; // previous software version +char software_version[7] = "V8"; // changing this value will cause WiFiManager to Reload and will have to re-configure Device eg if size of json changes then change this +char software_variant[7] = "00"; // change this for minor changes only to program...will not cause re configure options String firmware_installed = String(software_version)+"."+String(software_variant); String url = "http://mountaineagle-technologies.com.au/tasmota/version.json"; const char* POWER_TOPIC = "cmnd/power/POWER"; char data[80]; -int msgcommand = 180; //payload converted to initger number -String msgpayload = "NULL"; -String msgString = "180";// -String TiltPos = "100"; ////tilt position -String HA_Blind_State = "OPEN"; /// state for HA open, closed, opening, closing, stopped -String Blind_STATE = "100"; ////used in tele data +int msgcommand = 180; // payload converted to initger number +String msgpayload = "NULL"; +String msgString = "180"; +String TiltPos = "100"; // tilt position +String HA_Blind_State = "OPEN"; // state for HA open, closed, opening, closing, stopped +String Blind_STATE = "100"; // used in tele data String blindoffset = "0"; String blindstrim = blinds_trim_adjust; - -//char msgpayload[7] = "NULL"; +// char msgpayload[7] = "NULL"; int ServoPos = 180; int reboot = 0; int blinddelay = 0; int restartflag = 1; int bypassdevstat = 0; boolean isNum = false; -//Unique device ID +// Unique device ID const char* mqttDeviceID; -///////variable for battery monitor - +// variable for battery monitor int Battery_Cap = 100; float Battery_Voltage = 4.7; float Remaining_Time = 0.0; -float Discharge_Time = 6.5; ///discharge time in hours +float Discharge_Time = 6.5; // discharge time in hours char battery_system[6] = "OFF"; -char battery_capacity[8] = "3800"; //capacity in mHa -char system_power[8] = "10"; ///power in watts -unsigned long time_now_2 = 0; ///use for battery monitor reportng +char battery_capacity[8] = "3800"; // capacity in mHa +char system_power[8] = "10"; // power in watts +unsigned long time_now_2 = 0; // use for battery monitor reportng -//////NEW CODE FOR 4 FUNCTION BUTTON STATE +// NEW CODE FOR 4 FUNCTION BUTTON STATE const int buttonPin = 0; // analog input pin to use as a digital input -// MULTI-CLICK: One Button, Multiple Events +// MULTI-CLICK: One Button, Multiple Events // Button timing variables unsigned long debounce = 50; // ms debounce period to prevent flickering when pressing or releasing the button unsigned long DCgap = 250; // max ms between clicks for a double click event unsigned long holdTime = 2000; // ms hold period: how long to wait for press+hold event unsigned long longHoldTime = 6000; // ms long hold period: how long to wait for press+hold event -int button_result = 0; //button press result +int button_result = 0; // button press result int b = 0; // Button variables boolean buttonVal = HIGH; // value read from button @@ -166,15 +146,14 @@ boolean longHoldEventPast = false;// whether or not the long hold event happened bool lightOn = false; - -/////////End Code 4 FUNCTION BUTTON STATE +// End Code 4 FUNCTION BUTTON STATE String valueString = "180"; - int pos1 = 0; - int pos2 = 0; +int pos1 = 0; +int pos2 = 0; -/////////new code for switch detection +// new code for switch detection // constants won't change. They're used here to set pin numbers: -//const int buttonPin = 0; // the number of the pushbutton pin +// const int buttonPin = 0; // the number of the pushbutton pin const int ledPin = 12; // the number of the LED pin // Variables will change: @@ -187,528 +166,376 @@ int lastButtonState = HIGH; // the previous reading from the input pin unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 200; // the debounce time; increase if the output flickers - -//////////////////////////// -//Form Custom SSID based on Software name and version information and Chip ID +// Form Custom SSID based on Software name and version information and Chip ID String ssidAP = String(software_name) + "-" + String(software_version) + "-" + String(ESP.getChipId()); -//Set Default States - +// Set Default States boolean invert_state = false; boolean invert_command = false; -////////HA name conversiona +// HA name conversion String _name; String _identifier; -//////// -///LWT Config settings +// LWT Config settings String returnmsg; int reconnects = 0; const int RSSI_MAX = -50; // define maximum strength of signal in dBm const int RSSI_MIN = -100; // define minimum strength of signal in dBm - // Set tele reporting interval to MQTT broker for STATE, WiFi Level etc -int tele_period = 60000; //time in mili seconds 1000 ms = 1 sec +int tele_period = 60000; // time in mili seconds 1000 ms = 1 sec unsigned long time_now = 0; - -//flag for saving data +// flag for saving data bool shouldSaveConfig = false; -//callback notifying us of the need to save config -void saveConfigCallback () -{ - shouldSaveConfig = true; -} - WiFiClient net; int MQTTsize = 1200; MQTTClient client(1200); unsigned long lastMillis = 0; -///////////////////////////// -void moveServo(double pos) -{ - -myservo[0].write(ServoPos); -myservo[1].write(ServoPos); -if (!myservo[0].attached()) { // If the servo is not attached + +// saveConfigCallback - callback notifying us of the need to save config +void saveConfigCallback () { + shouldSaveConfig = true; +} + +// moveServo +void moveServo(double pos) { + myservo[0].write(ServoPos); + myservo[1].write(ServoPos); + + if (!myservo[0].attached()) { // If the servo is not attached myservo[0].attach(13, 544, 2200); myservo[1].attach(14, 544, 2200); } - delay(40); //40 - -blinddelay = 0; -if (String(blinds_speed).equalsIgnoreCase("LOW")){ - blinddelay = 80; - } - -if (String(blinds_speed).equalsIgnoreCase("MED")){ - blinddelay = 40; + delay(40); // 40 + + blinddelay = 0; + if (String(blinds_speed).equalsIgnoreCase("LOW")) { + blinddelay = 80; } -if (String(blinds_speed).equalsIgnoreCase("HIGH")){ - blinddelay = 0; - } - - - if (String(blinds_speed).equalsIgnoreCase("SLOW")) - { - if (pos < myservo[0].read()) - { - for (int tempPos = myservo[0].read(); pos <= tempPos; tempPos--) - { - - - // write to each server - myservo[0].write(tempPos); - myservo[1].write(tempPos); - - delay(40); //40 - } - } - else - { - for (int tempPos = myservo[0].read(); pos >= tempPos; tempPos++) - { - - - // write to each server - myservo[0].write(tempPos); - myservo[1].write(tempPos); - - delay(40); //40 - } - } + if (String(blinds_speed).equalsIgnoreCase("MED")) { + blinddelay = 40; } - else - { - - // write to each server - myservo[0].write(pos); - myservo[1].write(pos); - + + if (String(blinds_speed).equalsIgnoreCase("HIGH")) { + blinddelay = 0; + } + + if (String(blinds_speed).equalsIgnoreCase("SLOW")) { + if (pos < myservo[0].read()) { + for (int tempPos = myservo[0].read(); pos <= tempPos; tempPos--) { + // write to each server + myservo[0].write(tempPos); + myservo[1].write(tempPos); + + delay(40); // 40 + } + } else { + for (int tempPos = myservo[0].read(); pos >= tempPos; tempPos++) { + // write to each server + myservo[0].write(tempPos); + myservo[1].write(tempPos); + + delay(40); // 40 + } + } + } else { + // write to each server + myservo[0].write(pos); + myservo[1].write(pos); + delay(2000); } + ServoPos = myservo[0].read(); } - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void AutoConfigBlind(){ - ////////////////////////////////////////////////////////// - ////SET UP CODE FOR AUTO CONFIG - ///Code to setup servo, for swing state etc based on initial setup of blinds_swing_direction and side servo motor is installed on for blinds_servo_install - ///If you change sides of sevo motor the commands will have to be inverted as well as the states, the code below automatically sets these based on - ///WiFiManager Setup options . What Side Servo Motor Installed On and Swing Direction To Close.So Commands remain true states ie. 0=OPEN, 100=CLOSED etc +// AutoConfigBlind +void AutoConfigBlind() { + // SET UP CODE FOR AUTO CONFIG + // Code to setup servo, for swing state etc based on initial setup of blinds_swing_direction and side servo motor is installed on for blinds_servo_install + // If you change sides of sevo motor the commands will have to be inverted as well as the states, the code below automatically sets these based on + // WiFiManager Setup options . What Side Servo Motor Installed On and Swing Direction To Close.So Commands remain true states ie. 0=OPEN, 100=CLOSED etc // The Configuration Option Selected Is Published To MQTT on boot up of Blinds Controller - - - if ((String(blinds_servo_install).equalsIgnoreCase("LEFT")) && (String(blinds_swing_direction).equalsIgnoreCase("DOWN"))) - { + + if ((String(blinds_servo_install).equalsIgnoreCase("LEFT")) && (String(blinds_swing_direction).equalsIgnoreCase("DOWN"))) { invert_command = false; - invert_state = false; - } - - - else if ((String(blinds_servo_install).equalsIgnoreCase("LEFT")) && (String(blinds_swing_direction).equalsIgnoreCase("UP"))) - { + invert_state = false; + } else if ((String(blinds_servo_install).equalsIgnoreCase("LEFT")) && (String(blinds_swing_direction).equalsIgnoreCase("UP"))) { invert_command = true; - invert_state = true; - } - - - else if ((String(blinds_servo_install).equalsIgnoreCase("RIGHT")) && (String(blinds_swing_direction).equalsIgnoreCase("DOWN"))) - { + invert_state = true; + } else if ((String(blinds_servo_install).equalsIgnoreCase("RIGHT")) && (String(blinds_swing_direction).equalsIgnoreCase("DOWN"))) { invert_command = true; - invert_state = true; - } - - else if ((String(blinds_servo_install).equalsIgnoreCase("RIGHT")) && (String(blinds_swing_direction).equalsIgnoreCase("UP"))) - { + invert_state = true; + } else if ((String(blinds_servo_install).equalsIgnoreCase("RIGHT")) && (String(blinds_swing_direction).equalsIgnoreCase("UP"))) { invert_command = false; - invert_state = false; + invert_state = false; } -/////check for valid open limit set else pre configure -if ((String(open_limit_set).equalsIgnoreCase("")) || (String(close_limit_set).equalsIgnoreCase(""))) - { - if (invert_command == true) - - { + // check for valid open limit set else pre configure + if ((String(open_limit_set).equalsIgnoreCase("")) || (String(close_limit_set).equalsIgnoreCase(""))) { + if (invert_command == true) { strcpy(open_limit_set, "180"); - strcpy(close_limit_set, "0"); - } - else - { + strcpy(close_limit_set, "0"); + } else { strcpy(open_limit_set, "0"); - strcpy(close_limit_set, "180"); + strcpy(close_limit_set, "180"); } - } -//////set default limits reference based on swing directoin etc -if (invert_command == true) - { - strcpy(open_limit_default, "180"); - strcpy(close_limit_default, "0"); - - } - else - { - strcpy(open_limit_default, "0"); - strcpy(close_limit_default, "180"); - - } - - - + // set default limits reference based on swing directoin etc + if (invert_command == true) { + strcpy(open_limit_default, "180"); + strcpy(close_limit_default, "0"); + } else { + strcpy(open_limit_default, "0"); + strcpy(close_limit_default, "180"); + } } - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void SendHTML_Stop(){ +// SendHTML_Stop +void SendHTML_Stop() { httpServer.sendContent(""); httpServer.client().stop(); // Stop is needed because no content length was sent } -//~~~~~~ -//////config copy upgrade -void configupgrade(){ -//Serial.print("Checking For Configuration file "); - if (LittleFS.begin()) - { - SPIFFS_present = true; - //////check for version 7 if so copy to V8 +// configupgrade - config copy upgrade +void configupgrade() { + // Serial.print("Checking For Configuration file "); + if (LittleFS.begin()) { + SPIFFS_present = true; + + // check for version 7 if so copy to V8 + if (LittleFS.exists("/" + String(software_version_old) + ".json")) { + // file exists, reading and loading - ////// - - if (LittleFS.exists("/" + String(software_version_old) + ".json")) - { - //file exists, reading and loading - File configFile = LittleFS.open("/" + String(software_version_old) + ".json", "r"); - if (configFile) - { - //Serial.print("Con figuraton found....loading values "); - size_t size = configFile.size(); - ///size_t len = measureJson(configFile); json 6 - + + if (configFile) { + // Serial.print("Con figuraton found....loading values "); + size_t size = configFile.size(); + // size_t len = measureJson(configFile); json 6 + // Allocate a buffer to store contents of the file. std::unique_ptr buf(new char[size]); configFile.readBytes(buf.get(), size); - - DynamicJsonDocument json(1024); ////json6 + DynamicJsonDocument json(1024); // json6 auto deserializeError = deserializeJson(json, buf.get()); serializeJson(json, Serial); - + configFile.close(); - LittleFS.remove("/" + String(software_version_old) + ".json"); ///remove existing file before re writting + LittleFS.remove("/" + String(software_version_old) + ".json"); // remove existing file before re writting - - if ( ! deserializeError ) ////JSON6 - { + if ( ! deserializeError ) { // JSON6 + // save to new file + File configFile = LittleFS.open("/" + String(software_version) + ".json", "w"); - /////save to new file - - File configFile = LittleFS.open("/" + String(software_version) + ".json", "w"); + serializeJson(json, Serial); // JSON6 + serializeJson(json, configFile); // JSON6 - serializeJson(json, Serial); ////JSON6 - serializeJson(json, configFile); ///JSON6 - - configFile.close(); + configFile.close(); } - else - { - } - - - } - } - } - else - { - } - //end read - + // end read } - -//Procedure for handling servo control - -void handleServo(){ - +// handleServo - handle servo control +void handleServo() { String POS = httpServer.arg("servoPOS"); BufferPos = POS; - int pos = POS.toInt(); - - //moveServo(pos); + + // moveServo(pos); myservo[0].write(pos); //--> Move the servo motor according to the POS value delay(15); myservo[1].write(pos); //--> Move the servo motor according to the POS value delay(15); - httpServer.send(200, "text/plane",""); - } +// process_state +void process_state() { + // client.publish("stat/" + _identifier + "/caculating_State ", "processing_state"); + blindoffset = "0"; + String str_open_limit_set = open_limit_set; + String str_open_limit_default = open_limit_default; + String str_close_limit_set = close_limit_set; + String str_close_limit_default = close_limit_default; - -void process_state() - -{ -//client.publish("stat/" + _identifier + "/caculating_State ", "processing_state"); -blindoffset = "0"; -String str_open_limit_set = open_limit_set; -String str_open_limit_default = open_limit_default; -String str_close_limit_set = close_limit_set; -String str_close_limit_default = close_limit_default; - - if (HA_Blind_State == "OPENED") - { - - if (invert_state == true) - { - ///////// 180 minus 50 - blindoffset = String(str_open_limit_set.toInt() - str_open_limit_default.toInt()); - } - else - { - /////////// 0 plus 20 - blindoffset = String(str_open_limit_default.toInt() + str_open_limit_set.toInt()); - } + if (HA_Blind_State == "OPENED") { + if (invert_state == true) { + // 180 minus 50 + blindoffset = String(str_open_limit_set.toInt() - str_open_limit_default.toInt()); + } else { + // 0 plus 20 + blindoffset = String(str_open_limit_default.toInt() + str_open_limit_set.toInt()); } + } - - - if (HA_Blind_State == "CLOSED") - { - - if (invert_state == true) - { - //////////// 0 plus 20 - blindoffset = String(str_close_limit_default.toInt() + str_close_limit_set.toInt()); ////maybe plus - } - else - { - ///// 180 minus 160 - blindoffset = String(str_close_limit_set.toInt() - str_close_limit_default.toInt()); - } - + if (HA_Blind_State == "CLOSED") { + if (invert_state == true) { + // 0 plus 20 + blindoffset = String(str_close_limit_default.toInt() + str_close_limit_set.toInt()); // maybe plus + } else { + // 180 minus 160 + blindoffset = String(str_close_limit_set.toInt() - str_close_limit_default.toInt()); } - + } - - - - if (invert_state == true) - - { - if ((HA_Blind_State == "OPENED") || (HA_Blind_State == "CLOSED")) - { - ///use trim adjustmet on opened and closed vales only - Blind_STATE = String((int)(100 - ((myservo[0].read()-blindoffset.toInt()) / 1.8) + 0.5)); - ////new format - TiltPos = String((int)(100 - ((myservo[0].read() / 1.8) - 0))); // - } - else - { - ///////don't use trim offsets if blind is not opem\ned or closed fully - Blind_STATE = String((int)(100 - (myservo[0].read() / 1.8) + 0.5)); - TiltPos = String((int)(100 - ((myservo[0].read() / 1.8) - 0) )); // - } - - } - - - else - //////////////////opened = 0 closed 180 non inverted - { - if ((HA_Blind_State == "OPENED") || (HA_Blind_State == "CLOSED")) - { - - ///use trim adjustmet on opened and closed vales only - Blind_STATE = String((int)(((myservo[0].read()-blindoffset.toInt()) / 1.8) + 0.5)); - TiltPos = String((int)(((myservo[0].read() / 1.8) - 0) )); // add trim offsets - - - } - else - { - ///////don't use trim offsets if blind is not opem\ned or closed fully - Blind_STATE = String((int)((myservo[0].read() / 1.8) + 0.5)); - TiltPos = String((int)(((myservo[0].read() / 1.8) - 0) )); // add trim offsets - - } - - + if (invert_state == true) { + if ((HA_Blind_State == "OPENED") || (HA_Blind_State == "CLOSED")) { + // use trim adjustmet on opened and closed vales only + Blind_STATE = String((int)(100 - ((myservo[0].read()-blindoffset.toInt()) / 1.8) + 0.5)); + // new format + TiltPos = String((int)(100 - ((myservo[0].read() / 1.8) - 0))); // + } else { + // don't use trim offsets if blind is not opem\ned or closed fully + Blind_STATE = String((int)(100 - (myservo[0].read() / 1.8) + 0.5)); + TiltPos = String((int)(100 - ((myservo[0].read() / 1.8) - 0) )); // } - ServoPos = myservo[0].read(); //set servo posiotion to save in + } else { + // opened = 0 closed 180 non inverted + if ((HA_Blind_State == "OPENED") || (HA_Blind_State == "CLOSED")) { + // use trim adjustmet on opened and closed vales only + Blind_STATE = String((int)(((myservo[0].read()-blindoffset.toInt()) / 1.8) + 0.5)); + TiltPos = String((int)(((myservo[0].read() / 1.8) - 0) )); // add trim offsets + } else { + // don't use trim offsets if blind is not opem\ned or closed fully + Blind_STATE = String((int)((myservo[0].read() / 1.8) + 0.5)); + TiltPos = String((int)(((myservo[0].read() / 1.8) - 0) )); // add trim offsets + } + } + + ServoPos = myservo[0].read(); // set servo posiotion to save in } - -void publish_state() - -{ - -client.publish("stat/" + _identifier + "/STATE", Blind_STATE); -client.publish("stat/" + _identifier + "/HA_STATE", HA_Blind_State); -client.publish("stat/" + _identifier + "/SPEED", String(blinds_speed)); //publish blid speed -client.publish("stat/" + _identifier + "/position", String(TiltPos)); -client.publish("stat/" + _identifier + "/tilt-state", TiltPos); //tit message=power message - - - - - +// publish_state +void publish_state() { + client.publish("stat/" + _identifier + "/STATE", Blind_STATE); + client.publish("stat/" + _identifier + "/HA_STATE", HA_Blind_State); + client.publish("stat/" + _identifier + "/SPEED", String(blinds_speed)); // publish blid speed + client.publish("stat/" + _identifier + "/position", String(TiltPos)); + client.publish("stat/" + _identifier + "/tilt-state", TiltPos); // tit message=power message } -////////////////////////////// -int dBmtoPercentage(int dBm) -{ +// dBmtoPercentage +int dBmtoPercentage(int dBm) { int quality; - if (dBm <= RSSI_MIN) - { + + if (dBm <= RSSI_MIN) { quality = 0; - } - else if (dBm >= RSSI_MAX) - { + } else if (dBm >= RSSI_MAX) { quality = 100; - } - else - { + } else { quality = 2 * (dBm + 100); } return quality; -}//dBmtoPercentage - -///////////////////////////// -void HA_State() -{ -//////Create HA_Blind_State - ///HA_Blind_State - ////only do this while servo connected -// client.publish("stat/" + _identifier + "/HA_STATE","processig1"); - HA_Blind_State = "OPEN"; - - - if (String(myservo[0].read()) == String(open_limit_set)) - { - HA_Blind_State = "OPENED"; - } - if (String(myservo[0].read()) == String(close_limit_set)) - { - HA_Blind_State = "CLOSED"; - - } - } +// HA_State +void HA_State() { + // Create HA_Blind_State + // only do this while servo connected + // client.publish("stat/" + _identifier + "/HA_STATE","processig1"); + HA_Blind_State = "OPEN"; -////////////////// -void HAMDiscovery() -{ -_name = String(mqtt_topic); ///aka mqtt device ID will change in main program -HAMqttDevice mkblindcontrol(_name, HAMqttDevice::COVER); + if (String(myservo[0].read()) == String(open_limit_set)) { + HA_Blind_State = "OPENED"; + } + if (String(myservo[0].read()) == String(close_limit_set)) { + HA_Blind_State = "CLOSED"; + } +} + +// HAMDiscovery +void HAMDiscovery() { + _name = String(mqtt_topic); // aka mqtt device ID will change in main program + HAMqttDevice mkblindcontrol(_name, HAMqttDevice::COVER); // Configure extra config vars for Home assistant mkblindcontrol .enableAttributesTopic() - - //.addConfigVar("cmd_t", "cmnd/"+_identifier+"/POWER") //command topic - //.addConfigVar("stat_t", "stat/"+_identifier+"/STATE") //STATE topic - .addConfigVar("retain", "false") ///retain flag + //.addConfigVar("cmd_t", "cmnd/"+_identifier+"/POWER") // command topic + //.addConfigVar("stat_t", "stat/"+_identifier+"/STATE") // STATE topic + .addConfigVar("retain", "false") // retain flag .addConfigVar("availability_topic", "tele/"+_identifier+"/LWT") - .addConfigVar("payload_open", "OPEN") ///pay load open - .addConfigVar("payload_close", "CLOSED") ///payload closed - .addConfigVar("payload_stop", "STOP") ///pay load stop - .addConfigVar("stat_open", "0") ///state open - .addConfigVar("state_opening", "opening") ///state opening - .addConfigVar("state_closed", "100") ///state closed - .addConfigVar("state_closing", "closing") ///state closing - .addConfigVar("payload_available", "online") ///payload available - .addConfigVar("payload_not_available", "offline") ///payload not avilable - .addConfigVar("optimistic", "false") ///optimistic - .addConfigVar("value_template", "{{ value.x }}") ///value template - .addConfigVar("position_template", "{{ value.y }}") ///position value - .addConfigVar("tilt_command_topic", "cmnd/"+_identifier+"/tilt") ///tilt command topic - .addConfigVar("tilt_status_topic", "stat/"+_identifier+"/STATE") ///tilt status topic - .addConfigVar("tilt_status_template", "{{ value_json['PWM']['PWM1'] }}") ///tilt status template - .addConfigVar("tilt_min", "0") ///tilt minium - .addConfigVar("tilt_max", "100") ///tilt maxium - .addConfigVar("tilt_closed_value", "0") ///tilt closed value - .addConfigVar("tilt_opened_value", "100") ///tilt open value - .addConfigVar("device_class", "blind"); ///device class - -int len2 = mkblindcontrol.getConfigPayload().length()+1; -client.publish(mkblindcontrol.getConfigTopic(), mkblindcontrol.getConfigPayload(), len2, true); + .addConfigVar("payload_open", "OPEN") // pay load open + .addConfigVar("payload_close", "CLOSED") // payload closed + .addConfigVar("payload_stop", "STOP") // pay load stop + .addConfigVar("stat_open", "0") // state open + .addConfigVar("state_opening", "opening") // state opening + .addConfigVar("state_closed", "100") // state closed + .addConfigVar("state_closing", "closing") // state closing + .addConfigVar("payload_available", "online") // payload available + .addConfigVar("payload_not_available", "offline") // payload not avilable + .addConfigVar("optimistic", "false") // optimistic + .addConfigVar("value_template", "{{ value.x }}") // value template + .addConfigVar("position_template", "{{ value.y }}") // position value + .addConfigVar("tilt_command_topic", "cmnd/"+_identifier+"/tilt") // tilt command topic + .addConfigVar("tilt_status_topic", "stat/"+_identifier+"/STATE") // tilt status topic + .addConfigVar("tilt_status_template", "{{ value_json['PWM']['PWM1'] }}") // tilt status template + .addConfigVar("tilt_min", "0") // tilt minium + .addConfigVar("tilt_max", "100") // tilt maxium + .addConfigVar("tilt_closed_value", "0") // tilt closed value + .addConfigVar("tilt_opened_value", "100") // tilt open value + .addConfigVar("device_class", "blind"); // device class -mkblindcontrol - .clearAttributes() - .addAttribute("IP", WiFi.localIP().toString()); - client.publish(mkblindcontrol.getAttributesTopic(), mkblindcontrol.getAttributesPayload()); + int len2 = mkblindcontrol.getConfigPayload().length()+1; + client.publish(mkblindcontrol.getConfigTopic(), mkblindcontrol.getConfigPayload(), len2, true); + mkblindcontrol + .clearAttributes() + .addAttribute("IP", WiFi.localIP().toString()); + client.publish(mkblindcontrol.getAttributesTopic(), mkblindcontrol.getAttributesPayload()); } - - - - - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -////HA Auto descovery type1 - -///////////////////////////////////// -// -void HA_Discovery(){ - //Serial.print("Generating Homeassistant Discovery "); -/////asign variable from main -_name = String(mqtt_topic); ///aka mqtt device ID will change in main program -HAMqttDevice mkblindcontrol(_name, HAMqttDevice::COVER); - +// HA_Discovery - HA Auto descovery type1 +void HA_Discovery() { + // Serial.print("Generating Homeassistant Discovery "); + // asign variable from main + _name = String(mqtt_topic); // aka mqtt device ID will change in main program + HAMqttDevice mkblindcontrol(_name, HAMqttDevice::COVER); // Configure extra config vars for Home assistant mkblindcontrol .enableAttributesTopic(); -// Id = name to lower case replacing spaces by underscore (ex: name="Kitchen Light" -> id="kitchen_light") - _identifier = _name; - _identifier.replace(' ', '_'); - _identifier.toLowerCase(); + // Id = name to lower case replacing spaces by underscore (ex: name="Kitchen Light" -> id="kitchen_light") + _identifier = _name; + _identifier.replace(' ', '_'); + _identifier.toLowerCase(); StaticJsonDocument<800> root; + root["platform"] = "mqtt"; + root["~"] = _identifier; + root["name"] = String(mqtt_topic); + root["unique_id"] = _identifier; + root["command_topic"] = "cmnd/"+_identifier+"/POWER"; + root["state_topic"] = "stat/"+_identifier+"/STATE"; + root["availability_topic"] = "tele/"+_identifier+"/LWT"; + root["retain"] = false; + root["payload_open"] = "0"; + root["payload_close"] = "100"; + root["state_open"] = "0"; + root["state_closed"] = "100"; + root["payload_available"] = "Online"; + root["payload_not_available"] = "Offline"; + // root["value_template"] = "{% if value == '100' -%}closed{%- else -%}open{%- endif %}"; - root["platform"] = "mqtt"; - root["~"] = _identifier; - root["name"] = String(mqtt_topic); - root["unique_id"] = _identifier; - root["command_topic"] = "cmnd/"+_identifier+"/POWER"; - root["state_topic"] = "stat/"+_identifier+"/STATE"; - root["availability_topic"] = "tele/"+_identifier+"/LWT"; - root["retain"] = false; - root["payload_open"] = "0"; - root["payload_close"] = "100"; - root["state_open"] = "0"; - root["state_closed"] = "100"; - root["payload_available"] = "Online"; - root["payload_not_available"] = "Offline"; - //root["value_template"] = "{% if value == '100' -%}closed{%- else -%}open{%- endif %}"; - if (String(auto_discovery) == "ENABLED-TILT") - { + if (String(auto_discovery) == "ENABLED-TILT") { root["position_open"] = 0; root["position_closed"] = 100; root["tilt_command_topic"] = "cmnd/"+_identifier+"/tilt"; @@ -717,110 +544,113 @@ HAMqttDevice mkblindcontrol(_name, HAMqttDevice::COVER); root["tilt_max"] = 100; root["tilt_closed_value"] = 0; root["tilt_opened_value"] = 100; - } - root["device_class"] = "blind"; - - size_t len = measureJson(root); ///////JSON6 - //size_t len = root.measureLength(); ////JSON5 - size_t size = len + 1; + } - char JSONmessageBuffer[size]; + root["device_class"] = "blind"; - //root.printTo(JSONmessageBuffer, size); /////json5 - serializeJson(root, JSONmessageBuffer, size); ////json6 + size_t len = measureJson(root); // JSON6 + // size_t len = root.measureLength(); // JSON5 + size_t size = len + 1; + + char JSONmessageBuffer[size]; + + // root.printTo(JSONmessageBuffer, size); // json5 + serializeJson(root, JSONmessageBuffer, size); // json6 + + client.publish("homeassistant/cover/"+_identifier+"/config", JSONmessageBuffer, size, true); + // client.publish("ha/cover/"+_identifier+"/config", JSONmessageBuffer, size, true); - client.publish("homeassistant/cover/"+_identifier+"/config", JSONmessageBuffer, size, true); - //client.publish("ha/cover/"+_identifier+"/config", JSONmessageBuffer, size, true); - /// + // process attributes + mkblindcontrol + .clearAttributes() + .addAttribute("IP", WiFi.localIP().toString()) + .addAttribute("manufacturer", "MK-Smarthouse") + .addAttribute("model", "MK-BlindControl") + .addAttribute("sw_version", String(firmware_installed)); - ///////process attributes - mkblindcontrol - .clearAttributes() - .addAttribute("IP", WiFi.localIP().toString()) - .addAttribute("manufacturer", "MK-Smarthouse") - .addAttribute("model", "MK-BlindControl") - .addAttribute("sw_version", String(firmware_installed)); - client.publish(mkblindcontrol.getAttributesTopic(), mkblindcontrol.getAttributesPayload()); + client.publish(mkblindcontrol.getAttributesTopic(), mkblindcontrol.getAttributesPayload()); -//////////ADD SENSOR DATA FOR BATTERY MONITOR - - - -////////////////////////////////////////////// + // ADD SENSOR DATA FOR BATTERY MONITOR } -void SendHTML_Header(){ - httpServer.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - httpServer.sendHeader("Pragma", "no-cache"); - httpServer.sendHeader("Expires", "-1"); - httpServer.setContentLength(CONTENT_LENGTH_UNKNOWN); - httpServer.send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. +// SendHTML_Header +void SendHTML_Header() { + httpServer.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); + httpServer.sendHeader("Pragma", "no-cache"); + httpServer.sendHeader("Expires", "-1"); + httpServer.setContentLength(CONTENT_LENGTH_UNKNOWN); + httpServer.send(200, "text/html", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. append_page_header(); httpServer.sendContent(webpage); webpage = ""; } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void SendHTML_Content(){ + +// SendHTML_Content +void SendHTML_Content() { httpServer.sendContent(webpage); webpage = ""; } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void SelectInput(String heading1, String command, String arg_calling_name){ +// SelectInput +void SelectInput(String heading1, String command, String arg_calling_name) { SendHTML_Header(); - webpage += F("

"); webpage += heading1 + "

"; + webpage += F("

"); webpage += heading1 + "

"; webpage += F("
"; // Must match the calling argument e.g. '/chart' calls '/chart' after selection but with arguments! webpage += F("
"); webpage += F("

"); - //webpage += F(""); + // webpage += F(""); webpage += F("[Back]

"); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void ReportSPIFFSNotPresent(){ + +// ReportSPIFFSNotPresent +void ReportSPIFFSNotPresent() { SendHTML_Header(); - webpage += F("

No SPIFFS present

"); + webpage += F("

No SPIFFS present

"); webpage += F("[Back]

"); - //webpage += F(""); + // webpage += F(""); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void ReportFileNotPresent(String target){ + +// ReportFileNotPresent +void ReportFileNotPresent(String target) { SendHTML_Header(); - webpage += F("

File does not exist

"); + webpage += F("

File does not exist

"); webpage += F("[Back]

"; append_page_footer(); SendHTML_Content(); SendHTML_Stop(); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void ReportCouldNotCreateFile(String target){ + +// ReportCouldNotCreateFile +void ReportCouldNotCreateFile(String target) { SendHTML_Header(); - webpage += F("

Could Not Create Uploaded File (write-protected?)

"); + webpage += F("

Could Not Create Uploaded File (write-protected?)

"); webpage += F("[Back]

"; append_page_footer(); SendHTML_Content(); SendHTML_Stop(); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -String file_size(int bytes){ + +// file_size +String file_size(int bytes) { String fsize = ""; if (bytes < 1024) fsize = String(bytes)+" B"; - else if(bytes < (1024*1024)) fsize = String(bytes/1024.0,3)+" KB"; - else if(bytes < (1024*1024*1024)) fsize = String(bytes/1024.0/1024.0,3)+" MB"; + else if (bytes < (1024*1024)) fsize = String(bytes/1024.0,3)+" KB"; + else if (bytes < (1024*1024*1024)) fsize = String(bytes/1024.0/1024.0,3)+" MB"; else fsize = String(bytes/1024.0/1024.0/1024.0,3)+" GB"; + return fsize; } -///--------------------------------------------------------------------------- -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void DownloadFile(String filename){ - if (SPIFFS_present) { - /// File download = SPIFFS.open("/"+filename, "r"); ///old system +// DownloadFile +void DownloadFile(String filename) { + if (SPIFFS_present) { + // File download = SPIFFS.open("/"+filename, "r"); // old system File download = LittleFS.open("/"+filename, "r"); if (download) { httpServer.sendHeader("Content-Type", "text/text"); @@ -828,123 +658,120 @@ void DownloadFile(String filename){ httpServer.sendHeader("Connection", "close"); httpServer.streamFile(download, "application/octet-stream"); download.close(); - } else ReportFileNotPresent("download"); - } else ReportSPIFFSNotPresent(); + } else { + ReportFileNotPresent("download"); + } + } else { + ReportSPIFFSNotPresent(); + } } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void File_Upload(){ + +// File_Upload +void File_Upload() { append_page_header(); - webpage += F("

Select File to Upload

"); + webpage += F("

Select File to Upload

"); webpage += F(""); webpage += F("
"); webpage += F("

"); - //webpage += F(""); + // webpage += F(""); webpage += F("[Back]

"); - + append_page_footer(); httpServer.send(200, "text/html",webpage); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void SPIFFS_file_delete(String filename) { // Delete the file - if (SPIFFS_present) { + +// SPIFFS_file_delete +void SPIFFS_file_delete(String filename) { // Delete the file + if (SPIFFS_present) { SendHTML_Header(); - ///File dataFile = SPIFFS.open("/"+filename, "r"); // Now read data from SPIFFS Card /////old system - File dataFile = LittleFS.open("/"+filename, "r"); // Now read data from SPIFFS Card - if (dataFile) - { - ///if (SPIFFS.remove("/"+filename)) { ////old system + // File dataFile = SPIFFS.open("/"+filename, "r"); // Now read data from SPIFFS Card // old system + File dataFile = LittleFS.open("/"+filename, "r"); // Now read data from SPIFFS Card + + if (dataFile) { + // if (SPIFFS.remove("/"+filename)) { // old system if (LittleFS.remove("/"+filename)) { Serial.println(F("File deleted successfully")); - webpage += "

File '"+filename+"' has been erased

"; + webpage += "

File '"+filename+"' has been erased

"; webpage += F(""); - //webpage += F("[Back]

"); - } - else - { + // webpage += F("[Back]

"); + } else { webpage += F("

File was not deleted - error

"); - webpage += F(""); - //webpage += F("[Back]

"); + webpage += F(""); + // webpage += F("[Back]

"); } - } else ReportFileNotPresent("delete"); - append_page_footer(); - SendHTML_Content(); - SendHTML_Stop(); - } else ReportSPIFFSNotPresent(); -} -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void File_Delete(){ - if (httpServer.args() > 0 ) { // Arguments were received - if (httpServer.hasArg("delete")) SPIFFS_file_delete(httpServer.arg(0)); - } - else SelectInput("Select a File to Delete","delete","delete"); -} -////////////////////////////////////// -///////////////////////////// -/////////////////////////// -void get_save_state() { - -//////start checkpoint1 - ///if (SPIFFS.exists("/devicestate.dat")) ///old system - if (LittleFS.exists("/devicestate.dat")) - - { - Serial.print("Retriving Divice State..devicestate.data "); - //file exists, reading and loading - ///File configFile = SPIFFS.open("/devicestate.dat", "r"); ///old system - File configFile = LittleFS.open("/devicestate.dat", "r"); - if (configFile) - { - size_t size = configFile.size(); - // Allocate a buffer to store contents of the file. - std::unique_ptr buf(new char[size]); - - configFile.readBytes(buf.get(), size); - - DynamicJsonDocument devicestate(1024); ////JSON6 - auto deserializeError = deserializeJson(devicestate, buf.get()); ////json6 - serializeJson(devicestate, Serial); //////JSON6 - - - ///DynamicJsonBuffer jsonBuffer; /////JSON5 - //JsonObject& devicestate = jsonBuffer.parseObject(buf.get()); //////JSON5 - ///devicestate.printTo(Serial); /////JSON5 - - - configFile.close(); - - - - ///if (devicestate.success()) ///JSON5 - if ( ! deserializeError ) ////JSON6 - { - //client.publish("tele/" + String(_identifier) + "/DEVICE_STATE", "RETRIEVED"); - ServoPos = devicestate["ServoPos"]; - msgcommand = devicestate["POWER"]; - Blind_STATE = devicestate["STATE"].as(); - msgString = devicestate["TILT"].as(); - TiltPos = devicestate["TILT"].as(); - HA_Blind_State = devicestate["HAState"].as(); - TiltPos = devicestate["PWM1"].as(); - msgpayload = devicestate["cmnd"].as(); - strcpy(host, devicestate["Device"]); - strcpy(blinds_speed, devicestate["SPEED"]); - - - } - else - { - } - } - + } else { + ReportFileNotPresent("delete"); } + append_page_footer(); + SendHTML_Content(); + SendHTML_Stop(); + } else { + ReportSPIFFSNotPresent(); + } } -/////////////////////////////////////////////////////////////////////// -///OTA Server needs to be running eg on Raspberry Pi etc or access to resporitory + +// File_Delete +void File_Delete() { + if (httpServer.args() > 0 ) { // Arguments were received + if (httpServer.hasArg("delete")) { + SPIFFS_file_delete(httpServer.arg(0)); + } + } else { + SelectInput("Select a File to Delete","delete","delete"); + } +} + +// get_save_state +void get_save_state() { + // start checkpoint1 + // if (SPIFFS.exists("/devicestate.dat")) // old system + if (LittleFS.exists("/devicestate.dat")) { + Serial.print("Retriving Divice State..devicestate.data "); + // file exists, reading and loading + // File configFile = SPIFFS.open("/devicestate.dat", "r"); // old system + File configFile = LittleFS.open("/devicestate.dat", "r"); + + if (configFile) { + size_t size = configFile.size(); + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); + + configFile.readBytes(buf.get(), size); + + DynamicJsonDocument devicestate(1024); // JSON6 + auto deserializeError = deserializeJson(devicestate, buf.get()); // json6 + serializeJson(devicestate, Serial); // JSON6 + + // DynamicJsonBuffer jsonBuffer; // JSON5 + // JsonObject& devicestate = jsonBuffer.parseObject(buf.get()); // JSON5 + // devicestate.printTo(Serial); // JSON5 + + configFile.close(); + + // if (devicestate.success()) // JSON5 + if ( ! deserializeError ) { // JSON6 + // client.publish("tele/" + String(_identifier) + "/DEVICE_STATE", "RETRIEVED"); + ServoPos = devicestate["ServoPos"]; + msgcommand = devicestate["POWER"]; + Blind_STATE = devicestate["STATE"].as(); + msgString = devicestate["TILT"].as(); + TiltPos = devicestate["TILT"].as(); + HA_Blind_State = devicestate["HAState"].as(); + TiltPos = devicestate["PWM1"].as(); + msgpayload = devicestate["cmnd"].as(); + strcpy(host, devicestate["Device"]); + strcpy(blinds_speed, devicestate["SPEED"]); + } + } + } +} + +// OTAUpgrade - OTA Server needs to be running eg on Raspberry Pi etc or access to resporitory void OTAUpgrade() { -//Serial.print("OTA Upgrade Iniated... "); -restartflag = 1; -SendHTML_Header(); + // Serial.print("OTA Upgrade Iniated... "); + restartflag = 1; + SendHTML_Header(); webpage += F("

Auto Firmware Updater


"); webpage += F("

Connecting to OTA Server

"); webpage += F("

Downloading/Installing Firmware

"); @@ -952,102 +779,94 @@ SendHTML_Header(); webpage += F("

Wait about 20 seconds

"); webpage += F("

Press Reboot to Activate New Firmware

"); webpage += F("

Wait for about 10 seconds before pressing Back

"); - //webpage += F("

Blind Will Jolt After Restart Then Press Back

"); + // webpage += F("

Blind Will Jolt After Restart Then Press Back

"); webpage += F(""); - webpage += F(""); + webpage += F(""); SendHTML_Content(); - - //ESPhttpUpdate.rebootOnUpdate(false); - //t_httpUpdate_return ret = ESPhttpUpdate.update(net, OTAAuto_path); + + // ESPhttpUpdate.rebootOnUpdate(false); + // t_httpUpdate_return ret = ESPhttpUpdate.update(net, OTAAuto_path); t_httpUpdate_return ret = ESPhttpUpdate.update(net, OTAAuto_path); - //t_httpUpdate_return ret = ESPhttpUpdate.update(net, "http://mountaineagle-technologies.com.au/tasmota/mk-blindcontrol.bin"); - + // t_httpUpdate_return ret = ESPhttpUpdate.update(net, "http://mountaineagle-technologies.com.au/tasmota/mk-blindcontrol.bin"); + switch (ret) { case HTTP_UPDATE_FAILED: Serial.print("OTA Upgrade Failed "); client.publish("tele/" + _identifier + "/UPDATE", "HTTP_UPDATE_FAILD"); - //Serial.println("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); - //httpServer.send(201, "text/plain", "OTA Update Failed Error DownLoading Firmware from OTA Server"); - + // Serial.println("HTTP_UPDATE_FAILD Error (%d): %s", ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str()); + // httpServer.send(201, "text/plain", "OTA Update Failed Error DownLoading Firmware from OTA Server"); + webpage += F("

OTA Update Failed Error DownLoading Firmware from OTA Server

"); - //webpage += F("

OTA Update Failed Error DownLoading Firmware from OTA Server

"); + // webpage += F("

OTA Update Failed Error DownLoading Firmware from OTA Server

"); break; case HTTP_UPDATE_NO_UPDATES: Serial.print("No Updates Available from OTA Server "); client.publish("tele/" + _identifier + "/UPDATE", "HTTP_UPDATE_NO_UPDATES"); - //httpServer.send(201, "text/plain", "No Updates Available from OTA Server "); + // httpServer.send(201, "text/plain", "No Updates Available from OTA Server "); webpage += F("

No Updates Available from OTA Server

"); - //USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES"); + // USE_SERIAL.println("HTTP_UPDATE_NO_UPDATES"); break; case HTTP_UPDATE_OK: client.publish("tele/" + String(_identifier) + "/UPDATE", "HTTP_UPDATE_OK"); - //httpServer.send(201, "text/plain", "OTAUpdate OK , DownLoading Firmware from OTA Server and Installing "); + // httpServer.send(201, "text/plain", "OTAUpdate OK , DownLoading Firmware from OTA Server and Installing "); Serial.println("HTTP_UPDATE_OK"); webpage += F("

OTAUpdate OK

"); - + break; } - - webpage += F(""); + + webpage += F(""); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent - } -////////////////////////////////////////////// +// handleMoveServo void handleMoveServo() { - - - // Attach the servo to the servo object - //(13, 544, 2200); + // Attach the servo to the servo object + //(13, 544, 2200); // myservo[0].write(ServoPos); if (!myservo[0].attached()) { // If the servo is not attached myservo[0].attach(13, 544, 2200); myservo[1].attach(14, 544, 2200); } - - - - // Wait 500 milliseconds - delay(500); - + // Wait 500 milliseconds + delay(500); + String s = MAIN_page; // Read HTML contents + // String x = document.getElementById("demo"); + SendHTML_Header(); + httpServer.arg("this.value") == String(myservo[0].read()); + httpServer.arg("demo") == String(myservo[0].read()); + webpage += F("

Set Open and Closed Limits


"); -String s = MAIN_page; //Read HTML contents -//String x = document.getElementById("demo"); -SendHTML_Header(); - httpServer.arg("this.value") == String(myservo[0].read()); - httpServer.arg("demo") == String(myservo[0].read()); - webpage += F("

Set Open and Closed Limits


"); - - webpage += F(""); - webpage += ""; + webpage += F("
System Generated Open Limit "+String(open_limit_default)+"
"); + webpage += ""; webpage += ""; webpage += ""; webpage += ""; webpage += F("
System Generated Open Limit "+String(open_limit_default)+"
User Set Open Limit"+String(open_limit_set)+"
System Generated Closed Limit"+String(close_limit_default)+"
User Set Closed Limit"+String(close_limit_set)+"
"); - webpage += s; - + webpage += s; + webpage += F(""); webpage += F(""); webpage += F(""); - - //String s = MAIN_page; //Read HTML contents -append_page_footer(); + + // String s = MAIN_page; // Read HTML contents + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent - //httpServer.send(200, "text/html", s); //Send web page - + // httpServer.send(200, "text/html", s); // Send web page } -//////////////////////////////////// -void SetOpenLimit(){ - SendHTML_Header(); - webpage += F("

Set Open and Closed Limits


"); + +// SetOpenLimit +void SetOpenLimit() { + SendHTML_Header(); + webpage += F("

Set Open and Closed Limits


"); Serial.print("Open Limit Set To"); Serial.println(BufferPos.toInt()); strcpy(open_limit_set, BufferPos.c_str()); @@ -1060,14 +879,15 @@ void SetOpenLimit(){ SendHTML_Content(); SendHTML_Stop(); } -//////////////// -void SetClosedLimit(){ -SendHTML_Header(); - webpage += F("

Set Open and Closed Limits


"); + +// SetClosedLimit +void SetClosedLimit() { + SendHTML_Header(); + webpage += F("

Set Open and Closed Limits


"); Serial.print("Closed Limit Set To"); Serial.println(BufferPos.toInt()); strcpy(close_limit_set, BufferPos.c_str()); - webpage += ("

Closed Limit Has Been Set to

"+String(close_limit_set)+"

"); ///tr + webpage += ("

Closed Limit Has Been Set to

"+String(close_limit_set)+"

"); // tr webpage += F("

Setting has not been saved

"); webpage += F("

After Setting Limits, select SAVE from menu

"); webpage += F("

Press back to return to Limit settings

"); @@ -1075,21 +895,20 @@ SendHTML_Header(); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); - } -//////////////// -//////////////// -void ResetLimits(){ -SendHTML_Header(); - webpage += F("

Set Open and Closed Limits


"); + +// ResetLimits +void ResetLimits() { + SendHTML_Header(); + webpage += F("

Set Open and Closed Limits


"); Serial.print("Reset Limits Set To Default"); strcpy(close_limit_set, ""); strcpy(open_limit_set, ""); webpage += F("

Closed and Open Limits Have Been Set to Defaults

"); webpage += ("

Closed Limit Has Been Set to Auto Setup

"); - webpage += ("

Open Limit Has Been Set to Auto Setup

"); ///tr ///tr - webpage += ("

System will re-configure on reboot

"); ///tr ///tr - + webpage += ("

Open Limit Has Been Set to Auto Setup

"); // tr // tr + webpage += ("

System will re-configure on reboot

"); // tr // tr + webpage += F("

Settings have not been saved

"); webpage += F("

After Re-Setting Limits, select SAVE from menu

"); webpage += F("

Restart is Required for setting to take place

"); @@ -1097,128 +916,108 @@ SendHTML_Header(); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); - } -//////////// -//////////////////////////////////// + +// save_state void save_state() { -//New code to safe device state to SPIFF file -//Serial.print("Saving device state "); + // New code to safe device state to SPIFF file + // Serial.print("Saving device state "); -//const size_t capacitystate2 = JSON_OBJECT_SIZE(12); -StaticJsonDocument<512> devicestate; + // const size_t capacitystate2 = JSON_OBJECT_SIZE(12); + StaticJsonDocument<512> devicestate; -devicestate["Device"] = String(host); -devicestate["Name"] = String(mqtt_topic); -devicestate["ServoPos"] = ServoPos; -devicestate["cmnd"] = msgpayload; -devicestate["POWER"] = msgcommand; -devicestate["SPEED"] = String(blinds_speed); -devicestate["HAState"] = String(HA_Blind_State); -devicestate["TILT"] = String(TiltPos); -devicestate["PWM1"] = String(TiltPos); -devicestate["STATE"] = Blind_STATE; + devicestate["Device"] = String(host); + devicestate["Name"] = String(mqtt_topic); + devicestate["ServoPos"] = ServoPos; + devicestate["cmnd"] = msgpayload; + devicestate["POWER"] = msgcommand; + devicestate["SPEED"] = String(blinds_speed); + devicestate["HAState"] = String(HA_Blind_State); + devicestate["TILT"] = String(TiltPos); + devicestate["PWM1"] = String(TiltPos); + devicestate["STATE"] = Blind_STATE; -/////save software status.dat file/// - //File configFile = SPIFFS.open("/devicestate.dat", "w"); ////old system - File configFile = LittleFS.open("/devicestate.dat", "w"); - if (!configFile) - { - } - - - serializeJson(devicestate, Serial); ////JSON6 - serializeJson(devicestate, configFile); /////JSON6 + // save software status.dat file + // File configFile = SPIFFS.open("/devicestate.dat", "w"); // old system + File configFile = LittleFS.open("/devicestate.dat", "w"); + // if (!configFile) {} + serializeJson(devicestate, Serial); // JSON6 + serializeJson(devicestate, configFile); // JSON6 configFile.close(); - ////detach all servos -myservo[0].detach(); -myservo[1].detach(); - - + // detach all servos + myservo[0].detach(); + myservo[1].detach(); } -//////////////////////////////////////////// -boolean isValidNumber(String str) -{ +// isValidNumber +boolean isValidNumber(String str) { isNum = false; + if (!(str.charAt(0) == '+' || str.charAt(0) == '-' || isDigit(str.charAt(0)))) return false; - for (byte i = 1; i < str.length(); i++) - { + for (byte i = 1; i < str.length(); i++) { if (!(isDigit(str.charAt(i)) || str.charAt(i) == '.')) return false; } + return true; } -///////////////////////////////////////////// +// tele_update void tele_update() { - - int tele_period = String(tele_update_set).toInt() * 1000; //time converted to millseconds - - if ((millis() > time_now + tele_period) || (reboot==1)) { + int tele_period = String(tele_update_set).toInt() * 1000; // time converted to millseconds - + if ((millis() > time_now + tele_period) || (reboot==1)) { + // start new json coding + StaticJsonDocument<512> rootstate; -////start new json coding - - StaticJsonDocument<512> rootstate; - - rootstate["Device"] = mqttDeviceID; - rootstate["Name"] = String(mqtt_topic); - rootstate["ServoPos"] = ServoPos; - rootstate["POWER"] = msgcommand; - rootstate["HAState"] = HA_Blind_State; - rootstate["TILT"] = TiltPos; - rootstate["STATE"] = Blind_STATE; - rootstate["cmnd"] = String(msgpayload); - rootstate["SPEED"] = String(blinds_speed); - rootstate["BattVoltage"] = Battery_Voltage; - rootstate["ChargeCapacity"] = Battery_Cap; - rootstate["DischargeTime"] = Discharge_Time; - rootstate["RemainingTime"] = Remaining_Time; - rootstate["PWM1"] = TiltPos.toInt(); + rootstate["Device"] = mqttDeviceID; + rootstate["Name"] = String(mqtt_topic); + rootstate["ServoPos"] = ServoPos; + rootstate["POWER"] = msgcommand; + rootstate["HAState"] = HA_Blind_State; + rootstate["TILT"] = TiltPos; + rootstate["STATE"] = Blind_STATE; + rootstate["cmnd"] = String(msgpayload); + rootstate["SPEED"] = String(blinds_speed); + rootstate["BattVoltage"] = Battery_Voltage; + rootstate["ChargeCapacity"] = Battery_Cap; + rootstate["DischargeTime"] = Discharge_Time; + rootstate["RemainingTime"] = Remaining_Time; + rootstate["PWM1"] = TiltPos.toInt(); - JsonObject Wifi = rootstate.createNestedObject("Wifi"); ////JSON6 - - Wifi["AP"] = String(ssidAP); - Wifi["SSId"] = String(WiFi.SSID()); - Wifi["MAC"] = WiFi.macAddress(); - Wifi["Channel"] = WiFi.channel(); - Wifi["RSSI"] = dBmtoPercentage(WiFi.RSSI()); - Wifi["Signal"] = WiFi.RSSI(); - Wifi["IPAddress"] = WiFi.localIP().toString(); -//////end json encoding + JsonObject Wifi = rootstate.createNestedObject("Wifi"); // JSON6 + + Wifi["AP"] = String(ssidAP); + Wifi["SSId"] = String(WiFi.SSID()); + Wifi["MAC"] = WiFi.macAddress(); + Wifi["Channel"] = WiFi.channel(); + Wifi["RSSI"] = dBmtoPercentage(WiFi.RSSI()); + Wifi["Signal"] = WiFi.RSSI(); + Wifi["IPAddress"] = WiFi.localIP().toString(); + // end json encoding - time_now = millis(); - size_t lenstate = measureJson(rootstate); ///JSON6 - // size_t lenstate = rootstate.measureLength(); ///JSON5 + size_t lenstate = measureJson(rootstate); // JSON6 + // size_t lenstate = rootstate.measureLength(); // JSON5 size_t size = lenstate + 1; char JSONmessageBufferstate[size]; - serializeJson(rootstate, JSONmessageBufferstate, size); //JSON6 - //rootstate.printTo(JSONmessageBufferstate, size); ///JSON5 - -///////////get offset value based on open and closed limits and state of blind ie opened or closed - ////////////////////////////////////////// - - publish_state(); - - -client.publish("tele/" + _identifier + "/STATE", JSONmessageBufferstate);////full telementry only + serializeJson(rootstate, JSONmessageBufferstate, size); // JSON6 + // rootstate.printTo(JSONmessageBufferstate, size); // JSON5 + // get offset value based on open and closed limits and state of blind ie opened or closed -SSDP.begin(); - - } + publish_state(); -//////////////////////////////////////////////////// + client.publish("tele/" + _identifier + "/STATE", JSONmessageBufferstate); // full telementry only + + SSDP.begin(); + } } -//////////////////////////////////////////////////////////// -////////////////////////////////////////////// +// connect void connect() { String STRING_LWT_TOPIC = "tele/" + _identifier + "/LWT"; const char* MQTT_LWT_TOPIC = STRING_LWT_TOPIC.c_str(); @@ -1226,107 +1025,77 @@ void connect() { POWER_TOPIC = STRING_POWER_TOPIC.c_str(); const char* MQTT_LWT_MESSAGE = "Online"; - client.setWill(MQTT_LWT_TOPIC, "Offline", 0, true); //Set LWT state - //boolean connect (clientID, username, password, willTopic, willQoS, willRetain, willMessage, cleanSession) -WiFi.hostname(host); -WiFi.begin(); + client.setWill(MQTT_LWT_TOPIC, "Offline", 0, true); // Set LWT state + // boolean connect (clientID, username, password, willTopic, willQoS, willRetain, willMessage, cleanSession) + WiFi.hostname(host); + WiFi.begin(); + while (WiFi.status() != WL_CONNECTED) { delay(1000); } - - - //If authentication true then connect with username and password + // If authentication true then connect with username and password if (String(mqtt_isAuthentication).equalsIgnoreCase("TRUE")) { - while (!client.connect(mqttDeviceID, mqtt_username, mqtt_password)) { delay(1000); } - } - else - { + } else { while (!client.connect(mqttDeviceID)) { delay(1000); } } int len = strlen(MQTT_LWT_MESSAGE) + 1; - + client.publish(MQTT_LWT_TOPIC, MQTT_LWT_MESSAGE, len, true); client.subscribe("cmnd/" + _identifier + "/#"); - - client.subscribe("cmnd/tasmotas/#"); //allows for device reset, firmare upgrade etc commands via MQTT + + client.subscribe("cmnd/tasmotas/#"); // allows for device reset, firmare upgrade etc commands via MQTT Serial.print("cmnd/tasmotas/#"); - if (String(auto_discovery).equalsIgnoreCase("ENABLED-BASIC") || String(auto_discovery).equalsIgnoreCase("ENABLED-TILT")) - { - client.subscribe("homeassistant/status"); - + if (String(auto_discovery).equalsIgnoreCase("ENABLED-BASIC") || String(auto_discovery).equalsIgnoreCase("ENABLED-TILT")) { + client.subscribe("homeassistant/status"); }; -/////////////////////////////////////////////////////// - - -//get_save_state(); ///get saved state on reboot servo position message command speed -//moveServo(ServoPos); ///moves servo to set pos as on powerup servo pos defaults to 90 regardless of previous osition + // get_save_state(); // get saved state on reboot servo position message command speed -tele_update(); ///publish saved states - -publish_state(); ///publish states to MQTT + // moveServo(ServoPos); // moves servo to set pos as on powerup servo pos defaults to 90 regardless of previous osition + tele_update(); // publish saved states + publish_state(); // publish states to MQTT } +// end connection to WiFi and MQTT -///end connection to WiFi and MQTT - -/////Process message received - -void messageReceived(String &topic, String &payload) -{ - - bypassdevstat = 0; ////allow for bypass servo read when disconnested if messages are non servo movement.... e.h. HA activationand firmware update and device stat request +// messageReceived - Process message received +void messageReceived(String &topic, String &payload) { + bypassdevstat = 0; // allow for bypass servo read when disconnested if messages are non servo movement.... e.h. HA activationand firmware update and device stat request msgString = payload.c_str(); msgpayload = msgString; - - String blindstrim = blinds_trim_adjust; //new varible for open state adjustment -///////Home Assistant Auto discovery - - if ((topic == "homeassistant/status"||topic == "cmnd/" + _identifier + "/Config") && (msgString == "online"||msgString == "Set")) - { + String blindstrim = blinds_trim_adjust; // new varible for open state adjustment + + // Home Assistant Auto discovery + if ((topic == "homeassistant/status"||topic == "cmnd/" + _identifier + "/Config") && (msgString == "online"||msgString == "Set")) { bypassdevstat = 1; - HA_Discovery(); ////JSON GENERATED - - - delay(1000); ///wait 1 second to publish and settle + HA_Discovery(); // JSON GENERATED - } - - else if ((topic == "cmnd/tasmotas/Restart" || topic == "cmnd/" + _identifier + "/Restart") && msgString.toInt() == 1) - { - + delay(1000); // wait 1 second to publish and settle + } else if ((topic == "cmnd/tasmotas/Restart" || topic == "cmnd/" + _identifier + "/Restart") && msgString.toInt() == 1) { Serial.print("tele/" + String(mqtt_topic) + "/RESTART"+ " ACTIVATED"); ESP.reset(); - } - - - else if ((topic == "cmnd/tasmotas/Upgrade" || topic == "cmnd/" + _identifier + "/Upgrade") && msgString.toInt() == 1) - { + } else if ((topic == "cmnd/tasmotas/Upgrade" || topic == "cmnd/" + _identifier + "/Upgrade") && msgString.toInt() == 1) { Serial.print("tele/" + _identifier + "/UPGRADE"+ " ACTIVATED"); - ESPhttpUpdate.rebootOnUpdate(true); ///auto restart after firmware downloaded + ESPhttpUpdate.rebootOnUpdate(true); // auto restart after firmware downloaded bypassdevstat = 1; OTAUpgrade(); - } - -/////make Status STATUS - //////////Device Status - else if ((topic == "cmnd/tasmotas/STATUS" || topic == "cmnd" + _identifier + "/STATUS") && msgString.toInt() == 2) - { - //Serial.print("stat/" + _identifier + "/STATUS2"+ " GENERATED"); + } else if ((topic == "cmnd/tasmotas/STATUS" || topic == "cmnd" + _identifier + "/STATUS") && msgString.toInt() == 2) { + // make Status STATUS + // Serial.print("stat/" + _identifier + "/STATUS2"+ " GENERATED"); bypassdevstat = 1; - + StaticJsonDocument<512> root; - - JsonObject StatusFWR = root.createNestedObject("StatusFWR"); ////JSON6 + + JsonObject StatusFWR = root.createNestedObject("StatusFWR"); // JSON6 StatusFWR["Hostname"] = String(host); StatusFWR["Name"] = String(mqtt_topic); StatusFWR["Version"] = software_version; @@ -1338,32 +1107,25 @@ void messageReceived(String &topic, String &payload) StatusFWR["Slip"] = blinds_slip_correction; StatusFWR["Trim"] = blinds_trim_adjust; - - //root.printTo(Serial); - size_t len = measureJson(root); //json6 - //size_t len = root.measureLength(); ///json5 + // root.printTo(Serial); + size_t len = measureJson(root); // json6 + // size_t len = root.measureLength(); // json5 size_t size = len + 1; char JSONmessageBuffer[size]; serializeJson(root, JSONmessageBuffer, size); - //root.printTo(JSONmessageBuffer, size); ////json5 + // root.printTo(JSONmessageBuffer, size); // json5 - //client.publish("stat/" + String(mqtt_topic) + "/MessageSize", String(len)); ///enable for testing + // client.publish("stat/" + String(mqtt_topic) + "/MessageSize", String(len)); // enable for testing client.publish("stat/" + _identifier + "/STATUS2", JSONmessageBuffer); - //Serial.print("stat/" + _identifier + "/STATUS2 "+ JSONmessageBuffer); - - } - -/////// -////make Status STATUS 5 - //////////Device Status - else if ((topic == "cmnd/tasmotas/STATUS" || topic == "cmnd" + _identifier + "/STATUS") && msgString.toInt() == 5) - { + // Serial.print("stat/" + _identifier + "/STATUS2 "+ JSONmessageBuffer); + } else if ((topic == "cmnd/tasmotas/STATUS" || topic == "cmnd" + _identifier + "/STATUS") && msgString.toInt() == 5) { + // make Status STATUS 5 bypassdevstat = 1; StaticJsonDocument<512> root; - - JsonObject StatusNET = root.createNestedObject("StatusNET"); ////JSON6 + + JsonObject StatusNET = root.createNestedObject("StatusNET"); // JSON6 StatusNET["Hostname"] = String(host); StatusNET["Name"] = String(mqtt_topic); @@ -1375,219 +1137,149 @@ void messageReceived(String &topic, String &payload) StatusNET["Webserver"] = 2; StatusNET["WifiConfig"] = WiFi.channel(); StatusNET["WifiPower"] = dBmtoPercentage(WiFi.RSSI()); - - //root.printTo(Serial); - size_t len = measureJson(root); ////json6 - //size_t len = root.measureLength(); ////json5 + + // root.printTo(Serial); + size_t len = measureJson(root); // json6 + // size_t len = root.measureLength(); // json5 size_t size = len + 1; char JSONmessageBuffer[size]; - serializeJson(root, JSONmessageBuffer, size); /////json6 - //root.printTo(JSONmessageBuffer, size); //////json5 + serializeJson(root, JSONmessageBuffer, size); // json6 + // root.printTo(JSONmessageBuffer, size); // json5 - //client.publish("stat/" + String(mqtt_topic) + "/MessageSize", String(len)); ///enable for testing + // client.publish("stat/" + String(mqtt_topic) + "/MessageSize", String(len)); // enable for testing client.publish("stat/" + _identifier + "/STATUS5", JSONmessageBuffer); - - - } - - -/////// - - //////Device power command//Process non numeric commands eg up, down, on, off also convert command to numeric for Trim offset etc -////////////////////// -//SPEED Set - else if (topic == "cmnd/" + _identifier + "/SPEED") - //else if (payload == "OPEN" && topic == "cmnd/" + String(mqtt_topic) + "/POWER") - - { - - - if (String(msgString).equalsIgnoreCase("SLOW")) - { - + } else if (topic == "cmnd/" + _identifier + "/SPEED") { + // Device power command + // Process non numeric commands eg up, down, on, off also convert command to numeric for Trim offset etc + // SPEED Set + // else if (payload == "OPEN" && topic == "cmnd/" + String(mqtt_topic) + "/POWER") + if (String(msgString).equalsIgnoreCase("SLOW")) { strcpy(blinds_speed, "SLOW"); - - } - else - { - - strcpy(blinds_speed, "FAST"); - //client.publish("tele/" + String(mqtt_topic) + "/SPEED_CURRENT", String(blinds_speed)); //testing - - } - client.publish("stat/" + _identifier + "/SPEED", String(blinds_speed)); //testing - bypassdevstat = 1; - } - - -//if (msgString.equalsIgnoreCase("OPEN")) OPEN OFF and 0 - else if ((String(msgString).equalsIgnoreCase("OPEN") || String(msgString).equalsIgnoreCase("OFF") || String(msgString).equalsIgnoreCase("0")) && (topic == "cmnd/" + _identifier + "/POWER")) - - { - //client.publish("stat/" + _identifier + "/COMMAND", "OPEN,0,OFF PROCESSED" ); //publish position status must be nurmic - msgString = "0"; //allows for trim adj - TiltPos = "0"; - client.publish("stat/" + _identifier + "/HA_STATE", "OPENING"); - //HA_Blind_State = "open"; - client.publish("stat/" + _identifier + "/position", "0" ); //publish position status must be nurmic - if (invert_command == true) - //if (String(blinds_invert_command).equalsIgnoreCase("YES")) - { - - moveServo(String(open_limit_set).toInt()); ///old method - } - else - { - - moveServo(String(open_limit_set).toInt()); ///new method - } - } - //////////////////////////////////////////// + } else { + strcpy(blinds_speed, "FAST"); + // client.publish("tele/" + String(mqtt_topic) + "/SPEED_CURRENT", String(blinds_speed)); // testing + } - //if (msgString.equalsIgnoreCase("CLOSE")) or ON or 1 - else if ((String(msgString).equalsIgnoreCase("CLOSE") || String(msgString).equalsIgnoreCase("ON") || String(msgString).equalsIgnoreCase("1") || String(msgString).equalsIgnoreCase("100")) && (topic == "cmnd/" + _identifier + "/POWER")) - { - //client.publish("stat/" + _identifier + "/COMMAND", "CLOSE,1,100,ON PROCESSED" ); + client.publish("stat/" + _identifier + "/SPEED", String(blinds_speed)); // testing + bypassdevstat = 1; + } else if ((String(msgString).equalsIgnoreCase("OPEN") || String(msgString).equalsIgnoreCase("OFF") || String(msgString).equalsIgnoreCase("0")) && (topic == "cmnd/" + _identifier + "/POWER")) { + // if (msgString.equalsIgnoreCase("OPEN")) OPEN OFF and 0 + // client.publish("stat/" + _identifier + "/COMMAND", "OPEN,0,OFF PROCESSED" ); // publish position status must be nurmic + msgString = "0"; // allows for trim adj + TiltPos = "0"; + client.publish("stat/" + _identifier + "/HA_STATE", "OPENING"); + // HA_Blind_State = "open"; + client.publish("stat/" + _identifier + "/position", "0" ); // publish position status must be nurmic + + if (invert_command == true) { + // if (String(blinds_invert_command).equalsIgnoreCase("YES")) + moveServo(String(open_limit_set).toInt()); // old method + } else { + moveServo(String(open_limit_set).toInt()); // new method + } + } else if ((String(msgString).equalsIgnoreCase("CLOSE") || String(msgString).equalsIgnoreCase("ON") || String(msgString).equalsIgnoreCase("1") || String(msgString).equalsIgnoreCase("100")) && (topic == "cmnd/" + _identifier + "/POWER")) { + // if (msgString.equalsIgnoreCase("CLOSE")) or ON or 1 + // client.publish("stat/" + _identifier + "/COMMAND", "CLOSE,1,100,ON PROCESSED" ); msgString = "100"; TiltPos = "100"; - //HA_Blind_State = "closed"; - client.publish("stat/" + _identifier + "/HA_STATE", "CLOSING"); - client.publish("stat/" + _identifier + "/position", "100" ); //publish position status - if (invert_command == true) - //if (String(blinds_invert_command).equalsIgnoreCase("YES")) - { - - - moveServo(String(close_limit_set).toInt()); ////new method - } - else - { - - moveServo(String(close_limit_set).toInt()); ////new method - } - - } + // HA_Blind_State = "closed"; + client.publish("stat/" + _identifier + "/HA_STATE", "CLOSING"); + client.publish("stat/" + _identifier + "/position", "100" ); // publish position status - //if (msgString.equalsIgnoreCase("STOP")) - else if (String(msgString).equalsIgnoreCase("STOP") && topic == "cmnd/" + _identifier + "/POWER") - { - - //myservo[0].detach(); - //myservo[1].detach(); - - } - - //All other numeric values go here Note No Trim will be applied to these settings - //If the Blind Needs to be in the 50 percent range opened , then need to open blind first then set to new position - //This is due to mechanical slip of blind shaft mechinisim - - - else if ((topic == "cmnd/" + _identifier + "/POWER" || topic == "cmnd/" + _identifier + "/tilt") && (isValidNumber(msgString))) - { + if (invert_command == true) { + // if (String(blinds_invert_command).equalsIgnoreCase("YES")) + moveServo(String(close_limit_set).toInt()); // new method + } else { + moveServo(String(close_limit_set).toInt()); // new method + } + } else if (String(msgString).equalsIgnoreCase("STOP") && topic == "cmnd/" + _identifier + "/POWER") { + // if (msgString.equalsIgnoreCase("STOP")) + + // myservo[0].detach(); + // myservo[1].detach(); + } else if ((topic == "cmnd/" + _identifier + "/POWER" || topic == "cmnd/" + _identifier + "/tilt") && (isValidNumber(msgString))) { + // All other numeric values go here Note No Trim will be applied to these settings + // If the Blind Needs to be in the 50 percent range opened , then need to open blind first then set to new position + // This is due to mechanical slip of blind shaft mechinisim TiltPos = msgString; - //HA_Blind_State = "open"; - //client.publish("stat/" + _identifier + "/COMMAND", "NURMERIC RANGE PROCESSED" ); - if (invert_command == true) - //if (String(blinds_invert_command).equalsIgnoreCase("YES")) - { - - //client.publish(String(mqtt_topic) + "/Other Settings Applied inverted"); - if (msgString.toInt() <= 60 && msgString.toInt() >= 40 && String(blinds_slip_correction).equalsIgnoreCase("ON")) - { - //client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); - if (ServoPos/1.8 <= 60 && ServoPos/1.8 >=40) - { - //client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); + // HA_Blind_State = "open"; + // client.publish("stat/" + _identifier + "/COMMAND", "NURMERIC RANGE PROCESSED" ); + + if (invert_command == true) { + // if (String(blinds_invert_command).equalsIgnoreCase("YES")) + + // client.publish(String(mqtt_topic) + "/Other Settings Applied inverted"); + if (msgString.toInt() <= 60 && msgString.toInt() >= 40 && String(blinds_slip_correction).equalsIgnoreCase("ON")) { + // client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); + if (ServoPos/1.8 <= 60 && ServoPos/1.8 >=40) { + // client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); + } else { + moveServo(180); // Reset Allignment to closed state to obtain correct positioning if around 1/2 range } - else{ - moveServo(180); //Reset Allignment to closed state to obtain correct positioning if around 1/2 range - } - } - //actual move after alignment - // client.publish("stat/" + _identifier + "/MOVE-INVERTED", "MOVING" ); + + // actual move after alignment + // client.publish("stat/" + _identifier + "/MOVE-INVERTED", "MOVING" ); moveServo((100 - msgString.toInt()) * 1.8); - } + } else { + if (msgString.toInt() <= 60 && msgString.toInt() >= 40 && String(blinds_slip_correction).equalsIgnoreCase("ON")) { + if (ServoPos/1.8 <= 60 && ServoPos/1.8 >= 40) { + // client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); + } else { + moveServo(0); // Reset Allignment to open state to obtain correct positioning if around 1/2 range + } - - else - { - - if (msgString.toInt() <= 60 && msgString.toInt() >= 40 && String(blinds_slip_correction).equalsIgnoreCase("ON")) - { - if (ServoPos/1.8 <= 60 && ServoPos/1.8 >= 40) - { - //client.publish("stat/" + _identifier + "/ALLIGNING", "INVERTED" ); - } - else{ - moveServo(0); //Reset Allignment to open state to obtain correct positioning if around 1/2 range - } - - //moveServo(180); //Reset Allignment to open state to obtain correct positioning if around 1/2 range - //client.publish("stat/" + _identifier + "/ALLIGNING", "NON-INVERTED" ); - //moveServo(0); //Reset Allignment to open state to obtain correct positioning if around 1/2 range + // moveServo(180); // Reset Allignment to open state to obtain correct positioning if around 1/2 range + // client.publish("stat/" + _identifier + "/ALLIGNING", "NON-INVERTED" ); + // moveServo(0); // Reset Allignment to open state to obtain correct positioning if around 1/2 range } - //Actual move after alignment - //client.publish(String(mqtt_topic) + "/Other Settings Applied NOT inverted"); //can be removed Testing Debug - //client.publish("stat/" + _identifier + "/MOVE-NONINVERTED", "MOVING" ); - moveServo(msgString.toInt() * 1.8); //Move the Servo to other position + + // Actual move after alignment + // client.publish(String(mqtt_topic) + "/Other Settings Applied NOT inverted"); // can be removed Testing Debug + // client.publish("stat/" + _identifier + "/MOVE-NONINVERTED", "MOVING" ); + moveServo(msgString.toInt() * 1.8); // Move the Servo to other position } } - //Publish sevo blind state position before Trim adjustment is applied...this keeps Icon States true no fudge factor - //RollerShutter Icon position and 3 Button choice OPEN ,HALF, CLOSE and states Remain TRUE indication + // Publish sevo blind state position before Trim adjustment is applied...this keeps Icon States true no fudge factor + // RollerShutter Icon position and 3 Button choice OPEN ,HALF, CLOSE and states Remain TRUE indication msgcommand = msgString.toInt(); - //////////////////////////////////// - //////publish states etc//////////////////////////// -///////////////////////////////////////////////to be re programmed//////////////////////////////////////// - if (invert_state == true) - //if (String(blinds_invert_state).equalsIgnoreCase("YES")) - { - //client.publish("stat/" + _identifier + "/STATE", String((int)(100 - (myservo.read() / 1.8) + 0.5))); //publish before trim applied - - } - else - { - //client.publish("stat/" + _identifier + "/STATE", String((int)((myservo.read()) + 0.5))); //publish before trim applied - + // publish states etc + // to be re programmed + if (invert_state == true) { + // if (String(blinds_invert_state).equalsIgnoreCase("YES")) + // client.publish("stat/" + _identifier + "/STATE", String((int)(100 - (myservo.read() / 1.8) + 0.5))); // publish before trim applied + } else { + // client.publish("stat/" + _identifier + "/STATE", String((int)((myservo.read()) + 0.5))); // publish before trim applied } - - ///New code for Open Only Trim Adjustment after publishing state back to mqtt server - //////begin if statement - ///////////////////////////////////////////////////////////////////////////////// - if (blindstrim.toInt() > 0 && blindstrim.toInt() <= 75 && msgString.toInt() == 0) - { + // New code for Open Only Trim Adjustment after publishing state back to mqtt server + if (blindstrim.toInt() > 0 && blindstrim.toInt() <= 75 && msgString.toInt() == 0) { client.publish(String(mqtt_topic) + "/Executing Trim Adjustment of:- " + String(blindstrim) + " Percent"); - if (invert_command == true) - - { - moveServo((100 - blindstrim.toInt()) * 1.8); + + if (invert_command == true) { + moveServo((100 - blindstrim.toInt()) * 1.8); + } else { + moveServo(blindstrim.toInt() * 1.8); } - else - { - moveServo(blindstrim.toInt() * 1.8); - } } -//////////////////////////////////////////////////////////////////////////////////////////////// - -if (bypassdevstat == 0) - { - HA_State(); ////Create HA_Blind_State - process_state(); ///process state - publish_state(); ///publish states to MQTT - save_state(); ///save data to SPIFF File + if (bypassdevstat == 0) { + HA_State(); // Create HA_Blind_State + process_state(); // process state + publish_state(); // publish states to MQTT + save_state(); // save data to SPIFF File } } -///////////////////////////////////// -void File_Manager(){ +// File_Manager +void File_Manager() { SendHTML_Header(); - //webpage += ""+String(software_version)+""; + + // webpage += ""+String(software_version)+""; webpage += F("

File Manager


"); webpage += F(""); webpage += F("
"); @@ -1595,20 +1287,19 @@ void File_Manager(){ webpage += F(""); webpage += F(""); webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent } - -//~///////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void Firmware_Update(){ - ESPhttpUpdate.rebootOnUpdate(false); ///prevents reboot on AUTO upgrade selection user must restart manually +// Firmware_Update +void Firmware_Update() { + ESPhttpUpdate.rebootOnUpdate(false); // prevents reboot on AUTO upgrade selection user must restart manually SendHTML_Header(); - + webpage += F("

Firmware Updater


"); webpage += F(""); - webpage += F("

MANUAL - Upload Firmware from local folder or directory. User selects file

"); webpage += F("

AUTO - Upload Firmware from OTA Server as set it SETUP 'OTAAuto path'

"); webpage += F("

CHECK - Check Resportory Server for latest Firmware release, and advises of upgrade and impact advice

"); @@ -1617,40 +1308,37 @@ void Firmware_Update(){ webpage += F(""); webpage += F(""); webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void Device_Reboot(){ +// Device_Reboot +void Device_Reboot() { SendHTML_Header(); - + webpage += F("

Restart Controller


"); webpage += F("
"); - //webpage += F("

Device will AUTO Restart In 5 Seconds

"); + // webpage += F("

Device will AUTO Restart In 5 Seconds

"); webpage += F("

Blind Will Jolt After Restart

"); webpage += F("

Wait 10 seconds before pressing back

"); webpage += F("

After Restart Press BACK to return to Home

"); webpage += F("
"); webpage += F("
"); webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent -//delay(5000); -ESP.restart(); + // delay(5000); + ESP.restart(); } - - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void Set_Servo(){ +// Set_Servo +void Set_Servo() { SendHTML_Header(); - + webpage += F("

Aligning Servo Motor


"); webpage += F(""); webpage += F("

Servo Motor Positioned To OPEN State For Install

"); @@ -1660,144 +1348,131 @@ void Set_Servo(){ webpage += F("

After Restart Press BACK to return to Home

"); webpage += F("
"); webpage += F("
"); - //webpage += F("[BACK]

"); + // webpage += F("[BACK]

"); webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent -if (invert_command == true) -//if (String(blinds_invert_command).equalsIgnoreCase("YES")) - { - moveServo(180); - moveServo(180); //command to move 3 plus times to push servo motor, noticed some difference with just one command - moveServo(180); - moveServo(180); - // httpServer.send(201, "text/plain", "Servo Motor Positioned To OPEN State For Install, Please Disconnect Power From Device NOW...Before Device AUTO Restarts In 20Seconds "); - } - else - { + if (invert_command == true) { + // if (String(blinds_invert_command).equalsIgnoreCase("YES")) + moveServo(180); + moveServo(180); // command to move 3 plus times to push servo motor, noticed some difference with just one command + moveServo(180); + moveServo(180); + // httpServer.send(201, "text/plain", "Servo Motor Positioned To OPEN State For Install, Please Disconnect Power From Device NOW...Before Device AUTO Restarts In 20Seconds "); + } else { moveServo(0); - moveServo(0); //command to move 3 plus times to push servo motor, noticed some difference with just one command + moveServo(0); // command to move 3 plus times to push servo motor, noticed some difference with just one command moveServo(0); moveServo(0); - // httpServer.send(201, "text/plain", "Servo Motor Positioned To OPEN State For Install, Please Disconnect Power From Device NOW...Before Device AUTO Restarts In 20 Seconds "); - + // httpServer.send(201, "text/plain", "Servo Motor Positioned To OPEN State For Install, Please Disconnect Power From Device NOW...Before Device AUTO Restarts In 20 Seconds "); } -//////////// - -delay(20000); - ESP.restart(); + delay(20000); + ESP.restart(); } - -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void Config_Setup(){ -// + +// Config_Setup +void Config_Setup() { + // SendHTML_Header(); - - //webpage += F(""); + + // webpage += F(""); webpage += F(""); webpage += F("

Configuration Setup


"); webpage += F(""); webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + // webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + // webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += ""; + webpage += ""; // tr + webpage += F(""); + webpage += ""; // tr + webpage += F(""); -//webpage += ""; ///tr - -webpage += F(""); -webpage += ""; ///tr -//webpage += ""; ///tr -webpage += F(""); - - -webpage += ""; ///tr -webpage += F(""); - -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += ""; -webpage += ""; ///tr -webpage += F(""); -webpage += ""; ///tr -webpage += F(""); - - - -if (String(battery_system).equalsIgnoreCase("ON")) - { - webpage += ""; ///tr - webpage += ""; - webpage += ""; ///tr - webpage += ""; - webpage += ""; ///tr - webpage += ""; - } - -webpage += F("
NameSet ValueNew Value
DHCP/Network Device Name"+String(host)+"
Device Friendly Name"+String(mqtt_topic)+"
MQTT Server"+String(mqtt_server)+"
MQTT Port"+String(mqtt_port)+"
MQTT User ID"+String(mqtt_username)+"
MQTT Password"+String(mqtt_password)+"
MQTT Authentication"+String(mqtt_isAuthentication)+"
Admin Password"+String(update_password)+"
OTAAuto path"+String(OTAAuto_path)+"
Blind Speed"+String(blinds_speed)+"
Motor Installed Side"+String(blinds_servo_install)+"
Swing Direction To Close"+String(blinds_swing_direction)+"
Open Limit Default "+String(open_limit_default)+""+String(open_limit_set)+" Degrees"+"
DHCP/Network Device Name"+String(host)+"
Device Friendly Name"+String(mqtt_topic)+"
MQTT Server"+String(mqtt_server)+"
MQTT Port"+String(mqtt_port)+"
MQTT User ID"+String(mqtt_username)+"
MQTT Password"+String(mqtt_password)+"
MQTT Authentication"+String(mqtt_isAuthentication)+"
Admin Password"+String(update_password)+"
OTAAuto path"+String(OTAAuto_path)+"
Blind Speed"+String(blinds_speed)+"
Motor Installed Side"+String(blinds_servo_install)+"
Swing Direction To Close"+String(blinds_swing_direction)+"
Open Limit Default "+String(open_limit_default)+""+String(open_limit_set)+" Degrees"+"
Open Limit 0-180"+String(open_limit_set)+" Degrees"+"
Closed Limit Default "+String(close_limit_default)+""+String(close_limit_set)+" Degrees"+"
Closed Limit 0-180 "+String(close_limit_set)+" Degrees"+"
Weight Slip Correction"+String(blinds_slip_correction)+"
HA Auto Discovery"+String(auto_discovery)+"
Telemetry Period in Sec"+String(tele_update_set)+"
Remote Button Connected"+String(remote_switch)+"
Battery System"+String(battery_system)+"
Open Limit 0-180"+String(open_limit_set)+" Degrees"+"
Closed Limit Default "+String(close_limit_default)+""+String(close_limit_set)+" Degrees"+"
Closed Limit 0-180 "+String(close_limit_set)+" Degrees"+"
Weight Slip Correction"+String(blinds_slip_correction)+"
HA Auto Discovery"+String(auto_discovery)+"
Telemetry Period in Sec"+String(tele_update_set)+"
Remote Button Connected"+String(remote_switch)+"
Battery System"+String(battery_system)+"
Battery Capacity mAh"+String(battery_capacity)+"
System Power Watts"+String(system_power)+"
Battery check in Sec"+String(tele_battery_set)+"
"); + if (String(battery_system).equalsIgnoreCase("ON")) { + webpage += "Battery Capacity mAh"+String(battery_capacity)+""; // tr + webpage += ""; + webpage += "System Power Watts"+String(system_power)+""; // tr + webpage += ""; + webpage += "Battery check in Sec"+String(tele_battery_set)+""; // tr + webpage += ""; + } + webpage += F(""); webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void Help(){ +// Help +void Help() { SendHTML_Header(); - + webpage += F("

Home


"); webpage += F(""); webpage += F("
"); + append_page_footer();// SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void HomePage(){ -if (myservo[0].attached()) { // If the servo is attached + +// HomePage +void HomePage() { + if (myservo[0].attached()) { // If the servo is attached myservo[0].detach(); // detach the servo motor myservo[1].detach(); } -//myservo[0].detach(); -//myservo[1].detach(); + // myservo[0].detach(); + // myservo[1].detach(); SendHTML_Header(); - - - webpage += F("

Status


"); + + webpage += F("

Status


"); webpage += F(""); webpage += F(""); - webpage += ""; - webpage += ""; - webpage += ""; ////friendly name + webpage += ""; + webpage += ""; + webpage += ""; // friendly name webpage += ""; - webpage += ""; webpage += ""; webpage += ""; @@ -1805,107 +1480,108 @@ if (myservo[0].attached()) { // If the servo is attached webpage += ""; webpage += ""; webpage += ""; - webpage += ""; + webpage += ""; webpage += ""; webpage += ""; webpage += ""; -//if (String(auto_discovery).equalsIgnoreCase("ENABLED-TILT")) - // { - webpage += ""; - webpage += ""; - - // } + // if (String(auto_discovery).equalsIgnoreCase("ENABLED-TILT")) { + webpage += ""; + webpage += ""; + // } webpage += ""; webpage += ""; webpage += ""; - //webpage += ""; + // webpage += ""; webpage += ""; - webpage += ""; + webpage += ""; webpage += ""; webpage += ""; - webpage += ""; + webpage += ""; webpage += ""; webpage += ""; webpage += ""; webpage += ""; - if (String(battery_system).equalsIgnoreCase("ON")) - { - webpage += ""; - webpage += ""; - webpage += ""; - webpage += ""; - webpage += ""; - - } - - //// -webpage += F("
NameSet Value
Firmware"+String(firmware_installed)+"
DHCP/Network Device Name"+String(host)+"
Device Friendly Name"+String(mqtt_topic)+"
Firmware"+String(firmware_installed)+"
DHCP/Network Device Name"+String(host)+"
Device Friendly Name"+String(mqtt_topic)+"
Devive Unique Name"+String(_identifier)+"
SSID"+String(WiFi.SSID())+"
IP Address"+WiFi.localIP().toString()+"
RSSI "+String(dBmtoPercentage(WiFi.RSSI()))+"
Servo Position"+String(ServoPos)+"
Blind STATE"+Blind_STATE+"
Friendly Blind STATE"+HA_Blind_State+"
Blind Tilt Position"+TiltPos+"
Blind Tilt Position"+TiltPos+"
MQTT Server"+String(mqtt_server)+"
MQTT Command Topiccmnd/"+_identifier+"/POWER
MQTT Status Topicstat/"+_identifier+"/STATE
MQTT Tilt Command Topiccmnd/"+_identifier+"/tilt
MQTT Tilt Status Topicstat/"+_identifier+"/tilt-state
MQTT Tilt Command Topiccmnd/"+_identifier+"/tilt
MQTT Tilt Status Topicstat/"+_identifier+"/tilt-state
Blind Speed"+String(blinds_speed)+"
Servo Motor Installed Side"+String(blinds_servo_install)+"
Blinds Swing Direction To Close"+String(blinds_swing_direction)+"
Blinds Trim Adjustment Open State %"+String(blinds_trim_adjust)+"
Blinds Trim Adjustment Open State %"+String(blinds_trim_adjust)+"
Blinds Weight Slip Correction"+String(blinds_slip_correction)+"
HA Auto Discovery"+String(auto_discovery)+"
HA Auto Discovery"+String(auto_discovery)+"
System Telemetry Period"+String(tele_update_set)+" seconds
Remote Button Connected"+String(remote_switch)+"
Default Open Limit "+String(open_limit_default)+"
Default Open Limit "+String(open_limit_default)+"
User Set Open Limit"+String(open_limit_set)+"
Default Closed Limit"+String(close_limit_default)+"
User Set Closed Limit"+String(close_limit_set)+"
Battery System"+String(battery_system)+"
Battery Voltage"+String(Battery_Voltage)+" Volts
Charge Capacity"+String(Battery_Cap)+" %
Discharge Time"+String(Discharge_Time)+" Minutes
Remaining Time"+String(Remaining_Time)+" Minutes
Battery Check Period"+String(tele_battery_set)+" Seconds
"); - SendHTML_Content(); - append_page_footer(); - SendHTML_Content(); - SendHTML_Stop(); //Stop is needed because no content length was sent + if (String(battery_system).equalsIgnoreCase("ON")) { + webpage += "Battery Voltage"+String(Battery_Voltage)+" Volts"; + webpage += "Charge Capacity"+String(Battery_Cap)+" %"; + webpage += "Discharge Time"+String(Discharge_Time)+" Minutes"; + webpage += "Remaining Time"+String(Remaining_Time)+" Minutes"; + webpage += "Battery Check Period"+String(tele_battery_set)+" Seconds"; + } + webpage += F(""); + + SendHTML_Content(); + append_page_footer(); + SendHTML_Content(); + SendHTML_Stop(); // Stop is needed because no content length was sent } -//~~~~~~~~ - -void File_Download(){ // This gets called twice, the first pass selects the input, the second pass then processes the command line arguments +// File_Download +void File_Download() { // This gets called twice, the first pass selects the input, the second pass then processes the command line arguments if (httpServer.args() > 0 ) { // Arguments were received - if (httpServer.hasArg("download")) DownloadFile(httpServer.arg(0)); + if (httpServer.hasArg("download")) { + DownloadFile(httpServer.arg(0)); + } + } else { + SelectInput("Enter filename to download","download","download"); } - else SelectInput("Enter filename to download","download","download"); } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -File UploadFile; -void handleFileUpload(){ // upload a new file to the Filing system - HTTPUpload& uploadfile = httpServer.upload(); // See https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/srcv - // For further information on 'status' structure, there are other reasons such as a failed transfer that could be used - if(uploadfile.status == UPLOAD_FILE_START) - { + +// handleFileUpload +File UploadFile; +void handleFileUpload() { // upload a new file to the Filing system + // See https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266WebServer/srcv + // For further information on 'status' structure, there are other reasons such as a failed transfer that could be used + HTTPUpload& uploadfile = httpServer.upload(); + + if (uploadfile.status == UPLOAD_FILE_START) { String filename = uploadfile.filename; - if(!filename.startsWith("/")) filename = "/"+filename; + + if (!filename.startsWith("/")) { + filename = "/" + filename; + } + Serial.print("Upload File Name: "); Serial.println(filename); - ///SPIFFS.remove(filename); // Remove a previous version, otherwise data is appended the file again old system + // /SPIFFS.remove(filename); // Remove a previous version, otherwise data is appended the file again old system LittleFS.remove(filename); // Remove a previous version, otherwise data is appended the file again - ///UploadFile = SPIFFS.open(filename, "w"); // Open the file for writing in SPIFFS (create it, if doesn't exist) ////old system + // UploadFile = SPIFFS.open(filename, "w"); // Open the file for writing in SPIFFS (create it, if doesn't exist) // old system UploadFile = LittleFS.open(filename, "w"); // Open the file for writing in SPIFFS (create it, if doesn't exist) - } - else if (uploadfile.status == UPLOAD_FILE_WRITE) - { - if(UploadFile) UploadFile.write(uploadfile.buf, uploadfile.currentSize); // Write the received bytes to the file - } - else if (uploadfile.status == UPLOAD_FILE_END) - { - if(UploadFile) // If the file was successfully created - { + } else if (uploadfile.status == UPLOAD_FILE_WRITE) { + // Write the received bytes to the file + if (UploadFile) { + UploadFile.write(uploadfile.buf, uploadfile.currentSize); + } + } else if (uploadfile.status == UPLOAD_FILE_END) { + // If the file was successfully created + if (UploadFile) { UploadFile.close(); // Close the file again Serial.print("Upload Size: "); Serial.println(uploadfile.totalSize); webpage = ""; append_page_header(); - webpage += F("

File was successfully uploaded

"); + webpage += F("

File was successfully uploaded

"); webpage += F("

Uploaded File Name: "); webpage += uploadfile.filename+"

"; - webpage += F("

File Size: "); webpage += file_size(uploadfile.totalSize) + "


"; + webpage += F("

File Size: "); webpage += file_size(uploadfile.totalSize) + "


"; webpage += F("[Back]

"); append_page_footer(); httpServer.send(200,"text/html",webpage); - } - else - { + } else { ReportCouldNotCreateFile("upload"); } } } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// SPIFFS_dir & printDirectory for ESP32 #ifdef ESP32 -void SPIFFS_dir(){ +// SPIFFS_dir for ESP32 +void SPIFFS_dir() { if (SPIFFS_present) { - ///File root = SPIFFS.open("/"); /////old system + // File root = SPIFFS.open("/"); // old system File root = LittleFS.open("/"); + if (root) { root.rewindDirectory(); SendHTML_Header(); @@ -1916,744 +1592,715 @@ void SPIFFS_dir(){ webpage += F(""); SendHTML_Content(); root.close(); - } - else - { + } else { SendHTML_Header(); webpage += F("

No Files Found

"); } + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent - } else ReportSPIFFSNotPresent(); + } else { + ReportSPIFFSNotPresent(); + } } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -void printDirectory(const char * dirname, uint8_t levels){ - ///File root = SPIFFS.open(dirname); /////old system + +// printDirectory for ESP32 +void printDirectory(const char * dirname, uint8_t levels) { + // File root = SPIFFS.open(dirname); // old system File root = LittleFS.open(dirname); - if(!root){ + + if (!root) { return; } - if(!root.isDirectory()){ + + if (!root.isDirectory()) { return; } + File file = root.openNextFile(); - while(file){ + + while(file) { if (webpage.length() > 1000) { SendHTML_Content(); } - if(file.isDirectory()){ + + if (file.isDirectory()) { webpage += ""+String(file.isDirectory()?"Dir":"File")+""+String(file.name())+""; printDirectory(file.name(), levels-1); - } - else - { + } else { webpage += ""+String(file.name())+""; webpage += ""+String(file.isDirectory()?"Dir":"File")+""; int bytes = file.size(); String fsize = ""; - if (bytes < 1024) fsize = String(bytes)+" B"; - else if(bytes < (1024 * 1024)) fsize = String(bytes/1024.0,3)+" KB"; - else if(bytes < (1024 * 1024 * 1024)) fsize = String(bytes/1024.0/1024.0,3)+" MB"; - else fsize = String(bytes/1024.0/1024.0/1024.0,3)+" GB"; + + if (bytes < 1024) { + fsize = String(bytes)+" B"; + } else if (bytes < (1024 * 1024)) { + fsize = String(bytes/1024.0,3)+" KB"; + } else if (bytes < (1024 * 1024 * 1024)) { + fsize = String(bytes/1024.0/1024.0,3)+" MB"; + } else { + fsize = String(bytes/1024.0/1024.0/1024.0,3)+" GB"; + } + webpage += ""+fsize+""; } + file = root.openNextFile(); } + file.close(); } #endif -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +// SPIFFS_dir for ESP8266 #ifdef ESP8266 -void SPIFFS_dir(){ +void SPIFFS_dir() { String str; - if (SPIFFS_present) { - ///Dir dir = SPIFFS.openDir("/"); ////old system + + if (SPIFFS_present) { + // Dir dir = SPIFFS.openDir("/"); // old system Dir dir = LittleFS.openDir("/"); - + SendHTML_Header(); + webpage += F("

SPIFFS Contents


"); webpage += F(""); webpage += F(""); + while (dir.next()) { Serial.print(dir.fileName()); webpage += ""; - str = dir.fileName(); + str = dir.fileName(); str += " / "; - if(dir.fileSize()) { + + if (dir.fileSize()) { File f = dir.openFile("r"); Serial.println(f.size()); int bytes = f.size(); String fsize = ""; - if (bytes < 1024) fsize = String(bytes)+" B"; - else if(bytes < (1024 * 1024)) fsize = String(bytes/1024.0,3)+" KB"; - else if(bytes < (1024 * 1024 * 1024)) fsize = String(bytes/1024.0/1024.0,3)+" MB"; - else fsize = String(bytes/1024.0/1024.0/1024.0,3)+" GB"; + + if (bytes < 1024) { + fsize = String(bytes)+" B"; + } else if (bytes < (1024 * 1024)) { + fsize = String(bytes/1024.0,3)+" KB"; + } else if (bytes < (1024 * 1024 * 1024)) { + fsize = String(bytes/1024.0/1024.0,3)+" MB"; + } else { + fsize = String(bytes/1024.0/1024.0/1024.0,3)+" GB"; + } + webpage += ""; f.close(); } + str += String(dir.fileSize()); str += "\r\n"; Serial.println(str); } + webpage += F("
Name/TypeFile Size
"+String(dir.fileName())+""+fsize+"
"); + webpage += F(""); + webpage += F(""); + webpage += F(""); + webpage += F(""); - - //////////////////// - webpage += F(""); - webpage += F(""); - webpage += F(""); - webpage += F(""); - - ///////////////////// SendHTML_Content(); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); // Stop is needed because no content length was sent - } else ReportSPIFFSNotPresent(); + } else { + ReportSPIFFSNotPresent(); + } } #endif -///--------------------------------------------------------------------------- -void Submit_Config() { // submit config for changes - ////copy update to current variables - ///////////////// - - SendHTML_Header(); -if (httpServer.arg("input_host")!= ""){ - strcpy(host, httpServer.arg("input_host").c_str()); - reboot = 1; - } - if (httpServer.arg("input_mqtt_topic")!= ""){ - strcpy(mqtt_topic, httpServer.arg("input_mqtt_topic").c_str()); - reboot = 1; - } - - if (httpServer.arg("input_mqtt_server")!= ""){ - strcpy(mqtt_server, httpServer.arg("input_mqtt_server").c_str()); - reboot = 1; - } - if (httpServer.arg("input_mqtt_port")!= ""){ - strcpy(mqtt_port, httpServer.arg("input_mqtt_port").c_str()); - reboot = 1; - } - if (httpServer.arg("input_mqtt_username")!= ""){ - strcpy(mqtt_username, httpServer.arg("input_mqtt_username").c_str()); - reboot = 1; - } - if (httpServer.arg("input_mqtt_password")!= ""){ - strcpy(mqtt_password, httpServer.arg("input_mqtt_password").c_str()); - reboot = 1; - } - if (httpServer.arg("input_mqtt_isAuthentication")!= ""){ - strcpy(mqtt_isAuthentication, httpServer.arg("input_mqtt_isAuthentication").c_str()); - } - if (httpServer.arg("input_update_password")!= ""){ - strcpy(update_password, httpServer.arg("input_update_password").c_str()); - } - if (httpServer.arg("input_OTAAuto_path")!= ""){ - strcpy(OTAAuto_path, httpServer.arg("input_OTAAuto_path").c_str()); - } - if (httpServer.arg("input_blinds_speed")!= ""){ - strcpy(blinds_speed, httpServer.arg("input_blinds_speed").c_str()); - } - if (httpServer.arg("input_blinds_servo_install")!= ""){ - strcpy(blinds_servo_install, httpServer.arg("input_blinds_servo_install").c_str()); - reboot = 1; - strcpy(close_limit_set, ""); - strcpy(open_limit_set, ""); - } - if (httpServer.arg("input_blinds_swing_direction")!= ""){ - strcpy(blinds_swing_direction, httpServer.arg("input_blinds_swing_direction").c_str()); - reboot = 1; - strcpy(close_limit_set, ""); - strcpy(open_limit_set, ""); - } - //if (httpServer.arg("input_blinds_trim_adjust")!= ""){ - //strcpy(blinds_trim_adjust, httpServer.arg("input_blinds_trim_adjust").c_str()); - // } - if (httpServer.arg("input_blinds_slip_correction")!= ""){ - strcpy(blinds_slip_correction, httpServer.arg("input_blinds_slip_correction").c_str()); - } - if (httpServer.arg("input_tele_update_set")!= ""){ - strcpy(tele_update_set, httpServer.arg("input_tele_update_set").c_str()); - } - - if (httpServer.arg("input_battery_system")!= ""){ - strcpy(battery_system, httpServer.arg("input_battery_system").c_str()); - } - - if (httpServer.arg("input_remote_switch")!= ""){ - strcpy(remote_switch, httpServer.arg("input_remote_switch").c_str()); - } - - if (httpServer.arg("input_battery_capacity")!= ""){ - strcpy(battery_capacity, httpServer.arg("input_battery_capacity").c_str()); +// Submit_Config - submit config for changes +void Submit_Config() { + // copy update to current variables + SendHTML_Header(); + + if (httpServer.arg("input_host")!= "") { + strcpy(host, httpServer.arg("input_host").c_str()); + reboot = 1; } - if (httpServer.arg("input_system_power")!= ""){ - strcpy(system_power, httpServer.arg("input_system_power").c_str()); - } - if (httpServer.arg("input_tele_battery_set")!= ""){ - strcpy(tele_battery_set, httpServer.arg("input_tele_battery_set").c_str()); + if (httpServer.arg("input_mqtt_topic")!= "") { + strcpy(mqtt_topic, httpServer.arg("input_mqtt_topic").c_str()); + reboot = 1; } - if (httpServer.arg("input_auto_discovery")!= ""){ - strcpy(auto_discovery, httpServer.arg("input_auto_discovery").c_str()); - reboot = 1; + if (httpServer.arg("input_mqtt_server")!= "") { + strcpy(mqtt_server, httpServer.arg("input_mqtt_server").c_str()); + reboot = 1; } - if (httpServer.arg("input_open_limit_set")!= ""){ - strcpy(open_limit_set, httpServer.arg("input_open_limit_set").c_str()); - } - - if (httpServer.arg("input_close_limit_set")!= ""){ - strcpy(close_limit_set, httpServer.arg("input_close_limit_set").c_str()); + if (httpServer.arg("input_mqtt_port")!= "") { + strcpy(mqtt_port, httpServer.arg("input_mqtt_port").c_str()); + reboot = 1; } - - webpage += "

Changes Have Been Submitted BUT not saved

"; - //webpage += F("[Back]

"); - webpage += F(""); - webpage += F(""); + + if (httpServer.arg("input_mqtt_username")!= "") { + strcpy(mqtt_username, httpServer.arg("input_mqtt_username").c_str()); + reboot = 1; + } + + if (httpServer.arg("input_mqtt_password")!= "") { + strcpy(mqtt_password, httpServer.arg("input_mqtt_password").c_str()); + reboot = 1; + } + + if (httpServer.arg("input_mqtt_isAuthentication")!= "") { + strcpy(mqtt_isAuthentication, httpServer.arg("input_mqtt_isAuthentication").c_str()); + } + + if (httpServer.arg("input_update_password")!= "") { + strcpy(update_password, httpServer.arg("input_update_password").c_str()); + } + + if (httpServer.arg("input_OTAAuto_path")!= "") { + strcpy(OTAAuto_path, httpServer.arg("input_OTAAuto_path").c_str()); + } + + if (httpServer.arg("input_blinds_speed")!= "") { + strcpy(blinds_speed, httpServer.arg("input_blinds_speed").c_str()); + } + + if (httpServer.arg("input_blinds_servo_install")!= "") { + strcpy(blinds_servo_install, httpServer.arg("input_blinds_servo_install").c_str()); + reboot = 1; + strcpy(close_limit_set, ""); + strcpy(open_limit_set, ""); + } + + if (httpServer.arg("input_blinds_swing_direction")!= "") { + strcpy(blinds_swing_direction, httpServer.arg("input_blinds_swing_direction").c_str()); + reboot = 1; + strcpy(close_limit_set, ""); + strcpy(open_limit_set, ""); + } + + // if (httpServer.arg("input_blinds_trim_adjust")!= "") { + // strcpy(blinds_trim_adjust, httpServer.arg("input_blinds_trim_adjust").c_str()); + // } + + if (httpServer.arg("input_blinds_slip_correction")!= "") { + strcpy(blinds_slip_correction, httpServer.arg("input_blinds_slip_correction").c_str()); + } + + if (httpServer.arg("input_tele_update_set")!= "") { + strcpy(tele_update_set, httpServer.arg("input_tele_update_set").c_str()); + } + + if (httpServer.arg("input_battery_system")!= "") { + strcpy(battery_system, httpServer.arg("input_battery_system").c_str()); + } + + if (httpServer.arg("input_remote_switch")!= "") { + strcpy(remote_switch, httpServer.arg("input_remote_switch").c_str()); + } + + if (httpServer.arg("input_battery_capacity")!= "") { + strcpy(battery_capacity, httpServer.arg("input_battery_capacity").c_str()); + } + + if (httpServer.arg("input_system_power")!= "") { + strcpy(system_power, httpServer.arg("input_system_power").c_str()); + } + + if (httpServer.arg("input_tele_battery_set")!= "") { + strcpy(tele_battery_set, httpServer.arg("input_tele_battery_set").c_str()); + } + + if (httpServer.arg("input_auto_discovery")!= "") { + strcpy(auto_discovery, httpServer.arg("input_auto_discovery").c_str()); + reboot = 1; + } + + if (httpServer.arg("input_open_limit_set")!= "") { + strcpy(open_limit_set, httpServer.arg("input_open_limit_set").c_str()); + } + + if (httpServer.arg("input_close_limit_set")!= "") { + strcpy(close_limit_set, httpServer.arg("input_close_limit_set").c_str()); + } + + webpage += "

Changes Have Been Submitted BUT not saved

"; + // webpage += F("[Back]

"); + webpage += F(""); + webpage += F(""); + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); - } +} -/////////////////////////////////////////////////////////////////////////////////////// -void Save_Config() { //save configuration to spiffs - +// Save_Config - save configuration to spiffs +void Save_Config() { + DynamicJsonDocument json(1024); // json6 - DynamicJsonDocument json(1024); ////json6 + json["host"] = host; + json["mqtt_server"] = mqtt_server; + json["mqtt_port"] = mqtt_port; + json["mqtt_topic"] = mqtt_topic; // device friendly name + json["mqtt_isAuthentication"] = mqtt_isAuthentication; + json["mqtt_username"] = mqtt_username; + json["mqtt_password"] = mqtt_password; + json["update_username"] = update_username; + json["update_password"] = update_password; + json["battery_system"] = battery_system; + json["remote_switch"] = remote_switch; + json["auto_discovery"] = auto_discovery; + json["open_limit_set"] = open_limit_set; + json["close_limit_set"] = close_limit_set; + json["battery_capacity"] = battery_capacity; + json["system_power"] = system_power; + json["tele_battery_set"] = tele_battery_set; + json["update_path"] = update_path; + json["blinds_speed"] = blinds_speed; + json["blinds_swing_direction"] = blinds_swing_direction; + json["blinds_servo_install"] = blinds_servo_install; + json["blinds_trim_adjust"] = blinds_trim_adjust; + json["blinds_slip_correction"] = blinds_slip_correction; + json["OTAAuto_path"] = OTAAuto_path; + json["tele_update_set"] = tele_update_set; - json["host"] = host; - json["mqtt_server"] = mqtt_server; - json["mqtt_port"] = mqtt_port; - json["mqtt_topic"] = mqtt_topic; ///device friendly name - json["mqtt_isAuthentication"] = mqtt_isAuthentication; - json["mqtt_username"] = mqtt_username; - json["mqtt_password"] = mqtt_password; - json["update_username"] = update_username; - json["update_password"] = update_password; - json["battery_system"] = battery_system; - json["remote_switch"] = remote_switch; - json["auto_discovery"] = auto_discovery; - json["open_limit_set"] = open_limit_set; - json["close_limit_set"] = close_limit_set; - json["battery_capacity"] = battery_capacity; - json["system_power"] = system_power; - json["tele_battery_set"] = tele_battery_set; - json["update_path"] = update_path; - json["blinds_speed"] = blinds_speed; - json["blinds_swing_direction"] = blinds_swing_direction; - json["blinds_servo_install"] = blinds_servo_install; - json["blinds_trim_adjust"] = blinds_trim_adjust; - json["blinds_slip_correction"] = blinds_slip_correction; - json["OTAAuto_path"] = OTAAuto_path; - json["tele_update_set"] = tele_update_set; + if (SPIFFS_present) { + SendHTML_Header(); - - if (SPIFFS_present) { - SendHTML_Header(); - - if (LittleFS.exists("/" + String(software_version) + ".json")) - { - - LittleFS.remove("/" + String(software_version) + ".json"); ///remove existing file before re writting + if (LittleFS.exists("/" + String(software_version) + ".json")) { + LittleFS.remove("/" + String(software_version) + ".json"); // remove existing file before re writting } - - + File configFile = LittleFS.open("/" + String(software_version) + ".json", "w"); - - - if (configFile) - { - - serializeJson(json, Serial); ////json6 - serializeJson(json, configFile); ////json6 - + + if (configFile) { + serializeJson(json, Serial); // json6 + serializeJson(json, configFile); // json6 + configFile.close(); - + webpage += "

Changes Have Been Saved.

"; - if (String(auto_discovery) != "DISABLED") - { + + if (String(auto_discovery) != "DISABLED") { HA_Discovery(); webpage += "

Auto Discovery Updated.

"; - } - - if (reboot == 1) - { - webpage += "

(Reboot) Required

"; - webpage += F(""); - } - - - webpage += F(""); - - - } else ReportFileNotPresent("delete"); - append_page_footer(); + + if (reboot == 1) { + webpage += "

(Reboot) Required

"; + webpage += F(""); + } + + webpage += F(""); + } else { + ReportFileNotPresent("delete"); + } + + append_page_footer(); SendHTML_Content(); SendHTML_Stop(); - - } else ReportSPIFFSNotPresent(); + } else { + ReportSPIFFSNotPresent(); + } +} +// button control toggle open close external button on PGM pin nd ground -} - -////////////////////////button control toggle open close external button on PGM pin nd ground - -///Blind Open/close with trim adjustment enabled +// clickEvent - Blind Open/close with trim adjustment enabled void clickEvent() { - - if ((HA_Blind_State == "OPEN") || (HA_Blind_State == "OPENED")) - { - - moveServo(String(close_limit_set).toInt()); ////new method /// - HA_Blind_State == "CLOSED"; - } - else - { - - moveServo(String(open_limit_set).toInt()); ////new method - HA_Blind_State == "OPENED"; - } - HA_State(); - process_state(); - publish_state(); - save_state(); - + if ((HA_Blind_State == "OPEN") || (HA_Blind_State == "OPENED")) { + moveServo(String(close_limit_set).toInt()); // new method + HA_Blind_State == "CLOSED"; + } else { + moveServo(String(open_limit_set).toInt()); // new method + HA_Blind_State == "OPENED"; } - -///Blind position 50% + + HA_State(); + process_state(); + publish_state(); + save_state(); +} + +// doubleClickEvent - Blind position 50% void doubleClickEvent() { - ///code with slip correction added. i.e. if closed go fully open then back to 50% - //client.publish("stat/"+_identifier+"/ClickEventprocess", "DoublePress"); - HA_Blind_State == "OPEN"; - moveServo(90); - HA_State(); - process_state(); - publish_state(); - save_state(); - } - + // code with slip correction added. i.e. if closed go fully open then back to 50% + // client.publish("stat/"+_identifier+"/ClickEventprocess", "DoublePress"); + HA_Blind_State == "OPEN"; + moveServo(90); + HA_State(); + process_state(); + publish_state(); + save_state(); +} +// holdEvent void holdEvent() { - - - //client.publish("stat/"+_identifier+"/ClickEvent", "ShortHold"); - //if (String(blinds_invert_command).equalsIgnoreCase("YES")) - // moveServo(90); - //else - // moveServo(90); - } - + // client.publish("stat/"+_identifier+"/ClickEvent", "ShortHold"); + // if (String(blinds_invert_command).equalsIgnoreCase("YES")) + // moveServo(90); + // else + // moveServo(90); +} - -///Reset Controller to default and wipe all sata restart in AP mode +// longHoldEvent - Reset Controller to default and wipe all sata restart in AP mode void longHoldEvent() { - //client.publish("stat/"+_identifier+"/ClickEvent", "LongPress"); - SendHTML_Header(); - + // client.publish("stat/"+_identifier+"/ClickEvent", "LongPress"); + SendHTML_Header(); + webpage += F("

Reset Controller


"); webpage += F(""); webpage += F("

All Settings Have Been Deleted and Set To Defaults

"); webpage += F("

File System Erased and Reformated.....

"); webpage += F("

You Will Need To Connect Via AP Mode And Setup Device Again

"); webpage += F("

Device Will AUTO Restart In 10 Seconds in AP Setup mode

"); - //webpage += F("

Press Continue to Proceed or Cancel to Exit

"); + // webpage += F("

Press Continue to Proceed or Cancel to Exit

"); webpage += F(""); - append_page_footer(); - SendHTML_Content(); - SendHTML_Stop(); - - - WiFiManager wifiManager; - wifiManager.resetSettings(); - LittleFS.format(); // refomats SFIFFS erases all files clean setup - delay(10000); - ESP.restart(); ///better option then ESP.reset() - - -} -/// -void checkButton() { - int event = 0; - buttonVal = digitalRead(buttonPin); - // Button pressed down - if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce) - { - - downTime = millis(); - ignoreUp = false; - waitForUp = false; - singleOK = true; - holdEventPast = false; - longHoldEventPast = false; - if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true) DConUp = true; - else DConUp = false; - DCwaiting = false; - } - // Button released - else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce) - { - if (not ignoreUp) - { - upTime = millis(); - if (DConUp == false) DCwaiting = true; - else - { - //client.publish("stat/" + _identifier + "/Button_PRESS", "Event2" ); - - event = 2; - DConUp = false; - DCwaiting = false; - singleOK = false; - } - } - } - // Test for normal click event: DCgap expired - if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2) - { - client.publish("stat/" + _identifier + "/Button_PRESS", "Event1" ); - event = 1; - DCwaiting = false; - } - // Test for hold - if (buttonVal == LOW && (millis() - downTime) >= holdTime) { - // Trigger "normal" hold - if (not holdEventPast) - { - //client.publish("stat/" + _identifier + "/Button_PRESS", "Event3" ); - event = 3; - waitForUp = true; - ignoreUp = true; - DConUp = false; - DCwaiting = false; - //downTime = millis(); - holdEventPast = true; - } - // Trigger "long" hold - if ((millis() - downTime) >= longHoldTime) - { - if (not longHoldEventPast) - { - //client.publish("stat/" + _identifier + "/Button_PRESS", "Event4" ); - event = 4; - longHoldEventPast = true; - } - } - } - buttonLast = buttonVal; - button_result = event; - -} - -/////// -// Allocate a 1024-byte buffer for the JSON document. -void FirmwareCheck() { - -char firmware_release[7] = "Vx.xx"; -char firmware_impact[9] = "UNKNOWN"; -char firmware_date[12] = "99/99/9999"; - -HTTPClient http; - - DynamicJsonDocument firmware(1024); //json6 -SendHTML_Header(); - -webpage += F("

Check Firmware Update


"); - webpage += F("
"); - ///webpage += F("
"); - - - - http.setTimeout(1000); - http.begin(net, url); - - int status = http.GET(); - if (status <= 0) { - Serial.printf("HTTP error: %s\n", - http.errorToString(status).c_str()); - webpage += F("

Can not connect to REPO Update Server

"); - //return; - } - String payload = http.getString(); -//const String& payload = http.getString(); -http.end(); - - - //JsonObject& firmware = jsonBuffer.parseObject(payload); - - - auto deserializeError = deserializeJson(firmware, payload); - serializeJson(firmware, Serial); - - - - if (! deserializeError) ///json6 - ///if (firmware.success()) ///json5 - { - - strcpy(firmware_release, firmware["release"]); - strcpy(firmware_impact, firmware["impact"]); - strcpy(firmware_date, firmware["date"]); - webpage += F("

Firmware found on Repository Server

"); - webpage += F("
"); - - webpage += F(""); - webpage += ""; - webpage += F("
Installed on DeviceVersion Available Date Released
"+String(firmware_installed)+""+String(firmware_release)+""+String(firmware_date)+"
"); - //strcpy(blinds_speed, firmware["SPEED"]); - //// - if (firmware_installed==firmware_release) - { - webpage += F("

No Update Required, You have latest version installed

"); - } - else - { - webpage += F("

Update Required, Advised to install latest version

"); - } - if (String(firmware_impact).equalsIgnoreCase("HIGH")) - { - webpage += F("

Update has HIGH IMPACT to existing functions, resulting in possible AP configuration, see release notes for impact

"); - } - else - { - webpage += F("

Update has LOW IMPACT to existing functions, provides bug fixes and enhancements only

"); - - } - - } - else - { - - } - - - webpage += F(""); - webpage += F(""); - webpage += F(""); - //webpage += F("[Back]

"); append_page_footer(); SendHTML_Content(); SendHTML_Stop(); + WiFiManager wifiManager; + wifiManager.resetSettings(); + LittleFS.format(); // refomats SFIFFS erases all files clean setup + delay(10000); + ESP.restart(); // better option then ESP.reset() } -//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +// checkButton +void checkButton() { + int event = 0; + buttonVal = digitalRead(buttonPin); -void Battery_Check(){ - int tele_period = String(tele_battery_set).toInt() * 1000; //time converted to millseconds - if (millis() > time_now_2 + tele_period) - { - int nVoltageRaw = analogRead(A0); - float fVoltage = (float)nVoltageRaw * 0.00486; - String S_battery_capacity = battery_capacity; -String S_system_power = system_power; + // Button pressed down + if (buttonVal == LOW && buttonLast == HIGH && (millis() - upTime) > debounce) { + downTime = millis(); + ignoreUp = false; + waitForUp = false; + singleOK = true; + holdEventPast = false; + longHoldEventPast = false; -float fVoltageMatrix[22][2] = { - {4.2, 100}, - {4.15, 95}, - {4.11, 90}, - {4.08, 85}, - {4.02, 80}, - {3.98, 75}, - {3.95, 70}, - {3.91, 65}, - {3.87, 60}, - {3.85, 55}, - {3.84, 50}, - {3.82, 45}, - {3.80, 40}, - {3.79, 35}, - {3.77, 30}, - {3.75, 25}, - {3.73, 20}, - {3.71, 15}, - {3.69, 10}, - {3.61, 5}, - {3.27, 0}, - {0, 0} - }; + if ((millis()-upTime) < DCgap && DConUp == false && DCwaiting == true) { + DConUp = true; + } else { + DConUp = false; + } - int i, perc; + DCwaiting = false; + // Button released + } else if (buttonVal == HIGH && buttonLast == LOW && (millis() - downTime) > debounce) { + if (not ignoreUp) { + upTime = millis(); + if (DConUp == false) { + DCwaiting = true; + } else { + // client.publish("stat/" + _identifier + "/Button_PRESS", "Event2" ); - perc = 100; - - for(i=20; i>=0; i--) { - if(fVoltageMatrix[i][0] >= fVoltage) { - perc = fVoltageMatrix[i + 1][1]; - break; + event = 2; + DConUp = false; + DCwaiting = false; + singleOK = false; + } } } -//Battery_Cap = perc; -Battery_Voltage = fVoltage; + // Test for normal click event: DCgap expired + if ( buttonVal == HIGH && (millis()-upTime) >= DCgap && DCwaiting == true && DConUp == false && singleOK == true && event != 2) { + client.publish("stat/" + _identifier + "/Button_PRESS", "Event1" ); + event = 1; + DCwaiting = false; + } -//////test caculatoins -//Battery_Voltage = 3.7; -//S_system_power = "10"; -//S_battery_capacity = "1800"; -//perc = 50; + // Test for hold + if (buttonVal == LOW && (millis() - downTime) >= holdTime) { + // Trigger "normal" hold + if (not holdEventPast) { + // client.publish("stat/" + _identifier + "/Button_PRESS", "Event3" ); + event = 3; + waitForUp = true; + ignoreUp = true; + DConUp = false; + DCwaiting = false; + // downTime = millis(); + holdEventPast = true; + } -/////////////////////////////////////// -///for a 1800mAH 3.7v 18650 battery to power a 3.7V 10W digital device, how to calculate the running time? + // Trigger "long" hold + if ((millis() - downTime) >= longHoldTime) { + if (not longHoldEventPast) { + // client.publish("stat/" + _identifier + "/Button_PRESS", "Event4" ); + event = 4; + longHoldEventPast = true; + } + } + } -/////for 3.7V 10W device,working current would be 10÷3.7 = 2.7027A = 2702.7 mA -//////In theory that’s: 1800mAh ÷ 2702.7 mA = 0.666 h = 40 min -//////In reality that’s: 1800mAh ÷ 2702.7 mA *0.9 = 0.599h = 36 min + buttonLast = buttonVal; + button_result = event; +} -////////Quick Notes: 1A=1000mA (mA is current, mAh is Capacity) +// FirmwareCheck - Allocate a 1024-byte buffer for the JSON document. +void FirmwareCheck() { + char firmware_release[7] = "Vx.xx"; + char firmware_impact[9] = "UNKNOWN"; + char firmware_date[12] = "99/99/9999"; + HTTPClient http; + DynamicJsonDocument firmware(1024); // json6 -//////Or you can use 3.7V*1.8Ah(1800mAh)*0.9/10W=0.599h=36min -/////////////////////////////////////// - // DischargTime=Battery Capacity * Battery Volt*0.9 / Device Watt; + SendHTML_Header(); + webpage += F("

Check Firmware Update


"); + webpage += F(""); + // webpage += F("
"); + + http.setTimeout(1000); + http.begin(net, url); + + int status = http.GET(); -///////////////////////////////////////// + if (status <= 0) { + Serial.printf("HTTP error: %s\n", + http.errorToString(status).c_str()); + webpage += F("

Can not connect to REPO Update Server

"); + // return; + } + String payload = http.getString(); + // const String& payload = http.getString(); + http.end(); -Discharge_Time = (S_battery_capacity.toInt()/ (S_system_power.toFloat()/Battery_Voltage)/1000* 0.9)*60; ///convert to min -Remaining_Time = Discharge_Time*perc/100; -Battery_Cap = perc; + // JsonObject& firmware = jsonBuffer.parseObject(payload); -if (fVoltage <= 3) - {Remaining_Time = 0; -Discharge_Time = 0; - } + auto deserializeError = deserializeJson(firmware, payload); + serializeJson(firmware, Serial); -//Discharge_Time = ((S_battery_capacity.toInt()/ (S_system_power.toInt()/Battery_Voltage)*1000)* 0.9)*60 ; + // if (firmware.success()) // json5 + if (! deserializeError) { // json6 + strcpy(firmware_release, firmware["release"]); + strcpy(firmware_impact, firmware["impact"]); + strcpy(firmware_date, firmware["date"]); + webpage += F("

Firmware found on Repository Server

"); + webpage += F("
"); -StaticJsonDocument<256> ups; + webpage += F(""); + webpage += ""; + webpage += F("
Installed on DeviceVersion Available Date Released
"+String(firmware_installed)+""+String(firmware_release)+""+String(firmware_date)+"
"); + // strcpy(blinds_speed, firmware["SPEED"]); -ups["Device"] = String(host); -ups["Name"] = String(mqtt_topic); -ups["SystemPower"] = system_power; -ups["BatterySize"] = battery_capacity; -ups["BattVoltage"] = fVoltage; -ups["AOPINVoltage"] = nVoltageRaw; -ups["ChargeCapacity"] = perc; -ups["DischargeTime"] = Discharge_Time; -ups["RemainingTime"] = Remaining_Time; + if (firmware_installed==firmware_release) { + webpage += F("

No Update Required, You have latest version installed

"); + } else { + webpage += F("

Update Required, Advised to install latest version

"); + } + if (String(firmware_impact).equalsIgnoreCase("HIGH")) { + webpage += F("

Update has HIGH IMPACT to existing functions, resulting in possible AP configuration, see release notes for impact

"); + } else { + webpage += F("

Update has LOW IMPACT to existing functions, provides bug fixes and enhancements only

"); + } + } -size_t len = measureJson(ups); /////json6 + webpage += F(""); + webpage += F(""); + webpage += F(""); + // webpage += F("[Back]

"); + append_page_footer(); + SendHTML_Content(); + SendHTML_Stop(); +} + +// Battery_Check +void Battery_Check() { + int tele_period = String(tele_battery_set).toInt() * 1000; // time converted to millseconds + + if (millis() > time_now_2 + tele_period) { + int nVoltageRaw = analogRead(A0); + float fVoltage = (float)nVoltageRaw * 0.00486; + String S_battery_capacity = battery_capacity; + String S_system_power = system_power; + + float fVoltageMatrix[22][2] = { + {4.2, 100}, + {4.15, 95}, + {4.11, 90}, + {4.08, 85}, + {4.02, 80}, + {3.98, 75}, + {3.95, 70}, + {3.91, 65}, + {3.87, 60}, + {3.85, 55}, + {3.84, 50}, + {3.82, 45}, + {3.80, 40}, + {3.79, 35}, + {3.77, 30}, + {3.75, 25}, + {3.73, 20}, + {3.71, 15}, + {3.69, 10}, + {3.61, 5}, + {3.27, 0}, + {0, 0} + }; + + int i, perc; + + perc = 100; + + for (i=20; i>=0; i--) { + if (fVoltageMatrix[i][0] >= fVoltage) { + perc = fVoltageMatrix[i + 1][1]; + break; + } + } + + // Battery_Cap = perc; + Battery_Voltage = fVoltage; + + // test caculatoins + // Battery_Voltage = 3.7; + // S_system_power = "10"; + // S_battery_capacity = "1800"; + // perc = 50; + + // for a 1800mAH 3.7v 18650 battery to power a 3.7V 10W digital device, how to calculate the running time? + + // for 3.7V 10W device,working current would be 10÷3.7 = 2.7027A = 2702.7 mA + // In theory that’s: 1800mAh ÷ 2702.7 mA = 0.666 h = 40 min + // In reality that’s: 1800mAh ÷ 2702.7 mA *0.9 = 0.599h = 36 min + + // Quick Notes: 1A=1000mA (mA is current, mAh is Capacity) + + // Or you can use 3.7V*1.8Ah(1800mAh)*0.9/10W=0.599h=36min + + // DischargTime=Battery Capacity * Battery Volt*0.9 / Device Watt; + + Discharge_Time = (S_battery_capacity.toInt()/ (S_system_power.toFloat()/Battery_Voltage)/1000* 0.9)*60; // convert to min + Remaining_Time = Discharge_Time*perc/100; + Battery_Cap = perc; + + if (fVoltage <= 3) { + Remaining_Time = 0; + Discharge_Time = 0; + } + + // Discharge_Time = ((S_battery_capacity.toInt()/ (S_system_power.toInt()/Battery_Voltage)*1000)* 0.9)*60 ; + + StaticJsonDocument<256> ups; + + ups["Device"] = String(host); + ups["Name"] = String(mqtt_topic); + ups["SystemPower"] = system_power; + ups["BatterySize"] = battery_capacity; + ups["BattVoltage"] = fVoltage; + ups["AOPINVoltage"] = nVoltageRaw; + ups["ChargeCapacity"] = perc; + ups["DischargeTime"] = Discharge_Time; + ups["RemainingTime"] = Remaining_Time; + + size_t len = measureJson(ups); // json6 size_t size = len + 1; char JSONmessageBuffer[size]; - - serializeJson(ups, JSONmessageBuffer, size); ///json6 - - //client.publish(_topic, JSONmessageBuffer, size, true); + serializeJson(ups, JSONmessageBuffer, size); // json6 + + // client.publish(_topic, JSONmessageBuffer, size, true); client.publish("tele/"+_identifier+"/batt-state", JSONmessageBuffer); client.publish("stat/"+_identifier+"/batt-state", JSONmessageBuffer); -time_now_2 = millis(); - } + time_now_2 = millis(); + } } -//////////////////////////////////////////////////////////////~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - - - - - /////////////////////////////////////////////////////////////////////// -void setup() -{ - //client.packetSize(512); - // Configure extra config vars for Home assistant - - /////////////////////////////////////////////// +// setup +void setup() { + // client.packetSize(512); + // Configure extra config vars for Home assistant Serial.begin(115200); - pinMode(A0, INPUT); ////setup for battery monitor + pinMode(A0, INPUT); // setup for battery monitor pinMode(0, INPUT); // sets the digital pin 13 as output - //wifi_set_sleep_type(MODEM_SLEEP_T); - // Serial.print("Checking For Configuration file "); - if (LittleFS.begin()) - { - SPIFFS_present = true; - //////check for version 6 if so copy to V7 - configupgrade(); ////check for config file upgrade - ////// - - if (LittleFS.exists("/" + String(software_version) + ".json")) - { - //file exists, reading and loading - - File configFile = LittleFS.open("/" + String(software_version) + ".json", "r"); - if (configFile) - { - //Serial.print("Configuraton found....loading values "); - size_t size = configFile.size(); ///json 5 - ///size_t len = measureJson(configFile); json 6 - - // Allocate a buffer to store contents of the file. - std::unique_ptr buf(new char[size]); + // wifi_set_sleep_type(MODEM_SLEEP_T); + // Serial.print("Checking For Configuration file "); + if (LittleFS.begin()) { + SPIFFS_present = true; + // check for version 6 if so copy to V7 + configupgrade(); // check for config file upgrade - configFile.readBytes(buf.get(), size); - /////////new code JSON6 - DynamicJsonDocument json(1024); - auto deserializeError = deserializeJson(json, buf.get()); - serializeJson(json, Serial); - - //if (json.success()) /////json5 - if ( ! deserializeError ) /////json6 + // file exists, reading and loading + if (LittleFS.exists("/" + String(software_version) + ".json")) { + File configFile = LittleFS.open("/" + String(software_version) + ".json", "r"); - { - + if (configFile) { + // Serial.print("Configuraton found....loading values "); + size_t size = configFile.size(); // json 5 + // size_t len = measureJson(configFile); json 6 + + // Allocate a buffer to store contents of the file. + std::unique_ptr buf(new char[size]); + + configFile.readBytes(buf.get(), size); + // new code JSON6 + DynamicJsonDocument json(1024); + auto deserializeError = deserializeJson(json, buf.get()); + serializeJson(json, Serial); + + // if (json.success()) // json5 + if ( ! deserializeError ) { // json6 strcpy(host, json["host"]); strcpy(update_username, json["update_username"]); strcpy(update_password, json["update_password"]); - - if (json.containsKey("battery_system")) {strcpy(battery_system, json["battery_system"]);} - if (json.containsKey("battery_capacity")) {strcpy(battery_capacity, json["battery_capacity"]);} - if (json.containsKey("system_power")) {strcpy(system_power, json["system_power"]);} - if (json.containsKey("tele_battery_set")) {strcpy(tele_battery_set, json["tele_battery_set"]);} - if (json.containsKey("remote_switch")) {strcpy(remote_switch, json["remote_switch"]);} - if (json.containsKey("auto_discovery")) {strcpy(auto_discovery, json["auto_discovery"]);} - if (json.containsKey("open_limit_set")) {strcpy(open_limit_set, json["open_limit_set"]);} - if (json.containsKey("close_limit_set")) {strcpy(close_limit_set, json["close_limit_set"]);} - strcpy(mqtt_isAuthentication, json["mqtt_isAuthentication"]); + + if (json.containsKey("battery_system")) { + strcpy(battery_system, json["battery_system"]); + } + if (json.containsKey("battery_capacity")) { + strcpy(battery_capacity, json["battery_capacity"]); + } + if (json.containsKey("system_power")) { + strcpy(system_power, json["system_power"]); + } + if (json.containsKey("tele_battery_set")) { + strcpy(tele_battery_set, json["tele_battery_set"]); + } + if (json.containsKey("remote_switch")) { + strcpy(remote_switch, json["remote_switch"]); + } + if (json.containsKey("auto_discovery")) { + strcpy(auto_discovery, json["auto_discovery"]); + } + if (json.containsKey("open_limit_set")) { + strcpy(open_limit_set, json["open_limit_set"]); + } + if (json.containsKey("close_limit_set")) { + strcpy(close_limit_set, json["close_limit_set"]); + } + + strcpy(mqtt_isAuthentication, json["mqtt_isAuthentication"]); strcpy(mqtt_username, json["mqtt_username"]); strcpy(mqtt_password, json["mqtt_password"]); - strcpy(update_path, json["update_path"]); - strcpy(mqtt_server, json["mqtt_server"]); - - strcpy(mqtt_port, json["mqtt_port"]); - strcpy(mqtt_topic, json["mqtt_topic"]); ///device friendly name - strcpy(blinds_speed, json["blinds_speed"]); - strcpy(blinds_swing_direction, json["blinds_swing_direction"]); - strcpy(blinds_servo_install, json["blinds_servo_install"]); - strcpy(blinds_trim_adjust, json["blinds_trim_adjust"]); - strcpy(blinds_slip_correction, json["blinds_slip_correction"]); - strcpy(OTAAuto_path, json["OTAAuto_path"]); + strcpy(mqtt_port, json["mqtt_port"]); + strcpy(mqtt_topic, json["mqtt_topic"]); // device friendly name + strcpy(blinds_speed, json["blinds_speed"]); + strcpy(blinds_swing_direction, json["blinds_swing_direction"]); + strcpy(blinds_servo_install, json["blinds_servo_install"]); + strcpy(blinds_trim_adjust, json["blinds_trim_adjust"]); + strcpy(blinds_slip_correction, json["blinds_slip_correction"]); + strcpy(OTAAuto_path, json["OTAAuto_path"]); strcpy(tele_update_set, json["tele_update_set"]); - - } - else - { } + configFile.close(); } - } - } - else - { - } - - - - - //end read // The extra parameters to be configured (can be either global or just in the setup) // After connecting, parameter.getValue() will get you the configured value @@ -2696,22 +2343,21 @@ void setup() WiFiManagerParameter custom_text24("

Blinds Weight Slip Adjustment ? Moves Blind to Open Position before Moving to Mid Range Position, ON/OFF , OFF will give incorrect Position 25 percent error, Default is ON)*"); WiFiManagerParameter custom_blinds_slip_correction("Slip Correction", "Weight Slip Correction ? ", blinds_slip_correction, 5); WiFiManagerParameter custom_text16("

Setup Notes

"); - -WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, MQTT etc, SAVE, then goto IP/Host name and select Setup to configure extra paramaters, i.e. motor install, swing direction, speed etc *"); + WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, MQTT etc, SAVE, then goto IP/Host name and select Setup to configure extra paramaters, i.e. motor install, swing direction, speed etc *"); - //WiFiManager - //Local intialization. Once its business is done, there is no need to keep it around + // WiFiManager + // Local intialization. Once its business is done, there is no need to keep it around wifi_station_set_hostname(host); WiFi.hostname(host); WiFiManager wifiManager; - //set config save notify callback + // set config save notify callback wifiManager.setSaveConfigCallback(saveConfigCallback); - //set static ip - //wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); + // set static ip + // wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0)); - //add all your parameters here + // add all your parameters here wifiManager.setCustomHeadElement(""); wifiManager.addParameter(&custom_text0); wifiManager.addParameter(&custom_text1); @@ -2729,44 +2375,42 @@ WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, wifiManager.addParameter(&custom_mqtt_password); wifiManager.addParameter(&custom_text16); wifiManager.addParameter(&custom_text27); - - //reset settings - for testing - //wifiManager.resetSettings(); - //wifi_station_set_hostname(host); - //WiFi.hostname(host); - //WiFi.hostname(host); - //set minimu quality of signal so it ignores AP's under that quality - //defaults to 8% - //wifiManager.setMinimumSignalQuality(); + // reset settings - for testing + // wifiManager.resetSettings(); - //sets timeout until configuration portal gets turned off - //useful to make it all retry or go to sleep - //in seconds + // wifi_station_set_hostname(host); + // WiFi.hostname(host); + // WiFi.hostname(host); + // set minimu quality of signal so it ignores AP's under that quality + // defaults to 8% + // wifiManager.setMinimumSignalQuality(); + + // sets timeout until configuration portal gets turned off + // useful to make it all retry or go to sleep + // in seconds wifiManager.setTimeout(120); - wifiManager.setConfigPortalTimeout(120); ///new code replaces setTimeout() - //fetches ssid and pass and tries to connect - //if it does not connect it starts an access point with the specified name - //here "AutoConnectAP" - //and goes into a blocking loop awaiting configuration - - ///check here for possible error leaving AP open - ///if (!wifiManager.autoConnect(networkhost.c_str())) - if (!wifiManager.autoConnect(ssidAP.c_str())) - { - + wifiManager.setConfigPortalTimeout(120); // new code replaces setTimeout() + // fetches ssid and pass and tries to connect + // if it does not connect it starts an access point with the specified name + // here "AutoConnectAP" + // and goes into a blocking loop awaiting configuration + + // check here for possible error leaving AP open + // if (!wifiManager.autoConnect(networkhost.c_str())) + if (!wifiManager.autoConnect(ssidAP.c_str())) { delay(6000); - //reset and try again, or maybe put it to deep sleep - + // reset and try again, or maybe put it to deep sleep + ESP.reset(); delay(5000); } - //read updated parameters + // read updated parameters strcpy(host, custom_host.getValue()); strcpy(mqtt_server, custom_mqtt_server.getValue()); strcpy(mqtt_port, custom_mqtt_port.getValue()); - strcpy(mqtt_topic, custom_mqtt_topic.getValue()); ////device full friendly name + strcpy(mqtt_topic, custom_mqtt_topic.getValue()); // device full friendly name strcpy(mqtt_isAuthentication, custom_mqtt_isAuthentication.getValue()); strcpy(mqtt_username, custom_mqtt_username.getValue()); strcpy(mqtt_password, custom_mqtt_password.getValue()); @@ -2782,18 +2426,16 @@ WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, strcpy(OTAAuto_path, custom_OTAAuto_path.getValue()); strcpy(tele_update_set, custom_tele_update_set.getValue()); - //save the custom parameters to FS - if (shouldSaveConfig) - { - // Serial.print("Saving configuration file "); + // save the custom parameters to FS + if (shouldSaveConfig) { + // Serial.print("Saving configuration file "); - - DynamicJsonDocument json(1024); ////JSON6 + DynamicJsonDocument json(1024); // JSON6 json["host"] = host; json["mqtt_server"] = mqtt_server; json["mqtt_port"] = mqtt_port; - json["mqtt_topic"] = mqtt_topic; ////device full friendly name + json["mqtt_topic"] = mqtt_topic; // device full friendly name json["mqtt_isAuthentication"] = mqtt_isAuthentication; json["mqtt_username"] = mqtt_username; json["mqtt_password"] = mqtt_password; @@ -2816,47 +2458,36 @@ WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, json["open_limit_set"] = open_limit_set; json["close_limit_set"] = close_limit_set; - /////save software config.json file/// - //File configFile = SPIFFS.open("/" + String(software_version) + ".json", "w"); ////old system + // save software config.json file + // File configFile = SPIFFS.open("/" + String(software_version) + ".json", "w"); // old system File configFile = LittleFS.open("/" + String(software_version) + ".json", "w"); - if (!configFile) - { - } - - //////JSON6 - serializeJson(json, Serial); /////JSON6 - serializeJson(json, configFile); //////JSON6 - ////////// + // if (!configFile) {} + + // JSON6 + serializeJson(json, Serial); // JSON6 + serializeJson(json, configFile); // JSON6 configFile.close(); - } delay(5000); - if (digitalRead(0) == LOW || String(host).length() == 0 || String(mqtt_server).length() == 0 || String(mqtt_topic).length() == 0) - { - + if (digitalRead(0) == LOW || String(host).length() == 0 || String(mqtt_server).length() == 0 || String(mqtt_topic).length() == 0) { wifiManager.resetSettings(); ESP.reset(); } - mqttDeviceID = host; /////host is the nerwork name - /////asign variable from main - _name = String(mqtt_topic); ///aka mqtt device ID will change in main program friendly name -// Id = name to lower case replacing spaces by underscore (ex: name="Kitchen Light" -> id="kitchen_light") - _identifier = _name; - _identifier.replace(' ', '_'); - _identifier.toLowerCase(); -//////////////////////////////// + mqttDeviceID = host; // host is the nerwork name + // asign variable from main + _name = String(mqtt_topic); // aka mqtt device ID will change in main program friendly name + // Id = name to lower case replacing spaces by underscore (ex: name="Kitchen Light" -> id="kitchen_light") + _identifier = _name; + _identifier.replace(' ', '_'); + _identifier.toLowerCase(); - - - -///////////////////////////////// client.begin(mqtt_server, atoi(mqtt_port), net); client.onMessage(messageReceived); // existing process MQTT Messages - + connect(); MDNS.begin(host); @@ -2864,76 +2495,70 @@ WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, httpUpdater.setup(&httpServer); httpUpdater.setup(&httpServer, update_path, update_username, update_password); -//////new code - //---------------------------------------------------------------------- - - - httpServer.on("/description.xml", HTTP_GET, []() { - SSDP.schema(httpServer.client()); - }); - - - - ///////////////////////////// Server Commands - httpServer.on("/", HomePage); + // new code + httpServer.on("/description.xml", HTTP_GET, []() { + SSDP.schema(httpServer.client()); + }); + + // Server Commands + httpServer.on("/", HomePage); httpServer.on("/download", File_Download); - httpServer.on("/upload", File_Upload); - httpServer.on("/help", Help); - httpServer.on("/fupload", HTTP_POST,[](){ httpServer.send(200);}, handleFileUpload); - httpServer.on("/reboot", Device_Reboot); - httpServer.on("/delete", File_Delete); - httpServer.on("/dir", SPIFFS_dir); - httpServer.on("/setup", Config_Setup); - httpServer.on("/firmware", Firmware_Update); - httpServer.on("/firmwareupdate", Firmware_Update); - httpServer.on("/firmwareauto", OTAUpgrade); - httpServer.on("/firmwareauto", OTAUpgrade); - httpServer.on("/set-servo", Set_Servo); - httpServer.on("/set-limits", handleMoveServo); - - //httpServer.on("/servoaction", Servo_Action); - httpServer.on("/firmwarecheck", FirmwareCheck); - httpServer.on("/filemanager", File_Manager); - httpServer.on("/saveconfig", Save_Config); - httpServer.on("/submitconfig", Submit_Config); + httpServer.on("/upload", File_Upload); + httpServer.on("/help", Help); + httpServer.on("/fupload", HTTP_POST,[]() { httpServer.send(200);}, handleFileUpload); + httpServer.on("/reboot", Device_Reboot); + httpServer.on("/delete", File_Delete); + httpServer.on("/dir", SPIFFS_dir); + httpServer.on("/setup", Config_Setup); + httpServer.on("/firmware", Firmware_Update); + httpServer.on("/firmwareupdate", Firmware_Update); + httpServer.on("/firmwareauto", OTAUpgrade); + httpServer.on("/firmwareauto", OTAUpgrade); // DUPE + httpServer.on("/set-servo", Set_Servo); + httpServer.on("/set-limits", handleMoveServo); + // httpServer.on("/servoaction", Servo_Action); + httpServer.on("/firmwarecheck", FirmwareCheck); + httpServer.on("/filemanager", File_Manager); + httpServer.on("/saveconfig", Save_Config); + httpServer.on("/submitconfig", Submit_Config); // httpServer.on("/action_page", handleForm); - httpServer.on("/exit", HomePage); - httpServer.on("/resetcmd", longHoldEvent); + httpServer.on("/exit", HomePage); + httpServer.on("/resetcmd", longHoldEvent); httpServer.on("/setPOS", handleServo); //--> Sets servo position from Web request - httpServer.on("/SetOpenLimit", SetOpenLimit); - httpServer.on("/SetClosedLimit", SetClosedLimit); - httpServer.on("/ResetLimits", ResetLimits); - ///////////////////////////// End of Request commands + httpServer.on("/SetOpenLimit", SetOpenLimit); + httpServer.on("/SetClosedLimit", SetClosedLimit); + httpServer.on("/ResetLimits", ResetLimits); + // Send web page with input fields to client - - //New Code To run Reset Ap And Re Launch WiFiManager Portal + // New Code To run Reset Ap And Re Launch WiFiManager Portal httpServer.on("/reset", []() { - if (!httpServer.authenticate(update_username, update_password)) + if (!httpServer.authenticate(update_username, update_password)) { return httpServer.requestAuthentication(); - Serial.print("Resetting Devkce... "); - SendHTML_Header(); - - webpage += F("

Reset Controller


"); - webpage += F(""); - webpage += F("

All Settings Will Be Deleted and Set To Defaults

"); - webpage += F("

File System Will Be Reformated.....

"); - webpage += F("

You Will Need To Connect Via AP Mode And Setup Device Again

"); - //webpage += F("

Device Will AUTO Restart In 10 Seconds in AP Setup mode

"); - webpage += F("

Press Continue to Proceed or Cancel to Exit

"); - webpage += F("
"); - webpage += F("
"); - webpage += F(""); - webpage += F(""); - append_page_footer(); - SendHTML_Content(); - SendHTML_Stop(); // Stop is needed because no content length was sent + } + Serial.print("Resetting Devkce... "); + SendHTML_Header(); + + webpage += F("

Reset Controller


"); + webpage += F(""); + webpage += F("

All Settings Will Be Deleted and Set To Defaults

"); + webpage += F("

File System Will Be Reformated.....

"); + webpage += F("

You Will Need To Connect Via AP Mode And Setup Device Again

"); + // webpage += F("

Device Will AUTO Restart In 10 Seconds in AP Setup mode

"); + webpage += F("

Press Continue to Proceed or Cancel to Exit

"); + webpage += F("
"); + webpage += F("
"); + webpage += F(""); + webpage += F(""); + + append_page_footer(); + SendHTML_Content(); + SendHTML_Stop(); // Stop is needed because no content length was sent }); httpServer.begin(); -////////////////////////////// SSDP.setSchemaURL("description.xml"); SSDP.setHTTPPort(80); SSDP.setName(host); @@ -2945,65 +2570,57 @@ WiFiManagerParameter custom_text27("

*Once you have Configured SSID, PASSWORD, SSDP.setModelURL("https://github.com/mountain-pitt/mk-blindcontrol/wiki"); SSDP.setManufacturer("MK Smarthouse"); SSDP.setManufacturerURL("https://www.mksmarthouse.com"); -SSDP.begin(); + SSDP.begin(); -//////////////////////////// MDNS.addService("http", "tcp", 80); - //MDNS.addService("https", "tcp", 443); -///////////////////////////////////////// -AutoConfigBlind(); -get_save_state(); + // MDNS.addService("https", "tcp", 443); -moveServo(ServoPos); ///moves servo to set pos as on powerup servo pos defaults to 90 regardless of previous osition -myservo[0].detach(); -myservo[1].detach(); + AutoConfigBlind(); + get_save_state(); - } -///////main loop -void loop() -{ + moveServo(ServoPos); // moves servo to set pos as on powerup servo pos defaults to 90 regardless of previous osition + myservo[0].detach(); + myservo[1].detach(); +} + +// loop - main loop +void loop() { client.loop(); delay(10); - if (!client.connected()) - { - //connect(); + if (!client.connected()) { client.disconnect(); connect(); - } httpServer.handleClient(); MDNS.update(); - /////set to 0 to stop telementry update. help power save - if (String(tele_update_set).toInt()>0) - { - //Serial.printlnln("Telementry update..."); - tele_update(); + + // set to 0 to stop telementry update. help power save + if (String(tele_update_set).toInt()>0) { + // Serial.printlnln("Telementry update..."); + tele_update(); } - -////Battery Check Monitor - if (String(battery_system).equalsIgnoreCase("ON")) - { - //Serial.println("Checking Battery Status.. "); - Battery_Check(); + // Battery Check Monitor + if (String(battery_system).equalsIgnoreCase("ON")) { + // Serial.println("Checking Battery Status.. "); + Battery_Check(); } - -// Get button event and act accordingly - button_result = 0; - checkButton(); -if (String(remote_switch).equalsIgnoreCase("YES")) - { - - - if (button_result == 1) {clickEvent();} - if (button_result == 2) {doubleClickEvent();} - if (button_result == 3) {holdEvent();} - if (button_result == 4) {longHoldEvent();} ////allows for reset operation + + // Get button event and act accordingly + button_result = 0; + checkButton(); + if (String(remote_switch).equalsIgnoreCase("YES")) { + // TODO: change to switch + if (button_result == 1) { + clickEvent(); + } else if (button_result == 2) { + doubleClickEvent(); + } else if (button_result == 3) { + holdEvent(); + } else if (button_result == 4) { + longHoldEvent(); + } // allows for reset operation } - - } - -/////end void loop