web_buttons.tc¶
web_buttons.tc — Custom Web Buttons Demo
// ═══════════════════════════════════════════════════════════════════
// web_buttons.tc — Custom Web Buttons Demo
// Replicates Scripter's >w submenu with custom HTML buttons
//
// Scripter pattern:
// >w ⚙ Stromzähler / Daten <- submenu page with title
// <button onclick="seva(1,'_init')"> <- button calls subroutine #init
// ck(sndpwr "") <- checkbox widget
//
// TinyC equivalent:
// webPageLabel(0, "title") <- button on main page
// WebUI() with webPage()==0 <- submenu page content
// fetch('/cm?cmnd=SMInit') <- button calls Command()
// webCheckbox(var, "label") <- checkbox widget
// ═══════════════════════════════════════════════════════════════════
// ─── Persistent settings ───
persist watch int sndpwr; // MQTT: send averaged power
// ─── State ───
int counter;
char status[64];
// ═══════════════════════════════════════════════════════════════════
// "Subroutines" — equivalent of Scripter's #init, #init2, #save
// ═══════════════════════════════════════════════════════════════════
void doInit() {
counter = 0;
strcpy(status, "Zaehler initialisiert");
addLog("SM: Zaehler initialisiert");
}
void doInit2() {
strcpy(status, "Diagramme zurueckgesetzt");
addLog("SM: Diagramme zurueckgesetzt");
}
void doSave() {
saveVars();
strcpy(status, "Daten gespeichert");
addLog("SM: Daten gespeichert");
}
// ═══════════════════════════════════════════════════════════════════
// Command handler — called by fetch('/cm?cmnd=SMxxx') from buttons
// Equivalent of Scripter's seva(1,'_init') → #init
// ═══════════════════════════════════════════════════════════════════
void Command(char cmd[]) {
if (strFind(cmd, "Init2") == 0) {
doInit2();
responseCmnd("{\"SMInit2\":\"done\"}");
} else if (strFind(cmd, "Init") == 0) {
doInit();
responseCmnd("{\"SMInit\":\"done\"}");
} else if (strFind(cmd, "Save") == 0) {
doSave();
responseCmnd("{\"SMSave\":\"done\"}");
} else {
responseCmnd("{\"SM\":\"cmds: Init,Init2,Save\"}");
}
}
// ═══════════════════════════════════════════════════════════════════
// EverySecond
// ═══════════════════════════════════════════════════════════════════
void EverySecond() {
if (changed(sndpwr)) {
snapshot(sndpwr);
saveVars();
}
counter = counter + 1;
}
// ═══════════════════════════════════════════════════════════════════
// Main page — sensor values (same as Scripter >W section)
// ═══════════════════════════════════════════════════════════════════
void WebCall() {
char buf[80];
sprintf(buf, "{s}Counter{m}%d{e}", counter);
webSend(buf);
sprintf(buf, "{s}Status{m}%s{e}", status);
webSend(buf);
}
// ═══════════════════════════════════════════════════════════════════
// Settings page — exact replica of Scripter >w submenu
//
// Scripter: TinyC:
// >w ⚙ Title webPageLabel(0, "Title") in main()
// seva(1,'_init') fetch('/cm?cmnd=SMInit')
// ck(sndpwr "") webCheckbox(sndpwr, "...")
// ═══════════════════════════════════════════════════════════════════
void WebUI() {
int page;
page = webPage();
if (page == 0) {
char buf[64];
// --- Exact Scripter >w layout ---
webSend("<style>");
webSend(".flex-container{display:flex;justify-content:center}");
webSend(".center-flex-horizontally{width:270px;background-color:#f0f0f0;");
webSend("text-align:left;padding:20px;border:2px solid #ccc;color:#333}");
webSend(".button-group{display:flex;flex-direction:column;");
webSend("align-items:flex-start;gap:10px}");
webSend(".button-group button{background:#e0e0e0;color:#333;");
webSend("border:1px solid #999;border-radius:3px;padding:4px 10px;");
webSend("width:auto;font-size:13px;cursor:pointer}");
webSend("</style>");
webSend("<div class='flex-container'>");
webSend("<div class='center-flex-horizontally'>");
webSend("<div class='button-group'>");
// --- Script name header ---
webSend("<b>📄 web_buttons.tc</b>");
// --- Buttons with confirm (= Scripter seva(1,'_init')) ---
webSend("<button type='submit' onclick=\"if(confirm(");
webSend("'Zaehlerwerte und Diagramme zuruecksetzen?'");
webSend(")){fetch('/cm?cmnd=SMInit')}\">");
webSend("🔄 Zaehlerwerte initialisieren</button>");
webSend("<button type='submit' onclick=\"if(confirm(");
webSend("'Balkendiagramme zuruecksetzen?'");
webSend(")){fetch('/cm?cmnd=SMInit2')}\">");
webSend("📊 Reset Balkendiagramme</button>");
webSend("<button type='button' onclick=\"fetch('/cm?cmnd=SMSave');");
webSend("alert('Daten wurden gespeichert!')\">");
webSend("💾 Diagrammdaten speichern</button>");
webSend("</div>"); // button-group
webSend("<hr>");
// --- Options (= Scripter ck() checkbox) ---
webSend("<b>🔧 Optionen</b><br><br>");
webSend("MQTT: Gemittelte Leistung senden:");
webCheckbox(sndpwr, "");
webSend("<hr>");
// --- System info ---
webSend("<b>ℹ️ System</b><br>");
sprintf(buf, "Heap: %d KB", tasm_heap / 1024);
webSend(buf);
webSend("</div>"); // center-flex-horizontally
webSend("</div>"); // flex-container
}
}
// ═══════════════════════════════════════════════════════════════════
// WebPage — needed for webPageLabel button to appear on main page
// ═══════════════════════════════════════════════════════════════════
void WebPage() {
}
// ═══════════════════════════════════════════════════════════════════
// MAIN
// ═══════════════════════════════════════════════════════════════════
int main() {
counter = 0;
strcpy(status, "Ready");
snapshot(sndpwr);
// Register console command prefix (like Scripter subroutine calls)
addCommand("SM");
// Create submenu button on main page
// Equivalent of Scripter: >w ⚙️ Stromzähler / Daten
webPageLabel(0, "⚙️ Stromzaehler / Daten");
return 0;
}