greghesp / ha-bambulab

A Home Assistant Integration for Bambu Lab Printers
698 stars 59 forks source link

[Feature] Add timelapse to Media and show rendering videos #477

Open leinich opened 4 months ago

leinich commented 4 months ago

Describe the feature

It would be great to show the current rendered 3D print on homeassistant dashboard or to be able to view the timelapse (or even send it via push notification)

Currently it is possible to access timelapse and rendering previews of the prints via SFTP. The data can be accessed following: Protocol: sftp (Require implicit FTP over TLS ) User: bblp Password: AccessToken as shown on the screen

Unfortunatelly there is no easy way to currently use SFTP with homeassistant

What device is this for?

P1S

Other Information

No response

AdrianGarside commented 4 months ago

Which is the rendered 3d print file? Is it different to the cover image that home assistant already makes available when the printer is not in lan mode?

leinich commented 4 months ago

@AdrianGarside the rendered printjob is in the folder /image and seems to be the same as the image bambus studio shows in the last printing dialog. and looks like following: /image/34113264191.png File sizes are around 1 to 7KB

As I am only using the printer in LAN mode, i have never seen any cover image files in Home Assistant exposed.

The timelapse files are stored in the folder /timelapse and sorted the a timestamp /timelapse/timelapse_2024-02-25_05-51-06.avi

WolfwithSword commented 4 months ago

Since there isn't a way to do FTPS (or sftp, which is a different protocol than the printers use) easily within HA, perhaps it might be worth looking into some way to use another hacs integration, addon or script to perform the FTPS fetch based on an automation from ha-bambulab?

For example, you could run a python-script using the Python Scripts integration.

Note, I have not tested anything using the python-script integration, this is just giving an idea for functionality

Here's a "working" python script for creating the FTPS connection.

import ftplib
import ssl
import platform

ftplib.ssl_version = ssl.PROTOCOL_TLSv1_2

USER = "bblp"
ACCESS_CODE = "<access_code>"
PRINTER_IP = "<printer_ip>"

class ImplicitFTP_TLS(ftplib.FTP_TLS):
    """FTP_TLS subclass that automatically wraps sockets in SSL to support implicit FTPS."""

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._sock = None

    @property
    def sock(self):
        """Return the socket."""
        return self._sock

    @sock.setter
    def sock(self, value):
        """When modifying the socket, ensure that it is ssl wrapped."""
        if value is not None and not isinstance(value, ssl.SSLSocket):
            value = self.context.wrap_socket(value)
        self._sock = value

    def ntransfercmd(self, cmd, rest=None):
        conn, size = ftplib.FTP.ntransfercmd(self, cmd, rest)
        if self._prot_p:
            session = self.sock.session
            if isinstance(self.sock, ssl.SSLSocket):
                    session = self.sock.session
            conn = self.context.wrap_socket(conn,
                                            server_hostname=self.host,
                                            session=session)  # this is the fix
        return conn, size

ftps = ImplicitFTP_TLS()

ftps.connect(host=PRINTER_IP, port=990)

ftps.login(user=USER, passwd=ACCESS_CODE)
ftps.prot_p()

### Connection setup above, always required
### Logic below

## After logic
ftps.close()

You can use ftps.nlst() to list files. You can specify a directory in the nlst command, but note that results on P1 and A1 series at least (and I think X1 series, but I've long since fixed this to remember) do not prefix the provided path to the results.

You do have to use nlst though, as the other list command does not work on A1/P1. Also, wildcard searches or extension type searches do not work for A1/P1 series, so filtering must be done after getting results.

To download the file, you can do the following:

remote_file_with_path = "<from filtered results of nlst earlier>"
local_file_with_path = "<somewhere_in_HA_media?>"
with open(local_file_with_path , 'wb') as f:
    ftps.retrbinary('RETR ' + remote_file_with_path, f.write)

I can verify that listing and downloading from the printer via python ftps like this (standalone python program, not in HA) works for all series of bambu printers as of writing.

So theoretically, using python-scripts integration someone could piece together an automation blueprint that on print finish/failed, wait a few seconds, fetch a list of all timelapses, sort by name (timestamp format will sort as it's YYYY-MM-DD) and get newest that way. Download to HA's media folder and do something else with it?

Do note that the printer does not contain the generated model images like the "cover image" for X1C. I expect it is only on the P1 and A1 series due to those printers unpacking the 3mf on card or in cloud and downloading the results due to performance reasons. So for reliability reasons, if someone makes this an external automation for the "cover image rendering", it won't work for X1 printers without downloading and extracting the 3mf. There is no /image directory for X1 printers.

Additionally, timelapses are formatted differently on X1 series. It is in folder /timelapse with filename pattern and filename type "video_YYYY-mm-dd_HH-MM-SS.mp4". For example, /timelapse/video_2023-08-21_09-24-47.mp4. There also exists a /timelapse/thumbnail directory, which contains a thumbnail for each timelapse photo of same name but .jpg extension.

Full-recordings (not timelapse, realtime) are in /ipcam folder, and similar format regarding timelapse and thumbnail file location/naming, except instead of "video" it's "ipcam-record." with the dot instead of an underscore upfront.

And this likely cannot be used easily to download the whole 3mf file as there is the added step of needing to unzip it (likely into memory due to HA limitations) and then parse its internal data. But if it does work, opens up a lot of options.

Though, if using the python-scripts integration and a modified script like this works, it could open up an "advanced" usage for ha-bambulab maybe @AdrianGarside @greghesp thoughts? Might be worth looking into to create a blueprint for, though it likely won't add any data to the integration devices, but only provide media-files in HA, and that's if the python-script integration even allows access to the directory, which again I am not certain of.

AdrianGarside commented 4 months ago

I wrote a short python script way back that could download files via ftps. At the time they’d only just enabled it on the P1P and it was quite easy to hang the printer but hopefully that’s been fixed by now since they’ve finally added the Timelapse viewing in the slicer.

github-actions[bot] commented 2 months ago

Stale issue message