142 lines
3.5 KiB
HTML
142 lines
3.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|
<title>Fáfnir Doorbell</title>
|
|
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha256-4+XzXVhsDmqanXGHaHvgh1gMQKX40OUvDEBTu8JcmNs=" crossorigin="anonymous"></script>
|
|
<style>
|
|
body {
|
|
background-color: black;
|
|
color: white;
|
|
}
|
|
|
|
#status_box {
|
|
margin: auto;
|
|
width: 30%;
|
|
border-style: ridge;
|
|
border-color: yellow;
|
|
border-width: 5px;
|
|
padding: 15px;
|
|
}
|
|
|
|
#status_box th {
|
|
text-align: left;
|
|
padding-right: 2em;
|
|
}
|
|
|
|
.status {
|
|
font-family: monospace;
|
|
font-size: 250%;
|
|
font-variant: small-caps;
|
|
}
|
|
|
|
.connected {
|
|
color: green;
|
|
}
|
|
|
|
.disconnected {
|
|
color: red;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<section id="status_box">
|
|
<table>
|
|
<tr>
|
|
<th>Status:</th>
|
|
<td id="status_line"></td>
|
|
</tr><tr>
|
|
<th>Last Ring:</th>
|
|
<td id="last_ring" class="status"></td>
|
|
</tr>
|
|
</table>
|
|
</section>
|
|
|
|
<audio id="chime" src="indoor.mp3"></audio>
|
|
<template id="connected">
|
|
<span class="status connected">Connected</span>
|
|
</template>
|
|
<template id="disconnected">
|
|
<span class="status disconnected">Disconnected</span>
|
|
</template>
|
|
<script>
|
|
"use strict";
|
|
|
|
const CONNECT_TIMEOUT = 1_000;
|
|
const KEEPALIVE_TIMEOUT = 10_000;
|
|
|
|
let sse;
|
|
let reconnect;
|
|
let ping;
|
|
|
|
connect();
|
|
function connect() {
|
|
console.log('connecting');
|
|
set_status('disconnected');
|
|
if (sse) {
|
|
sse.onopen = undefined;
|
|
sse.close();
|
|
}
|
|
if (ping) { clearTimeout(ping); }
|
|
sse = new EventSource('events');
|
|
|
|
sse.onopen = () => {
|
|
console.log('connected');
|
|
set_status('connected');
|
|
clearTimeout(reconnect);
|
|
keepalive();
|
|
|
|
sse.onerror = () => {
|
|
console.log('sse error');
|
|
connect();
|
|
};
|
|
|
|
sse.addEventListener('ping', msg => {
|
|
clearTimeout(ping);
|
|
keepalive();
|
|
});
|
|
|
|
sse.addEventListener('ring', msg => {
|
|
let chime = document.getElementById('chime');
|
|
if (chime.paused) {
|
|
chime.play();
|
|
}
|
|
|
|
let now = new Date();
|
|
let hours = now.getHours();
|
|
let hours12 = (hours + 11) % 12 + 1;
|
|
let mins = now.getMinutes();
|
|
mins = (mins < 10) ? '0' + mins : mins;
|
|
let secs = now.getSeconds();
|
|
secs = (secs < 10) ? '0' + secs : secs;
|
|
let demidiemity = (hours / 12)|0 ? 'PM' : 'AM';
|
|
$('#last_ring').text(`${hours12}:${mins}:${secs} ${demidiemity}`);
|
|
});
|
|
};
|
|
|
|
reconnect = setTimeout(connect, CONNECT_TIMEOUT);
|
|
}
|
|
|
|
function get_template(name) {
|
|
return $('#' + name).map((_, n) => n.content).clone();
|
|
}
|
|
|
|
function keepalive() {
|
|
ping = setTimeout(() => {
|
|
console.warn('keepalive ping timed out');
|
|
connect();
|
|
}, KEEPALIVE_TIMEOUT);
|
|
}
|
|
|
|
function set_status(status_template) {
|
|
const template = get_template(status_template);
|
|
const status_line = $('#status_line');
|
|
status_line.empty();
|
|
status_line.append(template);
|
|
}
|
|
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|