Code Cleaning

Implement define for MONITORING_FEATURE and MSG_FEATURE
Add better FM for SD Files
Light review of printer UI to separate sections
Add more control on Serial commands
Fix Github address
Change version to 0.8.0
Change default baud to 115200
Add Marlinkimbra support
This commit is contained in:
luc lebosse 2016-08-21 17:11:50 +02:00
parent af283c8f23
commit 2728b467a1
9 changed files with 1412 additions and 628 deletions

View File

@ -35,10 +35,12 @@ void COMMAND::execute_command(int cmd,String cmd_params)
switch(cmd) {
byte mode;
case 800:
Serial.print(cmd_params);
Serial.print("\nFW version:");
Serial.println(FW_VERSION);
break;
case 100:
if (!CONFIG::isSSIDValid(cmd_params.c_str()))Serial.println("\nError");
if(!CONFIG::write_string(EP_SSID,cmd_params.c_str())) {
Serial.println("\nError");
} else {
@ -52,7 +54,8 @@ void COMMAND::execute_command(int cmd,String cmd_params)
Serial.println("\nOk");
}
break;
case 102:
case 102:
if (!CONFIG::isHostnameValid(cmd_params.c_str()))Serial.println("\nError");
if(!CONFIG::write_string(EP_HOSTNAME,cmd_params.c_str())) {
Serial.println("\nError");
} else {
@ -60,6 +63,7 @@ void COMMAND::execute_command(int cmd,String cmd_params)
}
break;
case 103:
if (cmd_params=="STA") {
mode = CLIENT_MODE;
} else {
@ -142,7 +146,7 @@ void COMMAND::execute_command(int cmd,String cmd_params)
if ((web_interface->blockserial)) break;
cmd_params.trim() ;
if ((cmd_params.length() > 0) && (cmd_params[0] != '/')) cmd_params = "/" + cmd_params;
File currentfile = SPIFFS.open(cmd_params, "r");
FSFILE currentfile = SPIFFS.open(cmd_params, "r");
if (currentfile) {//if file open success
//flush to be sure send buffer is empty
Serial.flush();
@ -172,16 +176,31 @@ void COMMAND::execute_command(int cmd,String cmd_params)
}
break;
case 999:
#ifdef ERROR_MSG_FEATURE
if (cmd_params=="ERROR") {
web_interface->error_msg.clear();
} else if (cmd_params=="INFO") {
}
#endif
#ifdef INFO_MSG_FEATURE
if (cmd_params=="INFO") {
web_interface->info_msg.clear();
} else if (cmd_params=="STATUS") {
}
#endif
#ifdef STATUS_MSG_FEATURE
if (cmd_params=="STATUS") {
web_interface->status_msg.clear();
} else if (cmd_params=="ALL") {
}
#endif
if (cmd_params=="ALL") {
#ifdef ERROR_MSG_FEATURE
web_interface->error_msg.clear();
#endif
#ifdef STATUS_MSG_FEATURE
web_interface->status_msg.clear();
#endif
#ifdef INFO_MSG_FEATURE
web_interface->info_msg.clear();
#endif
}
break;
//default:
@ -191,8 +210,8 @@ void COMMAND::execute_command(int cmd,String cmd_params)
void COMMAND::check_command(String buffer)
{
static bool bfileslist=false;
String buffer2;
static bool bfileslist=false;
static uint32_t start_list=0;
//if SD list is not on going
if (!bfileslist) {
@ -210,23 +229,47 @@ void COMMAND::check_command(String buffer)
(web_interface->blockserial) = true;
return;
}
#ifdef TEMP_MONITORING_FEATURE
int Tpos = buffer.indexOf("T:");
#endif
#ifdef POS_MONITORING_FEATURE
int Xpos = buffer.indexOf("X:");
int Ypos = buffer.indexOf("Y:");
int Zpos = buffer.indexOf("Z:");
#endif
#if FIRMWARE_TARGET == SMOOTHIEWARE
#ifdef SPEED_MONITORING_FEATURE
int Speedpos = buffer.indexOf("Speed factor at ");
#endif
#ifdef FLOW_MONITORING_FEATURE
int Flowpos = buffer.indexOf("Flow rate at ");
#endif
#ifdef ERROR_MSG_FEATURE
int Errorpos= buffer.indexOf("error:");
#endif
#ifdef INFO_MSG_FEATURE
int Infopos= buffer.indexOf("info:");
#endif
#ifdef STATUS_MSG_FEATURE
int Statuspos= buffer.indexOf("warning:");
#endif
#else
#ifdef SPEED_MONITORING_FEATURE
int Speedpos = buffer.indexOf("SpeedMultiply:");
#endif
#ifdef FLOW_MONITORING_FEATURE
int Flowpos = buffer.indexOf("FlowMultiply:");
#endif
#ifdef ERROR_MSG_FEATURE
int Errorpos= buffer.indexOf("Error:");
#endif
#ifdef INFO_MSG_FEATURE
int Infopos= buffer.indexOf("Info:");
#endif
#ifdef STATUS_MSG_FEATURE
int Statuspos= buffer.indexOf("Status:");
#endif
#endif
#ifdef SERIAL_COMMAND_FEATURE
String ESP_Command;
@ -250,6 +293,7 @@ void COMMAND::check_command(String buffer)
}
}
#endif
#ifdef TEMP_MONITORING_FEATURE
//check for temperature
if (Tpos>-1) {
//look for valid temperature answer
@ -261,14 +305,17 @@ void COMMAND::check_command(String buffer)
web_interface->last_temp=millis();
}
}
#endif
#ifdef POS_MONITORING_FEATURE
//Position of axis
if (Xpos>-1 && Ypos>-1 && Zpos>-1) {
web_interface->answer4M114=buffer;
}
#endif
#ifdef SPEED_MONITORING_FEATURE
//Speed
if (Speedpos>-1) {
//get just the value
#if FIRMWARE_TARGET == SMOOTHIEWARE
buffer2 =buffer.substring(Speedpos+16);
int p2 = buffer2.indexOf(".");
@ -276,12 +323,12 @@ void COMMAND::check_command(String buffer)
#else
web_interface->answer4M220=buffer.substring(Speedpos+14);
#endif
}
#endif
#ifdef FLOW_MONITORING_FEATURE
//Flow
if (Flowpos>-1) {
//get just the value
#if FIRMWARE_TARGET == SMOOTHIEWARE
buffer2 =buffer.substring(Flowpos+13);
int p2 = buffer2.indexOf(".");
@ -290,14 +337,20 @@ void COMMAND::check_command(String buffer)
web_interface->answer4M221=buffer.substring(Flowpos+13);
#endif
}
#endif
#ifdef ERROR_MSG_FEATURE
//Error
if (Errorpos>-1 && !(buffer.indexOf("Format error")!=-1 || buffer.indexOf("wait")==Errorpos+6) ) {
(web_interface->error_msg).add(buffer.substring(Errorpos+6).c_str());
}
#endif
#ifdef INFO_MSG_FEATURE
//Info
if (Infopos>-1) {
(web_interface->info_msg).add(buffer.substring(Infopos+5).c_str());
}
#endif
#ifdef STATUS_MSG_FEATURE
//Status
if (Statuspos>-1) {
#if FIRMWARE_TARGET == SMOOTHIEWARE
@ -306,6 +359,7 @@ void COMMAND::check_command(String buffer)
(web_interface->status_msg).add(buffer.substring(Statuspos+7).c_str());
#endif
}
#endif
} else { //listing file is on going
//check if we are too long
if ((millis()-start_list)>30000) { //timeout in case of problem
@ -328,7 +382,6 @@ void COMMAND::check_command(String buffer)
LOG('\n');
}
}
}
}

View File

