Zum Inhalt

sml_simple.tc

sml_simple.tc — minimal SML smart-meter reader & descriptor manager

Source on GitHub

// ============================================================================
// sml_simple.tc — minimal SML smart-meter reader & descriptor manager
// ============================================================================
//
// Smallest possible TinyC SML script: descriptor + pin management
// (sml_descriptor.tc include) plus a three-row readout (power /
// energy-in / energy-out) on the main sensor page.
//
// For charts + daily/monthly aggregation see sml_chart.tc.
// For pure-Scripter parity see ottelo's 0_SML_Simple.tas.
//
// Requires: USE_SML (or USE_SML_M) in firmware + USE_UFILESYS for
// /sml_meter.def persistence.
// ============================================================================

#include "sml_descriptor.tc"

// ── Transient UI flag (not persisted — reset on each boot) ────────────────
int do_reset;                  // webButton trigger → re-init SML driver

// ============================================================================
// Callbacks
// ============================================================================

void EverySecond() {
    sml_descriptor_apply();
    if (do_reset) {
        tasmCmd("Sensor53 r", sml_buf);
        addLog("sml_simple: manual SML reset triggered");
        do_reset = 0;
    }
}

// ── Main page sensor block ─────────────────────────────────────────────────
void WebCall() {
    if (!sml_activ) {
        webSend("{s}SML{m}disabled (Rule1 off){e}");
        return;
    }
    float pwr  = smlGet(1);
    float ein  = smlGet(2);
    float eout = smlGet(3);
    sprintf(sml_buf, "{s}SML Leistung{m}%.0f W{e}",        pwr);  webSend(sml_buf);
    sprintf(sml_buf, "{s}SML Bezug{m}%.3f kWh{e}",         ein);  webSend(sml_buf);
    sprintf(sml_buf, "{s}SML Einspeisung{m}%.3f kWh{e}",   eout); webSend(sml_buf);
}

// ── Settings page (single page, accessed via menu button) ──────────────────
void WebUI() {
    sml_render_settings_panel();
    webSend("<hr><b>&#x1F504; SML neu initialisieren</b>");
    webButton(do_reset, "Sensor53 r|SML neu geladen");
    webSend("<div style='text-align:center;font-size:10px;color:#777;margin-top:10px'><b>sml_simple.tc</b><br>TinyC port of ottelo's 0_SML_Simple.tas</div></div>");
}

// MQTT telemetry: nothing to do here — the SML driver publishes its own
// JSON block in the SENSOR message.

// ============================================================================
// main() — one-shot setup
// ============================================================================
int main() {
    // First-run defaults: -1 = "leave the %0?rxpin%/%0?txpin% placeholder
    // in /sml_meter.def alone until user picks something". 0 is a real GPIO,
    // can't be the sentinel.
    if (sml_rx_pin == 0 && sml_tx_pin == 0) {
        sml_rx_pin = -1;
        sml_tx_pin = -1;
    }

    // tasm_rule (Rule1) is the SML driver gate — make sure it matches the
    // persisted checkbox before SML_Init runs at boot.
    if (sml_activ != tasm_rule) {
        tasm_rule = sml_activ;
    }

    // Menu button label — kept short, panel header inside already says
    // "SML Zaehler" so prefixing here would stack redundantly with it.
    webPageLabel(0, "Einstellungen");
    smlScripterLoad("/sml_meter.def");

    addLog("sml_simple: started rx=%d tx=%d meter=%d active=%d",
           sml_rx_pin, sml_tx_pin, sml_meter_sel, sml_activ);
    return 0;
}