2
0
Эх сурвалжийг харах

Reorganize configuration UI - release

The System tab is now hidden by default and can be enabled via a toggle
under the Credits tab, similar to how NVS tab works.  A new tab was
created to hold configurations, and display configuration was added.
Sebastien 4 жил өмнө
parent
commit
889b1097cc

+ 24 - 0
components/display/display.c

@@ -396,3 +396,27 @@ const char *display_conf_get_driver_name(char * driver){
 	}
 	return NULL;
 }
+
+/****************************************************************************************
+ *
+ */
+char * display_get_supported_drivers(){
+	int total_size = 1;
+	char * supported_drivers=NULL;
+	const char * separator = "|";
+	int separator_len = strlen(separator);
+
+	for(uint8_t i=0;known_drivers[i]!=NULL && strlen(known_drivers[i])>0;i++ ){
+		total_size += strlen(known_drivers[i])+separator_len;
+	}
+	total_size+=2;
+	supported_drivers = malloc(total_size);
+	memset(supported_drivers,0x00,total_size);
+	strcat(supported_drivers,"<");
+	for(uint8_t i=0;known_drivers[i]!=NULL && strlen(known_drivers[i])>0;i++ ){
+		supported_drivers = strcat(supported_drivers,known_drivers[i]);
+		supported_drivers = strcat(supported_drivers,separator);
+	}
+	strcat(supported_drivers,">");
+	return supported_drivers;
+}

+ 2 - 0
components/display/display.h

@@ -10,6 +10,7 @@
 
 #include "gds.h"
 
+
 /* 
  The displayer is not thread-safe and the caller must ensure use its own 
  mutexes if it wants something better. Especially, text() line() and draw()
@@ -38,3 +39,4 @@ void displayer_scroll(char *string, int speed, int pause);
 void displayer_control(enum displayer_cmd_e cmd, ...);
 void displayer_metadata(char *artist, char *album, char *title);
 void displayer_timer(enum displayer_time_e mode, int elapsed, int duration);
+char * display_get_supported_drivers();

+ 33 - 11
components/platform_console/cmd_i2ctools.c

@@ -82,15 +82,17 @@ static struct {
 } i2ccheck_args;
 
 static struct {
-	struct arg_lit *clear;
-	struct arg_lit *hflip;
-	struct arg_lit *vflip;
-	struct arg_lit *rotate;
-	struct arg_int *address;
-	struct arg_int *width;
-	struct arg_int *height;
 	struct arg_str *name;
 	struct arg_str *driver;
+	struct arg_int *width;
+	struct arg_int *height;
+	struct arg_int *address;
+	struct arg_lit *rotate;
+	struct arg_lit *hflip;
+	struct arg_lit *vflip;
+	struct arg_int *speed;
+	struct arg_int *back;
+	struct arg_lit *clear;
 	struct arg_end *end;
 } i2cdisp_args;
 
@@ -368,7 +370,7 @@ static int do_i2c_show_display(int argc, char **argv){
 
 static int do_i2c_set_display(int argc, char **argv)
 {
-	int width=0, height=0, address=60;
+	int width=0, height=0, address=60, back=-1, speed=8000000 ;
 	int result = 0;
 	char * name = NULL;
 	char * driver= NULL;
@@ -426,6 +428,7 @@ static int do_i2c_set_display(int argc, char **argv)
 		fprintf(f,"Missing parameter: --height\n");
 		nerrors ++;
 	}
+
 	/* Check "--name" option */
 	if (i2cdisp_args.name->count) {
 		name=strdup(i2cdisp_args.name->sval[0]);
@@ -436,6 +439,21 @@ static int do_i2c_set_display(int argc, char **argv)
 		driver=strdup(i2cdisp_args.driver->sval[0]);
 	}
 
+	/* Check "--speed" option */
+	if (i2cdisp_args.speed->count) {
+		speed=i2cdisp_args.speed->ival[0];
+	}
+	/* Check "--back" option */
+	if (i2cdisp_args.back->count) {
+		back=i2cdisp_args.back->ival[0];
+		if(!GPIO_IS_VALID_OUTPUT_GPIO(back)){
+			fprintf(f,"Invalid GPIO for back light: %d %s\n", back, GPIO_IS_VALID_GPIO(back)?"has input capabilities only":"is not a GPIO");
+			back=-1;
+			nerrors ++;
+		}
+	}
+
+
 	if(!name) name = strdup("I2C");
 	if(!driver) driver = strdup("SSD1306");
 