@ -25,7 +25,146 @@ extern "C" {
}
extern String formatBytes(size_t bytes);
bool CONFIG::isHostnameValid(const char * hostname)
{
//limited size
char c;
if (strlen(hostname)>MAX_HOSTNAME_LENGTH || strlen(hostname) < 1) {
return false;
}
//only letter and digit
for (int i=0; i < strlen(hostname); i++) {
c = hostname[i];
if (!(isdigit(c) || isalpha(c) || c=='_')) {
return false;
}
if (c==' ') {
return false;
}
}
return true;
}
bool CONFIG::isSSIDValid(const char * ssid)
{
//limited size
char c;
if (strlen(ssid)>MAX_SSID_LENGTH || strlen(ssid)<MIN_SSID_LENGTH) {
return false;
}
//only letter and digit
for (int i=0; i < strlen(ssid); i++) {
c = ssid[i];
//if (!(isdigit(c) || isalpha(c))) return false;
if (c==' ') {
return false;
}
}
return true;
}
bool CONFIG::isPasswordValid(const char * password)
{
//limited size
if ((strlen(password)>MAX_PASSWORD_LENGTH)|| (strlen(password)<MIN_PASSWORD_LENGTH)) {
return false;
}
//no space allowed
for (int i=0; i < strlen(password); i++)
if (password[i] == ' ') {
return false;
}
return true;
}
bool CONFIG::isLocalPasswordValid(const char * password)
{
char c;
//limited size
if ((strlen(password)>MAX_LOCAL_PASSWORD_LENGTH)|| (strlen(password)<MIN_LOCAL_PASSWORD_LENGTH)) {
return false;
}
//no space allowed
for (int i=0; i < strlen(password); i++) {
c= password[i];
if (c==' ') {
return false;
}
}
return true;
}
bool CONFIG::isIPValid(const char * IP)
{
//limited size
int internalcount=0;
int dotcount = 0;
bool previouswasdot=false;
char c;
if (strlen(IP)>15 || strlen(IP)==0) {
return false;
}
//cannot start with .
if (IP[0]=='.') {
return false;
}
//only letter and digit
for (int i=0; i < strlen(IP); i++) {
c = IP[i];
if (isdigit(c)) {
//only 3 digit at once
internalcount++;
previouswasdot=false;
if (internalcount>3) {
return false;
}
} else if(c=='.') {
//cannot have 2 dots side by side
if (previouswasdot) {
return false;
}
previouswasdot=true;
internalcount=0;
dotcount++;
}//if not a dot neither a digit it is wrong
else {
return false;
}
}
//if not 3 dots then it is wrong
if (dotcount!=3) {
return false;
}
//cannot have the last dot as last char
if (IP[strlen(IP)-1]=='.') {
return false;
}
return true;
}
char * CONFIG::intTostr(int value)
{
static char result [12];
sprintf(result,"%d",value);
return result;
}
String CONFIG::formatBytes(size_t bytes)
{
if (bytes < 1024) {
return String(bytes)+" B";
} else if(bytes < (1024 * 1024)) {
return String(bytes/1024.0)+" KB";
} else if(bytes < (1024 * 1024 * 1024)) {
return String(bytes/1024.0/1024.0)+" MB";
} else {
return String(bytes/1024.0/1024.0/1024.0)+" GB";
}
}
//read a string
//a string is multibyte + \0, this is won't work if 1 char is multibyte like chinese char
@ -502,6 +641,7 @@ void CONFIG::print_config()
#else
Serial.println(F("???"));
#endif
Serial.print(F("SD Card support: "));
#ifdef DEBUG_ESP3D
Serial.print(F("Debug Enabled :"));
#ifdef DEBUG_OUTPUT_SPIFFS
@ -514,5 +654,4 @@ void CONFIG::print_config()
Serial.println(F("serial"));
#endif
#endif
}

View File

@ -22,7 +22,8 @@
#define REPETIER 0
#define REPETIER4DV 1
#define MARLIN 2
#define SMOOTHIEWARE 3
#define MARLINKIMBRA 3
#define SMOOTHIEWARE 4
//comment to disable
//MDNS_FEATURE: this feature allow type the name defined
@ -33,13 +34,13 @@
#define SSDP_FEATURE
//NETBIOS_FEATURE: this feature is a discovery protocol, supported on Windows out of the box
#define NETBIOS_FEATURE
//#define NETBIOS_FEATURE
//CAPTIVE_PORTAL_FEATURE: In SoftAP redirect all unknow call to main page
#define CAPTIVE_PORTAL_FEATURE
//AUTHENTICATION_FEATURE: protect pages by login password
#define AUTHENTICATION_FEATURE
//#define AUTHENTICATION_FEATURE
//WEB_UPDATE_FEATURE: allow to flash fw using web UI
#define WEB_UPDATE_FEATURE
@ -53,31 +54,61 @@
//RECOVERY_FEATURE: allow to use GPIO2 pin as hardware reset for EEPROM, add 8s to boot time to let user to jump GPIO2 to GND
#define RECOVERY_FEATURE
#ifdef RECOVERY_FEATURE
//pin used to reset setting
#define RESET_CONFIG_PIN 2
#endif
//INFO_MSG_FEATURE: catch the Info msg and filter it to specific table
#define INFO_MSG_FEATURE
//ERROR_MSG_FEATURE: catch the error msg and filter it to specific table
#define ERROR_MSG_FEATURE
//STATUS_MSG_FEATURE: catch the status msg and filter it to specific table
#define STATUS_MSG_FEATURE
//TEMP_MONITORING_FEATURE : catch the specific answer and store it to variable
#define TEMP_MONITORING_FEATURE
//SPEED_MONITORING_FEATURE : catch the specific answer and store it to variable
#define SPEED_MONITORING_FEATURE
//POS_MONITORING_FEATURE : catch the specific answer and store it to variable
#define POS_MONITORING_FEATURE
//FLOW_MONITORING_FEATURE : catch the specific answer and store it to variable
#define FLOW_MONITORING_FEATURE
//FIRMWARE_TARGET: the targeted FW, can be REPETIER (Original Repetier)/ REPETIER4DV (Repetier for Davinci) / MARLIN (Marlin)/ SMOOTHIEWARE (Smoothieware)
#define FIRMWARE_TARGET REPETIER4DV
//DEBUG Flag
//#define DEBUG_ESP3D
//#define DEBUG_OUTPUT_SPIFFS
#define DEBUG_OUTPUT_SERIAL
#ifdef DEBUG_ESP3D
#define LOG(string) {File logfile = SPIFFS.open("/log.txt", "a+");logfile.print(string);logfile.close();}
#ifdef DEBUG_OUTPUT_SPIFFS
#define LOG(string) {FSFILE logfile = SPIFFS.open("/log.txt", "a+");logfile.print(string);logfile.close();}
#else
#define LOG(string) {Serial.print(string);}
#endif
#else
#define LOG(string) {}
#endif
#define FSFILE File
#define FSDIR fs::Dir
#define FSINFO FSInfo
#ifndef CONFIG_h
#define CONFIG_h
#include <Arduino.h>
#include "wifi.h"
//version and sources location
#define FW_VERSION "0.7.81"
#define REPOSITORY "https://github.com/luc-github/ESP8266"
#define FW_VERSION "0.8.0"
#define REPOSITORY "https://github.com/luc-github/ESP3D"
//pin used to reset setting
#define RESET_CONFIG_PIN 2
//flags
#define AP_MODE 1
#define CLIENT_MODE 2
@ -119,7 +150,7 @@ const char DEFAULT_PASSWORD [] PROGMEM = "12345678";
const byte DEFAULT_IP_VALUE[] = {192, 168, 0, 1};
const byte DEFAULT_MASK_VALUE[] = {255, 255, 255, 0};
#define DEFAULT_GATEWAY_VALUE DEFAULT_IP_VALUE
const long DEFAULT_BAUD_RATE = 9600;
const long DEFAULT_BAUD_RATE = 115200;
const char M117_[] PROGMEM = "M117 ";
#define DEFAULT_PHY_MODE WIFI_PHY_MODE_11G
#define DEFAULT_SLEEP_MODE WIFI_MODEM_SLEEP
@ -165,6 +196,13 @@ public:
static bool write_byte(int pos, const byte value);
static bool reset_config();
static void print_config();
static bool isHostnameValid(const char * hostname);
static bool isSSIDValid(const char * ssid);
static bool isPasswordValid(const char * password);
static bool isLocalPasswordValid(const char * password);
static bool isIPValid(const char * IP);
static char * intTostr(int value);
static String formatBytes(size_t bytes);
};
#endif

View File

