214 lines
6.2 KiB
TypeScript
214 lines
6.2 KiB
TypeScript
import { loadGraph } from './tempgraph.ts';
|
|
|
|
let timer = 0;
|
|
let isRunning = false;
|
|
let log: Array<{ time: string, event: string, temp?: number }> = [];
|
|
let targets: number[] = [];
|
|
let currentTargetIndex = 0;
|
|
let interval: NodeJS.Timeout | null = null;
|
|
|
|
declare global {
|
|
interface Window {
|
|
startTimer: () => void;
|
|
stopTimer: () => void;
|
|
logEvent: (eventName: string) => void;
|
|
resetSystem: () => void;
|
|
setPlan: () => void;
|
|
navigateTemp: (direction: number) => void;
|
|
logTemp: (temp: number) => void;
|
|
exportCSV: () => void;
|
|
showGraph: () => void;
|
|
hideGraph: () => void;
|
|
}
|
|
}
|
|
|
|
|
|
function startTimer(): void {
|
|
if (isRunning) {
|
|
alert("Timer is already running. Click again to reset.");
|
|
return;
|
|
}
|
|
timer = 0;
|
|
updateTimerDisplay();
|
|
isRunning = true;
|
|
interval = setInterval(() => {
|
|
timer++;
|
|
updateTimerDisplay();
|
|
}, 1000);
|
|
}
|
|
|
|
function stopTimer(): void {
|
|
if(interval !== null){
|
|
clearInterval(interval);
|
|
}
|
|
isRunning = false;
|
|
}
|
|
|
|
function updateTimerDisplay(): void {
|
|
const minutes = Math.floor(timer / 60);
|
|
const seconds = timer % 60;
|
|
document.getElementById("timer")!.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`;
|
|
}
|
|
|
|
function logEvent(eventName: string): void {
|
|
if (eventName === "Charge") {
|
|
if (log.length > 0 || isRunning) {
|
|
if(isRunning){
|
|
stopTimer();
|
|
}
|
|
log = [];
|
|
timer = 0;
|
|
}
|
|
startTimer();
|
|
log.push({ time: formatTime(timer), event: eventName });
|
|
updateLog();
|
|
return;
|
|
}
|
|
if (eventName === "Drop") {
|
|
stopTimer();
|
|
log.push({ time: formatTime(timer), event: eventName });
|
|
updateLog();
|
|
document.getElementById("create-plan")!.classList.remove("hidden");
|
|
const tempButtons = document.getElementById("temp-buttons")!;
|
|
tempButtons.innerHTML = "";
|
|
return;
|
|
}
|
|
log.push({ time: formatTime(timer), event: eventName });
|
|
updateLog();
|
|
}
|
|
|
|
function resetSystem(): void {
|
|
stopTimer();
|
|
log = [];
|
|
updateLog();
|
|
document.getElementById("create-plan")!.classList.remove("hidden");
|
|
const tempButtons = document.getElementById("temp-buttons")!;
|
|
tempButtons.innerHTML = "";
|
|
}
|
|
|
|
function formatTime(seconds: number): string {
|
|
const minutes = Math.floor(seconds / 60);
|
|
const secs = seconds % 60;
|
|
return `${minutes}:${secs.toString().padStart(2, '0')}`;
|
|
}
|
|
|
|
function setPlan(): void {
|
|
const input = (document.getElementById("plan-input") as HTMLInputElement).value;
|
|
targets = input.split(',').map(Number);
|
|
currentTargetIndex = 0;
|
|
document.getElementById("controls")!.classList.remove("hidden");
|
|
document.getElementById("create-plan")!.classList.add("hidden");
|
|
generateTempButtons();
|
|
}
|
|
|
|
function generateTempButtons(): void {
|
|
const container = document.getElementById("temp-buttons")!;
|
|
container.innerHTML = "";
|
|
if (targets.length === 0) {
|
|
container.innerHTML = "<p>No temperature plan set.</p>";
|
|
return;
|
|
}
|
|
const currentTarget = targets[currentTargetIndex];
|
|
const buttons: string[] = [];
|
|
buttons.push('<button class="nav-btn" onclick="navigateTemp(-1);"><<</button>');
|
|
for (let i = -2; i <= 2; i++) {
|
|
const temp = currentTarget + i;
|
|
buttons.push(`<button onclick="logTemp(${temp})">${temp}</button>`);
|
|
}
|
|
buttons.push('<button class="nav-btn" onclick="navigateTemp(1);">>></button>');
|
|
container.innerHTML = buttons.join(" ");
|
|
}
|
|
|
|
function navigateTemp(direction: number): void {
|
|
currentTargetIndex += direction;
|
|
if (currentTargetIndex < 0) {
|
|
currentTargetIndex = 0;
|
|
} else if (currentTargetIndex >= targets.length) {
|
|
currentTargetIndex = targets.length - 1;
|
|
}
|
|
generateTempButtons();
|
|
}
|
|
|
|
function logTemp(temp: number): void {
|
|
log.push({ time: formatTime(timer), event: "Temp", temp });
|
|
updateLog();
|
|
currentTargetIndex++;
|
|
if (currentTargetIndex >= targets.length) {
|
|
currentTargetIndex = targets.length - 1;
|
|
}
|
|
generateTempButtons();
|
|
}
|
|
|
|
function updateLog(): void {
|
|
const tbody = document.getElementById("log-body")!;
|
|
tbody.innerHTML = log.map(entry => `
|
|
<tr>
|
|
<td>${entry.time}</td>
|
|
<td>${entry.event}</td>
|
|
<td>${entry.temp !== null ? entry.temp : ''}</td>
|
|
</tr>
|
|
`).join("");
|
|
}
|
|
|
|
// src/roast.ts
|
|
|
|
/**
|
|
* Generates an array of CSV strings line by line from log data.
|
|
*/
|
|
function createCSVData(): string[] {
|
|
const header = "Time,Event,Temperature";
|
|
const logEntries = log.map(entry => `${entry.time},${entry.event}${entry.temp !== null ? `,${entry.temp}` : ''}`);
|
|
return [header].concat(logEntries);
|
|
}
|
|
|
|
/**
|
|
* Creates CSV format content as a single string from the array returned by createCSVData().
|
|
*/
|
|
function generateCSVContent(): string {
|
|
return createCSVData().join("\n");
|
|
}
|
|
|
|
function exportCSV(): void {
|
|
const csvContent = generateCSVContent();
|
|
const blob = new Blob([csvContent], { type: "text/csv;charset=utf-8;" });
|
|
const link = document.createElement("a");
|
|
link.setAttribute("href", URL.createObjectURL(blob));
|
|
link.setAttribute("download", "roast_log.csv");
|
|
link.style.display = "none";
|
|
document.body.appendChild(link);
|
|
link.click();
|
|
document.body.removeChild(link);
|
|
}
|
|
|
|
function showGraph(): void {
|
|
const graphContainer = document.getElementById("graph-container");
|
|
if (graphContainer) {
|
|
loadGraph(createCSVData());
|
|
graphContainer.classList.remove("hidden");
|
|
graphContainer.classList.add("graph-display-flex");
|
|
}
|
|
}
|
|
|
|
function hideGraph(): void {
|
|
const graphContainer = document.getElementById("graph-container");
|
|
if (graphContainer) {
|
|
graphContainer.classList.add("hidden");
|
|
graphContainer.classList.remove("graph-display-flex");
|
|
}
|
|
}
|
|
|
|
// Expose functions to the global scope (allowing html direct access)
|
|
if (typeof window !== 'undefined') {
|
|
window.startTimer = startTimer;
|
|
window.stopTimer = stopTimer;
|
|
window.logEvent = logEvent;
|
|
window.resetSystem = resetSystem;
|
|
window.setPlan = setPlan;
|
|
window.navigateTemp = navigateTemp;
|
|
window.logTemp = logTemp;
|
|
window.exportCSV = exportCSV;
|
|
window.showGraph = showGraph;
|
|
window.hideGraph = hideGraph;
|
|
}
|
|
|
|
export {}; |