@@ -456,8 +474,8 @@ static int do_i2c_set_display(int argc, char **argv)
 	bool rotate = i2cdisp_args.rotate->count>0;
 
 	if(nerrors==0){
-		snprintf(config_string, sizeof(config_string),"%s:width=%i,height=%i,address=%i,driver=%s%s%s",
-				name,width,height,address,driver,rotate || i2cdisp_args.hflip->count?",HFlip":"",rotate || i2cdisp_args.vflip->count?",VFlip":"" );
+		snprintf(config_string, sizeof(config_string),"%s:back=%i,speed=%i,width=%i,height=%i,address=%i,driver=%s%s%s",
+				name,back,speed,width,height,address,driver,rotate || i2cdisp_args.hflip->count?",HFlip":"",rotate || i2cdisp_args.vflip->count?",VFlip":"" );
 		fprintf(f,"Updating display configuration string configuration to :\n"
 				"display_config = \"%s\"",config_string );
 		result = config_set_value(NVS_TYPE_STR, "display_config", config_string)!=ESP_OK;
@@ -897,15 +915,19 @@ cJSON * i2c_set_display_cb(){
 }
 
 static void register_i2c_set_display(){
+	char * supported_drivers = display_get_supported_drivers();
+
 	i2cdisp_args.address = arg_int0("a", "address", "<n>", "Set the device address, default 60");
 	i2cdisp_args.width = arg_int0("w", "width", "<n>", "Set the display width");
 	i2cdisp_args.height = arg_int0("h", "height", "<n>", "Set the display height");
 	i2cdisp_args.name = arg_str0("t", "type", "<I2C|SPI>", "Display type, I2C or SPI. Default I2C");
-	i2cdisp_args.driver = arg_str0("d", "driver", "<string>", "Set the display driver name. Default SSD1306");
+	i2cdisp_args.driver = arg_str0("d", "driver", supported_drivers?supported_drivers:"<string>", "Set the display driver name. Default SSD1306");
 	i2cdisp_args.clear = arg_lit0(NULL, "clear", "clear configuration and return");
 	i2cdisp_args.hflip = arg_lit0(NULL, "hf", "Flip picture horizontally");
 	i2cdisp_args.vflip = arg_lit0(NULL, "vf", "Flip picture vertically");
 	i2cdisp_args.rotate = arg_lit0("r", "rotate", "Rotate the picture 180 deg");
+	i2cdisp_args.back = arg_int0("b", "back", "<n>","Backlight GPIO (if applicable)");
+	i2cdisp_args.speed = arg_int0("s", "speed", "<n>","Default speed is 8000000 (8MHz) but SPI can work up to 26MHz or even 40MHz");
 	i2cdisp_args.end = arg_end(8);
 	const esp_console_cmd_t i2c_set_display= {
 	 		.command = "setdisplay",

+ 105 - 42
components/wifi-manager/code.js

@@ -63,6 +63,7 @@ var checkStatusInterval = null;
 var StatusIntervalActive = false;
 var RefreshAPIIntervalActive = false;
 var LastRecoveryState=null;
+var LastCommandsState=null;
 var output = '';
 
 function stopCheckStatusInterval(){
@@ -169,6 +170,7 @@ function getConfigJson(slimMode){
 
 	}
 	
+	
 	function onChooseFile(event, onLoadFileHandler) {
 	    if (typeof window.FileReader !== 'function')
 	        throw ("The file API isn't supported on this browser.");
@@ -186,7 +188,9 @@ function getConfigJson(slimMode){
 	    input.value="";
 	}
 	$(document).ready(function(){
-		$("#load-nvs").click(function () {
+        $("input#show-commands")[0].checked=LastCommandsState==1?true:false;
+        $('a[href^="#tab-commands"]').hide();
+        $("#load-nvs").click(function () {
 		    $("#nvsfilename").trigger('click');
 		});
     $("#wifi-status").on("click", ".ape", function() {
@@ -296,6 +300,17 @@ function getConfigJson(slimMode){
         $( "#connect-details" ).slideUp( "fast", function() {});
         $( "#wifi" ).slideDown( "fast", function() {})
     });
+    
+    $("input#show-commands").on("click", function() {
+        this.checked=this.checked?1:0;
+        if(this.checked){
+            $('a[href^="#tab-commands"]').show();
+            LastCommandsState = 1;
+        } else {
+        	LastCommandsState = 0;
+            $('a[href^="#tab-commands"]').hide();
+        }
+    });
 
     $("input#show-nvs").on("click", function() {
         this.checked=this.checked?1:0;
@@ -1006,7 +1021,8 @@ function checkStatus(){
         blockAjax = false;
     });
 }
-function runCommand(button) {
+
+function runCommand(button,reboot) {
 	pardiv = button.parentNode.parentNode;
 	fields=document.getElementById("flds-"+button.value);
 	cmdstring=button.value+' ';
@@ -1055,7 +1071,32 @@ function runCommand(button) {
 			console.log(xhr.status);
 			console.log(thrownError);
 			if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR');
-		}
+			
+		},
+        complete: function(response) {
+            //var returnedResponse = JSON.parse(response.responseText);
+            console.log(response.responseText);
+            if(reboot){
+            	showMessage('Applying. Please wait for the ESP32 to reboot', 'MESSAGING_WARNING');
+	            console.log('now triggering reboot');
+	            $.ajax({
+	                url: '/reboot.json',
+	                dataType: 'text',
+	                method: 'POST',
+	                cache: false,
+	                contentType: 'application/json; charset=utf-8',
+	                data: JSON.stringify({ 'timestamp': Date.now()}),
+	                error: function (xhr, ajaxOptions, thrownError) {
+	                    console.log(xhr.status);
+	                    console.log(thrownError);
+	                    if (thrownError != '') showMessage(thrownError, 'MESSAGING_ERROR');
+	                },
+	                complete: function(response) {
+	                	console.log('reboot call completed');
+	                }
+	            });
+            }
+        }
 	});
 	enableStatusTimer = true;
 }
@@ -1064,60 +1105,82 @@ function runCommand(button) {
 function getCommands() {
     $.getJSON("/commands.json", function(data) {
         console.log(data);
-		innerhtml='';
+		var advancedtabhtml='';
 		
 		data.commands.forEach(function(command) {
-			innerhtml+='<tr><td>';
-			innerhtml+=escapeHTML(command.help).replace(/\n/g, '<br />')+'<br>';
+			isConfig=($('#'+command.name+'-list').length>0);
+			innerhtml='';
+			innerhtml+='<tr><td>'+(isConfig?'<h1>':'');
+			innerhtml+=escapeHTML(command.help).replace(/\n/g, '<br />')+(isConfig?'</h1>':'<br>');
 			innerhtml+='<div >';
 			if(command.hasOwnProperty("argtable")){
 			innerhtml+='<table class="table table-hover" id="flds-'+command.name+'"><tbody>';
 				command.argtable.forEach(function (arg){
-					innerhtml+="<tr>";
+					placeholder=arg?.datatype || '';
 					ctrlname=command.name+'-'+arg.longopts;
-					innerhtml+='<td><label for="'+ctrlname+'">'+ arg.glossary+'</label></td>';
-					ctrltype="text";
-					if(arg.checkbox){
-						ctrltype="checkbox";
-					}
 					curvalue=data.values?.[command.name]?.[arg.longopts] || '';
-					placeholder=arg?.datatype || '';
-					innerhtml+='<td><input type="'+ctrltype+'" id="'+ctrlname+'" name="'+ctrlname+'" placeholder="'+placeholder+'" hasvalue="'+arg.hasvalue+'"   ';
-					
-
-					innerhtml+='datatype="'+arg.datatype+'" ';
-					innerhtml+='hasvalue='+arg.hasvalue+' ';
-					innerhtml+='longopts="'+arg.longopts+'" ';
-					innerhtml+='shortopts="'+arg.shortopts+'" ';
-					innerhtml+='checkbox='+arg.checkbox+' ';
-
-					
-					
-					if(arg.checkbox){
-						if(curvalue=data.values?.[command.name]?.[arg.longopts] ){
-							innerhtml+='checked=true ';							
-						}
-						else{
-							innerhtml+='checked=false ';							
-						}
-							
-
-						innerhtml+='></input></td>';
+					innerhtml+="<tr>";
+					var attributes ='datatype="'+arg.datatype+'" ';
+					attributes+='hasvalue='+arg.hasvalue+' ';
+					attributes+='longopts="'+arg.longopts+'" ';
+					attributes+='shortopts="'+arg.shortopts+'" ';
+					attributes+='checkbox='+arg.checkbox+' ';
+
+
+					if(placeholder.includes('|')){
+						placeholder = placeholder.replace('<','').replace('>','');
+						innerhtml+='<td><select name="'+ctrlname+'" ';
+						innerhtml+=attributes;
+						innerhtml+=' class="custom-select">';
+						innerhtml+='<option '+(curvalue.length>0?'value':'selected')+'>'+arg.glossary+'</option>'
+						placeholder.split('|').forEach(function(choice){
+							innerhtml+='<option '+(curvalue.length>0&&curvalue==choice?'selected':'value')+'="'+choice+'">'+choice+'</option>';
+						});
+						innerhtml+='</select></td>';
 					}
 					else {
-						innerhtml+='value="'+curvalue+'" ';
-						innerhtml+='></input></td>'+ curvalue.length>0?'<td>last: '+curvalue+'</td>':'';
+						ctrltype="text";
+						if(arg.checkbox){
+							ctrltype="checkbox";
+						}
+						
+						innerhtml+='<td><label for="'+ctrlname+'">'+ arg.glossary+'</label></td>';
+						innerhtml+='<td><input type="'+ctrltype+'" id="'+ctrlname+'" name="'+ctrlname+'" placeholder="'+placeholder+'" hasvalue="'+arg.hasvalue+'"   ';
+						innerhtml+=attributes;
+						if(arg.checkbox){
+							if(data.values?.[command.name]?.[arg.longopts] ){
+								innerhtml+='checked=true ';							
+							}
+							else{
+								innerhtml+='checked=false ';							
+							}
+								
+	
+							innerhtml+='></input></td>';
+						}
+						else {
+							innerhtml+='value="'+curvalue+'" ';
+							innerhtml+='></input></td>'+ curvalue.length>0?'<td>last: '+curvalue+'</td>':'';
+						}
 					}
-					
 					innerhtml+="</tr>";
 				});
-			innerhtml+='</tbody></table><br>';
+			innerhtml+='</tbody></table>';
 			
 			}
-			innerhtml+='<div class="buttons"><input id="btn-'+ command.name + '" type="button" class="btn btn-danger btn-sm" value="'+command.name+'" onclick="runCommand(this);"></div></div><td></tr>';
-
-            });		
-		$("#commands-list").append(innerhtml);
+			if(isConfig){
+				innerhtml+='<div class="buttons"><input id="btn-'+ command.name + '" type="button" class="btn btn-success" value="Save" onclick="runCommand(this,false);">';
+				innerhtml+='<input id="btn-'+ command.name + '-apply" type="button" class="btn btn-success" value="Apply" onclick="runCommand(this,true);"></div></div><td></tr>';
+				$('#'+command.name+'-list').append(innerhtml);
+			}
+			else {
+				advancedtabhtml+='<br>'+innerhtml;
+				advancedtabhtml+='<div class="buttons"><input id="btn-'+ command.name + '" type="button" class="btn btn-danger btn-sm" value="'+command.name+'" onclick="runCommand(this);"></div></div><td></tr>';
+			}
+			
+           });
+		$("#commands-list").append(advancedtabhtml);
+		
 		
     })
     .fail(function(xhr, ajaxOptions, thrownError) {

+ 15 - 2
components/wifi-manager/index.html

@@ -67,11 +67,14 @@
             <li class="nav-item">
                 <a class="nav-link" data-toggle="tab" href="#tab-firmware">Firmware</a>
             </li>
+            <li class="nav-item">
+                <a class="nav-link" data-toggle="tab" href="#tab-setdisplay">Display</a>
+            </li>
             <li class="nav-item">
                 <a class="nav-link" data-toggle="tab" href="#tab-syslog">Syslog</a>
             </li>
             <li class="nav-item">
-                <a class="nav-link" data-toggle="tab" href="#tab-commands">System</a>
+                <a class="nav-link" data-toggle="tab" href="#tab-commands">Advanced</a>
             </li>			
             <li class="nav-item">
                 <a class="nav-link" data-toggle="tab" href="#tab-nvs">NVS editor</a>
@@ -195,6 +198,12 @@
                         </div>
                     </div>
                 </div> <!-- wifi -->
+     			<div class="tab-pane fade" id="tab-setdisplay">
+     				<table class="table table-hover" id="setdisplay-table">
+					<tbody id="setdisplay-list">
+                    </tbody>
+                    </table>
+                </div> <!-- display -->
 
                 <div class="tab-pane fade" id="tab-audio">
                     <div id="audioout">
@@ -304,7 +313,6 @@
                     </tbody>
                     </table>
                 </div> <!-- system -->
-
                 <div class="tab-pane fade" id="tab-syslog">
                     <table class="table table-hover">
                         <thead>
@@ -366,6 +374,11 @@
 	                      <input type="checkbox" class="custom-control-input" id="show-nvs" checked="checked">
 	                      <label class="custom-control-label" for="show-nvs"></label>
 	                </div>
+	                <h2>Show Advanced Commands</h2>
+	                <div class="custom-control custom-switch">
+	                      <input type="checkbox" class="custom-control-input" id="show-commands" checked="checked">
+	                      <label class="custom-control-label" for="show-commands"></label>
+	                </div>
                 </div> <!-- credits -->
             </div>
             <footer class="footer"><span id="foot-fw"></span><span id="foot-wifi"></span></footer>