nurikk / zigbee2mqtt-frontend

Zigbee2MQTT frontend
https://www.zigbee2mqtt.io/
GNU General Public License v3.0
253 stars 184 forks source link

Serve device icons locally #1477

Open nohn opened 2 years ago

nohn commented 2 years ago

Is your feature request related to a problem? Please describe.

When my internet connection or the zigbee2mqtt.io server is down, Zigbee2MQTT frontend takes very long to load. See also https://github.com/Koenkk/zigbee2mqtt/issues/11908

Describe the solution you'd like

Serve device images locally.

Describe alternatives you've considered

-

Additional context

-

nurikk commented 2 years ago

There are some folks running z2m on some ludicrously underpowered hardware and very space constrained. Adding all z2m images into the bundle would be death sentence for them.

I just committed some changes regarding image loading, it should solve frontend loading issues in case of offline usage Try to switch to the latest dev branch

https://www.zigbee2mqtt.io/advanced/more/switch-to-dev-branch.html#switch-to-the-dev-branch

nohn commented 2 years ago

We are speaking about 17MB:

$ du -sh koenkk/zigbee2mqtt.io/public/images/devices/
17M koenkk/zigbee2mqtt.io/public/images/devices/

IMHO, hardware that is killed by that amount of data is already dead. You can't even properly upgrade any base package with that low amount of space left.

I'm running zigbee2mqtt-frontend as part of the official zigbee2mqtt Docker image, so I'll have to wait until your changes are merged and released to see them.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

nohn commented 2 years ago

Is still an issue and still not fixed.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

Starkstromkonsument commented 1 year ago

I would really appreciate this to be fixed. It would significantly increase privacy. There is no need to load resources from www.zigbee2mqtt.io (which resolves to ...github.io) on every move in the frontend, except for allowing github (=Microsoft) to track us. The reason I'm not using proprietary gateways / services etc. and supporting open source projects is that I don't want to be tracked.

Thank you.

Filipok-A commented 1 year ago

Fully agree with previous comment. In addition for me full refresh of the the page is slow. With about 15 unique devices, while most of the images load in 50ms, some take 3-5s to load.

@nurikk I understand your point about users with underpowered hardware, but maybe it is possible to add a setting to the frontend config to allow users to override base URL for the images?
For example, I am serving frontend behind nginx reverse proxy and it would be very easy for me to serve images from the /images/devices/ location. This could also benefit folks with limited hardware, as they would also have an option to serve images locally but on some other host and not z2m.

HalliHalloSchatz commented 1 year ago

I will serve the icons locally. I am full agree. That is privacy issue. That must be fixed, please Addon or an additional installation- & configuration-step.

Hypfer commented 1 year ago

https://github.com/nurikk/zigbee2mqtt-frontend/blob/a2e3dc31110b33aa5fe38e5e8ec7970aabf315bf/src/components/device-image/index.tsx#L19

What's stopping anyone from extending this function (that already exists!) to take an optional configuration parameter into account where you can specify a custom asset host? That can't be more annoying than fighting with the stale bot

nohn commented 1 year ago

I can only speak for myself: It's that it's more than extending that function.

The latter will become a real pain. In the end it would lead to requiring two separate Docker images of zigbee2mqtt, one including zigbee2mqtt-frontend without images and one with images being contained. To serve @nurikk s requirement of having a small image for underpowered devices and an docker image containing the image files. Another option would be some downloading mechanism within zigbee2mqtt-frontend itself, but that would be another thing one would have to implement and would still not solve the problem for people who would want to run their zigbee2mqtt outbound firewalled.

Overall, for me, it just was not worth the effort of implementing all that + likely having some back and forth until the MR would be accpeted compared to just accepting my problem of bad frontend performance if internet is down which happens once in a year.

I don't see any fighting with a stale bot here since one year but I also will never befriend with stalebot (see https://drewdevault.com/2021/10/26/stalebot.html)

Hypfer commented 1 year ago

Take all this with a grain of salt as I'm quite new to this project, but

You need a way to properly configure that

There's already a way to configure the frontend via the frontend. You'd just need to extend its configuration schema with another string.

As a tip on how to approach something like that in an unknown codebase: First, find a source file that is related to what you're after, then do git blame and try to locate a commit that does something as close to what you want to do as possible.

As an example, here's a commit that added a different new config option: https://github.com/Koenkk/zigbee2mqtt/commit/1f642d86e87f91cdef32f8405a336bc26a9b8f1c

Really not that much to change. Just some schemas and test case.

As for the frontend side.. the form seems to be generated automatically from the payload from the backend? If so then that's no change at all. Translations, maybe?

You need a way to fetch the images

