Jump to content

Welcome to Smart Home Forum by FIBARO

Dear Guest,

 

as you can notice parts of Smart Home Forum by FIBARO is not available for you. You have to register in order to view all content and post in our community. Don't worry! Registration is a simple free process that requires minimal information for you to sign up. Become a part of of Smart Home Forum by FIBARO by creating an account.

 

As a member you can:

  •     Start new topics and reply to others
  •     Follow topics and users to get email updates
  •     Get your own profile page and make new friends
  •     Send personal messages
  •     ... and learn a lot about our system!

 

Regards,

Smart Home Forum by FIBARO Team


Recommended Posts

Posted

iCal Parser + iCloud Calendar QuickApp

Repo: 

Please login or register to see this link.



A complete iCalendar (RFC 2445) parser library written in Lua, plus a Fibaro HC3 QuickApp for downloading and displaying events from your iCloud calendar.


Components

1. iCal.lua — Standalone Parser Library

A pure Lua library for parsing iCalendar format. Can be used standalone or embedded in a QuickApp.

Features:

  • Parses iCalendar (RFC 2445) format
  • Extracts VEVENT components with full property support
  • Automatic RRULE expansion into individual event instances
  • Handles EXDATE exclusions
  • Date range filtering (start/end dates)
  • Lenient error handling (skips malformed properties, logs warnings)
  • Supports DATE, DATE-TIME (local and UTC), and duration fields

Supported Properties:

  • SUMMARY, DTSTART, DTEND, UID, DESCRIPTION, LOCATION
  • ORGANIZER, ATTENDEE (email extraction)
  • LAST-MODIFIED, RRULE, EXDATE

RRULE Support:

  • FREQ: DAILY, WEEKLY, MONTHLY, YEARLY
  • COUNT, UNTIL, INTERVAL
  • BYDAY, BYMONTHDAY (basic support)

Example Usage:

Please login or register to see this code.


2. iCloud_Calendar.lua — QuickApp

A Fibaro HC3 QuickApp that downloads your iCloud calendar and displays upcoming events.

Features:

  • Download calendar from webcal:// or https:// URLs
  • Parse and display upcoming events
  • Configurable date range (default: next 30 days)
  • Shows event count, titles, dates, and descriptions
  • Error handling and status display
  • Lenient parsing (skips malformed events)

Configuration:

Set these QuickApp variables:

Variable Type Description Default
calendarUrl string Your iCloud calendar URL (webcal:// or https://) (empty)
daysAhead number Days into the future to fetch events 30

How to Set Up:

  1. Get your iCloud calendar URL:

    • On your iPhone/Mac: Settings → [Your Name] → iCloud → Calendars → Share Calendar
    • Copy the public "Calendar Link" (looks like webcal://p64-caldav.icloud.com/published/...)
    • Or use the https:// variant if available
  2. Add the QuickApp to your HC3:

    • Copy iCloud_Calendar.lua to your HC3
    • Create a Device/QuickApp with the file
    • Edit the QuickApp properties and set calendarUrl to your calendar link
    • Optionally adjust daysAhead for a different time window
  3. Download Events:

    • Click the "Download Calendar" button in the QuickApp UI
    • Wait for "Status: Complete"
    • View parsed events in the UI

UI Elements:

Element Purpose
Status Shows current operation status (Ready, Downloading, Complete, Error)
Events Count of events found in the date range
Download Calendar Button to trigger download & parse
Event List Shows first 5 upcoming events with dates and titles
Last Event Date and title of the last event in range

Usage Examples

Inside a QuickApp the library is available as the global fibaro.iCal
(loaded via --%%file:iCal.lua,ical). Standalone Lua scripts can use
require("iCal").

Download and list upcoming events from a QuickApp

Please login or register to see this code.

Download with an explicit time window

Please login or register to see this code.

opts fields: startTs, endTs, daysAhead (default 30, used when
endTs is omitted), timeout (ms, default 10000), maxRedirects
(default 3). webcal:// and webcals:// URLs are auto-rewritten to
https://.

Find events happening right now

Please login or register to see this code.

Parse a local iCal file (standalone Lua)

Please login or register to see this code.

Event fields

Each entry in events (sorted by dtstart ascending) has:

Field Type Notes
uid string Stable across recurring instances
summary string Title
description string May be nil; multi-line text is unfolded
location string May be nil
dtstart number Unix timestamp
dtend number Unix timestamp; may be nil for all-day or zero-length
allDay boolean true for DATE-only events
organizer string Email (lowercased), if present
attendees table List of email strings

Date Formats

The parser automatically detects and converts three iCalendar date formats:

Format Example Meaning
DATE 20260406 April 6, 2026 (all-day event)
DATE-TIME (local) 20260406T143000 April 6, 2026 at 2:30 PM (floating time)
DATE-TIME (UTC) 20260406T143000Z April 6, 2026 at 2:30 PM UTC

All times are converted to Unix timestamps (seconds since 1970-01-01 UTC) for comparison and filtering.


Recurrence Processing

How RRULE Works

When an event has a recurrence rule (RRULE), the parser expands it into individual event instances:

Input (Single Recurring Event):

Please login or register to see this code.

Output (5 Expanded Events):

  • April 10, 2026 10:00 - Team Meeting
  • April 17, 2026 10:00 - Team Meeting
  • April 24, 2026 10:00 - Team Meeting
  • May 1, 2026 10:00 - Team Meeting
  • May 8, 2026 10:00 - Team Meeting

EXDATE (Exception Dates)

If an event has exceptions (e.g., the April 24 meeting was cancelled):

Please login or register to see this code.

That instance is automatically excluded from the expanded set.


Limitations & Known Issues

  1. Timezone Handling (SIMPLIFIED)

    • The parser does not deeply parse TZID parameters or VTIMEZONE components.
    • All non-UTC times are treated as "floating" times and converted to Unix timestamps as-is.
    • Future enhancement: Parse VTIMEZONE blocks and apply TZID offsets.
  2. RRULE Support (BASIC)

    • Only basic recurrence rules are supported (DAILY, WEEKLY, MONTHLY, YEARLY with COUNT/UNTIL/INTERVAL/BYDAY/BYMONTHDAY).
    • Complex rules (e.g., BYSETPOS, BYHOUR, BYMINUTE) are not yet implemented.
    • Future enhancement: Add full RFC 2445 RRULE support.
  3. Performance

    • For calendars with > 1000 recurring instances, performance may degrade.
    • HC3 memory limits may be hit with very large calendars.
  4. Components Ignored (Out of Scope)

    • VALARM (alarms/notifications)
    • VTODO (to-do items)
    • VJOURNAL (journal entries)
    • VFREEBUSY (free/busy information)
    • Only VEVENT components are parsed.
  5. Error Recovery

    • Malformed properties are skipped (lenient mode).
    • Invalid lines don't halt parsing; they're logged and skipped.
    • If a critical property (UID, DTSTART) is missing, the entire VEVENT is dropped.

Testing

Manual Test with plua

  1. Test the parser library locally:

    Please login or register to see this code.

  2. Test the QuickApp:

    Please login or register to see this code.

    • Set the calendarUrl variable before running.
    • Trigger the download via debug console or plua HTTP API.

Unit Tests (Example)

Please login or register to see this code.


Output Structure

Events Table

Each event in the results table has this structure:

Please login or register to see this code.


iCloud Calendar Share Link Format

Public (Read-Only) Link:

Please login or register to see this code.

Notes:

  • Replace webcal:// with https:// if needed
  • The long token at the end (starting with 2/MTM...) is unique to your calendar
  • Do not share this link with anyone you don't trust; it grants read access to your calendar

Future Enhancements

  1. Full RRULE Support

    • Implement BYSETPOS, BYHOUR, BYMINUTE
    • Handle complex weekly recurrence rules
  2. Timezone Awareness

    • Parse VTIMEZONE components
    • Apply TZID offsets to event times
    • Support DST transitions
  3. Component Expansion

    • Add VTODO parsing (to-do items)
    • Add VALARM parsing (alarm/notification details)
    • Add VJOURNAL parsing (journal entries)
  4. QuickApp Enhancements

    • Display alarm information
    • Show attendee list with RSVP status
    • Sync to HC3 scenes/automations
    • Schedule actions based on upcoming events
  5. Performance Optimization

    • Pagination for large calendars
    • Incremental parsing (stream-based)
    • Caching of parsed results

Development Notes

RFC 2445 Compliance

The parser implements a subset of RFC 2445 (iCalendar specification):

  •  Implemented: VCALENDAR, VEVENT, SUMMARY, DTSTART, DTEND, UID, DESCRIPTION, LOCATION, ORGANIZER, ATTENDEE, RRULE, EXDATE, LAST-MODIFIED
  • ⚠️ Partial: Line folding, property parameters (VALUE, TZID, LANGUAGE)
  •  Not Implemented: VALARM, VTODO, VJOURNAL, VFREEBUSY, VTIMEZONE, RECURRENCE-ID, time zone offsets

For full RFC 2445 documentation, see: 

Please login or register to see this link.

Code Architecture

Please login or register to see this code.


Support & Troubleshooting

"Error: No calendar URL set"

  • Add your iCloud calendar URL to the calendarUrl QuickApp variable.
  • Format: webcal://p64-caldav.icloud.com/published/2/...

"Error: HTTP 404" or "HTTP 403"

  • Verify the calendar URL is correct and accessible.
  • If using a private calendar, ensure the share link grants public access.
  • Try accessing the URL in a browser to verify.

"Error: Network failure"

  • Check HC3 internet connectivity.
  • Verify the URL is reachable from your network.
  • Try a different calendar URL to test.

"Events: 0" (No events found)

  • Increase the daysAhead variable to look further into the future.
  • Check that your calendar actually has events in the specified date range.
  • Review the HC3 debug log for parser warnings.

Malformed events are skipped

  • The parser operates in lenient mode: badly-formed events are logged and skipped.
  • Check the debug console for "Skipped" messages.
  • Consider exporting your calendar to a desktop app to validate it first.

License & Attribution

This iCal parser is provided as-is for use with Fibaro HC3 QuickApps.

RFC 2445 (iCalendar) specification courtesy of the IETF.


Version History

  • v1.0 (2026-04-06) — Initial release
    • Basic iCal parser
    • Simple RRULE expansion (DAILY, WEEKLY, MONTHLY, YEARLY)
    • QuickApp for iCloud calendar download
    • Date range filtering
  • Thanks 1
  • Topic Author
  • Posted

    Calendar Automation QuickApp

    This is work in process...

    A Fibaro HC3 QuickApp that turns your iCloud / webcal calendar into an HC3
    scheduler: tag a calendar event with #HC3#… and the QA will call a
    matching method on itself when the event starts.

    Source: 

    Please login or register to see this link.

     · uses 

    Please login or register to see this link.


    How it works

    1. Every 6 h (and on startup or the Refresh now button) the QA downloads
      the calendar via fibaro.iCal.download.
    2. Each event's SUMMARY and DESCRIPTION is scanned for lines starting
      with the configured start-tag prefix (default #HC3#) or
      end-tag prefix (default #/HC3#).
    3. Tagged events are kept; everything else is discarded.
    4. A 30 s ticker checks each kept event:
      • When DTSTART is reached → fire all #HC3#… tags.
      • When DTEND is reached → fire all #/HC3#… tags.
        Each tag is dispatched at most once per occurrence
        (uid + phase + ts dedup key).
    5. Each tag becomes a method call on the QA itself:
      self:<methodName>(arg1, arg2, …).

    Why a 30 s ticker instead of setTimeout? HC3's setTimeout is unreliable
    for delays > a few hours; the ticker is robust against reboots, clock
    changes, and missed wake-ups.


    Tag syntax

    Please login or register to see this code.

    The two prefixes are paired like HTML open/close tags. Use either, both, or
    several of each in the same event — they're independent. The line ends at
    the next newline; everything after the prefix on that line becomes the call.

    Typical "on for the duration of the event" pattern:

    Please login or register to see this code.

    Argument coercion

    Token Becomes
    123, 1.5 number
    true / false boolean
    nil nil
    "hello,there" string "hello,there" (commas inside quotes still split — see below)
    anything else string (one layer of "…" or '…' stripped)

    Note: the splitter is a simple ,-based split. If you need a comma
    inside a string argument, prefer using a different separator in your
    handler — e.g. #HC3#say,Time-to-leave and have say replace - with space.

    Examples

    Tag in event body Equivalent call When
    #HC3#turnOn,88 self:turnOn(88) start
    #/HC3#turnOff,88 self:turnOff(88) end
    #HC3#setValue,42,80 self:setValue(42, 80) start
    #HC3#scene,17 self:scene(17) start
    #HC3#say,"Hej hopp" self:say("Hej hopp") start

    You can put multiple tags on the same event (one per line, in summary
    or description). All will fire at their respective phase.


    Setup

    1. Get an iCloud calendar URL

    Mac Calendar → right-click your calendar → Share Calendar → enable
    Public Calendar  Copy URL. Looks like:

    Please login or register to see this code.

    2. Install the QA on HC3

    Please login or register to see this code.

    Or copy Calendar_automation.lua (and iCal.lua — it's pulled in via the
    --%%file: directive) to a new QuickApp via the HC3 web UI.

    3. Set QA variables

    Variable Default Meaning
    calendarUrl env.ICAL Your webcal/https calendar URL
    daysAhead 7 How far ahead to look for tagged events
    tagPrefix #HC3# Start-of-event tag prefix
    tagPrefixEnd #/HC3# End-of-event tag prefix

    4. Add a calendar event

    Make a normal calendar entry. Anywhere in summary or notes, add a
    line like:

    Please login or register to see this code.

    Save. On the next refresh (or click Refresh now) the QA will pick it up;
    when the event's start time arrives, self:turnOff(88) runs.


    UI

    Element Purpose
    Status Ready / Downloading… / Complete / Error: …
    Upcoming Next 5 tagged events (date, summary, methods)
    Last Time and summary of the most recently fired event
    Refresh now Manual refresh + dispatch
    Action log Reserved for custom logging if you want it

    Defining your own actions

    Open the bottom of 

    Please login or register to see this link.

     and add
    methods. Each one becomes invocable from a #HC3#<name>,… tag.

    Please login or register to see this code.

    The bundled examples (turnOn, turnOff, setValue, scene, say) are
    starters — keep what you use, delete the rest.

    Safety rails built in

    • Unknown method names log a warning instead of crashing.
    • Each handler runs inside a pcall; an error in one tag never blocks the
      ticker or other tags.
    • firedKeys is keyed by uid + phase + ts, so a recurring event fires
      once per occurrence per phase, never twice for the same one.

    Recurring events

    RRULE is fully expanded by iCal.lua (DAILY / WEEKLY / MONTHLY /
    YEARLY with COUNT, UNTIL, INTERVAL). Each occurrence of a recurring
    event with a #HC3#… tag fires independently and exactly once.


    Troubleshooting

    Symptom Likely cause
    Error: No calendar URL set calendarUrl variable is empty
    Error: HTTP 403/404 Calendar URL wrong or not public-shared
    Refresh: N events, 0 tagged No events in the window contain #HC3#… — check spelling and that the prefix matches tagPrefix
    Unknown method '…' warning Tag references a method that isn't defined on the QA
    Method fires twice Probably not — but verify uid is stable in your calendar (some sync tools rewrite UIDs)

    For local testing without HC3:

    Please login or register to see this code.


    Related

    • Please login or register to see this link.

       — main project + parser library API
    • Please login or register to see this link.

       — internal design notes
    • Please login or register to see this link.

       — sibling QA that just lists / publishes events
    • Like 1
    • Thanks 1

    Join the conversation

    You can post now and register later. If you have an account, sign in now to post with your account.

    Guest
    Reply to this topic...

    ×   Pasted as rich text.   Paste as plain text instead

      Only 75 emoji are allowed.

    ×   Your link has been automatically embedded.   Display as a link instead

    ×   Your previous content has been restored.   Clear editor

    ×   You cannot paste images directly. Upload or insert images from URL.

    ×
    ×
    • Create New...