mirror of
https://github.com/esphome/esphome.git
synced 2024-11-25 00:18:11 +01:00
Add clean MQTT button to dashboard (#139)
This commit is contained in:
parent
12f20fc3cf
commit
ef54e33b70
4 changed files with 87 additions and 4 deletions
|
@ -451,6 +451,8 @@ def parse_args(argv):
|
|||
default=6052)
|
||||
dashboard.add_argument("--password", help="The optional password to require for all requests.",
|
||||
type=str, default='')
|
||||
dashboard.add_argument("--open-ui", help="Open the dashboard UI in a browser.",
|
||||
action='store_true')
|
||||
|
||||
return parser.parse_args(argv[1:])
|
||||
|
||||
|
|
|
@ -117,6 +117,13 @@ class EsphomeyamlValidateHandler(EsphomeyamlCommandWebSocket):
|
|||
return ["esphomeyaml", config_file, "config"]
|
||||
|
||||
|
||||
class EsphomeyamlCleanMqttHandler(EsphomeyamlCommandWebSocket):
|
||||
def build_command(self, message):
|
||||
js = json.loads(message)
|
||||
config_file = os.path.join(CONFIG_DIR, js['configuration'])
|
||||
return ["esphomeyaml", config_file, "clean-mqtt"]
|
||||
|
||||
|
||||
class SerialPortRequestHandler(BaseHandler):
|
||||
def get(self):
|
||||
if not self.is_authenticated():
|
||||
|
@ -213,6 +220,7 @@ def make_app(debug=False):
|
|||
(r"/run", EsphomeyamlRunHandler),
|
||||
(r"/compile", EsphomeyamlCompileHandler),
|
||||
(r"/validate", EsphomeyamlValidateHandler),
|
||||
(r"/clean-mqtt", EsphomeyamlCleanMqttHandler),
|
||||
(r"/download.bin", DownloadBinaryRequestHandler),
|
||||
(r"/serial-ports", SerialPortRequestHandler),
|
||||
(r"/wizard.html", WizardRequestHandler),
|
||||
|
@ -251,6 +259,12 @@ def start_web_server(args):
|
|||
args.port, CONFIG_DIR)
|
||||
app = make_app(args.verbose)
|
||||
app.listen(args.port)
|
||||
|
||||
if args.open_ui:
|
||||
import webbrowser
|
||||
|
||||
webbrowser.open('localhost:{}'.format(args.port))
|
||||
|
||||
try:
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
except KeyboardInterrupt:
|
||||
|
|
|
@ -159,6 +159,10 @@
|
|||
margin-right: 24px;
|
||||
width: 350px;
|
||||
}
|
||||
|
||||
.dropdown-trigger {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
|
@ -191,7 +195,7 @@
|
|||
|
||||
<main>
|
||||
<div class="container">
|
||||
{% for file, full_path in zip(files, full_path_files) %}
|
||||
{% for i, (file, full_path) in enumerate(zip(files, full_path_files)) %}
|
||||
<div class="row">
|
||||
<div class="col s8 offset-s2 m10 offset-m1 l12">
|
||||
<div class="card horizontal">
|
||||
|
@ -200,7 +204,10 @@
|
|||
</div>
|
||||
<div class="card-stacked">
|
||||
<div class="card-content">
|
||||
<span class="card-title">{{ escape(file) }}</span>
|
||||
<span class="card-title">
|
||||
{{ escape(file) }}
|
||||
<i class="material-icons right dropdown-trigger" data-target="dropdown-{{ i }}">more_vert</i>
|
||||
</span>
|
||||
<p>
|
||||
Full path: <code class="inlinecode">{{ escape(full_path) }}</code>
|
||||
</p>
|
||||
|
@ -211,6 +218,9 @@
|
|||
<a href="#" class="action-show-logs" data-node="{{ file }}">Show Logs</a>
|
||||
<a href="#" class="action-validate" data-node="{{ file }}">Validate</a>
|
||||
</div>
|
||||
<ul id="dropdown-{{ i }}" class="dropdown-content">
|
||||
<li><a href="#" class="action-clean-mqtt" data-node="{{ file }}">Clean MQTT</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -462,6 +472,18 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div id="modal-clean-mqtt" class="modal modal-fixed-footer">
|
||||
<div class="modal-content">
|
||||
<h4>Clean MQTT discovery <code class="inlinecode filename"></code></h4>
|
||||
<div class="log-container">
|
||||
<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>
|
||||
|
||||
<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>
|
||||
|
@ -539,6 +561,7 @@
|
|||
if (allEqual)
|
||||
return;
|
||||
}
|
||||
const hasNewPort = response.length >= ports.length;
|
||||
|
||||
ports = response;
|
||||
|
||||
|
@ -559,7 +582,7 @@
|
|||
}
|
||||
|
||||
M.FormSelect.init(portSelect, {});
|
||||
if (!begin)
|
||||
if (!begin && hasNewPort)
|
||||
M.toast({html: "Discovered new serial port."});
|
||||
});
|
||||
};
|
||||
|
@ -784,6 +807,48 @@
|
|||
link.click();
|
||||
});
|
||||
|
||||
const cleanMqttModalElem = document.getElementById("modal-clean-mqtt");
|
||||
|
||||
document.querySelectorAll(".action-clean-mqtt").forEach((btn) => {
|
||||
btn.addEventListener('click', (e) => {
|
||||
configuration = e.target.getAttribute('data-node');
|
||||
const modalInstance = M.Modal.getInstance(cleanMqttModalElem);
|
||||
const log = cleanMqttModalElem.querySelector(".log");
|
||||
log.innerHTML = "";
|
||||
const stopLogsButton = cleanMqttModalElem.querySelector(".stop-logs");
|
||||
let stopped = false;
|
||||
stopLogsButton.innerHTML = "Stop";
|
||||
modalInstance.open();
|
||||
|
||||
const filenameField = cleanMqttModalElem.querySelector('.filename');
|
||||
filenameField.innerHTML = configuration;
|
||||
|
||||
const logSocket = new WebSocket(wsUrl + "/clean-mqtt");
|
||||
logSocket.addEventListener('message', (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
if (data.event === "line") {
|
||||
const msg = data.data;
|
||||
log.innerHTML += colorReplace(msg);
|
||||
} else if (data.event === "exit") {
|
||||
stopLogsButton.innerHTML = "Close";
|
||||
stopped = true;
|
||||
}
|
||||
});
|
||||
logSocket.addEventListener('open', () => {
|
||||
const msg = JSON.stringify({configuration: configuration});
|
||||
logSocket.send(msg);
|
||||
});
|
||||
logSocket.addEventListener('close', () => {
|
||||
if (!stopped) {
|
||||
M.toast({html: 'Terminated process.'});
|
||||
}
|
||||
});
|
||||
modalInstance.options.onCloseStart = () => {
|
||||
logSocket.close();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
const modalSetupElem = document.getElementById("modal-wizard");
|
||||
const setupWizardStart = document.getElementById('setup-wizard-start');
|
||||
const startWizard = () => {
|
||||
|
|
|
@ -83,7 +83,9 @@ def clear_topic(config, topic, username=None, password=None, client_id=None):
|
|||
discovery_prefix = config[CONF_MQTT].get(CONF_DISCOVERY_PREFIX, u'homeassistant')
|
||||
name = config[CONF_ESPHOMEYAML][CONF_NAME]
|
||||
topic = u'{}/+/{}/#'.format(discovery_prefix, name)
|
||||
_LOGGER.info(u"Clearing messages from %s", topic)
|
||||
_LOGGER.info(u"Clearing messages from '%s'", topic)
|
||||
_LOGGER.info(u"Please close this window when no more messages appear and the "
|
||||
u"MQTT topic has been cleared of retained messages.")
|
||||
|
||||
def on_message(client, userdata, msg):
|
||||
if not msg.payload or not msg.retain:
|
||||
|
|
Loading…
Reference in a new issue