You mean git pull? They're here: https://github.com/Koenkk/zigbee2mqtt.io/tree/master/public/images/devices

You need a way to properly distribute that

See above. They're on GitHub. Same source where you also get the software from

Overall, for me, it just was not worth the effort of implementing all that compared to just accepting my problem of bad frontend performance if internet is down

I kinda suspect that the maintainers might feel the same way. It's probably just very low priority because it works fine and only causes mild unhappiness in probably less than 3% of installations.

So why this issue then? If you as the author don't even care about it then why have it in the first place?

I know the usual story is "Maybe some day someone will be looking to contribute something and then they will look at the list of feature requests" but that's frankly just not happening. It never has and it never will. There is no magic coding santa clause. Jesus also won't implement your feature requests, of that you can be sure.

This is just so very pointless and a waste of time for everyone involved. And it's everywhere in the issue trackers on GitHub. Especially worse when it comes to software close to consumer tech.

And that's likely why there's a stale bot active in the repo, because writing this reply took 40 minutes. Time a maintainer can better spend actually working on the software itself. Something that also is much more enjoyable than endless noise that leads nowhere.

Anyway, I threw in some pointers on how to approach this issue. I hope that can help reducing the scary-ness of tackling this task.

setfire2 commented 10 months ago

I also think that serving the icons locally is a good idea for privacy and stability reasons. The server serving the images seems to be down quite often.

i-am-at0m commented 10 months ago

zigbee2mqtt supports Base64 encoding them directly for Home Assistant. They don't even need to get downloaded en masse, when a url is found, instead snag it, encode it, and store the image that way maybe?

On Sat, Nov 11, 2023, 14:54 setfire2 @.***> wrote:

I also think that serving the icons locally is a good idea for privacy and stability reasons. The server serving the images seems to be down quite often.

— Reply to this email directly, view it on GitHub https://github.com/nurikk/zigbee2mqtt-frontend/issues/1477#issuecomment-1806903637, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAHROWYMOGMAKTVRNMNJ2I3YD7JV3AVCNFSM5V6ZN632U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCOBQGY4TAMZWGM3Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>

nurikk-sa commented 10 months ago

zigbee2mqtt supports Base64 encoding them directly for Home Assistant. They don't even need to get downloaded en masse, when a url is found, instead snag it, encode it, and store the image that way maybe?

This is a good point. Maybe someone can create a javascript code to automate this process?

nurikk commented 10 months ago

Okay folks, I just implemented feature for you. 1) Update to the latest dev 2) Navigate to Settings -> Tools -> Click Localise device images

This will download your device images and save them locally in devices.yaml as base64 data uri. Every time when you add new device, you have to run this procedure again in order to update image

setfire2 commented 10 months ago

How cool is this? Thank's man! I will try it as soon as this development makes it into the latest koenkk/zigbee2mqtt development Docker image.

@Koenkk ;-)

Koenkk commented 10 months ago

as soon as a new frontend release is made it will be in development dev docker image, awesome @nurikk !

cmsj commented 10 months ago

Looking forward to being able to host the images locally, thanks for adding that.

the zigbee2mqtt.io site is down right now (like, extremely down, I can't even dig -t ns the domain), so I would join the people suggesting that this just be the default.

Outsidewall commented 5 months ago

I have been playing around in having a nginx as a server for the images. I can display the images in a browser, aka using the url http:/images.xyz.home/zigbee2mqtt/devices/BSD29.png However I put this url in the icon setting for the device, I do not get an error message nor the image being displayed! Infact no image is displayed, not even the zigbee logo. I have tried the internet url https://www.zigbee2mqtt.io/images/devices/BSD29.png of the image, this works, as the icon setting . Anyone else have this type of setup working?

Outsidewall commented 5 months ago

I have been playing around in having a nginx as a server for the images. I can display the images in a browser, aka using the url http:/images.xyz.home/zigbee2mqtt/devices/BSD29.png However I put this url in the icon setting for the device, I do not get an error message nor the image being displayed! Infact no image is displayed, not even the zigbee logo. I have tried the internet url https://www.zigbee2mqtt.io/images/devices/BSD29.png of the image, this works, as the icon setting . Anyone else have this type of setup working?

FIXED: Found the issues, need TLS (https) and a CORS policy, generated certs, and updated nginx to support cors as well.

Mr-Kappelmann commented 4 months ago

with that new function in since Version 0.34.0

Navigate to Settings -> Tools -> Click Localise device images

WORKING great!

can be closed

jploonstra commented 4 months ago

The "Localize device images" stores the whole icon in the configuration.yaml file. I am not happy with this. Can the icons please be moved to the local file system?

By the way, can I just remove the icon data from the configuration.yaml and will the default (online) icons be used again? Or will the icons be gone?

Edit: Removed the icon data from the config.yaml and everything is back as it was. But I still have devices with wrong icons that I can't solve now...

Edit 2: I have two different devices: Zigbee model TS0201 Zigbee Fabrikant _TZ3210_ncw88jfq Zigbee model TS0201 Zigbee Fabrikant _TZ3000_rdhukkmi These are completely different. The first is with a square display and the second has no display at all, but both have the same icon with a round display. Is the icon only referenced from model? Or also from manufacturer? Is there a way to submit the correct icon for the manufacturer somewhere?

thargy commented 4 months ago

Base64 encoding increases size by 33-37% (33% because the encoding itself takes 4/3 times the space, and up to 4% due to additional newlines being added). It also clutters up the config with non-human-readable data.

It also increases the download speed for the same reason.

Far better would be to cache the images locally as jpegs/PNGs, which are already in their most compressed form. When serving the frontend Z2M should check for the presence of a cached image, and, if absent, download from the git repo and cache. If it fails to download it can put a placeholder image in the cache to prevent rechecks.

Even better would be to cache the images locally at the various required sizes. For example, the main device page shows 30x30 thumbnails, but the UI downloads every image at full resolution. Similarly, the main info on a device uses the images at 150x150. However, some images are 512x512, or bigger, in the Github! When creating the cache, it is trivial to use the Image library (or similar) to store a 150x150 version and a 30x30 version, using the appropriate one in each case. The size of these 2 smaller images would be smaller than some of the full-size images currently being downloaded!

Frankly, the bigger issue is that the cache expiry for images are set to be cached by the web browser for only 10 minutes! Pages would load much quicker if the cache expiry was longer, as your browser would only load them once rather than round-tripping every 10 minutes. However, if you implemented local server caching then a short remote cache duration would make more sense.

setfire2 commented 4 months ago

Edit 2: ... Is there a way to submit the correct icon for the manufacturer somewhere?

Get the image from the manufacturer, base64 encode it, put it in config.yaml?

For me I can say that I'm happy with the current solution. In todays plenty of storage I don't care about the few bytes.

pimlie commented 4 months ago

Unfortunately the localise_images options doesnt work for me as my zigbee2mqtt instance doesn't have internet access.

@nurikk Wdyt about the following workflow, could this be a definitive solution to be able to close this issue? If you approve I could help with this if you like.

Having a second docker build with all device images might not be super ideal, but the 150MB is not that big and could potentially also be optimized to use lower resolutions as @thargy already mentioned. Also it's quite easy to change the Cache-Control headers using serve-static for these static device images.

thargy commented 4 months ago

SERIOUS BUG

The localise images tool doesn't appear for me correctly: image

This is the button HTML (you can see it has no content:

<button type="button" class="btn btn-primary d-block mt-2"></button>

Clicking on it produces a long list of devices, and the Z2m dies. On reboot, the UI doesn't list any devices.

I only know this is the Localise Images button because I can see my configuration explode by 100s of Base64 icon keys. Worse, it encodes the image on every device, even when the image is the same. When you've got 180 devices, that creates a massive file.

Sure enough, restarting Z2m looks like there are no devices configured, and this was only fixed by reverting out the icon keys.

As mentioned above, I don't think you should be encoding the image into the config anyway, but it's unquestionably a bad idea to encode the same image repeatedly.

privx-de commented 3 months ago

SERIOUS BUG

The localise images tool doesn't appear for me correctly: image

This is the button HTML (you can see it has no content:

<button type="button" class="btn btn-primary d-block mt-2"></button>

Clicking on it produces a long list of devices, and the Z2m dies. On reboot, the UI doesn't list any devices.

I only know this is the Localise Images button because I can see my configuration explode by 100s of Base64 icon keys. Worse, it encodes the image on every device, even when the image is the same. When you've got 180 devices, that creates a massive file.

Sure enough, restarting Z2m looks like there are no devices configured, and this was only fixed by reverting out the icon keys.

As mentioned above, I don't think you should be encoding the image into the config anyway, but it's unquestionably a bad idea to encode the same image repeatedly.

Had the same problem today. Not nice at all. At first I thought I had broken my Zigbee2MQTT.

maxi1134 commented 2 months ago

How to fix? My zigbee fucked up due to that button!

jploonstra commented 2 months ago

The only way is to edit the configuration.yaml file and take all the lines for the encoded images out…

jploonstra commented 2 hours ago

Any news on this?

thargy commented 51 minutes ago

It's still there and it's a ticking time bomb for any unsuspecting user. It really needs removing as a feature for now until it is implemented properly.