Write calendar events to a json file, can't figure out how to format as dictionary

hello,

I just want to get calendar events and write a parsed down version to a json which I can then read with an esphome e-paper display I have been working on. I cannot for the life of me get the formatting on the template correct (at least I assume that’s the problem) YAML and templates are still dark magic to me.

I’m on
Core 2025.1.4
Supervisor 2025.03.0
Operating System 14.2

my YAML is here:

description: ""
mode: single
triggers:
  - at: "19:00:00"
    trigger: time
  - entity_id: input_button.coming_home
    trigger: state
conditions: []
actions:
  - action: calendar.get_events
    metadata: {}
    data:
      duration:
        hours: 48
        minutes: 0
        seconds: 0
    response_variable: agenda
    target:
      entity_id: calendar.calendar
  - action:
    - service: file.write
      data_template:
        file: /homeassistant/www/calendar_events.json
        append: false
        data: >-
          {
          {%- set work_events = [] -%}
            {%- for event in agenda["calendar.calendar"]["events"] -%}
    
              {%- set work_events = work_events + [{
                "start_time": (event.start|as_datetime|as_local).strftime("%H:%M"), 
                "end_time": (event.end|as_datetime|as_local).strftime("%H:%M"),
                "title": event.summary
              }]-%}
    
            {%- endfor -%}
          }

Error message is:
Message malformed: value should be a string for dictionary value @ data[‘actions’][1][‘action’]

Thanks for any help you can offer!!

There is no such thing as file.write, check the File integration
And you need a namespace to work within a for-loop
Likely this would work after (!) you setup the file integration and the entity is called notify.file File - Home Assistant

alias: Export Cal Events
description: ""
triggers:
  - at: "19:00:00"
    trigger: time
  - entity_id: input_button.coming_home
    trigger: state
conditions: []
actions:
  - action: calendar.get_events
    metadata: {}
    data:
      duration:
        hours: 48
        minutes: 0
        seconds: 0
    response_variable: agenda
    target:
      entity_id: calendar.calendar
  - action: notify.send_message
    metadata: {}
    data:
      message: >-
        {%- set ns = namespace(work_events=[]) -%} {%- for event in
        agenda["calendar.calendar"]["events"] -%}   {%- set
        ns.work_events = ns.work_events + [{     "start_time":
        (event.start|as_datetime|as_local).strftime("%H:%M"),      "end_time":
        (event.end|as_datetime|as_local).strftime("%H:%M"),     "title":
        event.summary   }]-%} {%- endfor -%} {{ ns.work_events }}
    target:
      entity_id: notify.file
mode: single
1 Like

great! That runs without any problems and I can see the events in the file. Thank you so much!

Can I make it overwrite the file instead of adding new lines?

Sadly not, you would need to add some bash and command(line) service/action