Prevent redraw when HTML page content hasn't changed (304 Not Modified)?

I’m using the Data HTML input to render a page as a PNG on the reTerminal E1002. It polls for a new page each time on a given interval and redraws even when the rendered image is identical to the previous one.

Is there a way to prevent the redraw when the content hasn’t changed? For example, having the device honour an HTTP 304 Not Modified response (or ETag / Last-Modified) so it skips the refresh when nothing has changed.

Thanks!

The Data HTML input always polls the configured URL. It fetches and renders every refresh cycle.
Identical content still triggers a redraw. HTTP cache validation seems unsupported currently.
That includes ETag and Last-Modified headers. HTTP 304 responses also appear ignored.
Increase the polling interval to reduce updates. Alternatively, detect changes on the server.
Serve new content only when necessary. Native cache support would greatly improve efficiency.

Hi there,

And Welcome here…

So there are 2 ways I find to enable this, The E1003 I won on live stream is OTW, so what I found… YMMV :v: You can switch from Web functions to “canvas functions” for stuff like this.
Instead of using the Web / Data HTML input—which forces the SenseCraft renderer to blindly re-render the page on a timer—move the logic into Canvas Function using a Custom Data Widget:

  1. Serve a JSON Endpoint Instead of HTML: Write a simple server endpoint that returns your data as JSON (e.g., {"title": "Room 1", "temp": 22.5, "updated": "12:00"}).

  2. Bind the Endpoint in SenseCraft HMI: Add a custom Data API source inside SenseCraft Canvas.

  3. How SenseCraft Handles It: SenseCraft’s cloud/relay engine regularly checks JSON values. It only redraws the display widgets on the reTerminal when the underlying JSON payload values change, automatically suppressing unnecessary screen refreshes.

or,

Server-Side Long Polling (If you MUST use HTML)

If you have to stay on the Data HTML / Web Function widget, you can make the SenseCraft rendering worker wait on your server:

[SenseCraft Worker] ─── Polling GET Request ───> [Your HTTP Server]
                                                      │
                       ┌──────────────────────────────┴──────────────────────────────┐
                       ▼                                                             ▼
                Content Changed                                              Content Unchanged
       Immediately Return 200 OK + HTML                             Hold Connection Open (e.g. 25–50s)
          (SenseCraft Renders Page)                                 (Delays Redraw Cycle until Timeout)

Instead of responding instantly on every poll, use a delay loop that checks if the internal state/hash has changed before sending the HTTP response:

import time
import hashlib
from flask import Flask, Response

app = Flask(__name__)
last_rendered_hash = ""

def generate_html_content():
    # Return your HTML string here
    return "<html><body><h1>Dashboard</h1></body></html>"

@app.route('/sensecraft-html')
def sensecraft_endpoint():
    global last_rendered_hash
    timeout = 30  # Hold the request for up to 30 seconds
    start_time = time.time()

    while (time.time() - start_time) < timeout:
        html = generate_html_content()
        current_hash = hashlib.md5(html.encode('utf-8')).hexdigest()

        # If content changed compared to last delivered render:
        if current_hash != last_rendered_hash:
            last_rendered_hash = current_hash
            return Response(html, mimetype='text/html', status=200)

        time.sleep(1) # Check state every second

    # If timeout reached with no changes, send 204 or same HTML
    return Response("", status=204)

Something else ,there is a time stamp also you can mess with, but the hash appears to be implementable also.
HTH
GL :slight_smile: PJ :v:

SensCraft should fix the site though , It needs to implement all of the HTML server side responses,
hopefully Seeedineers can IMPROVE the experience.

1 Like