esphome/esphome/dashboard/templates/index.html

506 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>ESPHome Dashboard</title>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="stylesheet" href="{{ get_static_file_url('materialize.min.css') }}">
<link rel="stylesheet" href="{{ get_static_file_url('materialize-stepper.min.css') }}">
<link rel="stylesheet" href="{{ get_static_file_url('esphome.css') }}">
<link rel="shortcut icon" href="{{ get_static_file_url('favicon.ico') }}">
<script src="{{ get_static_file_url('jquery.min.js') }}"></script>
<script src="{{ get_static_file_url('jquery-ui.min.js') }}"></script>
<script src="{{ get_static_file_url('materialize.min.js') }}"></script>
<script src="{{ get_static_file_url('jquery.validate.min.js') }}"></script>
<script src="{{ get_static_file_url('materialize-stepper.min.js') }}"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<script>const relative_url = "{{ relative_url }}";</script>
{% if streamer_mode %}
<style>
.log-secret {
visibility: hidden !important;
}
</style>
{% end %}
</head>
<body>
<header>
<nav>
<div class="nav-wrapper indigo">
<a href="#" class="brand-logo left">ESPHome Dashboard</a>
<div class="select-port-container right" id="select-port-target">
<select></select>
</div>
</div>
</nav>
{% if begin %}
<div class="tap-target pink lighten-1 select-port" data-target="select-port-target">
<div class="tap-target-content">
<h5>Select Upload Port</h5>
<p>
Here you can select where ESPHome will attempt to show logs and upload firmwares to.
For newly plugged in serial devices to be detected, restart the add-on.
(Also see <a href="https://esphome.io/guides/faq#i-can-t-get-flashing-over-usb-to-work" target="_blank">
esphomeflasher</a>)
</p>
</div>
</div>
{% end %}
<div class="ribbon"></div>
</header>
<main>
<div class="container">
{% for i, entry in enumerate(entries) %}
<div class="row entry-row" data-node="{{ entry.filename }}">
<div class="col s12 m10 offset-m1 l12">
<div class="card horizontal">
<div class="card-image center-align hide-on-small-only">
<i class="material-icons very-large icon-grey">memory</i>
</div>
<div class="card-stacked">
<div class="card-content">
<span class="card-title">
{{ escape(entry.name) }}
<i class="material-icons right dropdown-trigger" data-target="dropdown-{{ i }}">more_vert</i>
</span>
<p>
<span class="status-indicator unknown" data-node="{{ entry.filename }}">
<span class="status-indicator-icon"></span>
<span class="status-indicator-text"></span></span>.
Full path: <code class="inlinecode">{{ escape(entry.full_path) }}</code>
</p>
{% if entry.update_available %}
<p class="update-available" data-node="{{ entry.filename }}">
<i class="material-icons">system_update</i>
Update Available! {{ entry.update_old }} &#x27A1;&#xFE0F;{{ entry.update_new }}
</p>
{% end %}
</div>
<div class="card-action">
<a class="action-upload" data-node="{{ entry.filename }}">Upload</a>
<a class="action-edit" data-node="{{ entry.filename }}">Edit</a>
<a class="action-show-logs" data-node="{{ entry.filename }}">Show Logs</a>
<a class="action-validate" data-node="{{ entry.filename }}">Validate</a>
</div>
<ul id="dropdown-{{ i }}" class="select-action dropdown-content card-dropdown-action">
<li><a class="action-clean-mqtt" data-node="{{ entry.filename }}">Clean MQTT</a></li>
<li><a class="action-clean" data-node="{{ entry.filename }}">Clean Build</a></li>
<li><a class="action-compile" data-node="{{ entry.filename }}">Compile</a></li>
<li><a class="action-delete" data-node="{{ entry.filename }}">Delete</a></li>
</ul>
</div>
</div>
</div>
</div>
{% end %}
</div>
<div id="modal-logs" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Show Logs <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Close</a>
</div>
</div>
<div id="modal-upload" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Compile And Upload <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
<div class="modal-footer">
<a href="https://esphome.io/guides/faq.html#i-can-t-get-flashing-over-usb-to-work" target="_blank"
class="tooltipped" data-position="left" data-tooltip="Flash using esphomeflasher" rel="noreferrer">
<i class="material-icons flash-using-esphomeflasher">help_outline</i>
</a>
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<div id="modal-compile" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Compile <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
<div class="modal-footer">
<a href="https://esphome.io/guides/faq.html#i-can-t-get-flashing-over-usb-to-work"
target="_blank"
class="tooltipped" data-position="left" data-tooltip="Flash using esphomeflasher" rel="noreferrer">
<i class="material-icons flash-using-esphomeflasher">help_outline</i>
</a>
<a class="modal-close waves-effect waves-green btn-flat disabled download-binary">Download Binary</a>
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<div id="modal-validate" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Validate <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<div id="modal-wizard" class="modal">
<div class="modal-content">
<form action="/wizard.html" method="POST">
<ul class="stepper linear">
<li class="step active">
<div class="step-title waves-effect">Introduction And Name</div>
<div class="step-content">
<div class="row">
<p>
Hi there! This is the ESPHome setup wizard. It will guide you through setting up
your first ESP8266 or ESP32-powered device using ESPHome.
</p>
<a href="https://www.espressif.com/en/products/hardware/esp8266ex/overview" target="_blank">ESP8266s</a> and
their successors (the <a href="https://www.espressif.com/en/products/hardware/esp32/overview" target="_blank">ESP32s</a>)
are great low-cost microcontrollers that can communicate with the outside world using WiFi.
They're found in many devices such as the popular Sonoff/iTead, but also exist as development boards
such as the <a href="https://esphome.io/devices/nodemcu_esp8266.html" rel="noreferrer" target="_blank">NodeMCU</a>.
<p>
</p>
<a href="https://esphome.io/index.html" rel="noreferrer" target="_blank">ESPHome</a>,
the tool you're using here, creates custom firmwares for these devices using YAML configuration
files (similar to the ones you might be used to with Home Assistant).
<p>
</p>
This wizard will create a basic YAML configuration file for your "node" (the microcontroller).
Later, you will be able to customize this file and add some of ESPHome's many
integrations.
<p>
<p>
First, I need to know what this node should be called. Choose this name wisely, it should be unique among
all your ESPs.
Names must be <strong>lowercase</strong> and <strong>must not contain spaces</strong> (allowed characters: <code class="inlinecode">a-z</code>,
<code class="inlinecode">0-9</code> and <code class="inlinecode">_</code>)
</p>
<div class="input-field col s12">
<input id="node_name" class="validate" type="text" name="name" required>
<label for="node_name">Name of node</label>
</div>
</div>
<div class="step-actions">
<button class="waves-effect waves-dark btn indigo next-step">CONTINUE</button>
</div>
</div>
</li>
<li class="step">
<div class="step-title waves-effect">Device Type</div>
<div class="step-content">
<div class="row">
<p>
Great! Now I need to know what type of microcontroller you're using so that I can compile firmware for them.
Please choose the board you're using below.
</p>
<p>
If you're not sure you can also use similar ones or even the
"Generic" option. In most cases that will work too.
</p>
<div class="input-field col s12">
<select id="board" name="board" required>
<optgroup label="ESP8266">
<option value="esp01_1m">Generic ESP8266 (for example Sonoff)</option>
<option value="nodemcuv2">NodeMCU</option>
<option value="d1_mini">Wemos D1 and Wemos D1 mini</option>
<option value="d1_mini_lite">Wemos D1 mini Lite</option>
<option value="d1_mini_pro">Wemos D1 mini Pro</option>
<option value="huzzah">Adafruit HUZZAH ESP8266</option>
<option value="oak">DigiStump Oak</option>
<option value="thing">Sparkfun ESP8266 Thing</option>
<option value="thingdev">Sparkfun ESP8266 Thing - Dev Board</option>
</optgroup>
<optgroup label="ESP32">
<option value="esp-wrover-kit">Generic ESP32 (WROVER Module)</option>
<option value="nodemcu-32s">NodeMCU-32S</option>
<option value="lolin_d32">Wemos Lolin D32</option>
<option value="lolin_d32_pro">Wemos Lolin D32 Pro</option>
<option value="featheresp32">Adafruit ESP32 Feather</option>
<option value="m5stack-core-esp32">M5Stack Core ESP32</option>
</optgroup>
<optgroup label="Other ESP8266s">
<option value="gen4iod">4D Systems gen4 IoD Range</option>
<option value="wifi_slot">Amperka WiFi Slot</option>
<option value="espduino">Doit ESPDuino</option>
<option value="espectro">DycodeX ESPectro Core</option>
<option value="espino">ESPino</option>
<option value="esp_wroom_02">Espressif ESP-WROOM-02 module</option>
<option value="esp12e">Espressif ESP-12E module</option>
<option value="esp01">Espressif ESP-01 512k module</option>
<option value="esp07">Espressif ESP-07 module</option>
<option value="esp8285">Generic ESP8285 module</option>
<option value="espresso_lite_v1">ESPert ESPresso Lite 1.0</option>
<option value="espresso_lite_v2">ESPert ESPresso Lite 2.0</option>
<option value="phoenix_v1">ESPert Phoenix 1.0</option>
<option value="wifinfo">WiFInfo</option>
<option value="heltec_wifi_kit_8">Heltec WiFi kit 8</option>
<option value="nodemcu">NodeMCU 0.9</option>
<option value="modwifi">Olimex MOD-WIFI</option>
<option value="wio_link">SeedStudio Wio Link</option>
<option value="wio_node">SeedStudio Wio Node</option>
<option value="sparkfunBlynk">Sparkfun Blynk Board</option>
<option value="esp210">SweetPea ESP-210</option>
<option value="espinotee">ThaiEasyElec ESPino</option>
<option value="d1">Wemos D1 Revision 1</option>
<option value="wifiduino">WiFiDuino</option>
<option value="xinabox_cw01">XinaBox CW01</option>
</optgroup>
<optgroup label="Other ESP32s">
<option value="lolin32">Wemos Lolin 32</option>
<option value="esp32dev">Espressif ESP32 Dev Module</option>
<option value="m5stack-fire">M5Stack FIRE</option>
<option value="wemosbat">Wemos WiFi &amp; Bluetooth Battery</option>
<option value="node32s">Aiyarafun Node32s</option>
<option value="espea32">April Brother ESPea32</option>
<option value="firebeetle32">DFRobot FireBeetle-ESP32</option>
<option value="esp32doit-devkit-v1">Doit ESP32 Devkit v1</option>
<option value="pocket_32">Dongsen Tech Pocket 32</option>
<option value="espectro32">DycodeX ESPectro32</option>
<option value="esp32vn-iot-uno">ESP32vn IoT Uno</option>
<option value="esp320">Electronic SweetPeas ESP320</option>
<option value="pico32">Espressif ESP32 Pico Kit</option>
<option value="odroid_esp32">Hardkernel Odroid GO</option>
<option value="heltec_wifi_kit_32">Heltec WIFI Kit 32</option>
<option value="heltec_wifi_lora_32">Heltec WIFI LoRa 32</option>
<option value="hornbill32dev">Hornbill ESP32 Dev</option>
<option value="hornbill32minima">Hornbill ESP32 Minima</option>
<option value="intorobot">IntoRobot Fig</option>
<option value="mhetesp32devkit">MH-ET Live ESP32 Devkit</option>
<option value="mhetesp32minikit">MH-ET Live ESP32 Minikit</option>
<option value="nano32">MakerAsia Nano32</option>
<option value="microduino-core-esp32">Microduino Core ESP32</option>
<option value="quantum">Noduino Quantum</option>
<option value="esp32-evb">Olimex ESP32-EVB</option>
<option value="esp32-gateway">Olimex ESP32-GATEWAY</option>
<option value="esp32-pro">Olimex ESP32-PRO</option>
<option value="onehorse32dev">Onehorse ESP32 Dev Module</option>
<option value="alksesp32">RoboticsBrno ALKS ESP32</option>
<option value="esp32thing">Sparkfun ESP32 Thing</option>
<option value="ttgo-lora32-v1">TTGO LoRa32-OLED v1</option>
<option value="espino32">ThaiEasyElec ESPino32</option>
<option value="widora-air">Widora AIR</option>
<option value="xinabox_cw02">XinaBox CW02</option>
<option value="iotbusio">oddWires IoT-Bus Io</option>
<option value="iotbusproteus">oddWires Proteus IoT-Bus</option>
<option value="nina_w10">u-blox NINA-W10 series</option>
<option value="bpi-bit">BananaPi-Bit</option>
<option value="d-duino-32">DSTIKE D-duino-32</option>
<option value="fm-devkit">ESP32 FM DevKit</option>
<option value="esp32-poe">OLIMEX ESP32-PoE</option>
<option value="oroca_edubot">OROCA EduBot</option>
<option value="lopy">Pycom LoPy</option>
<option value="lopy4">Pycom LoPy4</option>
<option value="wesp32">Silicognition wESP32</option>
<option value="ttgo-t-beam">TTGO T-Beam</option>
<option value="turta_iot_node">Turta IoT Node</option>
</optgroup>
</select>
</div>
</div>
<div class="step-actions">
<button class="waves-effect waves-dark btn indigo next-step">CONTINUE</button>
</div>
</div>
</li>
<li class="step">
<div class="step-title waves-effect">WiFi And Over-The-Air Updates</div>
<div class="step-content">
<div class="row">
<p>
Thanks! Now I need to know what WiFi Access Point I should instruct the node to connect to.
Please enter an SSID (name of the WiFi network) and password (leave empty for no password).
</p>
<div class="input-field col s12">
<input id="wifi_ssid" class="validate" type="text" name="ssid" required>
<label for="wifi_ssid">WiFi SSID</label>
</div>
<div class="input-field col s12">
<input id="wifi_password" name="psk" type="password">
<label for="wifi_password">WiFi Password</label>
</div>
<p>
ESPHome automatically sets up an Over-The-Air update server on the node
so that you only need to flash a firmware via USB once. This password
is also used to connect to the ESP from Home Assistant.
Optionally, you can set a password for this upload process here:
</p>
<div class="input-field col s12">
<input id="password" class="validate" name="password" type="password">
<label for="password">Access Password</label>
</div>
</div>
<div class="step-actions">
<button class="waves-effect waves-dark btn indigo next-step">CONTINUE</button>
</div>
</div>
</li>
<li class="step">
<div class="step-title waves-effect">Done!</div>
<div class="step-content">
<p>
Hooray! 🎉🎉🎉 You've successfully created your first ESPHome configuration file.
When you click Submit, the wizard will save a configuration file under
<code class="inlinecode">&lt;HASS_CONFIG_FOLDER&gt;/esphome/&lt;NAME_OF_NODE&gt;.yaml</code>.
</p>
<h5>Next steps</h5>
<ul class="browser-default">
<li>
Flash the firmware. This can be done using the “UPLOAD” option in the dashboard. See
<a href="https://esphome.io/index.html#devices" rel="noreferrer" target="_blank">this</a>
for guides on how to flash different types of devices. For newly plugged in serial
devices to be detected, restart the add-on.
</li>
<li>
With the current configuration, your node will only connect to WiFi. To make it
actually <i>do</i> stuff, follow
<a href="https://esphome.io/guides/getting_started_hassio.html#adding-some-basic-features"
rel="noreferrer">
the rest of the getting started guide
</a>.
</li>
<li>
See the <a href="https://esphome.io/index.html" rel="noreferrer"
target="_blank">ESPHome index</a>
for a list of supported sensors/devices.
</li>
<li>
Join the <a href="https://discord.gg/KhAMKrd" target="_blank">Discord server</a> and
say hi! Discord's the best place to ask if you have issues/ideas.
</li>
<li>
Star <a href="https://github.com/esphome/esphome" target="_blank">ESPHome</a> on GitHub
if you find this software awesome and report issues using the bug trackers there.
</li>
</ul>
<div class="step-actions">
<button class="waves-effect waves-dark btn indigo" type="submit">SUBMIT</button>
</div>
</div>
</li>
</ul>
</form>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat">Abort</a>
</div>
</div>
<div id="modal-clean-mqtt" class="modal modal-fixed-footer">
<div class="modal-content">
<div>
<h4>Clean MQTT discovery <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Close</a>
</div>
</div>
<div id="modal-clean" class="modal modal-fixed-footer">
<div class="modal-content">
<div>
<h4>Clean Build Files <code class="inlinecode filename"></code></h4>
<pre class="log"></pre>
</div>
</div>
<div class="modal-footer">
<a class="modal-close waves-effect waves-green btn-flat stop-logs">Stop</a>
</div>
</div>
<div id="modal-editor" class="modal modal-fixed-footer">
<div class="modal-content">
<h4>Edit <code class="inlinecode filename"></code></h4>
<div id="editor">
</div>
</div>
<div class="modal-footer">
<a class="waves-effect waves-green btn-flat save-button">Save</a>
<a class="modal-close waves-effect waves-green btn-flat">Close</a>
</div>
</div>
<a class="btn-floating btn-large ribbon-fab waves-effect waves-light pink accent-2" id="setup-wizard-start">
<i class="material-icons">add</i>
</a>
{% if len(entries) == 0 %}
<div class="tap-target pink lighten-1 setup-wizard" data-target="setup-wizard-start">
<div class="tap-target-content">
<h5>Set up your first Node</h5>
<p>
Huh... It seems like you you don't have any ESPHome configuration files yet...
Fortunately, there's a setup wizard that will step you through setting up your first node 🎉
</p>
</div>
</div>
{% end %}
</main>
<footer class="page-footer indigo darken-1">
<div class="container">
</div>
<div class="footer-copyright">
<div class="container">
© 2019 Copyright Otto Winter, Made with <a class="grey-text text-lighten-4" href="https://materializecss.com/" target="_blank">Materialize</a>
<a class="grey-text text-lighten-4 right" href="{{ docs_link }}" target="_blank" rel="noreferrer">ESPHome {{ version }} Documentation</a>
</div>
</div>
</footer>
<script src="{{ get_static_file_url('ace.js') }}" type="text/javascript" charset="utf-8"></script>
<script src="{{ get_static_file_url('esphome.js') }}" type="text/javascript"></script>
{% if len(entries) == 0 %}
<script>
document.addEventListener('DOMContentLoaded', () => {
const tapTargetElem = document.querySelector('.tap-target.setup-wizard');
const tapTargetInstance = M.TapTarget.getInstance(tapTargetElem);
tapTargetInstance.options.onOpen = () => {
$('.tap-target-origin').on('click', () => {
startWizard();
});
};
tapTargetInstance.open();
});
</script>
{% end %}
{% if begin %}
<script>
window.history.replaceState({}, document.title, "/");
document.addEventListener('DOMContentLoaded', () => {
const tapTargetElem = document.querySelector('.tap-target.select-port');
const tapTargetInstance = M.TapTarget.getInstance(tapTargetElem);
tapTargetInstance.open();
tapTargetInstance.contentEl.style["top"] = "300px";
tapTargetInstance.contentEl.style["padding"] = "250px";
tapTargetInstance.waveEl.style["top"] = "250px";
tapTargetInstance.waveEl.style["left"] = "250px";
tapTargetInstance.waveEl.style["width"] = "300px";
tapTargetInstance.waveEl.style["height"] = "300px";
});
</script>
{% end %}
</body>
</html>