view web_to_mqtt.py @ 4:e273cc60b389

draft of web-to-lcd and simulator
author drewp@bigasterisk.com
date Tue, 05 Mar 2024 18:12:15 -0800
parents
children d97a5930db7e
line wrap: on
line source

import asyncio
import base64
import io
import subprocess
import tempfile

import aiomqtt
from PIL import Image, ImageChops


class WebRenderer:
    def __init__(self):
        self.chrome_proc = subprocess.Popen(["google-chrome"])
        print("Chrome subprocess started.")

    def capture_screenshot(self, url, output_path):
        out = tempfile.NamedTemporaryFile(suffix=".png")
        screenshot_command = [
            "google-chrome",
            "--headless",
            f"--screenshot={out.name}",
            url,
        ]
        subprocess.run(screenshot_command)
        return Image.open(out.name)



async def render_webpage_to_png():
    # Code to render the webpage to a PNG
    # Replace this with your actual code to render the webpage to a PNG
    # For example, you can use libraries like Selenium or requests-html to render the webpage and capture a screenshot
    pass


async def check_for_changes(renderer, last_image):

    renderer.capture_screenshot("https://en.wikipedia.org", "/tmp/output.png")

    current_image = await render_webpage_to_png()
    if last_image is not None:
        diff_image = ImageChops.difference(last_image, current_image)
        # Iterate over 64x64 pixel squares and check for changes
        for y in range(0, diff_image.height, 64):
            for x in range(0, diff_image.width, 64):
                box = (x, y, x + 64, y + 64)
                region = diff_image.crop(box)
                if (region.getbbox()
                    ):  # Check if region is not empty (i.e., contains changes)
                    # Send changed square as MQTT message
queue these
                    await send_mqtt_message(region)
    return current_image


async def send_mqtt_message(region):
    # Convert changed region to base64 encoded string
    buffer = io.BytesIO()
    region.save(buffer, format="PNG")
    base64_image = base64.b64encode(buffer.getvalue()).decode("utf-8")
    mqtt_client = aiomqtt.Client("mqtt_client")
    await mqtt_client.connect("mqtt://broker.example.com")
    await mqtt_client.publish("changed_squares", base64_image, qos=1)
    await mqtt_client.disconnect()


async def main():
    # also listen for dirty msgs from the web page; see ts
    renderer = WebRenderer()
    async with aiomqtt.Client("mqtt_client") as client:
        last_image = None
        while True:
            last_image = await check_for_changes(renderer,last_image)
            await asyncio.sleep(2)  # Adjust the interval as needed


if __name__ == "__main__":
    asyncio.run(main())