aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authors-ol <s+removethis@s-ol.nu>2024-03-09 23:33:42 +0000
committers-ol <s+removethis@s-ol.nu>2024-03-09 23:40:33 +0000
commit41fa62d188889dc27ad65ff47543b0184041824c (patch)
tree73365650c70b791ccf97146feeaa7043691c49eb
parentweb: add manual control (diff)
downloadt937-serial-41fa62d188889dc27ad65ff47543b0184041824c.tar.gz
t937-serial-41fa62d188889dc27ad65ff47543b0184041824c.zip
web: basic UI for start/stop
-rw-r--r--web/index.html26
-rw-r--r--web/main.js75
2 files changed, 88 insertions, 13 deletions
diff --git a/web/index.html b/web/index.html
index 9e79aa0..c778c46 100644
--- a/web/index.html
+++ b/web/index.html
@@ -5,13 +5,33 @@
</head>
<body>
<nav>
- <label id="status"></label>
+ <label id="temps"></label>
</nav>
<aside>
<section>
<h1>device</h1>
- <button id="connect">connect</button>
- <button id="disconnect">disconnect</button>
+ <div>
+ <label id="status"></label>
+ <button id="connect">connect</button>
+ </div>
+ <div>
+ <select id="profile" value="">
+ <option value="">none</option>
+ <option value="0">profile 1</option>
+ <option value="1">profile 2</option>
+ <option value="2">profile 3</option>
+ <option value="3">profile 4</option>
+ <option value="4">profile 5</option>
+ <option value="5">profile 6</option>
+ <option value="6">profile 7</option>
+ <option value="7">profile 8</option>
+ </select>
+ <button id="start">start</button>
+ </div>
+ <div>
+ <button id="read">read</button>
+ <button id="write">write</button>
+ </div>
</section>
<section>
<h1>manual control</h1>
diff --git a/web/main.js b/web/main.js
index 7c86ffe..06577a9 100644
--- a/web/main.js
+++ b/web/main.js
@@ -26,19 +26,31 @@ window.send8 = (func, ...data) => {
};
let PORT = null; // { port, reader, writer } | null
-let STATUS = null; // null | 'connecting' | 'manual' | 'running'
+let STATUS = null; // null | 'connecting' | 'idle' | 'manual' | 'running'
+let START_TIME = null;
+let END_TIME = null;
let TIMEOUT;
let TEMPS = '';
const elements = [
- 'connect', 'disconnect', 'status',
+ 'temps',
+ 'connect', 'status', 'profile', 'start', 'read', 'write',
'heat', 'heat_mode', 'cool', 'cool_mode',
];
const el = Object.fromEntries(elements.map(id => [id, document.getElementById(id)]));
const updateUI = () => {
- el.connect.disabled = !!PORT;
- el.disconnect.disabled = !PORT;
+ el.connect.innerText = !PORT ? 'connect' : 'disconnect';
+ const ready = STATUS && STATUS !== 'connecting';
+ el.profile.disabled = STATUS === 'running';
+ el.start.innerText = (STATUS !== 'running' && STATUS !== 'manual') ? 'start' : 'stop';
+ el.start.disabled = !ready;
+ el.read.disabled = !ready;
+ el.write.disabled = !ready;
+
+ el.temps.innerText = TEMPS;
+ const end = END_TIME ?? Date.now();
+ const duration = START_TIME && Math.floor((end - START_TIME) / 1000);
switch (STATUS) {
case null:
@@ -49,9 +61,16 @@ const updateUI = () => {
el.status.innerText = '(connecting)';
break;
+ case 'idle':
+ el.status.innerText = 'idle';
+ break;
+
case 'manual':
+ el.status.innerText = `manual mode - ${duration}s`;
+ break;
+
case 'running':
- el.status.innerText = TEMPS;
+ el.status.innerText = `profile ${+el.profile.value + 1} - ${duration}s`;
break;
}
};
@@ -92,7 +111,7 @@ const onMessage = async (msg) => {
case ARG.CONNECT_CONNECTED:
console.log('connection established');
- STATUS = 'manual';
+ STATUS = 'idle';
break;
}
break;
@@ -110,7 +129,9 @@ const onMessage = async (msg) => {
const temp2 = msg.get16(2);
const temp3 = msg.get16(4);
TEMPS = `${temp1}°C - ${temp2}°C // ${temp3}°C`;
- STATUS = 'manual';
+ if (!STATUS || STATUS === 'connecting') {
+ STATUS = 'idle';
+ }
break;
}
@@ -141,6 +162,8 @@ const loop = async () => {
};
el.connect.onclick = async () => {
+ if (!!PORT) return disconnect();
+
const port = await navigator.serial.requestPort();
await port.open({ baudRate: 38400 });
console.log('opened port');
@@ -161,9 +184,6 @@ el.connect.onclick = async () => {
}
};
-el.disconnect.onclick = disconnect;
-
-
const pwms = [
[el.heat, el.heat_mode],
[el.cool, el.cool_mode],
@@ -173,6 +193,12 @@ for (const [slider, checkbox] of pwms) {
checkbox.checked = +slider.value;
await send8(FUNC.C_PWM_HEAT, +el.heat.value, el.heat_mode.checked ? ARG.PWM_ON : ARG.PWM_OFF);
await send8(FUNC.C_PWM_COOL, +el.cool.value, el.cool_mode.checked ? ARG.PWM_ON : ARG.PWM_OFF);
+ if (STATUS === 'idle' && el.heat_mode.checked) {
+ STATUS = 'manual';
+ START_TIME = Date.now();
+ END_TIME = null;
+ updateUI();
+ }
};
checkbox.onchange = async () => {
if (checkbox.checked && +slider.value === 0) {
@@ -180,5 +206,34 @@ for (const [slider, checkbox] of pwms) {
}
await send8(FUNC.C_PWM_HEAT, +el.heat.value, el.heat_mode.checked ? ARG.PWM_ON : ARG.PWM_OFF);
await send8(FUNC.C_PWM_COOL, +el.cool.value, el.cool_mode.checked ? ARG.PWM_ON : ARG.PWM_OFF);
+ if (STATUS === 'idle' && el.heat_mode.checked) {
+ STATUS = 'manual';
+ START_TIME = Date.now();
+ END_TIME = null;
+ updateUI();
+ }
};
}
+
+el.start.onclick = () => {
+ if (STATUS === 'idle') {
+ STATUS = el.profile.value === '' ? 'manual' : 'running';
+ START_TIME = Date.now();
+ END_TIME = null;
+
+ if (el.profile.value !== '') {
+ const i = +el.profile.value;
+ send8(FUNC.C_STARTSTOP, i, ARG.STARTSTOP_START);
+ }
+ } else if (STATUS === 'running') {
+ STATUS = 'idle';
+ END_TIME = Date.now();
+
+ const i = +el.profile.value;
+ send8(FUNC.C_STARTSTOP, i, ARG.STARTSTOP_STOP);
+ } else if (STATUS === 'manual') {
+ STATUS = 'idle';
+ END_TIME = Date.now();
+ }
+ updateUI();
+};