REST Sensor with value tempalte always reporting Unknown, but works in DevTools and logs

Hello! This is my first time posting to this form, so bear with me :slight_smile:

I’m trying to create a sensor that’ll show me the time-til-next-train for our local Caltrain system. The Caltrain API is pretty straightforward, and I’ve been able to get it working in Siri shortcuts and (somewhat) in home assistant. Unfortuately, the json that gets returned is really gross (a bunch of nested dictionaries) so I decided to create a value template to format things a little nicer.

Here’s my current setup (I’m sure there’s a better way to do the time parsing, but this works for now :woman_shrugging:)

sensor:
  - platform: rest
    resource: <removed>
    method: GET
    name: bullet_train_data
    value_template: >-
      {% set test_list = value_json['ServiceDelivery']['StopMonitoringDelivery']['MonitoredStopVisit'] %}
      {% set data = namespace(times=[]) %}
      {% for train_json in test_list %}
      {% set inner_json = train_json['MonitoredVehicleJourney'] %}
      {% if inner_json['PublishedLineName'] == 'Local' %}
      {% set given_datetime = inner_json['MonitoredCall']['ExpectedDepartureTime'] %}
      {% set parsed_datetime = as_timestamp(strptime(given_datetime, '%Y-%m-%DT%H:%M:%SZ')) | timestamp_custom('%H:%m') %}
      {% set now_formatted =  now().timestamp() | timestamp_custom('%H:%M') %}
      {% set time_diff = ((as_timestamp(strptime(now_formatted, '%H:%M')) - as_timestamp(strptime(parsed_datetime, '%H:%M')) /60) | int) %}
      {% set formatted_time_diff = time_diff | timestamp_custom('%M') %}
      {% set data.times = data.times + [formatted_time_diff] %}
      {% endif %}
      {% endfor %}
      {{ data.times }}

I’ve also enabled debugging for REST and for REST sensors, which has let me verify that the query returns the data I expect. This is what I see in the log:

2021-09-07 08:58:12 DEBUG (MainThread) [homeassistant.components.rest.data] Updating from <redacted>
2021-09-07 08:58:16 DEBUG (MainThread) [homeassistant.components.rest.sensor] Data fetched from resource: {"ServiceDelivery":{"ResponseTimestamp":"2021-09-07T15:58:21Z","ProducerRef":"CT","Status":true,"StopMonitoringDelivery":{"version":"1.4","ResponseTimestamp":"2021-09-07T15:58:21Z","Status":true,"MonitoredStopVisit":[{"RecordedAtTime":"2021-09-07T15:58:16Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"504"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.396149","Latitude":"37.7754288"},"Bearing":null,"Occupancy":null,"VehicleRef":"504","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T16:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T16:14:00Z","ExpectedDepartureTime":"2021-09-07T16:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"112"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T16:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T16:38:00Z","ExpectedDepartureTime":"2021-09-07T16:38:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"506"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T17:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T17:14:00Z","ExpectedDepartureTime":"2021-09-07T17:14:00Z","Distances":""}}}]}}}

In terms of already-attempted-debugging, I’ve opened dev tools and set/run the following:

