Converting iOS Companion App time zone data to UTC offset in template

I have a watch complication that shows me several pieces of data and one of them is the date (because squeezing it in there saved me another complication slot), but I recently realized that it doesn’t account for changing time zones.

So the plan is to use the mobile iOS companion app’s reported time zone in the Time Zone attribute of the geocoded_location sensor to adjust the date reported by the template that fills that part of the complication. Currently the template I’m using for that complication slot looks like this:

{{ as_timestamp(states('sensor.date_time_iso')) | timestamp_custom('%-m/%d') }}

Very simple and gives me what I need, and I found I can extract the timezone data with another template line like this:

{{ state_attr('sensor.mobile_device_geocoded_location', 'Time Zone') }}

But that reports the time zone in the tz database format as America/Los_Angeles and as far as I can tell I will need to get that converted to a UTC offset value which I can then pipe into timestamp_custom to get the date converted to the current time zone.

I’m definitely improving with jinja in recent projects but this one is escaping me, anyone able to point me in the right direction?

The Android app has a “…current_time_zone” sensor.
You don’t have that on iOS?

image

Nope, more details available here.

:tada:

iOS is restrictive in what it sends out.

I can’t think of a way to do this without mapping it w/ and w/o dst.

Yeah it occurred to me that I’ll need to account for dst but one step at a time, for now just trying to figure out how I can incorporate the time zone.

Once I get it working I’ll probably just setup an if/then that checks another sensor for dst status and pipes in a different UTC offset as needed.

So I found this page which indicates that this should be very simple, actually. Supposedly I should just need to use the following:

{{ as_timestamp(now()) | timezone('America/Los_Angeles') | timestamp_custom('%-m/%d')}}

(where America/Los_Angeles would be replaced with a variable set from the location sensor on another line, obviously) but when I try that I get the error:

TemplateAssertionError: No filter named 'timezone'.

Then some googling led me to this similar issue reported on Github so I tried using timezone as a function instead of a filter but then I get the error:

UndefinedError: 'timezone' is undefined

Any jinja2 experts have any advice on getting the timezone filter to work in this context?

That page is for quickbase, it has its own special jinja filters and that’s one of them. It’s not in HA.

Too bad command_line doesn’t support templates, it’s a one-liner in shell

bash-5.1# TZ="America/Los_Angeles" date +"%z"
-0700

Looks like you might be on to something, the documentation for the command_line sensor says that you can use templates with it, so I figured I could make a sensor that would run the command you provided where TZ was set through a template like so:

sensor:
  - platform: command_line
    name: tz_convert
    command: 'TZ={{ state_attr("sensor.mobile_device_geocoded_location", "Time Zone") }} date +"%z"'

But the sensor returns a state of unknown. If I swap out the template for the a static string value like this it works fine:

sensor:
  - platform: command_line
    name: tz_convert
    command: 'TZ="America/Los_Angeles" date +"%z"'

I’ve tried rigging up a simple command_line sensor that just uses echo followed by a template to troubleshoot this but that sensor just has no state when it is echoing a template, even with a template confirmed as valid in the developer tools.

Thanks for the help so far, slowly making progress here lol, anyone have experience making templates work with command_line sensors?

If that’s the case, the template you made isn’t correct. Try this:

    command: 'TZ="{{ state_attr("sensor.mobile_device_geocoded_location", "Time Zone") }}" date +"%z"'

No luck, sensor configs currently look like this:

sensor:
  - platform: command_line
    name: tz_convert
    command: 'TZ="{{ state_attr("sensor.mobile_device_geocoded_location", "Time Zone") }}" date +"%z"'
  - platform: command_line
    name: cl_test
    command: 'echo "{{ state_attr("sensor.mobile_device_geocoded_location", "Time Zone") }}"'

tz_convert sensor has the state “unknown” while cl_test sensor has the state “America/Los_Angeles”. Turns out the echo sensor I setup to test was working all along but needed a couple extra minutes after HA said it had finished starting up before it would work properly, which makes it that much more confusing that tz_convert won’t work.

My point with “too bad” is that command_line DOES NOT support templates in command: :wink:

Right I do understand what you were saying, it’s just that it’s at odds with the documentation for the command_line sensor. This section of the documentation provides the following summary and example:

Templates are supported in the command configuration variable. This could be used if you want to include the state of a specific sensor as an argument to your external script.

# Example configuration.yaml entry
sensor:
  - platform: command_line
    name: wind direction
    command: "sh /home/pi/.homeassistant/scripts/wind_direction.sh {{ states('sensor.wind_direction') }}"
    unit_of_measurement: "Direction"

it should work,

try:

    command: TZ="{{ state_attr("sensor.mobile_device_geocoded_location", "Time Zone") }}" date +"%z"

Oh, good!
I didn’t went further below that the settings section, which still says “string”, and the examples which didn’t show any templates.

PS The code tells me it doesn’t support it, though, so I’m confused now.

PPS Ah, it’s the core code that was confusing. It uses templates in a peculiar way. Only arguments (anything after the first blank) are evaluated as potential templates, which explains why Petro’s version didn’t work, I guess

Tried this and no change, have actually tried a bunch of tweaks on the quotations and formatting with no luck either. When I try those same changes to the cl_test sensor that uses the simple echo command it always works fine, so it seems like there’s some flexibility on the formatting of quotes and something else is going wrong with the time zone conversion command.

Update:

Was looking over the documentation again and had a real duh moment and figured out the simplest way to make this work: pass the template data to the script as an argument just like the documentation’s example. I’ve confirmed this config works:

  - platform: command_line
    name: sh_test
    command: "sh tz_convert.sh {{ state_attr('sensor.mobile_device_geocoded_location', 'Time Zone') }}"

Where the script referenced is just the following:

TZ="$1" date +"%z"

Now I have a sensor that will give me a UTC offset in the form of -0700, so all I have to do is figure out how to pull that sensor data into the original template that prints the date to offset it as needed. If anyone out there has experience there let me know as I’m starting from scratch on that one.

Update 2:

Got this working with the following config:

sensor:
  - platform: command_line
    name: tz_convert
    command: "sh tz_convert.sh {{ state_attr('sensor.mobile_device_geocoded_location', 'Time Zone') }}"
    value_template: "{{ value | float | multiply(0.01) }}"

{% set offset = states('sensor.tz_convert') | float %}
{{ as_timestamp(utcnow() + timedelta( hours = offset )) | timestamp_custom('%-m/%d') }}
1 Like

Hi @sheller ,

Thanks for the solution, I am trying to get something similar to work myself but am not too familiar with all the command line stuff. I have the sensor and template set up, but cannot get the shell script to work. Do I just need to create a “tz_convert.sh” file somewhere? Sorry, total noob at this stuff.

Thanks!
Will

Yeap that’s basically it. Go to Settings > Add Ons and install the “File Editor” add on, then you can use that to easily create a file named tz_convert.sh in the same folder that you find the configuration.yaml file in. The contents of the tz_convert.sh file should only be:

TZ="$1" date +"%z"

From there you can use the sensor and template data I posted in Update 2 of the solution I posted here you’re all set.

Thanks @sheller, had some trouble getting it working myself but need to have another play around with it when I get time. Use case for me is different, I do a lot of travelling because of my job and thought it would be cool if I could automatically show my local time based on my iOS device on home assistant. This was the closest solution I found to be able to do this.

Will