<!DOCTYPE html>
<html lang="en">

<head>
  <!--  Copyright (c) 2023-24 David Kerr, https://github.com/dkerr64 -->
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1">
  <meta name="apple-mobile-web-app-title" content="RATDGO">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>HomeKit Garage Door Opener</title>
  <link rel="stylesheet" href="style.css?v=CRC-32">
  <link rel="icon" href="favicon.png?v=CRC-32" type="image/png">
  <link rel="apple-touch-icon" href="apple-touch-icon.png?v=CRC-32" type="image/png">
  <script src="functions.js?v=CRC-32"></script>
</head>

<body>
  <!-- Title section of page ------------------------------------------------------------------>
  <div class="fullpage">
    <div id="loader" class="ldrcenter"></div>
    <main>
      <div class="header">
        <div class="logo">
          <pre class="logo">
 _____ _____ _____ _____ ____  _____
| __  |  _  |_   _|   __|    \|     |
|    -|     | | | |  |  |  |  |  |  |
|__|__|__|__| |_| |_____|____/|_____|
          </pre>
          <p class="logo"> for HomeKit</p>
        </div>
        <div class="name">
          <p id="deviceName" style="margin:0px;">Garage Door</p>
        </div>
        <div style="float:right;vertical-align: middle; padding-left: 0; padding-right: 0; cursor: pointer;">
          <img id="settings-icon" src="settings-sliders.svg?v=CRC-32" alt="Settings" style="width:1.5em;height:1.5em;">
          <img id="main-icon" src="garage-car.svg?v=CRC-32" alt="Homepage" onclick="history.back()"
            style="display:none; width:1.5em;height:1.5em;">
        </div>
      </div>
      <!-- Main section of page ------------------------------------------------------------------>
      <div id="main-page" style="padding: 0px; padding-bottom: 10px;">
        <div class="serverstatus">
          <table>
            <tr>
              <td style="width: 40%">Firmware:</td>
              <td><span id="firmwareVersion"></span><br><sup style="font-size: 0.6em;"><span
                    id="newversion"></span><span id="dotdot1"></span></sup></td>
            </tr>
            <tr>
              <td style="white-space: pre;">Up Time:</td>
              <td><span id="upTime"></span><br><sup style="font-size: 0.6em;">(days:hrs:min:sec)</sup></td>
            </tr>
            <tr style="height: 2px">
              <td colspan="2"></td>
            </tr>
            <tr>
              <td>WiFi SSID:</td>
              <td id="wifiSSID"></td>
            </tr>
            <tr>
              <td>WiFi RSSI:</td>
              <td id="wifiRSSI"></td>
            </tr>
            <tr>
              <td>WiFi AP:</td>
              <td><span id="wifiBSSID"></span><br><sup style="font-size: 0.6em;"><span id="lockedAP"
                    style="display: none">(Locked to AP)</span></sup></td>
            </tr>
            <tr>
              <td>MAC Address:</td>
              <td id="macAddress"></td>
            </tr>
            <tr>
              <td>IP Address:</td>
              <td id="localIP"></td>
            </tr>
            <tr>
              <td>Netmask:</td>
              <td id="subnetMask"></td>
            </tr>
            <tr>
              <td>Gateway IP:</td>
              <td id="gatewayIP"></td>
            </tr>
            <tr style="height: 10px">
              <td colspan="2"></td>
            </tr>
            <tr>
              <td>HomeKit ID:</td>
              <td><span id="accessoryID"></span><br><sup style="font-size: 0.6em;">HomeKit connected: <span
                    id="clients">No</span></sup></td>
            </tr>
          </table>
        </div>
        <div class="qrcode">
          <img id="qrcode" src="qrcode.svg?v=CRC-32" alt="QR Code" style="display:none;">
          <p id="re-pair-info" style="display:none; font-size: 10px;">If you wish to pair to another HomeKit home, you
            must first un-pair from existing home.
          </p>
        </div>
        <div class="fullwidth" style="padding: 0px;">
          <div class="serverstatus" style="padding: 0px; padding-bottom: 5px;">
            <input type="button" value="Reboot RATGDO" onclick="rebootRATGDO(true)">
            <input type="button" value="Firmware Update" onclick="showUpdateDialog()">
          </div>
          <div class="qrcode center">
            <input type="button" id="unpair" value="Reset HomeKit" onclick="unpairRATGDO()">
          </div>
        </div>
        <div class="fullwidth">
          <table>
            <tr>
              <td style="width: 35%;">Door State:</td>
              <td style="width: 20%;" id="garageDoorState"></td>
              <td style="width: 35%;">Light On:</td>
              <td style="width: 10%;" id="garageLightOn"></td>
            </tr>
            <tr>
              <td>Lock State:</td>
              <td id="garageLockState"></td>
              <td>Obstruction:</td>
              <td id="garageObstructed"></td>
            </tr>
            <tr>
              <td>Door Protocol:</td>
              <td id="GDOSecurityType"></td>
              <td>Motion:</td>
              <td id="garageMotion"></td>
            </tr>
          </table>
        </div>
        <div id="GDOcontrols" class="fullwidth"
          style="padding-left: 0px; padding-right: 0px; display: flex; justify-content: space-between;">
          <input type="button" value="Light On" onclick="setGDO('garageLightOn', '1')">
          <input type="button" value="Light Off" onclick="setGDO('garageLightOn', '0')">
          <input type="button" value="Door Open" onclick="setGDO('garageDoorState', '1')">
          <input type="button" value="Door Close" onclick="setGDO('garageDoorState', '0')">
          <input type="button" value="Door Lock" onclick="setGDO('garageLockState', '1')">
          <input type="button" value="Door Unlock" onclick="setGDO('garageLockState', '0')">
        </div>
      </div>
      <!-- Settings section of page ------------------------------------------------------------------>
      <div id="settings-page" style="display: none; padding-left: 0px; padding-right: 0px;">
        <div class="fullwidth" style="padding-top: 0px; padding-bottom: 0px;">
          <div>
            <table class="password">
              <tr>
                <td class="label">Username:</td>
                <td>&nbsp;
                  <input id="newUserName" type="text" placeholder="admin" maxlength="30" minlength="1">
                </td>
                <td></td>
              </tr>
              <tr>
                <td class="label">Password:</td>
                <td>&nbsp;
                  <input id="newPassword" type="password" placeholder="new password" autocomplete="new-password">
                </td>
                <td></td>
              </tr>
              <tr>
                <td class="label">Confirm:</td>
                <td>&nbsp;
                  <input id="confirmPassword" type="password" placeholder="confirm new password">
                </td>
                <td>&nbsp;&nbsp;&nbsp;&nbsp;
                  <input type="button" value="Save User/Password" onclick="changePassword()">
                </td>
              </tr>
            </table>
          </div>
        </div>
        <div class="fullwidth" style="padding-top: 0px; padding-bottom: 0px;">
          <div>
            <table class="settings">
              <tr>
                <td style="font-size: 0.65em;"><u>No reboot required:</u></td>
                <td></td>
              </tr>
              <tr>
                <td class="label">Name:</td>
                <td>&nbsp;
                  <input id="newDeviceName" type="text" placeholder="" maxlength="30" minlength="1">
                </td>
              </tr>
              <tr>
                <td class="label">Door Close Delay:</td>
                <td>&nbsp;
                  <input type="range" min="0" max="60" value="0" id="TTCseconds" name="TTCseconds" class="slider"
                    style="width:150px;">
                  <span style="vertical-align: middle; font-size: 0.8em"><span id="TTCsecondsValue"></span>
                    Seconds</span>
                </td>
              </tr>
              <tr>
                <td class="label">Require Password:</td>
                <td>&nbsp;
                  <input type="checkbox" id="pwreq" name="pwreq" value="no">
                  <span style="font-size: 0.8em;">default: admin/password</span>
                </td>
              </tr>
              <tr>
                <td class="label">LED on when idle:</td>
                <td>&nbsp;
                  <input type="checkbox" id="LEDidle" name="LEDidle" value="yes">
                  <span style="font-size: 0.8em;">LED will flash on activity</span>
                </td>
              </tr>
              <tr>
                <td class="label">Syslog:</td>
                <td>&nbsp;
                  <input type="checkbox" id="syslogEn" name="syslogEn" value="no" onchange="toggleSyslog()">
                  <span style="font-size: 0.8em;">Send logs to a syslog server</span>
                </td>
              </tr>
              <tr>
                <td></td>
                <td>
                  <table class="settings" id="syslogTable" style="display: none;">
                    <tr>
                      <td class="IPlabel">Syslog Server:</td>
                      <td>&nbsp;
                        <input class="syslogIPinput IPinput" id="syslogIP" type="text" placeholder="0.0.0.0"
                          minlength="7" maxlength="15" size="15">
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td style="font-size: 0.65em;"><br><u>Reboot may be required:</u></td>
                <td></td>
              </tr>
              <tr>
                <td class="label">Motion Triggers:</td>
                <td>&nbsp;
                  <input type="checkbox" id="motionMotion" name="motionMotion" value="no" disabled>
                  <label for="motionMotion">Motion</label>
                  <input type="checkbox" id="motionObstruction" name="motionObstruction" value="no">
                  <label for="motionObstruction">Obstruction</label>
                  <!--
                  <input type="checkbox" id="motionLight" name="motionLight" value="no">
                  <label for="motionLight">Light</label>
                  <input type="checkbox" id="motionDoor" name="motionDoor" value="no">
                  <label for="motionDoor">Door</label>
                  <input type="checkbox" id="motionLock" name="motionLock" value="no">
                  <label for="motionLock">Lock</label>
                  -->
                  <input type="checkbox" id="motionWallPanel" name="motionWallPanel" value="no">
                  <label for="motionWallPanel">Wall Panel</label>
                </td>
              </tr>
              <tr>
                <td style="font-size: 0.65em;"><br><u>Reboot required:</u></td>
                <td></td>
              </tr>
              <tr>
                <td class="label">Door Protocol:</td>
                <td>&nbsp;
                  <input type="radio" id="gdosec1" name="gdosecuritysetting" value="1">
                  <label for="gdosec1">Sec+</label>
                  <input type="radio" id="gdosec2" name="gdosecuritysetting" value="2">
                  <label for="gdosec2">Sec+ 2.0</label>
                </td>
              </tr>
              <tr>
                <td class="label">WiFi Version:</td>
                <td>&nbsp;
                  <input type="radio" id="wifiPhyMode0" name="wifiPhyMode" value="0">
                  <label for="wifiPhyMode0">Auto</label>
                  <input type="radio" id="wifiPhyMode1" name="wifiPhyMode" value="1">
                  <label for="wifiPhyMode1">802.11b</label>
                  <input type="radio" id="wifiPhyMode2" name="wifiPhyMode" value="2">
                  <label for="wifiPhyMode2">802.11g</label>
                  <input type="radio" id="wifiPhyMode3" name="wifiPhyMode" value="3">
                  <label for="wifiPhyMode3">802.11n</label>
                </td>
              </tr>
              <tr>
                <td class="label">WiFi Tx Power:</td>
                <td>&nbsp;
                  <input type="range" min="0" max="20" value="20" id="wifiPower" name="wifiPower" class="slider"
                    style="width:100px;">
                  <span style="vertical-align: middle; font-size: 0.8em"><span id="wifiPowerValue"></span> dBm</span>
                </td>
              </tr>
              <tr>
                <td class="label">Static IP:</td>
                <td>&nbsp;
                  <input type="checkbox" id="staticIP" name="staticIP" value="no" onchange="toggleStaticIP()">
                </td>
              </tr>
              <tr>
                <td></td>
                <td>
                  <table class="settings" id="staticIPtable" style="display: none;">
                    <tr>
                      <td class="IPlabel">IP Address:</td>
                      <td>&nbsp;
                        <input class="staticIPinput IPinput" id="IPaddress" type="text" placeholder="0.0.0.0"
                          minlength="7" maxlength="15" size="15">
                      </td>
                    </tr>
                    <tr>
                      <td class="IPlabel">Netmask:</td>
                      <td>&nbsp;
                        <input class="staticIPinput IPinput" id="IPnetmask" type="text" placeholder="0.0.0.0"
                          minlength="7" maxlength="15" size="15">
                      </td>
                    </tr>
                    <tr>
                      <td class="IPlabel">Gateway:</td>
                      <td>&nbsp;
                        <input class="staticIPinput IPinput" id="IPgateway" type="text" placeholder="0.0.0.0"
                          minlength="7" maxlength="15" size="15">
                      </td>
                    </tr>
                    <tr>
                      <td class="IPlabel">DNS Server:</td>
                      <td>&nbsp;
                        <input class="staticIPinput IPinput" id="IPnameserver" type="text" placeholder="0.0.0.0"
                          minlength="7" maxlength="15" size="15">
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td class="label">Enable NTP:</td>
                <td>&nbsp;
                  <input type="checkbox" id="enableNTP" name="enableNTP" value="no" onchange="toggleTimeZone()">
                  <span style="font-size: 0.8em;">Obtain time from NTP server</span>
                </td>
              </tr>
              <tr>
                <td></td>
                <td>
                  <table class="settings" id="timeZoneTable" style="display: none;">
                    <tr>
                      <td class="IPlabel">Time Zone:</td>
                      <td>&nbsp;
                        <select class="timeZoneInput TZinput" id="timeZoneInput">
                        </select>
                      </td>
                    </tr>
                  </table>
                </td>
              </tr>
              <tr>
                <td>
                  <!--
                    Future settings go here
                  -->
                </td>
              </tr>
              <tr>
                <td class="label">Reboot Every:</td>
                <td>&nbsp;
                  <input type="number" id="rebootHours" name="rebootHours" value="0" , min="0" , max="72" , step="1">
                  Hours <span style="font-size: 0.8em;">(never:0, min:1, max:72)</span>
                </td>
              </tr>
              <tr>
                <td></td>
              </tr>
              <tr>
                <td colspan="2" style="text-align: center;">
                  <input type="button" value="Save Settings" onclick="saveSettings()">&nbsp;
                  <input type="button" value="Reset Door" onclick="resetDoor()">&nbsp;
                  <input type="button" value="Set WiFi SSID" onclick="setSSID()">
                </td>
              </tr>
            </table>
          </div>
        </div>
      </div>
    </main>
    <!-- Footer section of page ------------------------------------------------------------------>
    <footer>
      <div class="footer">
        <p style="margin:0px;">For documentation and support see the <a
            href="https://github.com/ratgdo/homekit-ratgdo">GitHub</a>
          page.<br>Copyright (c) 2023-24 <a
            href="https://github.com/ratgdo/homekit-ratgdo/graphs/contributors">homekit-ratgdo
            contributors.</a><br>Licensed under terms of the <a
            href="https://www.gnu.org/licenses/gpl-3.0.en.html">GPL-3.0
            License.</a>
        </p>
        <br>
        <table style="border-collapse: collapse">
          <tr id="freeMemRow">
            <td colspan="2" style="width: 30%; padding: 0px">
              freeHeap:&nbsp;<span id="freeHeap">0</span>&nbsp;
            </td>
            <td colspan="2" style="width: 30%; padding: 0px; text-align: center;">
              minHeap:&nbsp;<span id="minHeap">0</span>&nbsp;
            </td>
            <td colspan="2" style="width: 30%; padding: 0px; text-align: right;">
              minStack:&nbsp;<span id="minStack">0</span>&nbsp;
            </td>
          </tr>
        </table>
        <table style="border-collapse: collapse">
          <tr>
            <td style="width: 40%; padding: 0px">lastDoorChange:&nbsp;</td>
            <td style="width: 60%; padding: 0px" id="lastDoorUpdateAt"></td>
          </tr>
          <tr>
            <td style="width: 40%; padding: 0px">lastReboot:&nbsp;</td>
            <td style="width: 60%; padding: 0px" id="lastRebootAt"></td>
          </tr>
        </table>
        <p style="margin:0px;">
          <a href="logs.html" target="_blank">Show system logs</a>&nbsp;(crashCount:&nbsp;<span id="crashCount"></span>)
        </p>
        <p style="margin:0px; color:red;">
          <span id="checkFlashCRC" style="display:none;">
            checkFlashCRC() failed. Flash new firmware by USB cable to recover.
          </span>
        </p>
      </div>
    </footer>
  </div>

  <!-- Popup / modal dialog ------------------------------------------------------------------>
  <div id="myModal" class="modal">
    <div class="modal-content">
      <span id="modalClose" class="close"
        onclick="document.getElementById('myModal').style.display = 'none'">&times;</span>
      <span id="modalTitle">Installed Firmware:&nbsp;<span id="firmwareVersion2">xxx</span><br></span><br>
      <div id="updateDialog" style="float: none; padding:0px">
        <span id="modalFlashCRC" style="font-size: 0.8em; display: block">xxx</span><br>
        <fieldset>
          <legend>Update from GitHub</legend>
          <table>
            <tr>
              <td style="text-align: right;">Latest available at GitHub:</td>
              <td><span id="newversion2"></span><span id="dotdot2"></span></td>
            </tr>
          </table>
          <input type="button" value="Check for update" onclick="checkVersion('dotdot2')">
          <input type="checkbox" id="prerelease" name="prerelease" value="no">
          <span style="font-size: 0.8em;">Include pre-releases</span>
          <input type="button" value="Update" style="float: right;" onclick="firmwareUpdate(true)">
        </fieldset>
        <br>
        <fieldset>
          <legend>Update from local file</legend>
          <input type="file" accept=".bin,.bin.gz" name="firmware" style="border: 0px; padding: 0px;">
          <input type="button" value="Update" style="float: right;" onclick="firmwareUpdate(false)">
        </fieldset>
      </div>
      <div id="updateDotDot" style="display:none; float: none; padding:0px">
        <span id="updateMsg">Do not close browser until update completes. Device will reboot when complete.<br></span>
        <span id="updatePercent" style="display:none;"></span><span id="dotdot3"></span>
        <br><br>
      </div>
    </div>
  </div>

  <!-- Simple please wait dialog --------------------------------------------------------------->
  <!-- Only used for CRC check at reboot which we no longer do.
  <div id="pleaseWait" class="modal">
    <div class="modal-content">
      Checking flash CRC. please wait...
    </div>
  </div>
  -->

  <!-- Initialization scripts ------------------------------------------------------------------>
  <script>
    console.log('Client UUID: ' + clientUUID);
    const loaderElem = document.getElementById("loader"); // Spinner while pages load


    // Retrieve status from the server
    loaderElem.style.visibility = "visible";
    checkStatus()
      .then(() => {
        loaderElem.style.visibility = "hidden";
        checkVersion("dotdot1");
      });
    // Load time zone info, this runs asynchronously
    loadTimeZones();

    // reload status if visibility change
    window.addEventListener("visibilitychange", (event) => {
      if (document.visibilityState === "visible") {
        loaderElem.style.visibility = "visible";
        checkStatus()
          .then(() => {
            loaderElem.style.visibility = "hidden";
            checkVersion("dotdot1");
          });
      }
    });

    // Handle mobile device swipe-down to reload...
    document.addEventListener('touchstart', function (e) { swipeStart(e); }, false);
    document.addEventListener('touchend', function (e) { swipeEnd(e); }, false);

    // When the user clicks anywhere outside of the modal, close it
    /*** Disable this as it causes countdown/reboot/update dialog to hide in the middle of activity.
    const modal = document.getElementById("myModal");
    window.onclick = function (event) {
      if (event.target == modal) {
        modal.style.display = "none";
      }
    };
    */

    document.getElementById("settings-icon").onclick = async () => {
      // Only display the Settings page if user is authenticated.
      if (await checkAuth()) {
        showSettings();
        history.pushState("settings", "");
      }
    };
    function showSettings() {
      document.getElementById("settings-icon").style.display = "none";
      document.getElementById("main-page").style.display = "none";
      document.getElementById("settings-page").style.display = "block";
      document.getElementById("main-icon").style.display = "block";
      loadTZinfo(document.getElementById("timeZoneInput"));
    }
    function showMainpage() {
      document.getElementById("main-icon").style.display = "none";
      document.getElementById("settings-page").style.display = "none";
      document.getElementById("main-page").style.display = "block";
      document.getElementById("settings-icon").style.display = "block";
    };
    history.replaceState("mainpage", "");
    window.addEventListener("popstate", (e) => {
      if (e.state === "mainpage") {
        showMainpage();
      }
      else if (e.state === "settings") {
        showSettings();
      }
    });

    // Check new passwords match when typed in.
    newPW = document.getElementById("newPassword");
    confirmPW = document.getElementById("confirmPassword");
    matchMsg = document.getElementById("matchMsg");
    newPW.oninput = (event) => {
      if (newPW.value === confirmPW.value) {
        matchMsg.innerHTML = "<br>";
      }
      else {
        matchMsg.innerHTML = "Passwords do not match<br>";
      }
    };
    confirmPW.oninput = (event) => {
      if (newPW.value === confirmPW.value) {
        matchMsg.innerHTML = "<br>";
      }
      else {
        matchMsg.innerHTML = "Passwords do not match<br>";
      }
    };

    // Allow only numeric keystrokes into the reboot every X hours field
    document.getElementById("rebootHours").addEventListener("keypress", (event) => {
      if (event.which < 48 || event.which > 57) {
        event.preventDefault();
      }
    });

    // Allow only numeric and dot keystrokes into IP Address fields
    Array.from(document.getElementsByClassName("IPinput")).forEach(function (inputField) {
      inputField.addEventListener("keypress", (event) => {
        if ((event.which < 48 || event.which > 57) && (event.which != 46)) {
          event.preventDefault();
        }
      });
    });

    // This handles user control of sliders
    WiFiSlider = document.getElementById("wifiPower");
    WiFiText = document.getElementById("wifiPowerValue");
    WiFiText.innerHTML = WiFiSlider.value;
    WiFiSlider.oninput = function () {
      WiFiText.innerHTML = this.value;
    };
    TTCslider = document.getElementById("TTCseconds");
    TTCtext = document.getElementById("TTCsecondsValue");
    TTCtext.innerHTML = TTCslider.value;
    TTCslider.oninput = function () {
      TTCtext.innerHTML = this.value;
    }
  </script>
</body>

</html>