{% set value_json = {"ServiceDelivery":{"ResponseTimestamp":"2021-09-07T15:58:21Z","ProducerRef":"CT","Status":true,"StopMonitoringDelivery":{"version":"1.4","ResponseTimestamp":"2021-09-07T15:58:21Z","Status":true,"MonitoredStopVisit":[{"RecordedAtTime":"2021-09-07T15:58:16Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"504"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.396149","Latitude":"37.7754288"},"Bearing":null,"Occupancy":null,"VehicleRef":"504","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T16:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T16:14:00Z","ExpectedDepartureTime":"2021-09-07T16:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"112"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T16:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T16:38:00Z","ExpectedDepartureTime":"2021-09-07T16:38:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-07","DatedVehicleJourneyRef":"506"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-07T17:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-07T17:14:00Z","ExpectedDepartureTime":"2021-09-07T17:14:00Z","Distances":""}}}]}}} %}
// this is the copy-pasted log output from above
{% set test_list = value_json['ServiceDelivery']['StopMonitoringDelivery']['MonitoredStopVisit'] %}
{% set data = namespace(times=[]) %}
{% for train_json in test_list %}
{% set inner_json = train_json['MonitoredVehicleJourney'] %}
{% if inner_json['PublishedLineName'] == 'Local' %}
{% set given_datetime = inner_json['MonitoredCall']['ExpectedDepartureTime'] %}
{% set parsed_datetime = as_timestamp(strptime(given_datetime, '%Y-%m-%DT%H:%M:%SZ')) | timestamp_custom('%H:%m') %}
{% set now_formatted =  now().timestamp() | timestamp_custom('%H:%M') %}
{% set time_diff = ((as_timestamp(strptime(now_formatted, '%H:%M')) - as_timestamp(strptime(parsed_datetime, '%H:%M')) /60) | int) %}
{% set formatted_time_diff = time_diff | timestamp_custom('%M') %}
{% set data.times = data.times + [formatted_time_diff] %}
{% endif %}
{% endfor %}
{{ data.times }}
// this is copy-pasted from the value template above

which gives me my desired output:

[
  "39"
]

When I try to view the sensor in devtools or on the entities page, it always reads Unknown. I’ve tried calling homeassistant.update_entity on it, which doesn’t change the value, and I’ve tried setting a value manually in devtools (which works) and then calling update, but that just sets it back to Unknown. I’ve also tried setting the value to only one element from the list instead of the list as a whole, but no dice.

Any idea where I’m going wrong? If there are better ways to debug templates, I’d be interested to know, since I think the problem probably lies there instead of in the REST query directly (since I’m getting my expected response back in logs).

Hi Morgan,
I guess sensor is waiting for a number or a string, not an array.

Hi Sébastien!
Thanks for taking a look – I also tried to have it return {{ data.times[0] }}, but that didn’t change it from Unknown (but when I do that in dev tools, it does change to be only an int: 39).

Let me try it on my test instance :stuck_out_tongue:

With a full template sensor, this is working. Now let’s try it with rest

Err, got the same Unknown state, I’m not an expert in Rest things… :stuck_out_tongue:

I’ve checked the doc, looks your syntax is OK…

1 Like

Weird! Which URL were you using to test?

Thanks for poking around, good to know its at least reproducible.

I have an apache test server, then i could serve the datas you’ve set in your post to my HA instance :stuck_out_tongue:

1 Like

oh fancy!
I guess that narrows the problem a little in that communicating the data might not be the problem? Maybe its parsing it?

Idk. Do you know if there are any significant differences in how dev tools works vs. how sensors get parsed from configuration.yaml? :thinking:

Based on my experience, what’s works in template works in yaml config files, just taking care of what you are returning (as I said, array, number…)

Hu got an error on config check, did not see it first time.

Do you have any error on config check ?

My bad, this one is from me haha ! copy/paste master

1 Like

hahaha all good! I was gonna say – nothing on my end!

Me again.
It’s working !
No change on your config. My apache was misconfigured…
Try to remove the value template part of your config.
The state should be the full JSON or an error should pop with max length of state is 255 chars.
Or you will have like I had an http error.

Oh, I used the template version with data.times[0]|int

huh! Can you send me the entry in your config? I tried just changing {{ data.times }} to {{ data.times[0] | int }} but I’m still getting Unknown :frowning: did you call update_entity or anything?

If I remove the template, I get the “max length cannot exceed 255” error.

Here is what i’ve set as config :

platform: rest
resource: http://192.168.1.10:81/test.json
method: GET
verify_ssl: false
name: bullet_train_data
value_template: >-
  {% set test_list = value_json['ServiceDelivery']['StopMonitoringDelivery']['MonitoredStopVisit'] %}
  {% set data = namespace(times=[]) %}
  {% for train_json in test_list %}
  {% set inner_json = train_json['MonitoredVehicleJourney'] %}
  {% if inner_json['PublishedLineName'] == 'Local' %}
  {% set given_datetime = inner_json['MonitoredCall']['ExpectedDepartureTime'] %}
  {% set parsed_datetime = as_timestamp(strptime(given_datetime, '%Y-%m-%DT%H:%M:%SZ')) | timestamp_custom('%H:%m') %}
  {% set now_formatted =  now().timestamp() | timestamp_custom('%H:%M') %}
  {% set time_diff = ((as_timestamp(strptime(now_formatted, '%H:%M')) - as_timestamp(strptime(parsed_datetime, '%H:%M')) /60) | int) %}
  {% set formatted_time_diff = time_diff | timestamp_custom('%M') %}
  {% set data.times = data.times + [formatted_time_diff] %}
  {% endif %}
  {% endfor %}
  {{ data.times[0]|int }}

and the JSON input from my apache is just what you tried in dev templates tools.

Edit : indentation is different for me because my config is using splitted YAML files. But htis is the config you have too…
My sensor changed state a lot since it is configured and working :
image

The API endpoints for your datas are http, you must set verify_ssl: false Just tested it after registering for an API key. HTTPS is available and valid…

Could you tell the API endpoint you are calling ? Delete you API key from it, I have mine now :smiley:

Edit : is it this one ? Looks familiar with the result :slight_smile:
https://api.511.org/transit/StopMonitoring?api_key=xxx&agency=CT&Format=JSON&stopcode=70012

If my guess on API endpoint is correct I also en with unkown…Will have another look later.

Enabled debug on rest sensor and I can see the datas are correctly read. This drives me crazy lol

OK, think I have it… In the API response there is in the 1st char the BOM “\ufeff” wich is not part of the JSON and crashes everything…
In the debug log, you can see the message Data Fetched From Ressource :
If you copy / Paste it from the “:” of the message and paste it in template tool :
TemplateSyntaxError: unexpected char '\ufeff' at 20

Now, we have to find a way to get rid of this…

I tried to setup the rest sensor with template_value: "OK" and a json_attributes: ServiceDelivery and here are the logs I end up with :

2021-09-08 21:08:59 DEBUG (MainThread) [homeassistant.components.rest.sensor] Data fetched from resource: {"ServiceDelivery":{"ResponseTimestamp":"2021-09-08T19:09:00Z","ProducerRef":"CT","Status":true,"StopMonitoringDelivery":{"version":"1.4","ResponseTimestamp":"2021-09-08T19:09:00Z","Status":true,"MonitoredStopVisit":[{"RecordedAtTime":"2021-09-08T19:08:59Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"510"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.39624","Latitude":"37.7754784"},"Bearing":null,"Occupancy":null,"VehicleRef":"510","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T19:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T19:14:00Z","ExpectedDepartureTime":"2021-09-08T19:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"118"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T19:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T19:38:00Z","ExpectedDepartureTime":"2021-09-08T19:38:00Z","Distances":""}}},{"RecordedAtTime":"2021-09-08T19:08:59Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"512"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.396111","Latitude":"37.7753792"},"Bearing":null,"Occupancy":null,"VehicleRef":"512","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T20:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T20:14:00Z","ExpectedDepartureTime":"2021-09-08T20:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"120"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T20:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T20:38:00Z","ExpectedDepartureTime":"2021-09-08T20:38:00Z","Distances":""}}}]}}}
2021-09-08 21:08:59 WARNING (MainThread) [homeassistant.components.rest.sensor] REST result could not be parsed as JSON
2021-09-08 21:08:59 DEBUG (MainThread) [homeassistant.components.rest.sensor] Erroneous JSON: {"ServiceDelivery":{"ResponseTimestamp":"2021-09-08T19:09:00Z","ProducerRef":"CT","Status":true,"StopMonitoringDelivery":{"version":"1.4","ResponseTimestamp":"2021-09-08T19:09:00Z","Status":true,"MonitoredStopVisit":[{"RecordedAtTime":"2021-09-08T19:08:59Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"510"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.39624","Latitude":"37.7754784"},"Bearing":null,"Occupancy":null,"VehicleRef":"510","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T19:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T19:14:00Z","ExpectedDepartureTime":"2021-09-08T19:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"118"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T19:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T19:38:00Z","ExpectedDepartureTime":"2021-09-08T19:38:00Z","Distances":""}}},{"RecordedAtTime":"2021-09-08T19:08:59Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L5","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"512"},"PublishedLineName":"LTD 5","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70262","DestinationName":"San Jose Diridon","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"-122.396111","Latitude":"37.7753792"},"Bearing":null,"Occupancy":null,"VehicleRef":"512","MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T20:14:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T20:14:00Z","ExpectedDepartureTime":"2021-09-08T20:14:00Z","Distances":""}}},{"RecordedAtTime":"1970-01-01T00:00:00Z","MonitoringRef":"70012","MonitoredVehicleJourney":{"LineRef":"L1","DirectionRef":"S","FramedVehicleJourneyRef":{"DataFrameRef":"2021-09-08","DatedVehicleJourneyRef":"120"},"PublishedLineName":"Local","OperatorRef":"CT","OriginRef":"70012","OriginName":"San Francisco Caltrain Station","DestinationRef":"70272","DestinationName":"Tamien","Monitored":true,"InCongestion":null,"VehicleLocation":{"Longitude":"","Latitude":""},"Bearing":null,"Occupancy":null,"VehicleRef":null,"MonitoredCall":{"StopPointRef":"70012","StopPointName":"San Francisco Caltrain Station","VehicleLocationAtStop":"","VehicleAtStop":"","AimedArrivalTime":"2021-09-08T20:38:00Z","ExpectedArrivalTime":null,"AimedDepartureTime":"2021-09-08T20:38:00Z","ExpectedDepartureTime":"2021-09-08T20:38:00Z","Distances":""}}}]}}}

We can clearly see the returned JSON has something wrong. And this wrong thing is the BOM for utf-8. This shouldn’t be here.
I could find another example on the forum as well :

but this leads to closed issues/PR…

At that time I have no idea on how to fix it. Sorry.

If anyone comes across this – I was not able to solve this issue, but I did migrate my caltrain schedule code to python where I was able to integrate it to home assistant via pyscript :slight_smile:

Lemme know if you’re after the code and I’ll post it up on github.