@ -11,4 +11,17 @@ background-image:none;border:1px solid transparent;white-space:nowrap;padding:6p
.filelink {color:#000000;}
.filelink:hover, .filelink:focus {color:#0094FF;}
.panel-footer{padding:10px 15px;color:#31708f;background-color:#f5f5f5;border-color:#dddddd;border-top:1px solid #dddddd;}
.loader {
border: 4px solid #f3f3f3; /* Light grey */
border-top: 4px solid #3498db; /* Blue */
border-radius: 50%;
width: 12px;
height: 12px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</STYLE>

View File

@ -1,153 +1,374 @@
$INCLUDE[header.inc]$
$INCLUDE[css2.inc]$
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="control_expanded = expand_collapse(control_expanded,'pin_control','control')" id="pin_control">&#9660;</div></td><td>Control</td></tr></table></div>
<div class="panel-body" id="control">
<table>
<tr><td style="padding:0px;"><div id="Extruder1" style="visibility:hidden;height:0px;">
<table><tr><td><label>E1:&nbsp;</label></td>
<td id="data_extruder1" style="overflow: hidden;"></td><td>0<input id="rangeinput1" type="range" min=0 max=270 onchange="Updatenumber('1');">270</td>
<td><input class="form-control" id="numberinput1" type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('1');"></td><td> &#176;C
<td><input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M104 T0 S', '1');"></td></tr></table></div></td></tr>
<tr ><td style="padding:0px;"><div id="Extruder2" style="visibility:hidden;height:0px;">
<table><tr><td><label>E2:&nbsp;</label></td>
<td id="data_extruder2" style="overflow: hidden;"></td><td>0<input id="rangeinput2" type="range" min=0 max=270 onchange="Updatenumber('2');">270</td>
<td><input class="form-control" id="numberinput2" type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('2');"></td><td>&#176;C
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M104 T1 S', '2');">
</td></tr></table></div></td></tr>
<tr><td style="padding:0px;"><div id="Bed" style="visibility:hidden;height:0px;">
<table><tr><td><label>Bed:</label></td>
<td id="data_bed" style="overflow: hidden;"></td><td>0<input id="rangeinputbed" type="range" min=0 max=130 onchange="Updatenumber('bed');">130</td>
<td><input class="form-control" id="numberinputbed"type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('bed');"></td><td>&#176;C
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M140 S', 'bed');">
</td></tr></table></div></td></tr>
<tr><td id="speed"><table><tr>
<td><label>Speed:</label></td><td><label class="text-info" id="currentspeed"></label></td>
<td>0<input id="rangeinputspeed" type="range" min=0 max=300 onchange="Updatenumber('speed');">300</td>
<td><input class="form-control" id="numberinputspeed" type="number" size="3" min=0 max=300 step=1 value=0 onchange="Updaterange('speed');"></td><td>%
<input type="button" class="btn btn-primary" class="btn btn-primary" value="Set" onclick="SendValue( 'M220 S', 'speed');"></td>
<td>&nbsp;&nbsp;</td><td>Status:</td><td id="status" align="center" valign="middle">
<svg width="20" height="20"><circle cx="10" cy="10" r="8" stroke="black" stroke-width="2" fill="white"></circle></svg></td>
<td id="status-text" style="width:100px;"></td><td>&nbsp;&nbsp;</td><td class="btnimg" onclick="OnclickEmergency();">
<svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="red" />
<circle cx="20" cy="20" r="10" stroke="black" stroke-width="4" fill="red" /><rect x="15" y="8" width="10" height="10" style="fill:red;stroke-width:1;stroke:red" />
<rect x="18" y="6" rx="1" ry="1" width="4" height="14" style="fill:black;stroke-width:1;stroke:black" /></svg></td></tr></table></td></tr>
<tr><td id="flow"><table><tr><td><label>Flow:</label></td><td><label class="text-info" id="currentflow"></label></td>
<td>0<input id="rangeinputflow" type="range" min=0 max=300 onchange="Updatenumber('flow');">300</td>
<td><input class="form-control" id="numberinputflow" size="3" type="number" min=0 max=300 step=1 value=0 onchange="Updaterange('flow');"></td><td>%
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M221 S', 'flow');"></td><td>&nbsp;&nbsp;</td>
<td><label>X:</label></td><td><label class="text-info" id="posx"></label></td><td>&nbsp;&nbsp;</td><td><label>Y:</label></td><td><label class="text-info" id="posy"></label></td><td>&nbsp;&nbsp;</td>
<td><label>Z:</label></td><td><label class="text-info" id="posz" ></label></td></tr></table></td></tr>
<tr><td><table width="100%"><tr><td width="auto"><label>Command:</label></td>
<tr><td style="padding:0px;">
<div id="Extruder1" style="visibility:hidden;height:0px;">
<table><tr><td><label>E1:&nbsp;</label></td>
<td id="data_extruder1" style="overflow: hidden;"></td><td>0<input id="rangeinput1" type="range" min=0 max=270 onchange="Updatenumber('1');">270</td>
<td><input class="form-control" id="numberinput1" type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('1');"></td><td> &#176;C
<td><input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M104 T0 S', '1');"></td></tr>
</table>
</div>
</td></tr>
<tr ><td style="padding:0px;">
<div id="Extruder2" style="visibility:hidden;height:0px;">
<table><tr><td><label>E2:&nbsp;</label></td>
<td id="data_extruder2" style="overflow: hidden;"></td><td>0<input id="rangeinput2" type="range" min=0 max=270 onchange="Updatenumber('2');">270</td>
<td><input class="form-control" id="numberinput2" type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('2');"></td><td>&#176;C
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M104 T1 S', '2');">
</td></tr>
</table>
</div>
</td></tr>
<tr><td style="padding:0px;">
<div id="Bed" style="visibility:hidden;height:0px;">
<table><tr><td><label>Bed:</label></td>
<td id="data_bed" style="overflow: hidden;"></td><td>0<input id="rangeinputbed" type="range" min=0 max=130 onchange="Updatenumber('bed');">130</td>
<td><input class="form-control" id="numberinputbed"type="number" min=0 max=270 step=1 value=0 onchange="Updaterange('bed');"></td><td>&#176;C
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M140 S', 'bed');">
</td></tr>
</table>
</div>
</td></tr>
<tr><td id="speed">
<table>
<tr>
<td><label>Speed:</label></td><td><label class="text-info" id="currentspeed"></label></td>
<td>0<input id="rangeinputspeed" type="range" min=0 max=300 onchange="Updatenumber('speed');">300</td>
<td><input class="form-control" id="numberinputspeed" type="number" size="3" min=0 max=300 step=1 value=0 onchange="Updaterange('speed');"></td><td>%
<input type="button" class="btn btn-primary" class="btn btn-primary" value="Set" onclick="SendValue( 'M220 S', 'speed');"></td>
<td>&nbsp;&nbsp;</td><td>Status:</td><td id="status" align="center" valign="middle">
<svg width="20" height="20"><circle cx="10" cy="10" r="8" stroke="black" stroke-width="2" fill="white"></circle></svg></td>
<td id="status-text" style="width:100px;"></td><td>&nbsp;&nbsp;</td><td class="btnimg" onclick="OnclickEmergency();">
<svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="red" />
<circle cx="20" cy="20" r="10" stroke="black" stroke-width="4" fill="red" /><rect x="15" y="8" width="10" height="10" style="fill:red;stroke-width:1;stroke:red" />
<rect x="18" y="6" rx="1" ry="1" width="4" height="14" style="fill:black;stroke-width:1;stroke:black" /></svg></td>
</tr>
</table>
</td></tr>
<tr><td id="flow">
<table>
<tr>
<td><label>Flow:</label></td><td><label class="text-info" id="currentflow"></label></td>
<td>0<input id="rangeinputflow" type="range" min=0 max=300 onchange="Updatenumber('flow');">300</td>
<td><input class="form-control" id="numberinputflow" size="3" type="number" min=0 max=300 step=1 value=0 onchange="Updaterange('flow');"></td><td>%
<input type="button" class="btn btn-primary" value="Set" onclick="SendValue( 'M221 S', 'flow');"></td><td>&nbsp;&nbsp;</td>
<td><label>X:</label></td><td><label class="text-info" id="posx"></label></td><td>&nbsp;&nbsp;</td>
<td><label>Y:</label></td><td><label class="text-info" id="posy"></label></td><td>&nbsp;&nbsp;</td>
<td><label>Z:</label></td><td><label class="text-info" id="posz" ></label></td>
</tr>
</table>
</td></tr>
</table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="command_expanded = expand_collapse(command_expanded,'pin_command','command')" id="pin_command">&#9660;</div></td><td>Command</td></tr></table></div>
<div class="panel-body" id="command">
<table width="100%"><tr>
<td width="100%"><input class="form-control" id="cmd" type="text" style="width: 100%;"></td>
<td width="auto"><input type="button" class="btn btn-primary" value="Send" onclick="Sendcustomcommand();"></td></tr></table></td></tr>
<tr><td><hr></td></tr><tr><td><table><tr><td><label>Info:</label><br>
<td width="auto"><input type="button" class="btn btn-primary" value="Send" onclick="Sendcustomcommand();"></td></tr></table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="information_expanded = expand_collapse(information_expanded,'pin_information','information')" id="pin_information">&#9660;</div></td><td>Information</td></tr></table></div>
<div class="panel-body" id="information">
<table><tr><td>
<center><table><tr><td><div class="btnimg" onclick="if(confirm('Clear Info log ?'))Sendcommand('[ESP999]INFO');">
<svg height="20" width="20" viewBox="0 0 40 40" >";
<circle cx="20" cy="20" r="17" stroke="black" stroke-width="1" fill="red" />
<line x1="11" y1="11" x2="29" y2="29" style="stroke:white;stroke-width:6" />
<line x1="29" y1="11" x2="11" y2="29" style="stroke:white;stroke-width:6" /></svg></div></td></tr></table></center>
</td><td width=100% id="infomsg" class="text-info"></td></tr></table></tr>
<tr><td><hr></td></tr><tr><td><table><tr><td><label>Error:</label><br>
</td><td width=100% id="infomsg" class="text-info"></td></tr></table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="error_expanded = expand_collapse(error_expanded,'pin_error','error')" id="pin_error">&#9660;</div></td><td>Error</td></tr></table></div>
<div class="panel-body" id="error">
<table><tr><td>
<center><table><tr><td><div class="btnimg" onclick="if(confirm('Clear Error log ?'))Sendcommand('[ESP999]ERROR');">
<svg height="20" width="20" viewBox="0 0 40 40" >";
<circle cx="20" cy="20" r="17" stroke="black" stroke-width="1" fill="red" />
<line x1="11" y1="11" x2="29" y2="29" style="stroke:white;stroke-width:6" />
<line x1="29" y1="11" x2="11" y2="29" style="stroke:white;stroke-width:6" /></svg></div></td></tr></table></center>
</td><td width=100% id="errormsg" class="text-info"></td></tr></table></tr>
<tr><td><hr></td></tr><tr><td><table><tr><td><label>Status:</label><br>
</td><td width=100% id="errormsg" class="text-info"></td></tr></table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="status_expanded = expand_collapse(status_expanded,'pin_status','statusdisplay')" id="pin_status">&#9660;</div></td><td>Status</td></tr></table></div>
<div class="panel-body" id="statusdisplay">
<table><tr><td>
<center><table><tr><td><div class="btnimg" onclick="if(confirm('Clear Status log ?'))Sendcommand('[ESP999]STATUS');">
<svg height="20" width="20" viewBox="0 0 40 40" >";
<circle cx="20" cy="20" r="17" stroke="black" stroke-width="1" fill="red" />
<line x1="11" y1="11" x2="29" y2="29" style="stroke:white;stroke-width:6" />
<line x1="29" y1="11" x2="11" y2="29" style="stroke:white;stroke-width:6" /></svg></div></td></tr></table></center>
</td><td width=100% id="statusmsg" class="text-info"></td></tr></table></tr>
<tr><td><hr></td></tr><tr><td><table><tr><td class="btnimg" onclick="Sendcommand('M24');">
<svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" /><polygon points="15,10 30,20 15,30" fill:"white" stroke:"white" stroke-width:"1" /></svg></td>
<td class="btnimg" onclick="Sendcommand('M25');"><svg width="40" height="40" viewBox="0 0 40 40"> <circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" />
<rect x="10" y="10" width="7" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /> <rect x="23" y="10" width="7" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /></svg></td>
<td class="btnimg" onclick="Sendcommand('M50');"><svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" />
<rect x="10" y="10" width="20" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /></svg></td>
<td class="btnimg" onclick="refreshSDfiles();"><svg width="40" height="40" viewBox="0 0 40 40"><rect x="5" y="10" width="30" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" />
<rect x="20" y="5" width="15" height="15" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /><text x="10" y="25" font-family="Verdana" font-size="14" fill="white">SD</text></svg></td>
<td>&nbsp;&nbsp;</td>
<td id="SDLIST"></td></tr></table></td></tr>
<tr><td><table><tr><td><input type="file" id="file-select" name="myfiles[]" /></td>
<td><input class="btn btn-primary" type="button" id="upload-button" onclick="Sendfile();" value="Upload"/></td>
<td><progress style="visibility:hidden;" name='prg' id='prg' max='100'></progress></td></tr><table></td></tr>
<tr><td><table><tr align="center" valign="middle"><td class="btnimg" onclick=" Sendcommand('G28 X');">
<svg width="40" height="40" viewBox="0 0 40 40" ><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="black" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" />
<text x="15" y="35" font-family="Verdana" font-size="14" fill="white">X</text></svg></td><td>
<table><tr><td class="btnimg" onclick="SendJogcommand( 'Y-10',XYfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Y-1',XYfeedrate);"><svg width="40" height="20" viewBox="0 2 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:5"/><text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Y-0.1',XYfeedrate);"><svg width="40" height="20" viewBox="0 4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:2"/><text x="12" y="20" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg></td></tr></table></td>
<td class="btnimg" onclick=" Sendcommand('G28 Y');"><svg width="40" height="40" viewBox="0 0 40 40">
<polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="blue" stroke-width:"1" stroke:"black" /><line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" />
<polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /><text x="15" y="35" font-family="Verdana" font-size="14" fill="white">Y</text></svg></td>
<td></td><td><table><tr><td class="btnimg" onclick="SendJogcommand( 'Z-10',Zfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Z-1',Zfeedrate);"><svg width="40" height="20" viewBox="0 2 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:5"/><text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Z-0.1',Zfeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:2"/>
<text x="12" y="20" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg></td></tr></table></td>
<td></td><td id="JogExtruder1-1" style="visibility:hidden;"><table><tr><td class="btnimg" onclick="SendJogcommand( 'E0-50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-50</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E0-10',Efeedrate);"><svg width="40" height="20" viewBox="0 2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:5"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E0-1',Efeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:2"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td></tr></table></td>
<td></td><td id="JogExtruder2-1" style="visibility:hidden;"><table><tr><td class="btnimg" onclick="SendJogcommand( 'E1-50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-50</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E1-10',Efeedrate);"><svg width="40" height="20" viewBox="0 2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:5"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E1-1',Efeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:2"/>
<text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td></tr></table></td></tr>
<tr align="center" valign="middle"><td><table><tr><td class="btnimg" onclick="SendJogcommand( 'X10',XYfeedrate);"><svg width="20" height="40" viewBox="12 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:7" transform="rotate(-90 20 10)"/><text x="22" y="13" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X1',XYfeedrate);"><svg width="20" height="40" viewBox="10 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:5" transform="rotate(-90 20 10)"/>
<text x="21" y="13" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X0.1',XYfeedrate);"><svg width="20" height="40" viewBox="14 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:2" transform="rotate(-90 20 10)"/><text x="19" y="13" font-family="Verdana" font-size="7" fill="black">0.1</text></svg></td></tr>
</table></td><td></td><td><table><tr><td class="btnimg" onclick="SendJogcommand( 'X-0.1',XYfeedrate);"><svg width="20" height="40" viewBox="6 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:3" transform="rotate(90 20 10)"/><text x="7" y="12" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X-1',XYfeedrate);"><svg width="20" height="40" viewBox="8 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:5" transform="rotate(90 20 10)"/>
<text x="11" y="13" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td><td class="btnimg" onclick="SendJogcommand( 'X-10',XYfeedrate);">
<svg width="20" height="40" viewBox="8 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:7" transform="rotate(90 20 10)"/>
<text x="7" y="12" font-size="7" fill="black">-10</text></svg></td></tr></table></td>
<td></td><td><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="green">Z</text></svg></td>
<td></td><td id="JogExtruder1-2" style="visibility:hidden;"><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="orange">1</text></svg></td>
<td></td><td id="JogExtruder2-2" style="visibility:hidden;"><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="pink">2</text></svg></td></tr>
<tr align="center" valign="middle"><td class="btnimg" onclick=" Sendcommand('G28');"><svg width="40" height="40" viewBox="0 0 40 40"><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="purple" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /></svg></td><td>
<table><tr><td class="btnimg" onclick="SendJogcommand( 'Y0.1',XYfeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:3" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">0.1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Y1',XYfeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="17" y="7" font-family="Verdana" font-size="7" fill="black">1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Y10',XYfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:7" transform="rotate(180 20 10)"/>
<text x="15" y="6" font-family="Verdana" font-size="7" fill="black">10</text></svg></td></tr></table></td>
<td class="btnimg" onclick=" Sendcommand('G28 Z');"><svg width="40" height="40" viewBox="0 0 40 40"><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="green" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /><text x="15" y="35" font-family="Verdana" font-size="14" fill="white">Z</text></svg></td>
<td></td><td><table><tr><td class="btnimg" onclick="SendJogcommand( 'Z0.1',Zfeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:3" transform="rotate(180 20 10)"/><text x="14" y="6" font-family="Verdana" font-size="7" fill="black">0.1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Z1',Zfeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="18" y="7" font-family="Verdana" font-size="7" fill="black">1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'Z10',Zfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:7" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">10</text></svg></td></tr></table></td>
<td></td><td id="JogExtruder1-3" style="visibility:hidden;"><table><tr><td class="btnimg" onclick="SendJogcommand( 'E0+1',Efeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:3" transform="rotate(180 20 10)"/><text x="18" y="6" font-family="Verdana" font-size="7" fill="black">1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E0+10',Efeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="14" y="7" font-family="Verdana" font-size="7" fill="black">10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E0+50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:7" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">50</text></svg></td></tr></table></td>
<td></td><td id="JogExtruder2-3" style="visibility:hidden;"><table><tr><td class="btnimg" onclick="SendJogcommand( 'E1+1',Efeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:3" transform="rotate(180 20 10)"/><text x="18" y="6" font-family="Verdana" font-size="7" fill="black">1</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E1+10',Efeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="14" y="7" font-family="Verdana" font-size="7" fill="black">10</text></svg></td></tr>
<tr><td class="btnimg" onclick="SendJogcommand( 'E1+50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20" ><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:7" transform="rotate(180 20 10)"/>
<text x="15" y="6" font-family="Verdana" font-size="7" fill="black">50</text></svg></td></tr></table></td></tr></table></td></tr></table>
</td><td width=100% id="statusmsg" class="text-info"></td></tr></table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="printcommands_expanded = expand_collapse(printcommands_expanded,'pin_printcommands','printcommands')" id="pin_printcommands">&#9660;</div></td><td>Print</td></tr></table></div>
<div class="panel-body" id="printcommands">
<table>
<tr>
<td class="btnimg" onclick="Sendcommand('M24');">
<svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" /><polygon points="15,10 30,20 15,30" fill:"white" stroke:"white" stroke-width:"1" /></svg></td>
<td class="btnimg" onclick="Sendcommand('M25');"><svg width="40" height="40" viewBox="0 0 40 40"> <circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" />
<rect x="10" y="10" width="7" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /> <rect x="23" y="10" width="7" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /></svg></td>
<td class="btnimg" onclick="Sendcommand('M50');"><svg width="40" height="40" viewBox="0 0 40 40"><circle cx="20" cy="20" r="18" stroke="black" stroke-width="2" fill="white" />
<rect x="10" y="10" width="20" height="20" rx="2" ry="2" style="fill:rgb(0,0,0);stroke-width:1;stroke:rgb(0,0,0)" /></svg></td>
<td>&nbsp;&nbsp;</td>
<td id="SDLIST"></td>
</tr>
</table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="jog_expanded = expand_collapse(jog_expanded,'pin_jog','jogcommands')" id="pin_jog">&#9660;</div></td><td>Jog</td></tr></table></div>
<div class="panel-body" id="jogcommands">
<table>
<tr align="center" valign="middle">
<td class="btnimg" onclick=" Sendcommand('G28 X');">
<svg width="40" height="40" viewBox="0 0 40 40" ><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="black" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" />
<text x="15" y="35" font-family="Verdana" font-size="14" fill="white">X</text></svg></td><td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y-10',XYfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y-1',XYfeedrate);"><svg width="40" height="20" viewBox="0 2 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:5"/><text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y-0.1',XYfeedrate);"><svg width="40" height="20" viewBox="0 4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:2"/><text x="12" y="20" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg></td>
</tr>
</table>
</td>
<td class="btnimg" onclick=" Sendcommand('G28 Y');"><svg width="40" height="40" viewBox="0 0 40 40">
<polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="blue" stroke-width:"1" stroke:"black" /><line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" />
<polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /><text x="15" y="35" font-family="Verdana" font-size="14" fill="white">Y</text></svg>
</td>
<td></td>
<td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z-10',Zfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z-1',Zfeedrate);"><svg width="40" height="20" viewBox="0 2 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:5"/><text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z-0.1',Zfeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:2"/>
<text x="12" y="20" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg>
</td>
</tr>
</table>
</td>
<td></td>
<td id="JogExtruder1-1" style="visibility:hidden;">
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0-50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-50</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0-10',Efeedrate);"><svg width="40" height="20" viewBox="0 2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:5"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0-1',Efeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:2"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg>
</td>
</tr>
</table>
</td>
<td></td>
<td id="JogExtruder2-1" style="visibility:hidden;">
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1-50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:7"/><text x="13" y="20" font-family="Verdana" font-size="7" fill="black">-50</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1-10',Efeedrate);"><svg width="40" height="20" viewBox="0 2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:5"/>
<text x="14" y="20" font-family="Verdana" font-size="7" fill="black">-10</text></svg>
</td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1-1',Efeedrate);"><svg width="40" height="20" viewBox="0 4 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:2"/>
<text x="15" y="20" font-family="Verdana" font-size="7" fill="black">-1</text></svg>
</td>
</tr>
</table>
</td>
</tr>
<tr align="center" valign="middle">
<td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'X10',XYfeedrate);"><svg width="20" height="40" viewBox="12 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:7" transform="rotate(-90 20 10)"/><text x="22" y="13" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X1',XYfeedrate);"><svg width="20" height="40" viewBox="10 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:5" transform="rotate(-90 20 10)"/>
<text x="21" y="13" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X0.1',XYfeedrate);"><svg width="20" height="40" viewBox="14 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:2" transform="rotate(-90 20 10)"/><text x="19" y="13" font-family="Verdana" font-size="7" fill="black">0.1</text></svg>
</td>
</tr>
</table>
</td>
<td></td>
<td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'X-0.1',XYfeedrate);"><svg width="20" height="40" viewBox="6 -10 20 40">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:3" transform="rotate(90 20 10)"/><text x="7" y="12" font-family="Verdana" font-size="7" fill="black">-0.1</text></svg></td>
<td class="btnimg" onclick="SendJogcommand( 'X-1',XYfeedrate);"><svg width="20" height="40" viewBox="8 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:5" transform="rotate(90 20 10)"/>
<text x="11" y="13" font-family="Verdana" font-size="7" fill="black">-1</text></svg></td><td class="btnimg" onclick="SendJogcommand( 'X-10',XYfeedrate);">
<svg width="20" height="40" viewBox="8 -10 20 40"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:black;stroke-width:7" transform="rotate(90 20 10)"/>
<text x="7" y="12" font-size="7" fill="black">-10</text></svg>
</td>
</tr>
</table>
</td>
<td></td>
<td><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="green">Z</text></svg></td>
<td></td>
<td id="JogExtruder1-2" style="visibility:hidden;"><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="orange">1</text></svg></td>
<td></td>
<td id="JogExtruder2-2" style="visibility:hidden;"><svg width="20" height="20" viewBox="0 0 20 20"><text x="1" y="18" font-family="Verdana" font-size="22" fill="pink">2</text></svg></td>
</tr>
<tr align="center" valign="middle">
<td class="btnimg" onclick=" Sendcommand('G28');"><svg width="40" height="40" viewBox="0 0 40 40"><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="purple" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /></svg></td>
<td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y0.1',XYfeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:3" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">0.1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y1',XYfeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="17" y="7" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Y10',XYfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:blue;stroke-width:7" transform="rotate(180 20 10)"/>
<text x="15" y="6" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
</tr>
</table>
</td>
<td class="btnimg" onclick=" Sendcommand('G28 Z');"><svg width="40" height="40" viewBox="0 0 40 40"><polygon points="7,40 7,25 4,28 0,24 20,4 26,10 26,6 32,6 32,16 40,24 36,28 33,25 33,40" fill="green" stroke-width:"1" stroke:"black" />
<line x1="25" y1="8" x2="33" y2="16" style="stroke:white;stroke-width:1" /><polyline points="4,28 20,12 36,28" style="fill:none;stroke:white;stroke-width:1" /><text x="15" y="35" font-family="Verdana" font-size="14" fill="white">Z</text></svg></td>
<td></td>
<td>
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z0.1',Zfeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:3" transform="rotate(180 20 10)"/><text x="14" y="6" font-family="Verdana" font-size="7" fill="black">0.1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z1',Zfeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="18" y="7" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'Z10',Zfeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:green;stroke-width:7" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
</tr>
</table>
</td>
<td></td>
<td id="JogExtruder1-3" style="visibility:hidden;">
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0+1',Efeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:3" transform="rotate(180 20 10)"/><text x="18" y="6" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0+10',Efeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="14" y="7" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E0+50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:orange;stroke-width:7" transform="rotate(180 20 10)"/><text x="15" y="6" font-family="Verdana" font-size="7" fill="black">50</text></svg></td>
</tr>
</table>
</td>
<td></td>
<td id="JogExtruder2-3" style="visibility:hidden;">
<table>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1+1',Efeedrate);"><svg width="40" height="20" viewBox="0 -4 40 20">
<polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:3" transform="rotate(180 20 10)"/><text x="18" y="6" font-family="Verdana" font-size="7" fill="black">1</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1+10',Efeedrate);"><svg width="40" height="20" viewBox="0 -2 40 20"><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:5" transform="rotate(180 20 10)"/>
<text x="14" y="7" font-family="Verdana" font-size="7" fill="black">10</text></svg></td>
</tr>
<tr>
<td class="btnimg" onclick="SendJogcommand( 'E1+50',Efeedrate);"><svg width="40" height="20" viewBox="0 0 40 20" ><polyline points="5,18 20,5 35,18" style="fill:none;stroke:pink;stroke-width:7" transform="rotate(180 20 10)"/>
<text x="15" y="6" font-family="Verdana" font-size="7" fill="black">50</text></svg></td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</div>
<div class="panel">
<div class="panel-heading"><table><tr><td><div class="btnimg" onclick="filemanager_expanded = expand_collapse(filemanager_expanded,'pin_filemanager','filemanager')" id="pin_filemanager">&#9660;</div></td><td>SD Files</td></tr></table></div>
<div class="panel-body" id="filemanager">
<input type="file" id="file-select" name="myfiles[]" multiple/>
<input class="btn btn-primary" type="button" id="upload-button" onclick="Sendfile();" value="Upload"/>&nbsp;&nbsp;<progress style="visibility:hidden;" name='prg' id='prg' max='100'></progress>
<br><br><div class="panel">
<div class="panel-body">
<table><tr><td width="0%">
<div onclick="Createdir()" class="btnimg" id="iconcreatedir" style="display:none;"><svg width="40" height="40" viewBox="0 0 40 40"><rect x="5" y="10" width="30" height="20" rx="2" ry="2" fill="#31b0d5" />
<rect x="20" y="5" width="15" height="15" rx="2" ry="2" fill="#31b0d5" /><text x="15" y="25" font-size="18" font-weight="800" fill="white">+</text></svg>
</div>
</td><td><div id="loader" class="loader"></div></td><td width="100%"><div id="path" class="info" >&nbsp</div>
</td>
</tr></table>
<table class="table table-striped" style="border:1px;solid #dddddd;margin-bottom:20px;" ><thead><tr><th width='0%'>Type</th><th>Name</th><th>Size</th><th width='0%'></th><th width='0%'></th><th width='100%'></th></tr></thead><tbody id="file_list"><tbody></table>
</div>
<div class="panel-footer " id="filestatus"></div>
</div>
</div>
</div>
<script type="text/javascript">
var control_expanded = true;
var command_expanded = true;
var information_expanded = true;
var status_expanded = true;
var error_expanded = true;
var filemanager_expanded = true;
var printcommands_expanded = true;
var jog_expanded = true;
function expand_collapse(flag, targetpin,targetdiv){
if (flag) {
document.getElementById(targetpin).innerHTML = '&#9658;';
document.getElementById(targetdiv).style.display = 'none';
return false;
} else {
document.getElementById(targetpin).innerHTML = '&#9660;';
document.getElementById(targetdiv).style.display = 'block';
return true;
}
}
var XYfeedrate=$XY_FEEDRATE$;
var Zfeedrate=$Z_FEEDRATE$;
var Efeedrate=$E_FEEDRATE$;
@ -197,6 +418,8 @@ var initialization_done = false;
var pos=0;
function displaytemp(temperature, target,item,factor){
var displaypicture = "<svg width='300' height='30' viewBox='0 0 300 30'>\n";
if (temperature.length ==0)temperature=0;
if (target.length ==0)target=0;
var description = String (temperature) + "/";
if (target>0)description += String (target);
else description += "Off ";
@ -336,8 +559,9 @@ initialization_done=true;}
document.getElementById("currentspeed").innerHTML=jsonresponse.speed + "%";
document.getElementById("currentflow").innerHTML=jsonresponse.flow + "%";
}
var canrefresh = true;
function getstatus(){
if (canrefresh){
var xmlhttp = new XMLHttpRequest();
var url = "http://$WEB_ADDRESS$/STATUS";
xmlhttp.onreadystatechange = function() {
@ -348,66 +572,210 @@ dispatchstatus(jsonresponse);}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function printfile(){
var filename = document.getElementById("sdfilelist").value;
if (filename.length>0){
Sendcommand("M23 " + filename);
delay(100);
Sendcommand("M24");}
}
var retry = 0;
function refreshfilelist(jsonresponse){
var list2display="<table><tr><td><select class=\"form-control\" id=\"sdfilelist\">";
var content="";
var i;
if (jsonresponse.status != "Ok"){
delay(1000);
retry = retry +1;
if (retry < 6) getSDfiles();
return;
}
retry = 0;
for (i = 0; i < jsonresponse.file.length; i++){
content =jsonresponse.file[i].entry;
var tcontent=content.split(" ");
if ((tcontent.length==2) || (tcontent.length==1 && tcontent[0].indexOf("/")==-1)){
list2display+="<OPTION value=\"";
list2display+=tcontent[0];
list2display+="\">";
list2display+=tcontent[0] ;
list2display+="</OPTION>";}
var currentpath = "/";
function navbar(){
var content="<table><tr>";
var tlist = currentpath.split("/");
var path="/";
var nb = 1;
content+="<td class='btnimg' onclick=\"currentpath='/'; refreshSDfiles();\">/</td>";
while (nb < (tlist.length-1))
{
path+=tlist[nb] + "/";
content+="<td class='btnimg' onclick=\"currentpath='"+path+"'; SendFileCommand('list','all');\">"+tlist[nb] +"</td><td>/</td>";
nb++;
}
content+="</tr></table>";
return content;
}
list2display+="</select>";
if ( jsonresponse.file.length>0){
list2display+="</td><td>&#8667;</td><td>";
list2display+="<div class=\"btnimg\" Onclick=\"printfile();\" ><svg width=\"40\" height=\"40\">";
list2display+="<rect width=\"40\" height=\"40\" style=\"fill:black;\"/>";
list2display+="<rect x=\"3\" y=\"3\" rx=\"5\" ry=\"5\" width=\"34\" height=\"34\" style=\"fill:white;\"/>";
list2display+="<line x1=\"0\" y1=\"15\" x2=\"15\" y2=\"15\" style=\"stroke:black;stroke-width:2\"/>";
list2display+="<line x1=\"25\" y1=\"15\" x2=\"40\" y2=\"15\" style=\"stroke:black;stroke-width:2\"/>";
list2display+="<polygon points=\"12,10 20,18 28,10\" style=\"fill:black;stroke-width:1\"/>";
list2display+="<polyline points=\"20,18 25,25\" style=\"stroke:black;stroke-width:1\" />";
list2display+="<text x=\"10\" y=\"35\" fill=\"black\">3D</text></svg></div>";}
list2display+="</td></tr></table>";
document.getElementById("SDLIST").innerHTML=list2display;
function print_icon(){
var content ="<svg width='24' height='24' viewBox='-10 -10 138 138'>";
content +="<rect x='20' y='0' rx='10' ry='10' width='88' height='127' style='fill:black;' />";
content +="<rect x='0' y='40' rx='10' ry='10' width='127' height='58' style='fill:black;' />";
content +="<rect x='29' y='9' rx='10' ry='10' width='70' height='109' style='fill:white;' />";
content +="<rect x='29' y='40' width='88' height='32' style='fill:black;' />";
content +="<line x1='20' y1='72' x2='20' y2='98' style='stroke:white;stroke-width:1' />";
content +="<line x1='108' y1='72' x2='108' y2='98' style='stroke:white;stroke-width:1' />";
content +="<circle cx='105' cy='56' r='7' fill='white' />";
content +="<rect x='38' y='82' width='51' height='10' style='fill:black;' />";
content +="<rect x='38' y='98' width='32' height='10' style='fill:black;' />";
content +="</svg>";
return content;
}
function trash_icon(){
var content ="<svg width='24' height='24' viewBox='0 0 128 128'>";
content +="<rect x='52' y='12' rx='6' ry='6' width='25' height='7' style='fill:red;' />";
content +="<rect x='52' y='16' width='25' height='2' style='fill:white;' />";
content +="<rect x='30' y='18' rx='6' ry='6' width='67' height='100' style='fill:red;' />";
content +="<rect x='20' y='18' rx='10' ry='10' width='87' height='14' style='fill:red;' />";
content +="<rect x='20' y='29' width='87' height='3' style='fill:white;' />";
content +="<rect x='40' y='43' rx='7' ry='7' width='7' height='63' style='fill:white;' />";
content +="<rect x='60' y='43' rx='7' ry='7' width='7' height='63' style='fill:white;' />";
content +="<rect x='80' y='43' rx='7' ry='7' width='7' height='63' style='fill:white;' /></svg>";
return content;
}
function back_icon(){
var content ="<svg width='24' height='24' viewBox='0 0 24 24'><path d='M7,3 L2,8 L7,13 L7,10 L17,10 L18,11 L18,15 L17,16 L10,16 L9,17 L9,19 L10,20 L20,20 L22,18 L22,8 L20,6 L7,6 z' stroke='black' fill='white' /></svg>";
return content;
}
function select_dir(directoryname){
currentpath+=directoryname + "/";
SendFileCommand('list','all');
}
function compareStrings(a, b) {
// case-insensitive comparison
a = a.toLowerCase();
b = b.toLowerCase();
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
var retry = 0;
var serialsdmode = true;
function refreshSDfiles(){
document.getElementById("SDLIST").innerHTML="";
Sendcommand("M20");
delay(1000);
if (serialsdmode){
Sendcommand("M20");
delay(1000);
}
retry = 0;
getSDfiles();
SendFileCommand("list","all");
}
function getSDfiles(){
function dispatchfilestatus(jsonresponse)
{
var content ="";
if (!jsonresponse.status) {
document.getElementById('filestatus').innerHTML="&nbsp;&nbsp;Status: Error!";
return;
}
if (jsonresponse.status == "processing"){
document.getElementById('filestatus').innerHTML="&nbsp;&nbsp;Status: Processing";
delay(1000);
retry = retry +1;
if (retry < 6) SendFileCommand("list","all");
else document.getElementById('filestatus').innerHTML="&nbsp;&nbsp;Status: No answer";
return;
}
if (jsonresponse.mode){
if (jsonresponse.mode == "direct") {
serialsdmode=false;
document.getElementById('iconcreatedir').style.display='block';
}
}
content ="&nbsp;&nbsp;Status: "+jsonresponse.status;
retry = 0;
if (jsonresponse.files){
if (jsonresponse.total && !serialsdmode){
content +="&nbsp;&nbsp;|&nbsp;&nbsp;Total space: "+jsonresponse.total;
content +="&nbsp;&nbsp;|&nbsp;&nbsp;Used space: "+jsonresponse.used;
content +="&nbsp;&nbsp;|&nbsp;&nbsp;Occupation: ";
content +="<meter min='0' max='100' high='90' value='"+jsonresponse.occupation +"'></meter>&nbsp;"+jsonresponse.occupation +"%";
}
}
document.getElementById('filestatus').innerHTML=content;
content ="";
if (serialsdmode)currentpath="/";
if (currentpath!="/")
{
var pos = currentpath.lastIndexOf("/",currentpath.length-2)
var previouspath = currentpath.slice(0,pos+1);
content +="<tr style='cursor:hand;' onclick=\"currentpath='"+previouspath+"'; SendFileCommand('list','all');\"><td >"+back_icon()+"</td><td colspan='4'> Up..</td></tr>";
}
if (jsonresponse.files){
jsonresponse.files.sort(function(a, b) {
return compareStrings(a.name, b.name);
});
var linenumber=1;
for (var i=0;i <jsonresponse.files.length;i++){
//first display files
if (String(jsonresponse.files[i].size) != "-1")
{
content +="<TR>";
content +="<td id='line"+linenumber+"'><svg height='24' width='24' viewBox='0 0 24 24' > <path d='M1,2 L1,21 L2,22 L16,22 L17,21 L17,6 L12,6 L12,1 L2,1 z' stroke='black' fill='white' /><line x1='12' y1='1' x2='17' y2='6' stroke='black' stroke-width='1'/>";
content +="<line x1='5' y1='10' x2='13' y2='10' stroke='black' stroke-width='1'/> <line x1='5' y1='14' x2='13' y2='14' stroke='black' stroke-width='1'/> <line x1='5' y1='18' x2='13' y2='18' stroke='black' stroke-width='1'/></svg></td>";
if (serialsdmode) content +="<TD>";
else content +="<TD class='btnimg' style=\"padding:0px;\"><a href=\"/SD"+jsonresponse.path+jsonresponse.files[i].name+"\" target=_blank><div class=\"blacklink\">";
content +=jsonresponse.files[i].name;
if (serialsdmode) content +="</TD>";
else content +="</div></a></TD>";
content +="<TD>";
content +=jsonresponse.files[i].size;
content +="</TD><TD width='0%'><div class=\"btnimg\" onclick=\"Delete('"+jsonresponse.files[i].name+"','line"+linenumber+"')\">";
content +=trash_icon();
content +="</div></TD><td><div class=\"btnimg\" onclick=\"if(confirm('Print "+jsonresponse.files[i].name+"?'))printfile('"+jsonresponse.files[i].name+"')\">";
content +=print_icon();
content +="</div></td><td></td></TR>";
linenumber++;
}
}
//then display directories
for (var i=0;i <jsonresponse.files.length;i++){
if (String(jsonresponse.files[i].size) == "-1")
{
content +="<TR>";
content+="<td id='line"+linenumber+"'><svg height='24' width='24' viewBox='0 0 24 24' ><path d='M19,11 L19,8 L18,7 L8,7 L8,5 L7,4 L2,4 L1,5 L1,22 L19,22 L20,21 L23,11 L5,11 L2,21 L1,22' stroke='black' fill='white' /></svg></td>";
if (serialsdmode) content +="<TD>";
else content +="<TD class='btnimg blacklink' style='padding:10px 15px;' onclick=\"select_dir('" + jsonresponse.files[i].name+"');\">";
content +=jsonresponse.files[i].name;
content +="</TD><TD></TD>";
if (serialsdmode) content +="<TD></TD>";
else {
content +="<TD width='0%'><div class=\"btnimg\" onclick=\"Deletedir('"+jsonresponse.files[i].name+"','line"+linenumber+"')\">";
content +=trash_icon();
content +="</div></TD>";
}
content +="<td></td><td></td></TR>";
linenumber++;
}
}
}
document.getElementById('file_list').innerHTML=content;
document.getElementById('path').innerHTML=navbar();}
function Delete(filename,icon){
if (confirm("Confirm deletion of file: " + filename)) {
document.getElementById(icon).innerHTML = "<div id=\"loader\" class=\"loader\"></div>";
if (serialsdmode)
{
Sendcommand("M30 " + filename);
refreshSDfiles();
}
else{
SendFileCommand("delete",filename);
}
}
}
function Deletedir(filename,icon){
if (confirm("Confirm deletion of directory: " + filename)){
document.getElementById(icon).innerHTML = "<div id=\"loader\" class=\"loader\"></div>";
SendFileCommand("deletedir",filename);
}
}
function Createdir(){
var filename = prompt("Please enter directory name", "");
if (filename != null) {
SendFileCommand("createdir",filename.trim());
}
}
function SendFileCommand(action,filename){
canrefresh = false;
var xmlhttp = new XMLHttpRequest();
var url = "/SDFILES";
var url = "/SDFILES?action="+action;
url += "&filename="+encodeURI(filename);
url += "&path="+encodeURI(currentpath);
document.getElementById('loader').style.visibility="visible";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var jsonresponse = JSON.parse(xmlhttp.responseText);
refreshfilelist(jsonresponse);}
dispatchfilestatus(jsonresponse);document.getElementById('loader').style.visibility="hidden";
canrefresh = true;}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
@ -416,12 +784,14 @@ xmlhttp.send();
function Sendfile(){
var files = document.getElementById('file-select').files;
if (files.length==0)return;
canrefresh = false;
document.getElementById('upload-button').value = "Uploading...";
document.getElementById('prg').style.visibility = "visible";
var formData = new FormData();
formData.append('path', currentpath);
for (var i = 0; i < files.length; i++) {
var file = files[i];
formData.append('myfiles[]', file, "/"+file.name);}
formData.append('myfiles[]', file, currentpath+file.name);}
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('POST', '/SDFILES', true);
//progress upload event
@ -442,12 +812,29 @@ document.getElementById('upload-button').value = 'Upload';
document.getElementById('prg').style.visibility = "hidden";
document.getElementById('file-select').value="";
var jsonresponse = JSON.parse(xmlhttp.responseText);
refreshfilelist(jsonresponse);
dispatchfilestatus(jsonresponse);
canrefresh = true;
} else alert('An error occurred!');
}
xmlhttp.send(formData);
}
setInterval(function(){getstatus();},$REFRESH_PAGE$);
window.onload = function() {
refreshSDfiles();
if ($REFRESH_PAGE$)setInterval(function(){getstatus();},$REFRESH_PAGE$);
}
function printfile(filename){
if (filename.length>0){
Sendcommand("M23 " + currentpath + filename);
delay(100);
Sendcommand("M24");}
}
</script>
$INCLUDE[footer.inc]$

View File

@ -8,7 +8,7 @@ $INCLUDE[css2.inc]$
<div class="panel-body">
<form method="POST">
<div class="form-group $REFRESH_PAGE_STATUS$"><label class="control-label" for="CONFIG1">Refresh page time: </label><br>
<input type="number" class="form-control" id="CONFIG1" name="REFRESH_PAGE" placeholder="Time in minutes 1~120 " value="$REFRESH_PAGE$" min="1"max="120" step="1"style="width: auto;"></div>
<input type="number" class="form-control" id="CONFIG1" name="REFRESH_PAGE" placeholder="Time in minutes 0~120, 0 = disabled " value="$REFRESH_PAGE$" min="0"max="120" step="1"style="width: auto;"></div>
<div class="form-group $XY_FEEDRATE_STATUS$"><label class="control-label" for="CONFIG2">XY axis feedrate: </label><br>
<input type="number" class="form-control" id="CONFIG2" name="XY_FEEDRATE" placeholder="1~9999 " value="$XY_FEEDRATE$" min="1"max="9999" step="1"style="width: auto;"></div>
<div class="form-group $Z_FEEDRATE_STATUS$"><label class="control-label" for="CONFIG3">Z axis feedrate: </label><br>
@ -27,7 +27,7 @@ $SUCCESS_MSG$
</div>
</div>
<div class="panel">
<div class="panel-heading">Filesystem</div>
<div class="panel-heading">Flash Filesystem</div>
<div class="panel-body">
<input type="file" id="file-select" name="myfiles[]" multiple />
<input class="btn btn-primary" type="button" id="upload-button" onclick="Sendfile();" value="Upload"/>&nbsp;&nbsp;<progress style="visibility:hidden;" name='prg' id='prg' max='100'></progress>
@ -37,7 +37,7 @@ $SUCCESS_MSG$
<div onclick="Createdir()" class="btnimg"><svg width="40" height="40" viewBox="0 0 40 40"><rect x="5" y="10" width="30" height="20" rx="2" ry="2" fill="#31b0d5" />
<rect x="20" y="5" width="15" height="15" rx="2" ry="2" fill="#31b0d5" /><text x="15" y="25" font-size="18" font-weight="800" fill="white">+</text></svg>
</div>
</td><td width="100%"><div id="path" class="info" >&nbsp</div>
</td><td><div id="loader" class="loader"></div></td><td width="100%"><div id="path" class="info" >&nbsp</div>
</td>
</tr></table>
<table class="table table-striped" style="border:1px;solid #dddddd;margin-bottom:20px;" ><thead><tr><th width='0%'>Type</th><th>Name</th><th>Size</th><th width='0%'></th><th width='100%'></th></tr></thead><tbody id="file_list"><tbody></table>
@ -83,7 +83,13 @@ function select_dir(directoryname){
currentpath+=directoryname + "/";
SendCommand('list','all');
}
function dispatchstatus(jsonresponse)
function compareStrings(a, b) {
// case-insensitive comparison
a = a.toLowerCase();
b = b.toLowerCase();
return (a < b) ? -1 : (a > b) ? 1 : 0;
}
function dispatchfilestatus(jsonresponse)
{
var content ="";
content ="&nbsp;&nbsp;Status: "+jsonresponse.status;
@ -99,6 +105,9 @@ if (currentpath!="/")
var previouspath = currentpath.slice(0,pos+1);
content +="<tr style='cursor:hand;' onclick=\"currentpath='"+previouspath+"'; SendCommand('list','all');\"><td >"+back_icon()+"</td><td colspan='4'> Up..</td></tr>";
}
jsonresponse.files.sort(function(a, b) {
return compareStrings(a.name, b.name);
});
for (var i=0;i <jsonresponse.files.length;i++){
//first display files
if (String(jsonresponse.files[i].size) != "-1")
@ -149,10 +158,12 @@ var xmlhttp = new XMLHttpRequest();
var url = "/FILES?action="+action;
url += "&filename="+encodeURI(filename);
url += "&path="+encodeURI(currentpath);
document.getElementById('loader').style.visibility="visible";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var jsonresponse = JSON.parse(xmlhttp.responseText);
dispatchstatus(jsonresponse);}
document.getElementById('loader').style.visibility="hidden";
dispatchfilestatus(jsonresponse);}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
@ -188,13 +199,16 @@ document.getElementById('upload-button').value = 'Upload';
document.getElementById('prg').style.visibility = "hidden";
document.getElementById('file-select').value="";
var jsonresponse = JSON.parse(xmlhttp.responseText);
dispatchstatus(jsonresponse);
dispatchfilestatus(jsonresponse);
} else alert('An error occurred!');
}
xmlhttp.send(formData);
}
window.onload = function() {
SendCommand('list','all');
}
</script>
$INCLUDE[footer.inc]$

