diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web_to_mqtt.py	Tue Mar 05 18:12:15 2024 -0800
@@ -0,0 +1,78 @@
+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())