GeekMagicClock / smalltv

firmware for GeekMagic smalltv - smart weather station clock
44 stars 5 forks source link

[VOTE 👍🏻🤩] HTTP custom text and images #15

Open mungle opened 6 months ago

mungle commented 6 months ago

Hello! I’d like to display some text messages and images via http requests using nodered. As you don’t distribute the source code, can you implement similar features for the “basic” version? Thank you!

GeekMagicClock commented 6 months ago

Hello, this is possible, but it also depends on your needs, how big the font size and layout style you need, maybe a simple interface can be provided.

mungle commented 6 months ago

It can be displayed an html with a simple css style?

With a HTTP request like: http://192.168.0.2/message?title=hello&message=world

and a html section in the web admin like:

<h1 class=“uppercase”>%title%</h1>
<p class=“red”>%message%</p>

and a css section with:

.uppercase{ text-transform: uppercase; }
.red{ color: red; }

the message can be easily customized! There are also other and better methods I believe (JSON?). It would be great to display also images sent by HTTP requests! When a new image has been sent received and displayed by the device, the previous will be deleted. 👍👍👍

This would be very appreciated by me 🤩 and many, many users, I believe!!!

GeekMagicClock commented 6 months ago

Okay, let's vote & talk.

GeekMagicClock commented 6 months ago

Is it some thing like this? image Title section: font size, font color. Message section: font size, font color. Image section: image size.

It's better to fix the font-size and image size, since only a few font-size is designed in the firmware for the present. And I wonder what's that used for, what kind of situation.

mungle commented 6 months ago

Hello, I'd use to send home notifications like, reminders, appointments or post-it messages. I'd also like to use to view custom image screenshot from my security camera system when a motion alert is detected (I'm now using a telegram bot and it's super useful!!!)

To be as flexible as possible I suggest four style:

1 - Text only

1

2 - Text + custom icon

2 3 4

3 - Text + background image

6 Credits: Unsplash

4 - Image only

5 Credits: Unsplash 7

The display style change based on the HTTP message. If there's message=[text] only, the smalltv will ignore the other inputs (title, icon and image) as they're "empty" displaying the message field only.

Once a new message is sent, the previous one will be deleted.

The image only can be the most flexible solution as you can generate with an external script an image with any content in any style and layout you like mixing text and images.

GeekMagicClock commented 6 months ago

Hi, your PS skills is great.

Anyone interested in this please leave your message.

mungle commented 5 months ago

Hello! Do you have updates on this?

PhantomArt commented 5 months ago

I would like to be able to display a custom 240x240 image via the API, no animation needed, just a static image. Then I could create an image with my application with any information and any design, and use the device only as a display to display this image.

DanHKfree97 commented 3 months ago

Hi, im here for vote! Would be geat function... :)

Martinho672 commented 3 months ago

I will love that function too

GeekMagicClock commented 3 months ago

Hello! Do you have updates on this?

Hello, I'm going to add the image full screen update feature.

Andre-Lehrmann commented 2 months ago

Hello, i am always interested in this function. Have a nice day.

pmout commented 2 months ago

Hello, GeekMagicClock Can you share if it is possible to connect to the device via SSH and how to do it?

mungle commented 2 months ago

Hello! Do you have updates on this?

Hello, I'm going to add the image full screen update feature.

I’m super excited as many others I believe. Do you have any ETA for the feature?

4mitabh commented 1 month ago

This will be a great addition. Please make this happen!

gholtike commented 1 month ago

I'm also here to vote, I'm excited about the idea, I think it can meet the needs of many different applications.

4mitabh commented 1 month ago

Or if we can configure an HTTP API what the device can poll, and update the screen with the data returned (in a predefined schema that the device supports) by the API.

donatellosantoro commented 1 month ago

Hi there +1

Similar to https://github.com/GeekMagicClock/smalltv-pro/issues/42

Rhsameera commented 1 month ago

+1

florentineprinzessinzusachsen commented 1 month ago

+1

callumj commented 4 weeks ago

If this was supported: I’d be ordering at least 5. I have a need to display custom notifications as well as stats from my weather station or motion sensors.

ijavid commented 3 weeks ago

Voting here +1

Alexshch09 commented 3 weeks ago

+1

gholtike commented 2 weeks ago

Pleeeease

4mitabh commented 2 weeks ago

Here is a proposal for API support what will greatly help users who want to display their own data on this cute little device.

  1. We add a new ‘Theme’ for API along with the existing ones. Like, in the screen below: 1

  2. Users can go to the API tab and configure their own API URLs. They can also configure the time in seconds between subsequent API polls and updates. This is pretty similar to what we have on the ‘Photo Albums’ tab.

2

Once the user has added their API URLs, the device will periodically query these APIs, fetch the data, and automatically display it on the device's screen. This would provide users with a powerful and flexible way to display their own data on the device, tailoring the content and update frequency to their specific needs.

The APIs must return the data in JSON format, following a standardized structure that the device can easily parse and display. We can publish this JSON schema on smalltv github page.

I propose the following schema for the JSON API response structure. This is based on the beautiful design mockups that have been shared previously by @mugle.

Text Only:

{
  "layout": 1,
  "title": "Lorem Ipsum",
  "text": "Lore  ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor"
}

Text and Icon:

{
  "layout": 2,
  "icon": "🔔",
  "title": "Lorem Ipsum",
  "text": "Lore  ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor"
}

Text and background Image

{
  "layout": 3,
  "image": "http://url.to/image",
  "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor"
}

Image Only:

{
  "layout": 4,
  "image": "http://url.to/image"
}
mattkri commented 2 weeks ago

Voting here for the Smalltv-ultra!

mattkri commented 1 week ago

I know this isn't a great solution and kind of hacky, but if you want to just have a script monitor a folder for a jpeg and upload it, I wrote this script in python that will monitor a directory that you set (in the bottom) for any jpg, and then resize, and upload that jpg to your device, while deleting the previous image.

Just set your device's IP address, and the correct folders to watch.

You could modify this to use in whatever setup you want.

import os
import time
import requests
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from PIL import Image, ImageOps
import shutil

class ImageHandler(FileSystemEventHandler):
    def __init__(self, upload_url, delete_url, filename, temp_dir):
        self.upload_url = upload_url
        self.delete_url = delete_url
        self.filename = filename
        self.temp_dir = temp_dir
        os.makedirs(temp_dir, exist_ok=True)

    def on_modified(self, event):
        if event.src_path.endswith(".jpg") or event.src_path.endswith(".jpeg"):
            print(f"Detected change in {event.src_path}. Processing...")
            temp_image_path = self.resize_and_pad_image(event.src_path)
            self.delete_previous_image()
            self.upload_image(temp_image_path)

    def resize_and_pad_image(self, image_path):
        with Image.open(image_path) as img:
            img = ImageOps.pad(img, (240, 240), color="black")
            temp_image_path = os.path.join(self.temp_dir, self.filename)
            img.save(temp_image_path)
            print(f"Image resized and padded to 240x240 pixels: {temp_image_path}")
        return temp_image_path

    def delete_previous_image(self):
        response = requests.get(self.delete_url)
        print(f"Deleting previous image at {self.delete_url}")
        print(f"Response status code: {response.status_code}")
        if response.status_code == 200:
            print("Deletion successful")
        else:
            print(f"Deletion failed with status code {response.status_code}")

    def upload_image(self, image_path):
        with open(image_path, 'rb') as image_file:
            files = {'file': (self.filename, image_file)}
            response = requests.post(self.upload_url, files=files)
            print(f"Uploading to {self.upload_url} with file {self.filename}")
            print(f"Response status code: {response.status_code}")
            print(f"Response text: {response.text}")
            if response.status_code == 200:
                print("Upload successful")
            else:
                print(f"Upload failed with status code {response.status_code}")
                print(f"Response headers: {response.headers}")
                print(f"Response content: {response.content}")

def monitor_directory(directory_path, upload_url, delete_url, filename, temp_dir):
    event_handler = ImageHandler(upload_url, delete_url, filename, temp_dir)
    observer = Observer()
    observer.schedule(event_handler, directory_path, recursive=False)
    observer.start()
    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()

if __name__ == "__main__":
    # Use raw string to handle backslashes in Windows paths
    directory_to_watch = r"D:\My Documents\Picture Watchdog\Picture"
    upload_endpoint = "http://192.168.0.172/doUpload?dir=/image/"
    delete_endpoint = "http://192.168.0.172/delete?file=%2Fimage%2F%2Fimage.jpg"
    image_filename = "image.jpg"
    temp_directory = r"D:\My Documents\Picture Watchdog\Picture\temp"
    monitor_directory(directory_to_watch, upload_endpoint, delete_endpoint, image_filename, temp_directory)
callumj commented 1 week ago

Building on @mattkri what I am doing for now is using an image library in my preferred programming language (Go) to build an image with my preferred data that I want to display and then uploading the image inside my program.

4mitabh commented 1 week ago

My worry is that this solution might kill the flash with too many writes, if we are updating the images frequently. That's why, an API that fetches and displays text would have been really great.

philipag commented 3 days ago

+1 for smalltv-pro

A very useful API function which I did not see mentioned here is for the API to return a "touch count" which is incremented each time the user touches the sensor. This would allow the web clients to respond to touch events and e.g. cycle camera views or photos. When in API mode and showing a photo, only long touch would be processed by the smalltv in order to exit into the main menu. Short touches just increment the touch count.

philipag commented 1 day ago

Would it not be better to have the small TV act as server? The small TV simply has a fixed API url which the client can use to post images and query touch count. In fact, the same url could be used to manually set an image via a web browser and to configure API mode. I.e. the API configuration page is also the url used by the PC client to upload images. These image uploads are not store in flash and are volatile.

It seems to me that this is simpler to implement and has the advantage of not requiring the small TV to constantly poll for new content. The PC/content creator just posts updated content when it becomes available. This way the PC can also get the touch count to change its content. Also, the small TV can automatically enter API mode when it receives a request to show an image.