View File

@ -18,7 +18,7 @@
https://github.com/esp8266/Arduino from Bootmanager
Latest version of the code and documentation can be found here :
https://github.com/luc-github/ESP8266
https://github.com/luc-github/ESP3D
Main author: luc lebosse
@ -49,7 +49,6 @@ DNSServer dnsServer;
#ifdef NETBIOS_FEATURE
#include <ESP8266NetBIOS.h>
#endif
#include <FS.h>
#define MAX_SRV_CLIENTS 1
WiFiServer * data_server;
WiFiClient serverClients[MAX_SRV_CLIENTS];
@ -57,10 +56,14 @@ WiFiClient serverClients[MAX_SRV_CLIENTS];
void setup()
{
// init:
#ifdef DEBUG_ESP3D
Serial.begin(DEFAULT_BAUD_RATE);
delay(2000);
LOG("Debug Serial set\n")
#endif
web_interface = NULL;
data_server = NULL;
WiFi.disconnect();
WiFi.mode(WIFI_OFF);
bool breset_config=false;
#ifdef RECOVERY_FEATURE
delay(8000);
@ -87,11 +90,11 @@ void setup()
breset_config=true; //cannot access to config settings=> reset settings
}
SPIFFS.begin();
//reset is requested
if(breset_config) {
//update EEPROM with default settings
Serial.begin(9600);
Serial.begin(DEFAULT_BAUD_RATE);
delay(2000);
Serial.println(F("M117 ESP EEPROM reset"));
CONFIG::reset_config();
@ -112,6 +115,7 @@ void setup()
//setup serial
Serial.begin(baud_rate);
delay(1000);
LOG("Serial Set\n");
wifi_config.baud_rate=baud_rate;
//setup wifi according settings
if (!wifi_config.Setup()) {
@ -137,7 +141,7 @@ void setup()
//start TCP/IP interface
data_server = new WiFiServer (wifi_config.idata_port);
data_server->begin();
//data_server->setNoDelay(true);
data_server->setNoDelay(true);
#endif
#ifdef MDNS_FEATURE
@ -166,7 +170,6 @@ String shost;
SSDP.setDeviceType("upnp:rootdevice");
SSDP.begin();
#endif
SPIFFS.begin();
#ifdef NETBIOS_FEATURE
NBNS.begin(shost.c_str());
#endif

File diff suppressed because it is too large Load Diff

View File

@ -49,27 +49,51 @@ public:
WEBINTERFACE_CLASS (int port = 80);
~WEBINTERFACE_CLASS();
ESP8266WebServer WebServer;
File fsUploadFile;
bool isSSIDValid(const char * ssid);
bool isPasswordValid(const char * password);
bool isLocalPasswordValid(const char * password);
bool isHostnameValid(const char * hostname);
bool isIPValid(const char * IP);
FSFILE fsUploadFile;
#ifdef TEMP_MONITORING_FEATURE
String answer4M105;
uint32_t last_temp;
#endif
#ifdef POS_MONITORING_FEATURE
String answer4M114;
#endif
#ifdef SPEED_MONITORING_FEATURE
String answer4M220;
#endif
#ifdef FLOW_MONITORING_FEATURE
String answer4M221;
#endif
STORESTRINGS_CLASS fileslist;
uint32_t last_temp;
#ifdef ERROR_MSG_FEATURE
STORESTRINGS_CLASS error_msg;
#endif
#ifdef INFO_MSG_FEATURE
STORESTRINGS_CLASS info_msg;
#endif
#ifdef STATUS_MSG_FEATURE
STORESTRINGS_CLASS status_msg;
#endif
bool restartmodule;
char * create_session_ID();
bool processTemplate(const char * filename, STORESTRINGS_CLASS & KeysList , STORESTRINGS_CLASS & ValuesList );
void GetFreeMem(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
void GeLogin(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList,level_authenticate_type auth_level);
void GetIpWeb(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
void GetMode(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
void GetPorts(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
void SetPageProp(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList,
const __FlashStringHelper *title, const __FlashStringHelper *filename);
void GetDHCPStatus(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
void ProcessAlertError(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList, String & smsg);
void ProcessAlertSuccess(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList, String & smsg);
void ProcessNoAlert(STORESTRINGS_CLASS & KeysList, STORESTRINGS_CLASS & ValuesList);
String getContentType(String filename);
level_authenticate_type is_authenticated();
bool AddAuthIP(auth_ip * item);
bool blockserial;
#ifdef AUTHENTICATION_FEATURE
level_authenticate_type ResetAuthIP(IPAddress ip,const char * sessionID);
char * create_session_ID();
#endif
uint8_t _upload_status;
private: