sibbl / hass-lovelace-kindle-screensaver

This tool generates a png from a Home Assistant Lovelace view, which can be displayed on a Kindle device which has the Online Screensaver plugin installed.
MIT License
315 stars 71 forks source link

Ability to set timezone when launching puppeteer? #7

Closed jbraceg closed 2 years ago

jbraceg commented 3 years ago

Hi there,

Thanks for pushing this out - finding it saved me a ton of fiddly work making something similar myself!

I have found one issue - when I launch the process in a Docker container, it seems that the timezone Chromium detects is UTC. This means that widgets that depend on date/time like the calendar display the wrong values.

It's possible to force the timezone Chromium uses by setting the TZ env var when launching puppeteer. Very happy to send a PR for this, as long as you agree that it's a sensible thing to do.

What are your thoughts?

rogatty commented 3 years ago

@jbraceg thanks for the link. They say:

You can override the timezone in chromium by setting the TZ env var.

It's enough to set the TZ env variable in docker, e.g. in docker-compose.yaml. This worked for me:

environment:
  ...
  - TZ=Europe/Warsaw

Would be nice to add it to the README but it's not obvious where to put it with the current structure 🙂

bictorv commented 3 years ago

Another way is using "docker -v /etc/localtime:/etc/localtime:ro".

lanrat commented 2 years ago

I've tried setting the TZ variable and using a /etc/localtime:/etc/localtime:ro volume with no luck. In both cases I still get UTC timezones.

Have anyone found a way to get the screenshot to use the correct timezone?

bictorv commented 2 years ago

I also get UTC since a few weeks, and I'm struggling to see what causes the problem. "It used to work". :-(

lanrat commented 2 years ago

I spent some time playing with this and tweaking the container and code.

Installing the tzdata package will have the alpine node container set its local timezone/date to whatever you pass in with the TZ variable. but I'm not sure if this is needed for chrome. When doing this, node gets the correct timezone, and so does chrome.

I suspect that the issue might have something to do with a change on Home Assistant's end. The problem is definitively in Home Assistant's front end as I hard-coded all of the backend to use my timezone, but when rendering the front end it uses UTC.

I'm trying to figure out how Home Assistant determines what timezone to use for the front end. My guess is that its missing some HTTP header.

lanrat commented 2 years ago

@bictorv did you upgrade hass-lovelace-kindle-screensaver or Home Assistant when you started noticing the issue? If we can narrow down a change to either that introduced the issue I might be able to find a fix.

bictorv commented 2 years ago

Yes I did, and I thought I reported it here, but apparently not. Now I forget exactly which update it was, but will try to find out.

Do you mean installing tzdata helps? More precisely which tzdata package, installed where/how? (I'm new to docker and alpine and puppeteer and... feeling a bit old sometimes.)

lanrat commented 2 years ago

@bictorv do you remember about when you upgraded? or when you last remember it working? Was the upgrade that broke it Home Assistant or hass-lovelace-kindle-screensaver?

I installed tzdata by adding it to the Dockerfile and rebuilding, but it did not fix the issue for chrome, so its not a solution.

bictorv commented 2 years ago

It was an Home Assistant upgrade, I would guess 2021.10.x, or possibly 2021.9.x.

When you write chrome, do you mean/include chromium, which I believe is what my installation is using?

And adding tzdata to Dockerfile in the RUN apk line or or elsewhere?

bictorv commented 2 years ago

Well with 2021.11 I just get a screenshot of the Home Assistant logo with "Loading data" under it. Something changed, apparently.

lanrat commented 2 years ago

I found and solved the issue!

I think the problem has to do with the alpine linux docker container's version of libc and chrome's. There is a slight version incompatibility that breaks chrome's ability to use the correct timezone.

Luckily this has been fixed already in the newer versions of the base container. Edit the Dockerfile and set it to use node:17-alpine as the base and rebuild the image. All dates and local setting should work now!

I'll be submitting a PR soon from my fork with this fix and some other features.

sibbl commented 2 years ago

@lanrat I've just fixed another issue and also updated both Puppeteer and Alpine.

However, I was forced to use Alpine 3.11 instead of the latest version 3.14 as its the last version where a armv7 binary of chromium is available for (see here).

I'd be happy to know if this already fixes the issue or whether we might have to think about other solutions. Thanks in advance!

lanrat commented 2 years ago

Thanks for updating the base image.

When using the base image node:16-alpine3.11 the correct timezone is being used by chrome. But the date local formatting does not work. When using node:17-alpine as the base, both the timezone and local formatting work. See the below examples from my weather card:

Image built from node:16-alpine3.11:

Screen Shot 2021-11-10 at 11 36 22 AM

Image built from node:17-alpine:

Screen Shot 2021-11-10 at 11 37 02 AM

As you can see, with alpine 3.11, the times use a 24 hour format (the default if unset by the local) but when using the latest version they are correctly shown with AM/PM.

I'm unsure of the underlying cause for this and if its possible to fix it without using node:17-alpine.

sibbl commented 2 years ago

@lanrat thanks for your reply including the new details! It's good to now that at least the timezone works now, if I understand you correct.

Regarding formatting of numbers and dates, I guess we have to wait until a newer chromium binary will be available.

Until then, I think it might be the best to set specific number + date/time formats within home assistant. For each user, this can be done in the profile by clicking the user profile icon in the lower left corner and by default it's set to "auto (use browser settings)". I know it's not perfect, but perhaps it also solves the issue meanwhile?

lanrat commented 2 years ago

Correct, the timezone issue appears to be fixed.

I just did a test using node:16-alpine and can confirm that both the timezone and local formatting work correctly. So its an issue with alpine3.11 and not the difference in node versions.

lanrat commented 2 years ago

The date is still formatted wrong when using node:16-alpine3.11.

Using node:17-alpine fixes the date formatting issue.

bictorv commented 2 years ago

How can I (most easily) get/setup/compile a version of node:17-alpine with chromium, given there is no armv7 binary of chromium at the link @sibbl gave above?

sibbl commented 1 year ago

Fyi, the alpine 3.17 build of chromium included an armv7 binary again. I've just updated the image to use this as a new base.