Skip to content

Easyiq calendar - #375

Merged
scaarup merged 2 commits into
scaarup:mainfrom
MrMEEE:easyiq-calendar
Sep 7, 2026
Merged

Easyiq calendar#375
scaarup merged 2 commits into
scaarup:mainfrom
MrMEEE:easyiq-calendar

Conversation

@MrMEEE

@MrMEEE MrMEEE commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Exporting the EasyIQ as a calendar in Home assistant...

Schools on the modern EasyIQ Skoleportal expose the Ugeplan through
widget 0128, which the legacy api.easyiqcloud.dk endpoint rejects with
"Institutionen har ikke licens til EasyIQ Ugeplan widget".

Implement the Skoleportal browser flow:
  1. GET /UgeplanWidget?token=<jwt> to bootstrap the ASP.NET session
  2. POST /Aula/AuthenticateAulaUser (empty body) to obtain the loginId
     and FedAuth cookies
  3. GET /Calendar/CalendarGetWeekplanEvents?loginId=..&date=.. for the
     week plan events

Details:
- Add EASYIQ_SKOLEPORTAL_API and extend EASYIQ_WIDGETS with "0128"
- Send the widget headers the Skoleportal requires (X-Login,
  X-InstitutionFilter, X-ChildFilter, X-Child, X-WidgetInstanceId, ...)
- Resolve and cache the EasyIQ loginId per child, and skip children whose
  school has no EasyIQ licence instead of showing another childs plan
- Render the week plan as grouped HTML with notices under
  "Vigtig information" and lessons grouped per day
- Classify notices by an empty CoursesDisplay field; IsAllDay is not
  reliable and Title is always blank in the 0128 payload
- Add is_ugeplan_all_day() since the API returns the string "false",
  which bool() would otherwise treat as True
- Only fall back to the legacy EasyIQ API when Skoleportal auth did not
  respond
Add a calendar.ugeplan_<child> entity per child, backed by the EasyIQ
Ugeplan data already fetched by the client.

- client.py: build CalendarEvent objects into Client.ugep_events while
  parsing the Skoleportal week plan. Lessons become timed events in
  Europe/Copenhagen; notices (empty CoursesDisplay) become all-day
  events, since IsAllDay from the API cannot be trusted.
- calendar.py: add UgeplanCalendarDevice implementing async_get_events
  and next-event lookup, with timezone-safe comparison between aware and
  naive event boundaries.
- calendar.py: gate the school schedule and birthday calendars behind
  CONF_SCHOOLSCHEDULE and the new Ugeplan calendar behind CONF_UGEPLAN,
  so the platform is set up when either option is enabled.
@scaarup
scaarup merged commit 66db6bc into scaarup:main Sep 7, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants