|  | @@ -106,7 +106,7 @@
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		/* Power Button */
 | 
	
		
			
				|  |  | -		.pwrbtn {
 | 
	
		
			
				|  |  | +		#pwrbtn {
 | 
	
		
			
				|  |  |  			display:block;
 | 
	
		
			
				|  |  |  			height: 80px;
 | 
	
		
			
				|  |  |  			width: 80px;
 | 
	
	
		
			
				|  | @@ -117,22 +117,22 @@
 | 
	
		
			
				|  |  |  			background-color: #f8f8f8;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.pwrbtn:hover{
 | 
	
		
			
				|  |  | +		#pwrbtn:hover{
 | 
	
		
			
				|  |  |  			background-color: #c7c7c7;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.pwrbtn:active{
 | 
	
		
			
				|  |  | +		#pwrbtn:active{
 | 
	
		
			
				|  |  |  			background-color: #868686;
 | 
	
		
			
				|  |  |  			box-shadow: inset 10px 10px 18px 0px rgba(0,0,0,0.38);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.pwrbtn svg{
 | 
	
		
			
				|  |  | +		#pwrbtn svg{
 | 
	
		
			
				|  |  |  			margin-top: 1.5em;
 | 
	
		
			
				|  |  | -			margin-left: 0.2em;
 | 
	
		
			
				|  |  | +			margin-left: 0.1em;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		/* Reset Button */
 | 
	
		
			
				|  |  | -		.rstbtn {
 | 
	
		
			
				|  |  | +		#rstbtn {
 | 
	
		
			
				|  |  |  			display:block;
 | 
	
		
			
				|  |  |  			height: 40px;
 | 
	
		
			
				|  |  |  			width: 40px;
 | 
	
	
		
			
				|  | @@ -143,16 +143,16 @@
 | 
	
		
			
				|  |  |  			box-shadow: 10px 10px 18px 0px rgba(0,0,0,0.38);
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.rstbtn svg{
 | 
	
		
			
				|  |  | +		#rstbtn svg{
 | 
	
		
			
				|  |  |  			margin-top: 0.5em;
 | 
	
		
			
				|  |  | -			margin-left: 0.2em;
 | 
	
		
			
				|  |  | +			margin-left: 0.1em;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.rstbtn:hover{
 | 
	
		
			
				|  |  | +		#rstbtn:hover{
 | 
	
		
			
				|  |  |  			background-color: #c7c7c7;
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -		.rstbtn:active{
 | 
	
		
			
				|  |  | +		#rstbtn:active{
 | 
	
		
			
				|  |  |  			background-color: #868686;
 | 
	
		
			
				|  |  |  			box-shadow: inset 10px 10px 18px 0px rgba(0,0,0,0.38);
 | 
	
		
			
				|  |  |  		}
 | 
	
	
		
			
				|  | @@ -203,11 +203,11 @@
 | 
	
		
			
				|  |  |  						</tr>
 | 
	
		
			
				|  |  |  						<tr>
 | 
	
		
			
				|  |  |  							<td>Power Status<br></td>
 | 
	
		
			
				|  |  | -							<td>OFF</td>
 | 
	
		
			
				|  |  | +							<td id="powerLED">OFF</td>
 | 
	
		
			
				|  |  |  						</tr>
 | 
	
		
			
				|  |  |  						<tr>
 | 
	
		
			
				|  |  |  							<td>HDD Status<br></td>
 | 
	
		
			
				|  |  | -							<td>IDLE</td>
 | 
	
		
			
				|  |  | +							<td id="hddStatus">IDLE</td>
 | 
	
		
			
				|  |  |  						</tr>
 | 
	
		
			
				|  |  |  					</tbody>
 | 
	
		
			
				|  |  |  				</table>
 | 
	
	
		
			
				|  | @@ -221,24 +221,131 @@
 | 
	
		
			
				|  |  |  			</code></div>
 | 
	
		
			
				|  |  |  			<br>
 | 
	
		
			
				|  |  |  			<div class="divider"></div>
 | 
	
		
			
				|  |  | -			<small>ESPWoL Prototype | CopyRight tobychui 2023 - 2024</small>
 | 
	
		
			
				|  |  | +			<small>ESPWoL | Deisnged by tobychui 2023 - 2024</small>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			<div class="controlEmu" align="center">
 | 
	
		
			
				|  |  | -				<div class="rstbtn" title="Reset Computer">
 | 
	
		
			
				|  |  | +				<div id="rstbtn" title="Reset Computer">
 | 
	
		
			
				|  |  |  					<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-122q-121-15-200.5-105.5T160-440q0-66 26-126.5T260-672l57 57q-38 34-57.5 79T240-440q0 88 56 155.5T440-202v80Zm80 0v-80q87-16 143.5-83T720-440q0-100-70-170t-170-70h-3l44 44-56 56-140-140 140-140 56 56-44 44h3q134 0 227 93t93 227q0 121-79.5 211.5T520-122Z"/></svg>
 | 
	
		
			
				|  |  |  				</div>
 | 
	
		
			
				|  |  |  				<div class="leds">
 | 
	
		
			
				|  |  |  					<div class="ledlabel">HDD <div class="led"></div></div><br>
 | 
	
		
			
				|  |  |  					<div class="ledlabel">PWR <div class="led"></div></div>
 | 
	
		
			
				|  |  |  				 </div>
 | 
	
		
			
				|  |  | -				 <div class="pwrbtn" title="Power On / Off">
 | 
	
		
			
				|  |  | -					<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32"><path d="M440-440v-400h80v400h-80Zm40 320q-74 0-139.5-28.5T226-226q-49-49-77.5-114.5T120-480q0-80 33-151t93-123l56 56q-48 40-75 97t-27 121q0 116 82 198t198 82q117 0 198.5-82T760-480q0-64-26.5-121T658-698l56-56q60 52 93 123t33 151q0 74-28.5 139.5t-77 114.5q-48.5 49-114 77.5T480-120Z"/></svg>
 | 
	
		
			
				|  |  | +				 <div id="pwrbtn" title="Power On / Off">
 | 
	
		
			
				|  |  | +					<svg id="pwricon" fill="#eb4034" xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32"><path d="M440-440v-400h80v400h-80Zm40 320q-74 0-139.5-28.5T226-226q-49-49-77.5-114.5T120-480q0-80 33-151t93-123l56 56q-48 40-75 97t-27 121q0 116 82 198t198 82q117 0 198.5-82T760-480q0-64-26.5-121T658-698l56-56q60 52 93 123t33 151q0 74-28.5 139.5t-77 114.5q-48.5 49-114 77.5T480-120Z"/></svg>
 | 
	
		
			
				|  |  |  				 </div>
 | 
	
		
			
				|  |  |  			</div>
 | 
	
		
			
				|  |  |  		</div>
 | 
	
		
			
				|  |  |  	</div>
 | 
	
		
			
				|  |  |  	<script>
 | 
	
		
			
				|  |  | +		/* 
 | 
	
		
			
				|  |  | +			The update interval will change based on the current status of the remote
 | 
	
		
			
				|  |  | +			computer. By default, it update the status LED every seconds. When the 
 | 
	
		
			
				|  |  | +			remote is powered on, it update with 100ms delay between response and new requests.
 | 
	
		
			
				|  |  | +		*/
 | 
	
		
			
				|  |  | +		let updateInterval = 1000; 
 | 
	
		
			
				|  |  | +		//Set the power status and hdd led status to off
 | 
	
		
			
				|  |  | +		togglePowerState(false);
 | 
	
		
			
				|  |  | +		toggleHDDLED(false);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +		/* Read the status from server */
 | 
	
		
			
				|  |  | +		function updateLEDStatus(){
 | 
	
		
			
				|  |  | +			fetch('/status', {
 | 
	
		
			
				|  |  | +				method: 'GET'
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  | +			.then(response => {
 | 
	
		
			
				|  |  | +				if (!response.ok) {
 | 
	
		
			
				|  |  | +					throw new Error('Network error');
 | 
	
		
			
				|  |  | +					updateInterval = 1000;
 | 
	
		
			
				|  |  | +					setTimeout(updateLEDStatus, updateInterval);
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				return response.json();
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  | +			.then(data => {
 | 
	
		
			
				|  |  | +				//Update the power LED and update interval
 | 
	
		
			
				|  |  | +				togglePowerState(data.pwr);
 | 
	
		
			
				|  |  | +				if (data.pwr){
 | 
	
		
			
				|  |  | +					updateInterval = 100;
 | 
	
		
			
				|  |  | +				}else{
 | 
	
		
			
				|  |  | +					updateInterval = 1000;
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +				setTimeout(updateLEDStatus, updateInterval);
 | 
	
		
			
				|  |  | +				//Update the hdd led 
 | 
	
		
			
				|  |  | +				toggleHDDLED(data.hdd);
 | 
	
		
			
				|  |  | +			})
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		setTimeout(updateLEDStatus, updateInterval);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		/* Status LED Rendering */
 | 
	
		
			
				|  |  | +		function togglePowerState(powerIsOn = true){
 | 
	
		
			
				|  |  | +			if (powerIsOn){
 | 
	
		
			
				|  |  | +				document.getElementById("powerLED").innerHTML = "🟢 ON";
 | 
	
		
			
				|  |  | +				document.getElementById("pwricon").setAttribute("fill", "#7fe38b");
 | 
	
		
			
				|  |  | +			}else{
 | 
	
		
			
				|  |  | +				document.getElementById("powerLED").innerHTML = "⚫ OFF";
 | 
	
		
			
				|  |  | +				document.getElementById("pwricon").setAttribute("fill", "#eb4034");
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		function toggleHDDLED(hddLEDOn = true){
 | 
	
		
			
				|  |  | +			if (hddLEDOn){
 | 
	
		
			
				|  |  | +				document.getElementById("hddStatus").innerHTML = "🔵 R/W";
 | 
	
		
			
				|  |  | +			}else{
 | 
	
		
			
				|  |  | +				document.getElementById("hddStatus").innerHTML = "⚫ IDLE";
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		/* Button Emulations */
 | 
	
		
			
				|  |  | +		function handlePowerButtonPress(){
 | 
	
		
			
				|  |  | +			fetch('/power/press', {
 | 
	
		
			
				|  |  | +				method: 'GET'
 | 
	
		
			
				|  |  | +			}).then(response => {
 | 
	
		
			
				|  |  | +				if (!response.ok) {
 | 
	
		
			
				|  |  | +					console.log("Error when trying to press power button")
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		function handlePowerButtonRelease(){
 | 
	
		
			
				|  |  | +			fetch('/power/release', {
 | 
	
		
			
				|  |  | +				method: 'GET'
 | 
	
		
			
				|  |  | +			}).then(response => {
 | 
	
		
			
				|  |  | +				if (!response.ok) {
 | 
	
		
			
				|  |  | +					console.log("Error when trying to press power button")
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		function handleResetButtonPress(){
 | 
	
		
			
				|  |  | +			fetch('/reset/press', {
 | 
	
		
			
				|  |  | +				method: 'GET'
 | 
	
		
			
				|  |  | +			}).then(response => {
 | 
	
		
			
				|  |  | +				if (!response.ok) {
 | 
	
		
			
				|  |  | +					console.log("Error when trying to press reset button")
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		function handlResetButtonRelease(){
 | 
	
		
			
				|  |  | +			fetch('/reset/release', {
 | 
	
		
			
				|  |  | +				method: 'GET'
 | 
	
		
			
				|  |  | +			}).then(response => {
 | 
	
		
			
				|  |  | +				if (!response.ok) {
 | 
	
		
			
				|  |  | +					console.log("Error when trying to press reset button")
 | 
	
		
			
				|  |  | +				}
 | 
	
		
			
				|  |  | +			});
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		/* Bind events for the buttons */
 | 
	
		
			
				|  |  | +		document.getElementById("pwrbtn").addEventListener("mousedown", handlePowerButtonPress);
 | 
	
		
			
				|  |  | +		document.getElementById("pwrbtn").addEventListener("touchstart", handlePowerButtonPress);
 | 
	
		
			
				|  |  | +		document.getElementById("pwrbtn").addEventListener("mouseup", handlePowerButtonRelease);
 | 
	
		
			
				|  |  | +		document.getElementById("pwrbtn").addEventListener("touchend", handlePowerButtonRelease);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		document.getElementById("rstbtn").addEventListener("mousedown", handleResetButtonPress);
 | 
	
		
			
				|  |  | +		document.getElementById("rstbtn").addEventListener("touchstart", handleResetButtonPress);
 | 
	
		
			
				|  |  | +		document.getElementById("rstbtn").addEventListener("mouseup", handlResetButtonRelease);
 | 
	
		
			
				|  |  | +		document.getElementById("rstbtn").addEventListener("touchend", handlResetButtonRelease);
 | 
	
		
			
				|  |  |  	</script>
 | 
	
		
			
				|  |  |  </body>
 | 
	
		
			
				|  |  |  </html>
 |