@ -20,54 +20,108 @@ 
			
		
	
		
		
			
				
					        < div  id = "wrapper" >         < div  id = "wrapper" >  
			
		
	
		
		
			
				
					            < div  id = "content" >             < div  id = "content" >  
			
		
	
		
		
			
				
					                < form  method = "post"  action = "/save" >                 < form  method = "post"  action = "/save" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < button  type = "button"  class = "s_collapsible mt-4" > System Config< / button >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    < div  class = "s_content" >  
			
		
	
		
		
			
				
					                    < fieldset  class = "mb-2" >  
			
		
	
		
		
			
				
					                        < legend  class = "des" > Device Host Name< / legend >                         < legend  class = "des" > Device Host Name< / legend >  
			
		
	
		
		
			
				
					
					                        < label  for = "device" > Device Name< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  name = "device"  class = "text" / >                             < div  class = "col-12 col-sm-3" > Device Name< / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "device" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > Dark Mode< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "darkMode" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >  
			
		
	
		
		
			
				
					                    < fieldset  class = "mb-4" >  
			
		
	
		
		
			
				
					                        < legend  class = "des" > System Config< / legend >  
			
		
	
		
		
			
				
					                        < p  class = "des" > Pinout< / p >  
			
		
	
		
		
			
				
					                        < div  id = "pinout" > < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        < p  class = "des" > Radio (NRF24L01+)< / p >  
			
		
	
		
		
			
				
					                        < div  id = "rf24" > < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        < p  class = "des" > Serial Console< / p >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > print inverter data< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "serEn" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > Serial Debug< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "serDbg" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-3 my-2" > Interval [s]< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "serIntvl"  pattern = "[0-9]+"  title = "Invalid input" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > Network< / button >                     < button  type = "button"  class = "s_collapsible" > Network< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                        < fieldset >                         < fieldset  class = "mb-2"  >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            < legend  class = "des" > WiFi< / legend >                             < legend  class = "des" > WiFi< / legend >  
			
		
	
		
		
			
				
					                            < p > Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.< / p >                             < p > Enter the credentials to your prefered WiFi station. After rebooting the device tries to connect with this information.< / p >  
			
		
	
		
		
			
				
					
					                            < label  for = "scanbtn" > Search Networks< / label > 
 
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "button"  name = "scanbtn"  id = "scanbtn"  class = "btn"  value = "scan"  onclick = "scan()" / > < br / >                             < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "networks" > Avail Networks< / label >                                 < div  class = "col-12 col-sm-3 my-2" > Search Networks< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < select  name = "networks"  id = "networks"  onChange = "selNet()" >                                 < div  class = "col-12 col-sm-9" > < input  type = "button"  name = "scanbtn"  id = "scanbtn"  class = "btn"  value = "scan"  onclick = "scan()" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                                < option  value = "-1"  selected  disabled  hidden > not scanned< / option >                             < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < / select > 
 
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "ssid" > SSID< / label >                             < div  class = "row mb-2 mb-sm-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ssid"  class = "text" / >                                 < div  class = "col-12 col-sm-3 my-2" > Avail Networks< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "pwd" > Password< / label >                                 < div  class = "col-12 col-sm-9" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "password"  class = "text"  name = "pwd"  value = "{PWD}" / >                                     < select  name = "networks"  id = "networks"  onChange = "selNet()" >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                                        < option  value = "-1"  selected  disabled  hidden > not scanned< / option >  
			
		
	
		
		
			
				
					                                    < / select >  
			
		
	
		
		
			
				
					                                < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                            < div  class = "row mb-2 mb-sm-3" >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-3 my-2" > SSID< / div >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ssid" / > < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                            < div  class = "row mb-2 mb-sm-3" >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-3 my-2" > Password< / div >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-9" > < input  type = "password"  name = "pwd"  value = "{PWD}" / > < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                        < / fieldset >                         < / fieldset >  
			
		
	
		
		
			
				
					
					                        < fieldset >                         < fieldset  class = "mb-4"  >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            < legend  class = "des" > Static IP (optional)< / legend >                             < legend  class = "des" > Static IP (optional)< / legend >  
			
		
	
		
		
			
				
					                            < p >                             < p >  
			
		
	
		
		
			
				
					                                Leave fields blank for DHCP< br / >                                 Leave fields blank for DHCP< br / >  
			
		
	
		
		
			
				
					
					                                The following fields are parsed in this format: 192.168.1.1                                The following fields are parsed in this format: 192.168.4 .1 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            < / p >                             < / p >  
			
		
	
		
		
			
				
					
					                            < label  for = "ipAddr" > IP Address< / label >                             < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ipAddr"  class = "text"  maxlength = "15"  / >                                 < div  class = "col-12 col-sm-3 my-2" > IP Address< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "ipMask" > Submask< / label >                                 < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ipAddr"  maxlength = "15"  / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ipMask"  class = "text"  maxlength = "15"  / >                             < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "ipDns1" > DNS 1< / label >                             < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ipDns1"  class = "text"  maxlength = "15"  / >                                 < div  class = "col-12 col-sm-3 my-2" > Submask< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "ipDns2" > DNS 2< / label >                                 < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ipMask"  maxlength = "15"  / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ipDns2"  class = "text"  maxlength = "15"  / >                             < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "ipGateway" > Gateway< / label >                             < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "text"  name = "ipGateway"  class = "text"  maxlength = "15"  / >                                 < div  class = "col-12 col-sm-3 my-2" > DNS 1< / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ipDns1"  maxlength = "15"  / > < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                            < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-3 my-2" > DNS 2< / div >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ipDns2"  maxlength = "15"  / > < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                            < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-3 my-2" > Gateway< / div >  
			
		
	
		
		
			
				
					                                < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ipGateway"  maxlength = "15"  / > < / div >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                        < / fieldset >                         < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > Protection< / button >                     < button  type = "button"  class = "s_collapsible" > Protection< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                        < fieldset >                         < fieldset  class = "mb-4" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < legend  class = "des" > Protection< / legend >                             < legend  class = "des mx-2" > Protection< / legend >  
			
				
				
			
		
	
		
		
			
				
					
					                            < label  for = "adminpwd" > Admin Password< / label >                             < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "password"  name = "adminpwd"  class = "text"  value = "{PWD}" / >                                 < div  class = "col-12 col-sm-3 mb-2 mt-2" > Admin Password< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                            < input  type = "hidden"  name = "disclaimer"  value = "false"  id = "disclaimer" >                                 < div  class = "col-12 col-sm-9" > < input  type = "password"  name = "adminpwd"  value = "{PWD}" / > < / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                            < p > Select pages which should be protected by password< / p >                             < p > Select pages which should be protected by password< / p >  
			
		
	
		
		
			
				
					                            < div  id = "prot_mask" > < / div >                             < div  id = "prot_mask" > < / div >  
			
		
	
		
		
			
				
					                        < / fieldset >                         < / fieldset >  
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -75,140 +129,178 @@ 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > Inverter< / button >                     < button  type = "button"  class = "s_collapsible" > Inverter< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < fieldset  class = "mb-4"  >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    < legend  class = "des" > Inverter< / legend >                     < legend  class = "des" > Inverter< / legend >  
			
		
	
		
		
			
				
					
					                        < div  id = "inverter" > < / div > < br / >                         < div  id = "inverter" > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "button"  id = "btnAdd"  class = "btn"  value = "Add Inverter" / >                         < div  class = "row mb-2" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < p  class = "subdes" > General< / p >                             < div  class = "col-12 col-sm-3" > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "invInterval" > Interval [s]< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "button"  id = "btnAdd"  class = "btn"  value = "Add Inverter" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "invInterval"  pattern = "[0-9]+"  title = "Invalid input" / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "invRetry" > Max retries per Payload< / label >                         < div  class = "row mb-2" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "invRetry" / >                             < div  class = "col-12 col-sm-3" > < p  class = "subdes" > General< / p > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					
                            < div  class = "col-12 col-sm-9" > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					
                        < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "invRstMid" > Reset values and YieldDay at midnight< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "invRstMid" / > < br / >                             < div  class = "col-12 col-sm-3 my-2" > Interval [s]< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "invRstComStop" > Reset values when inverter polling stops at sunset< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "invInterval"  pattern = "[0-9]+"  title = "Invalid input" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "invRstComStop" / > < br / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "invRstNotAvail" > Reset values when inverter status is 'not available'< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "invRstNotAvail" / > < br / >                             < div  class = "col-12 col-sm-3 my-2" > Max retries per Payload< / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "invRetry" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3 mb-2" > Reset values and YieldDay at midnight< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "invRstMid" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3 mb-2" > Reset values when inverter polling stops at sunset< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "invRstComStop" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > Reset values when inverter status is 'not available'< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "invRstNotAvail" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > NTP Server< / button >                     < button  type = "button"  class = "s_collapsible" > NTP Server< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < fieldset  class = "mb-4" >  
			
				
				
			
		
	
		
		
			
				
					
					                    < legend  class = "des" > NTP Server< / legend >                         < legend  class = "des" > NTP Server< / legend >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "ntpAddr" > NTP Server / IP< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "ntpAddr" / >                             < div  class = "col-12 col-sm-3 my-2" > NTP Server / IP< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "ntpPort" > NTP Port< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ntpAddr" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "ntpPort" / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "ntpBtn" > set system time< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "button"  name = "ntpBtn"  id = "ntpBtn"  class = "btn"  value = "from browser"  onclick = "setTime()" / >                             < div  class = "col-12 col-sm-3 my-2" > NTP Port< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "button"  name = "ntpSync"  id = "ntpSync"  class = "btn"  value = "sync NTP"  onclick = "syncTime()" / >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "ntpPort" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < span  id = "apiResultNtp" > < / span >                         < / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-3 my-2" > set system time< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" >  
			
		
	
		
		
			
				
					                                < input  type = "button"  name = "ntpBtn"  id = "ntpBtn"  class = "btn"  value = "from browser"  onclick = "setTime()" / >  
			
		
	
		
		
			
				
					                                < input  type = "button"  name = "ntpSync"  id = "ntpSync"  class = "btn"  value = "sync NTP"  onclick = "syncTime()" / >  
			
		
	
		
		
			
				
					                                < span  id = "apiResultNtp" > < / span >  
			
		
	
		
		
			
				
					                            < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > Sunrise &  Sunset< / button >                     < button  type = "button"  class = "s_collapsible" > Sunrise &  Sunset< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < fieldset  class = "mb-4" >  
			
				
				
			
		
	
		
		
			
				
					
					                    < legend  class = "des" > Sunrise &  Sunset< / legend >                         < legend  class = "des" > Sunrise &  Sunset< / legend >  
			
				
				
			
		
	
		
		
			
				
					
					                        < p >                         < p > Use a decimal separator: '.' (dot) for Latitude and Longitude< / p >  
			
				
				
			
		
	
		
		
			
				
					
					                            Use a decimal separator: '.' (dot) for Latitude and Longitude
 
			
				
				
			
		
	
		
		
			
				
					
					                        < / p >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "sunLat" > Latitude (decimal)< / label >                             < div  class = "col-12 col-sm-3 my-2" > Latitude (decimal)< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "sunLat" / >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "sunLat" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "sunLon" > Longitude (decimal)< / label >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "sunLon" / >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "sunOffs" > Offset (pre sunrise, post sunset)< / label >                             < div  class = "col-12 col-sm-3 my-2" > Longitude (decimal)< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < select  name = "sunOffs" > < / select >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "sunLon" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < br >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "sunDisNightCom" > Stop polling inverters during night< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "sunDisNightCom" / > < br / >                             < div  class = "col-12 col-sm-3 my-2" > Offset (pre sunrise, post sunset)< / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < select  name = "sunOffs" > < / select > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > Stop polling inverters during night< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "sunDisNightCom" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > MQTT< / button >                     < button  type = "button"  class = "s_collapsible" > MQTT< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < fieldset  class = "mb-4" >  
			
				
				
			
		
	
		
		
			
				
					
					                    < legend  class = "des" > MQTT< / legend >                         < legend  class = "des" > MQTT< / legend >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttAddr" > Broker / Server IP< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "mqttAddr" / >                             < div  class = "col-12 col-sm-3 my-2" > Broker / Server IP< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttPort" > Port< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "mqttAddr" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "mqttPort" / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttUser" > Username (optional)< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "mqttUser" / >                             < div  class = "col-12 col-sm-3 my-2" > Port< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttPwd" > Password (optional)< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "mqttPort" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "password"  class = "text"  name = "mqttPwd" / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttTopic" > Topic< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "mqttTopic"  pattern = "[A-Za-z0-9./#$%&=+_-]+"  title = "Invalid input"  / >                             < div  class = "col-12 col-sm-3 my-2" > Username (optional)< / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "mqttUser" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-3 my-2" > Password (optional)< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "password"  name = "mqttPwd" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-3 my-2" > Topic< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "mqttTopic"  pattern = "[A-Za-z0-9./#$%&=+_-]+"  title = "Invalid input"  / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < p  class = "des" > Send Inverter data in a fixed interval, even if there is no change. A value of '0' disables the fixed interval. The data is published once it was successfully received from inverter. (default: 0)< / p >                         < p  class = "des" > Send Inverter data in a fixed interval, even if there is no change. A value of '0' disables the fixed interval. The data is published once it was successfully received from inverter. (default: 0)< / p >  
			
		
	
		
		
			
				
					
					                        < label  for = "mqttIntvl" > Interval [s]< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "text"  class = "text"  name = "mqttInterval"  pattern = "[0-9]+"  title = "Invalid input"  / >                             < div  class = "col-12 col-sm-3 my-2" > Interval [s]< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "mqttBtn" > Discovery Config (homeassistant)< / label >                             < div  class = "col-12 col-sm-9" > < input  type = "text"  name = "mqttInterval"  pattern = "[0-9]+"  title = "Invalid input"  / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "button"  name = "mqttDiscovery"  id = "mqttDiscovery"  class = "btn"  value = "send"  onclick = "sendDiscoveryConfig()" / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < span  id = "apiResultMqtt" > < / span >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                    < / fieldset >                             < div  class = "col-12 col-sm-3 my-2" > Discovery Config (homeassistant)< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                    < / div >                             < div  class = "col-12 col-sm-9" >  
			
				
				
			
		
	
		
		
			
				
					
					
                                < input  type = "button"  name = "mqttDiscovery"  id = "mqttDiscovery"  class = "btn"  value = "send"  onclick = "sendDiscoveryConfig()" / >  
			
				
				
			
		
	
		
		
			
				
					
					                    < button  type = "button"  class = "s_collapsible" > System Config< / button >                                 < span  id = "apiResultMqtt" > < / span >  
			
				
				
			
		
	
		
		
			
				
					
					                    < div  class = "s_content" >                             < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                    < fieldset >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					                        < legend  class = "des" > System Config< / legend >  
			
		
	
		
		
			
				
					                        < p  class = "des" > Pinout< / p >  
			
		
	
		
		
			
				
					                        < div  id = "pinout" > < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        < p  class = "des" > Radio (NRF24L01+)< / p >  
			
		
	
		
		
			
				
					                        < div  id = "rf24" > < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        < p  class = "des" > Serial Console< / p >  
			
		
	
		
		
			
				
					                        < label  for = "serEn" > print inverter data< / label >  
			
		
	
		
		
			
				
					                        < input  type = "checkbox"  class = "cb"  name = "serEn" / > < br / >  
			
		
	
		
		
			
				
					                        < label  for = "serDbg" > Serial Debug< / label >  
			
		
	
		
		
			
				
					                        < input  type = "checkbox"  class = "cb"  name = "serDbg" / > < br / >  
			
		
	
		
		
			
				
					                        < label  for = "serIntvl" > Interval [s]< / label >  
			
		
	
		
		
			
				
					                        < input  type = "text"  class = "text"  name = "serIntvl"  pattern = "[0-9]+"  title = "Invalid input" / >  
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < button  type = "button"  class = "s_collapsible" > Display Config< / button >                     < button  type = "button"  class = "s_collapsible" > Display Config< / button >  
			
		
	
		
		
			
				
					                    < div  class = "s_content" >                     < div  class = "s_content" >  
			
		
	
		
		
			
				
					
					                    < fieldset >                     < fieldset  class = "mb-4" >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                        < legend  class = "des" > Display Config< / legend >                         < legend  class = "des" > Display Config< / legend >  
			
		
	
		
		
			
				
					                        < div  id = "dispType" > < / div >                         < div  id = "dispType" > < / div >  
			
		
	
		
		
			
				
					
					                        < label  for = "logoEn" > Show Logo< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "logoEn" / > < br / >                             < div  class = "col-8 col-sm-3" > Show Logo< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "dispPwr" > Turn off while inverters are offline< / label >                             < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "logoEn" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "dispPwr" / > < br / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "dispPxSh" > Enable pixel shifting< / label >                         < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "dispPxSh" / > < br / >                             < div  class = "col-8 col-sm-3" > Turn off while inverters are offline< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "disp180" > Rotate 180 degree< / label >                             < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "dispPwr" / > < / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "disp180" / > < br / >                         < / div >  
			
				
				
			
		
	
		
		
			
				
					
					
                        < div  class = "row mb-3" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "dispCont" > Contrast< / label >                             < div  class = "col-8 col-sm-3" > Enable pixel shifting< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < select  name = "dispCont"  id = "contrast" > < / select >                             < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "dispPxSh" / > < / div >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-8 col-sm-3" > Rotate 180 degree< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-4 col-sm-9" > < input  type = "checkbox"  name = "disp180" / > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < div  class = "row mb-3" >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-3 my-2" > Contrast< / div >  
			
		
	
		
		
			
				
					                            < div  class = "col-12 col-sm-9" > < select  name = "dispCont"  id = "contrast" > < / select > < / div >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                        < label  for = "dispCont" > < / label >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        < p  class = "des" > Pinout< / p >                         < p  class = "des" > Pinout< / p >  
			
		
	
		
		
			
				
					                        < div  id = "dispPins" > < / div >                         < div  id = "dispPins" > < / div >  
			
		
	
		
		
			
				
					                    < / fieldset >                     < / fieldset >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					                    < div  class = "mt-3" >                     < div  class = "row mb-4 mt-4" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < label  for = "reboot" > Reboot device after successful save< / label >                         < div  class = "col-8 col-sm-3" > Reboot device after successful save< / div >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "checkbox"  class = "cb"  name = "reboot"  checked  / >                         < div  class = "col-2 col-md-6" >  
			
				
				
			
		
	
		
		
			
				
					
					                        < input  type = "submit"  value = "save"  class = "btn right" / >                             < input  type = "checkbox"  name = "reboot"  checked  / >  
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                            < input  type = "submit"  value = "save"  class = "btn right" / >  
			
		
	
		
		
			
				
					                        < / div >  
			
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    < div  class = "hr mb-3 mt-3" > < / div >                     < div  class = "hr mb-3 mt-3" > < / div >  
			
		
	
		
		
			
				
					
					                    < div  class = "mb-4" >                     < div  class = "mb-4 mt-4 " >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                        < a  class = "btn"  href = "/erase" > ERASE SETTINGS (not WiFi)< / a >                         < a  class = "btn"  href = "/erase" > ERASE SETTINGS (not WiFi)< / a >  
			
		
	
		
		
			
				
					
					                        < fieldset >                         < fieldset  class = "mb-4"  >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            < legend  class = "des" > Upload / Store JSON Settings< / legend >                             < legend  class = "des" > Upload / Store JSON Settings< / legend >  
			
		
	
		
		
			
				
					                            < form  id = "form"  method = "POST"  action = "/upload"  enctype = "multipart/form-data"  accept-charset = "utf-8" >                             < form  id = "form"  method = "POST"  action = "/upload"  enctype = "multipart/form-data"  accept-charset = "utf-8" >  
			
		
	
		
		
			
				
					                                < input  type = "file"  name = "upload" >                                 < input  type = "file"  name = "upload" >  
			
		
	
		
		
			
				
					                                < input  type = "button"  class = "btn"  value = "Upload"  onclick = "hide()" >                                 < input  type = "button"  class = "btn"  value = "Upload"  onclick = "hide()" >  
			
		
	
		
		
			
				
					                            < / form >                             < / form >  
			
		
	
		
		
			
				
					                        < / fieldset >                         < / fieldset >  
			
		
	
		
		
			
				
					
					                        < a  class = "btn"  href = "/get_setup"  target = "_blank" > Download settings (JSON file)< / a >  (only saved values, passwords will be removed!)                        < a  class = "btn"  href = "/get_setup"  target = "_blank" > Download settings (JSON file)< / a > < span > < / span >  
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    < / div >                     < / div >  
			
		
	
		
		
			
				
					                < / form >                 < / form >  
			
		
	
		
		
			
				
					            < / div >             < / div >  
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -343,23 +435,38 @@ 
			
		
	
		
		
			
				
					                document.getElementsByName(id + "Name")[0].value = "";                document.getElementsByName(id + "Name")[0].value = ""; 
			
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function mlCb(id, des, chk=false) { 
			
		
	
		
		
			
				
					                var cb = ml("input", {type: "checkbox", id: id, name: id}, ""); 
			
		
	
		
		
			
				
					                if(chk) 
			
		
	
		
		
			
				
					                    cb.checked = true; 
			
		
	
		
		
			
				
					                return ml("div", {class: "row mb-3"}, [ 
			
		
	
		
		
			
				
					                    ml("div", {class: "col-8 col-sm-3"}, des), 
			
		
	
		
		
			
				
					                    ml("div", {class: "col-4 col-sm-9"}, cb) 
			
		
	
		
		
			
				
					                ]); 
			
		
	
		
		
			
				
					            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function mlE(des, e) { 
			
		
	
		
		
			
				
					                return ml("div", {class: "row mb-3"}, [ 
			
		
	
		
		
			
				
					                    ml("div", {class: "col-12 col-sm-3 my-2"}, des), 
			
		
	
		
		
			
				
					                    ml("div", {class: "col-12 col-sm-9"}, e) 
			
		
	
		
		
			
				
					                ]); 
			
		
	
		
		
			
				
					            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function ivHtml(obj, id) {            function ivHtml(obj, id) { 
			
		
	
		
		
			
				
					                highestId = id + 1;                highestId = id + 1; 
			
		
	
		
		
			
				
					                if(highestId == maxInv)                if(highestId == maxInv) 
			
		
	
		
		
			
				
					                    setHide("btnAdd", true);                    setHide("btnAdd", true); 
			
		
	
		
		
			
				
					
					                iv = document.getElementById("inverter");
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                var iv = document.getElementById("inverter"); 
			
		
	
		
		
			
				
					                iv.appendChild(des("Inverter " + id));                iv.appendChild(des("Inverter " + id)); 
			
		
	
		
		
			
				
					                id = "inv" + id;                id = "inv" + id; 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                iv.appendChild(lbl(id + "Enable", "Communication Enable")); 
			
		
	
		
		
			
				
					                var en = inp(id + "Enable", null, null, ["cb"], id + "Enable", "checkbox"); 
			
		
	
		
		
			
				
					                en.checked = obj["enabled"]; 
			
		
	
		
		
			
				
					                iv.appendChild(en); 
			
		
	
		
		
			
				
					                iv.appendChild(br()); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                iv.appendChild(lbl(id + "Addr", "Serial Number (12 digits)*")); 
			
		
	
		
		
			
				
					                var addr = inp(id + "Addr", obj["serial"], 12, ["text"], null, "text", "[0-9]+", "Invalid input");                var addr = inp(id + "Addr", obj["serial"], 12, ["text"], null, "text", "[0-9]+", "Invalid input"); 
			
		
	
		
		
			
				
					
					                iv.appendChild(addr);                iv.append( 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    mlCb(id + "Enable", "Communication Enable", obj["enabled"]), 
			
		
	
		
		
			
				
					                    mlE("Serial Number (12 digits)*", addr) 
			
		
	
		
		
			
				
					                ); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                ['keyup', 'change'].forEach(function(evt) {                ['keyup', 'change'].forEach(function(evt) { 
			
		
	
		
		
			
				
					                    addr.addEventListener(evt, (e) => {                    addr.addEventListener(evt, (e) => { 
			
		
	
		
		
			
				
					                        var serial = addr.value.substring(0,4);                        var serial = addr.value.substring(0,4); 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -369,9 +476,9 @@ 
			
		
	
		
		
			
				
					                            setHide(id+"ModName"+i, true);                            setHide(id+"ModName"+i, true); 
			
		
	
		
		
			
				
					                            setHide(id+"YieldCor"+i, true);                            setHide(id+"YieldCor"+i, true); 
			
		
	
		
		
			
				
					                        }                        } 
			
		
	
		
		
			
				
					
					                        setHide("lbl "+id+"ModPwr", true);                        setHide("row "+id+"ModPwr", true); 
			
				
				
			
		
	
		
		
			
				
					
					                        setHide("lbl "+id+"ModName", true);                        setHide("row "+id+"ModName", true); 
			
				
				
			
		
	
		
		
			
				
					
					                        setHide("lbl "+id+"YieldCor", true);                        setHide("row "+id+"YieldCor", true); 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                        if(serial.charAt(0) == 1) {                        if(serial.charAt(0) == 1) { 
			
		
	
		
		
			
				
					                            if((serial.charAt(1) == 0) || (serial.charAt(1) == 1)) {                            if((serial.charAt(1) == 0) || (serial.charAt(1) == 1)) { 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -391,39 +498,44 @@ 
			
		
	
		
		
			
				
					                                setHide(id+"ModName"+i, false);                                setHide(id+"ModName"+i, false); 
			
		
	
		
		
			
				
					                                setHide(id+"YieldCor"+i, false);                                setHide(id+"YieldCor"+i, false); 
			
		
	
		
		
			
				
					                            }                            } 
			
		
	
		
		
			
				
					
					                            setHide("lbl "+id+"ModPwr", false);                            setHide("row "+id+"ModPwr", false); 
			
				
				
			
		
	
		
		
			
				
					
					                            setHide("lbl "+id+"ModName", false);                            setHide("row "+id+"ModName", false); 
			
				
				
			
		
	
		
		
			
				
					
					                            setHide("lbl "+id+"YieldCor", false);                            setHide("row "+id+"YieldCor", false); 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                        }                        } 
			
		
	
		
		
			
				
					                    })                    }) 
			
		
	
		
		
			
				
					                });                }); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					
					                iv.append(                iv.append(mlE("Name*", inp(id + "Name", obj["name"], 16, ["text"], null, "text", "[A-Za-z0-9./#$%& =+_-]+", "Invalid input"))); 
			
				
				
			
		
	
		
		
			
				
					                    lbl(id + "Name", "Name*"), 
			
		
	
		
		
			
				
					                    inp(id + "Name", obj["name"], 16, ["text"], null, "text", "[A-Za-z0-9./#$%& =+_-]+", "Invalid input") 
			
		
	
		
		
			
				
					                ); 
			
		
	
		
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                for(var j of [                for(var j of [ 
			
		
	
		
		
			
				
					                    ["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"],                    ["ModPwr", "ch_max_power", "Max Module Power (Wp)", 4, "[0-9]+"], 
			
		
	
		
		
			
				
					                    ["ModName", "ch_name", "Module Name", 16, null],                    ["ModName", "ch_name", "Module Name", 16, null], 
			
		
	
		
		
			
				
					                    ["YieldCor", "ch_yield_cor", "Yield Total Correction [kWh]", 16, "[0-9-]+"]]) {                    ["YieldCor", "ch_yield_cor", "Yield Total Correction [kWh]", 16, "[0-9-]+"]]) { 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                    var cl = (re.test(obj["serial"])) ? null : ["hide"];                    var cl = (re.test(obj["serial"])) ? null : ["hide"]; 
			
		
	
		
		
			
				
					
					                    iv.appendChild(lbl(null, j[2], cl, "lbl" + id + j[0]));
 
			
				
				
			
		
	
		
		
			
				
					                    d = div([j[0]]); 
			
		
	
		
		
	
		
		
			
				
					                    i = 0;                    i = 0; 
			
		
	
		
		
			
				
					
					                    cl = (re.test(obj["serial"])) ? ["text", "sh"] : ["text", "sh", "hide" ];                    arrIn = [ ]; 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    for(it of obj[j[1]]) {                    for(it of obj[j[1]]) { 
			
		
	
		
		
			
				
					
					                        d.appendChild(inp(id + j[0] + i, it, j[3], cl, id + j[0] + i, "text", j[4], "Invalid input"));                        arrIn.push(ml("div", {class: "col-3 "}, 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                            inp(id + j[0] + i, it, j[3], [], id + j[0] + i, "text", j[4], "Invalid input") 
			
		
	
		
		
			
				
					                        )); 
			
		
	
		
		
			
				
					                        i++;                        i++; 
			
		
	
		
		
			
				
					                    }                    } 
			
		
	
		
		
			
				
					
					                    iv.appendChild(d);
 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                    iv.append( 
			
		
	
		
		
			
				
					                        ml("div", {class: "row mb-2 mb-sm-3", id: "row" + id + j[0]}, [ 
			
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-3 my-2"}, j[2]), 
			
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-9"}, 
			
		
	
		
		
			
				
					                                ml("div", {class: "row"}, arrIn) 
			
		
	
		
		
			
				
					                            ) 
			
		
	
		
		
			
				
					                        ]) 
			
		
	
		
		
			
				
					                    ); 
			
		
	
		
		
			
				
					                }                } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button");                var del = inp(id+"del", "X", 0, ["btn", "btnDel"], id+"del", "button"); 
			
		
	
		
		
			
				
					                del.addEventListener("click", delIv);                del.addEventListener("click", delIv); 
			
		
	
		
		
			
				
					
					                iv.append(                iv.append(mlE("Delete", del)); 
			
				
				
			
		
	
		
		
			
				
					                    lbl(id + "lbldel", "Delete"), 
			
		
	
		
		
			
				
					                    del 
			
		
	
		
		
			
				
					                ); 
			
		
	
		
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function ivGlob(obj) {            function ivGlob(obj) { 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -436,20 +548,18 @@ 
			
		
	
		
		
			
				
					            function parseSys(obj) {            function parseSys(obj) { 
			
		
	
		
		
			
				
					                for(var i of [["device", "device_name"], ["ssid", "ssid"]])                for(var i of [["device", "device_name"], ["ssid", "ssid"]]) 
			
		
	
		
		
			
				
					                    document.getElementsByName(i[0])[0].value = obj[i[1]];                    document.getElementsByName(i[0])[0].value = obj[i[1]]; 
			
		
	
		
		
			
				
					
					                var e = document.getElementsByName("adminpwd")[0];                document.getElementsByName("darkMode")[0].checked = obj["dark_mode"]; 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                e = document.getElementsByName("adminpwd")[0]; 
			
		
	
		
		
			
				
					                if(!obj["pwd_set"])                if(!obj["pwd_set"]) 
			
		
	
		
		
			
				
					                    e.value = "";                    e.value = ""; 
			
		
	
		
		
			
				
					                var d = document.getElementById("prot_mask");                var d = document.getElementById("prot_mask"); 
			
		
	
		
		
			
				
					
					                var a = ["Index", "Live", "Serial / Console", "Settings", "Update", "System"]                var a = ["Index", "Live", "Serial / Console", "Settings", "Update", "System"]; 
			
				
				
			
		
	
		
		
	
		
		
			
				
					                var el = []; 
			
		
	
		
		
			
				
					                for(var i = 0; i <  6 ;  i + + )  {                 for(var i = 0; i <  6 ;  i + + )  {  
			
		
	
		
		
			
				
					
					                    var chkd = ((obj["prot_mask"] &  (1 < <  i ) )  = =  ( 1  < <  i ) ) ;                     var chk = ((obj["prot_mask"] &  (1 < <  i ) )  = =  ( 1  < <  i ) ) ;  
			
				
				
			
		
	
		
		
			
				
					
					                    var sp = lbl("protMask" + i, a[i]);                    el.push(mlCb("protMask" + i, a[i], chk)) 
			
				
				
			
		
	
		
		
			
				
					                    var cb = inp("protMask" + i, null, null, ["cb"], "protMask" + i, "checkbox", null, null, chkd); 
			
		
	
		
		
			
				
					                    if(0 == i) 
			
		
	
		
		
			
				
					                        d.replaceChildren(sp, cb, br()); 
			
		
	
		
		
			
				
					                    else 
			
		
	
		
		
			
				
					                        d.append(sp, cb, br()); 
			
		
	
		
		
	
		
		
	
		
		
			
				
					                }                } 
			
		
	
		
		
			
				
					                d.append(...el); 
			
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function parseGeneric(obj) {            function parseGeneric(obj) { 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -495,20 +605,31 @@ 
			
		
	
		
		
			
				
					                var e = document.getElementById("pinout");                var e = document.getElementById("pinout"); 
			
		
	
		
		
			
				
					                pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['led0', 'pinLed0'], ['led1', 'pinLed1']];                pins = [['cs', 'pinCs'], ['ce', 'pinCe'], ['irq', 'pinIrq'], ['led0', 'pinLed0'], ['led1', 'pinLed1']]; 
			
		
	
		
		
			
				
					                for(p of pins) {                for(p of pins) { 
			
		
	
		
		
			
				
					
					                    e.appendChild(lbl(p[1], p[0].toUpperCase()));                    e.append( 
			
				
				
			
		
	
		
		
			
				
					
					                    e.appendChild(sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]]));                        ml("div", {class: "row mb-3"}, [ 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()), 
			
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-9"}, 
			
		
	
		
		
			
				
					                                sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[0]]) 
			
		
	
		
		
			
				
					                            ) 
			
		
	
		
		
			
				
					                        ]) 
			
		
	
		
		
			
				
					                    ); 
			
		
	
		
		
			
				
					                }                } 
			
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function parseRadio(obj) {            function parseRadio(obj) { 
			
		
	
		
		
			
				
					
					                var e = document.getElementById("rf24");                var e = document.getElementById("rf24").append( 
			
				
				
			
		
	
		
		
			
				
					
					                e.appendChild(lbl("rf24Power", "Amplifier Power Level"));                    ml("div", {class: "row mb-3"}, [ 
			
				
				
			
		
	
		
		
			
				
					
					                e.appendChild(sel("rf24Power", [                        ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()), 
			
				
				
			
		
	
		
		
			
				
					
					                    [0, "MIN"],                        ml("div", {class: "col-12 col-sm-9"}, 
			
				
				
			
		
	
		
		
			
				
					
					                    [1, "LOW"],                            sel("rf24Power", [ 
			
				
				
			
		
	
		
		
			
				
					
					                    [2, "HIGH"],                                [0, "MIN"], 
			
				
				
			
		
	
		
		
			
				
					
					                    [3, "MAX"]                                [1, "LOW"], 
			
				
				
			
		
	
		
		
			
				
					
					                ], obj["power_level"]));                                [2, "HIGH"], 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					                                [3, "MAX"] 
			
		
	
		
		
			
				
					                            ], obj["power_level"]) 
			
		
	
		
		
			
				
					                        ) 
			
		
	
		
		
			
				
					                    ]) 
			
		
	
		
		
			
				
					                ); 
			
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            function parseSerial(obj) {            function parseSerial(obj) { 
			
		
	
	
		
		
			
				
					
						
						
						
							
								 
						
					 
					@ -524,14 +645,22 @@ 
			
		
	
		
		
			
				
					                var e = document.getElementById("dispPins");                var e = document.getElementById("dispPins"); 
			
		
	
		
		
			
				
					                pins = [['SCL / CS', 'pinDisp0'], ['SDA / DC', 'pinDisp1']];                pins = [['SCL / CS', 'pinDisp0'], ['SDA / DC', 'pinDisp1']]; 
			
		
	
		
		
			
				
					                for(p of pins) {                for(p of pins) { 
			
		
	
		
		
			
				
					
					                    e.appendChild(lbl(p[1], p[0].toUpperCase()));                    e.append( 
			
				
				
			
		
	
		
		
			
				
					
					                    e.appendChild(sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[1]]));                        ml("div", {class: "row mb-3"}, [ 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-3 my-2"}, p[0].toUpperCase()), 
			
		
	
		
		
			
				
					                            ml("div", {class: "col-12 col-sm-9"}, 
			
		
	
		
		
			
				
					                                sel(p[1], ("ESP8266" == type) ? esp8266pins : esp32pins, obj[p[1]]) 
			
		
	
		
		
			
				
					                            ) 
			
		
	
		
		
			
				
					                        ]) 
			
		
	
		
		
			
				
					                    ); 
			
		
	
		
		
			
				
					                }                } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                var opts = [[0, "None"], [1, "Nokia5110"], [2, "SSD1306 0.96\""], [3, "SH1106 1.3\""]];                var opts = [[0, "None"], [1, "Nokia5110"], [2, "SSD1306 0.96\""], [3, "SH1106 1.3\""]]; 
			
		
	
		
		
			
				
					                document.getElementById("dispType").append(                document.getElementById("dispType").append( 
			
		
	
		
		
			
				
					
					                    lbl("dispType", "Type"),                    ml("div", {class: "row mb-3"}, [ 
			
				
				
			
		
	
		
		
			
				
					
					                    sel("dispType", opts, obj["disp_type"])                        ml("div", {class: "col-12 col-sm-3 my-2"}, "Type"), 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					                        ml("div", {class: "col-12 col-sm-9"}, sel("dispType", opts, obj["disp_type"])) 
			
		
	
		
		
			
				
					                    ]) 
			
		
	
		
		
			
				
					                );                ); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					                e = document.getElementById("contrast");                e = document.getElementById("contrast"); 
			
		
	
	
		
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
					@ -576,11 +705,7 @@ 
			
		
	
		
		
			
				
					                    e.value = s.value;                    e.value = s.value; 
			
		
	
		
		
			
				
					            }            } 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            hiddenInput = document.getElementById("disclaimer") 
			
		
	
		
		
			
				
					            hiddenInput.value = sessionStorage.getItem("gDisclaimer"); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					            getAjax("/api/setup", parse);            getAjax("/api/setup", parse); 
			
		
	
		
		
			
				
					
 
			
		
	
		
		
			
				
					        < / script >         < / script >  
			
		
	
		
		
			
				
					    < / body >     < / body >  
			
		
	
		
		
			
				
					< / html > < / html >