🎓 New Magister Custom Components Integration

:mortar_board: New Magister Custom Components Integration

Dear Home Assistant community,

I’m excited to announce my latest project: a complete Magister integration for Home Assistant, consisting of two custom components. Both components are now available and I’m looking for enthusiastic users to test them.

:books: Project Overview

1. Magister School Integration

GitHub Repository

The backend component that handles the connection with Magister and fetches school data as sensors in Home Assistant.

Main features:

  • Secure OAuth2 authentication with Magister
  • Automatic token refresh
  • Extensive data synchronization
  • Configuration via UI or YAML

2. Magister School Card

GitHub Repository

A visually appealing frontend card that displays the school data in a clear dashboard.

Main features:

  • Multiple layout options (1, 2, 3 columns or auto-fit)
  • Responsive design for all devices
  • Customizable widget selection
  • Real-time data display

:dart: Available Features

  • Schedule: Current and upcoming classes
  • Grades: Recent assessments and averages
  • Assignments: Homework with deadlines and priority indicators
  • Absences: Missed classes and attendance issues
  • Changes: Schedule changes
  • Enrollments: Study registrations
  • Activities: School announcements and events

:rocket: Installation

Both components can be installed via HACS as custom repositories:

  • Magister School Integration (backend):
    https://github.com/OdynBrouwer/magister-school-integration

  • Magister School Card (frontend):
    https://github.com/OdynBrouwer/magister-school-card

I’m specifically looking for users who want to test this integration - all feedback is welcome!

Greetings,
Mupsje


Examples (contains Dutch Language)


Example sensor template:

template:
  - sensor:
      name: "Magister Agenda Vandaag en Morgen"
      state: "OK"
      availability: >
        {{ state_attr('sensor.magister_data', 'kinderen') is not none }}
      attributes:
        agenda: |
          {%- set data = state_attr('sensor.magister_data', 'kinderen') -%}
          {%- if not data -%}
          Geen data beschikbaar
          {%- else -%}

          {%- set vandaag = now().strftime('%Y-%m-%d') -%}
          {%- set morgen = (now() + timedelta(days=1)).strftime('%Y-%m-%d') -%}

          📅 **Vandaag ({{ now().strftime('%-d %B') }})**
          {%- for naam, info in data.items() %}
          **{{ naam }}**:
          {%- for a in info.afspraken | selectattr('start', 'search', vandaag) | sort(attribute='start') %}
            {{ a.start.split(' ')[1][:5] }} – {{ a.einde.split(' ')[1][:5] }} | {{ a.omschrijving }}{% if a.is_huiswerk %} (huiswerk){% elif a.type == 'SO' %} (SO){% endif %}
          {%- else %}
            Geen afspraken vandaag
          {%- endfor %}
          {% endfor %}

          📅 **Morgen ({{ (now() + timedelta(days=1)).strftime('%-d %B') }})**
          {%- for naam, info in data.items() %}
          **{{ naam }}**:
          {%- for a in info.afspraken | selectattr('start', 'search', morgen) | sort(attribute='start') %}
            {{ a.start.split(' ')[1][:5] }} – {{ a.einde.split(' ')[1][:5] }} | {{ a.omschrijving }}{% if a.is_huiswerk %} (huiswerk){% elif a.type == 'SO' %} (SO){% endif %}
          {%- else %}
            Geen afspraken morgen
          {%- endfor %}
          {% endfor %}

          {%- endif -%}

Example markdown chart

type: vertical-stack
cards:
  - type: markdown
    content: |
      # 📅 Rooster
  - type: markdown
    content: >
      ## 🟢 Vandaag

      {% set vandaag = now().strftime('%Y-%m-%d') %}
      {% set afspraken = state_attr('sensor.magister_voornaam_achternaam', 'afspraken') %}
      {% set afspraken_vandaag = afspraken | selectattr('start', 'match', '^' + vandaag) | list %}

      {% if afspraken_vandaag %}
        {% for afspraak in afspraken_vandaag %}
      **{{ afspraak.start[11:16] }} - {{ afspraak.einde[11:16] }}**
      {{ afspraak.omschrijving }}
          {% if afspraak.lokaal %}({{ afspraak.lokaal }}){% endif %}
        {% endfor %}
      {% else %}
      Geen afspraken vandaag
      {% endif %}
      
  - type: markdown
    content: >
      ## 🔵 Morgen

      {% set morgen = (now() + timedelta(days=1)).strftime('%Y-%m-%d') %}
      {% set afspraken = state_attr('sensor.magister_voornaam_achternaam', 'afspraken') %}
      {% set afspraken_morgen = afspraken | selectattr('start', 'match', '^' + morgen) | list %}

      {% if afspraken_morgen %}
        {% for afspraak in afspraken_morgen %}
      **{{ afspraak.start[11:16] }} - {{ afspraak.einde[11:16] }}**
      {{ afspraak.omschrijving }}
          {% if afspraak.lokaal %}({{ afspraak.lokaal }}){% endif %}
        {% endfor %}
      {% else %}
      Geen afspraken morgen
      {% endif %}

3 Likes

Looks cool!!!

1 Like

Very nice !
I will have a look into it.

1 Like

After installing it and providing the login details i get an error message:

  • Failed setup, will retry: Error communicating with Magister API: Expecting value: line 1 column 1 (char 0)

I installed it ten times now, no failure at all.
Did you enter the right credentials and school name?
Because I know 100% thats the problem

you only need the first school name.

My kids school is : Trevianum Scholengroep
I only need to fill : trevianum

only the first name off the school.

Also sometimes you need to login first into the webpage,
allot times Magister ask for password renewal.

check first online

On the website at school i only give in Porteum
Then user name and password, but then getting the error

Also tried capital and small letters, username iwth and without domain.

When i give in the wrong (ex. Port) schoolname, it gives a different error:
Failed setup, will retry: Error communicating with Magister API: Command ‘[‘python3’, ‘/config/custom_components/magister_school/magister.py’, ‘–json’, ‘–schoolserver’, ‘Port.magister.net’, ‘–username’, ‘XXXXX’, ‘–password’, ‘XXXX’, ‘–authcode’, ‘00000000000000000000000000000000’]’ returned non-zero exit status 1.

School name is indeed porteum

please try this

  • Run this from the machine that runs Home Assistant (use the same Python as HA, often python3 in a terminal on the host). Replace USER and PASS with your credentials.
python3 /config/custom_components/magister_school/magister.py --json --schoolserver porteum.magister.net --username 'USER' --password 'PASS'
  • If that returns nothing or non-JSON, run the script without --json and with debug so you can see diagnostic prints:
python3 /config/custom_components/magister_school/magister.py --debug --schoolserver porteum.magister.net --username 'USER' --password 'PASS'

also as I said before:

Sometimes Magister requires you to renew password or accept something on the web; try logging in at https://porteum.magister.net (or the correct URL) via a browser first.

  • Add to your configuration.yaml:
logger:
  default: info
  logs:
    custom_components.magister_school: debug

greets

It comes back with: Invalid challenge.
Will try to reset the password later

i speak dutch engels is mine second leangis ik heb hulp nodig ik krijg deze erro als ik de school kaart wil dawlode via hacs en ik de kaar will dawlode

ik heb het zelfde probleem het alles al gebrobeert maar niks werkt en ik snap het niet echt( ik ben maar 12) @mupsje

Thanks and sorry for the late respons.
Dank en sorry voor late bericht,

You guys need to select “Dashboard” in the custom HACS
Julie moeten HACS Custom en dan Dashboard kiezen.

After that you need click on the repo, then on the bottom click on the button “download”
Daarna moet je op de repo klikken en dan op “download” knop klikken.

image

ik heb dat gedaan aleen ik heb een andere probleem het lukt me niet met die inigratie in de logge ik probeerde wat jij zij maar het lukt niet ik heb al een foto van de erro gestuurd en het was 100 procent de goeie inlog gegevens

Alles werkt perfect,

Je zult eens moeten inloggen via de webpagina.
Want waarschijnlijk moet je wachtwoord veranderen.

Hier liep ik ook tegenaan in het begin.

Ook de schoolnaam moet goed worden ingevuld.
ik heb net ook een Patch geupdate


het werkt nog steedst niet weet je meschien waar door het komt @mupsje
en alles klopt alles is goed de goeie naam de goeie inlog gegeven s en ik heb ook wachtwoord reset en de nieuw in gevuld maar nog steeds niet

en nog iets als ik de debug in terminal doe welke jij had gestuurd en de link aan pas naar mij school en mijn inlog gevevens doe en dan schroll ik na boven in terminal en dan staat daar wel mijn achter naam en mijn voor naam en mijn info dus dat werk wel

Ja ik heb het gezien en ben er mee bezig.

Ik kom erop terug [soon]

:tada: Magister School Integration v1.0.7 Release

Nederlands

Hallo allemaal!

Ik ben blij om versie 1.0.7 aan te kondigen met twee belangrijke nieuwe features!

:sparkles: Wat is er nieuw?

:bust_in_silhouette: Student Account Support

Studenten kunnen nu de integratie gebruiken met hun eigen credentials! Voorheen werkte de integratie alleen met ouder-accounts. Nu detecteert de integratie automatisch of je met een student account inlogt en toont dan de data van de ingelogde student zelf.

Hoe werkt het?

  • Student logt in met eigen Magister credentials

  • Integratie detecteert automatisch dat het een student account is

  • Creëert één ‘kind’ entry met de eigen data van de student

  • Alle sensors (cijfers, rooster, huiswerk, etc.) werken gewoon!

:closed_lock_with_key: Multi-Account Cache Fix

Een kritieke fix voor wie meerdere Magister accounts in Home Assistant gebruikt. Voorheen overschreven verschillende accounts elkaars access tokens, wat leidde tot “Invalid Operation” errors.

Wat is er veranderd?

  • Elke account krijgt nu zijn eigen cache file: .magister_auth_cache_<schoolserver>_<username>

  • Speciale karakters (@, ., /) worden automatisch gesanitized naar underscores

  • Backward compatible - oude setups blijven gewoon werken

  • Nu kun je bijvoorbeeld een student account én een ouder account tegelijk gebruiken!

:test_tube: Uitgebreid Getest

De release is uitgebreid getest met:

:package: Installatie/Update

Via HACS (aanbevolen):

  1. Ga naar HACS → Integrations

  2. Zoek “Magister School Integration”

  3. Klik op “Update”

  4. Herstart Home Assistant

Handmatig:

Download de release van GitHub

:link: Links

:speech_balloon: Feedback

Zoals altijd: feedback, bug reports en feature requests zijn welkom in de GitHub Issues!

Veel plezier met de update! :rocket:


English

Hello everyone!

I’m excited to announce version 1.0.7 with two important new features!

:sparkles: What’s New?

:bust_in_silhouette: Student Account Support

Students can now use the integration with their own credentials! Previously, the integration only worked with parent accounts. Now the integration automatically detects when you log in with a student account and displays the data of the logged-in student.

How does it work?

  • Student logs in with their own Magister credentials

  • Integration automatically detects it’s a student account

  • Creates a single ‘child’ entry with the student’s own data

  • All sensors (grades, schedule, homework, etc.) work normally!

:closed_lock_with_key: Multi-Account Cache Fix

A critical fix for those using multiple Magister accounts in Home Assistant. Previously, different accounts would overwrite each other’s access tokens, leading to “Invalid Operation” errors.

What changed?

  • Each account now gets its own cache file: .magister_auth_cache_<schoolserver>_<username>

  • Special characters (@, ., /) are automatically sanitized to underscores

  • Backward compatible - existing setups continue to work

  • You can now use a student account and a parent account simultaneously!

:test_tube: Extensively Tested

This release has been thoroughly tested with:

:package: Installation/Update

Via HACS (recommended):

  1. Go to HACS → Integrations

  2. Search for “Magister School Integration”

  3. Click “Update”

  4. Restart Home Assistant

Manual:

Download the release from GitHub

:link: Links

:speech_balloon: Feedback

As always: feedback, bug reports, and feature requests are welcome in the GitHub Issues!

Enjoy the update! :rocket:

het werkt dank u wel voor u hulp nog een vraag je hoe kan ik aan passe dat het automatisch een wekker aan zet en menneer nog een vraag je hoe zet ik notificatie aan

meneer ik heb nog een vraag je kunt u meschien ( hoeft niet gewoon in vraag je meschien is het er al ) dat ik elke tabel met info zelf kan schijfen en in veschilende collome want nu zit het vast onderelkaar of naast elkaar gepropt

Hoi Mark,

Wat leuk dat de integratie werkt! :tada: Hier zijn de antwoorden op je vragen:

:one: Automatisch wekker aanzetten op basis van je rooster

Wat je eerst moet aanmaken:

  1. Ga naar SettingsDevices & ServicesHelpers
  2. Klik + Create HelperDate and/or Time
  3. Naam: “Wekker Mark”
  4. Entity ID: input_datetime.wekker_mark
  5. Selecteer alleen “Time”

Dan kun je deze helper gebruiken om je wekker-app aan te sturen!

Je kunt dan een automatisering maken die kijkt naar je eerste afspraak en dan een wekker zdet. Hier is een voorbeeld:

automation:
  - alias: "Wekker op basis van rooster Mark"
    trigger:
      - platform: time
        at: "21:00:00"  # Elke avond om 21:00 checken
    action:
      - service: input_datetime.set_datetime
        target:
          entity_id: input_datetime.wekker_mark
        data:
          time: >
            {% set rooster = state_attr('sensor.magister_mark_gollov', 'afspraken') %}
            {% if rooster and rooster|length > 0 %}
              {% set eerste_afspraak = rooster[0].start %}
              {% set tijd = eerste_afspraak.split(' ')[1] %}
              {% set uur = tijd.split(':')[0]|int - 1 %}
              {{ '%02d:00:00' % uur }}
            {% else %}
              07:00:00
            {% endif %}

:two: Notificaties aanzetten

Er zijn verschillende soorten notificaties die je kunt instellen:

Notificatie bij nieuw cijfer:

automation:
  - alias: "Notificatie nieuw cijfer Mark"
    trigger:
      - platform: state
        entity_id: sensor.magister_mark_gollov_cijfers
    condition:
      - condition: template
        value_template: "{{ trigger.to_state.state != trigger.from_state.state }}"
    action:
      - service: notify.mobile_app_jouw_telefoon  # Vervang door je telefoon naam
        data:
          title: "📊 Nieuw cijfer!"
          message: "Er is een nieuw cijfer toegevoegd voor Mark"

Notificatie bij huiswerk:

automation:
  - alias: "Herinnering huiswerk Mark"
    trigger:
      - platform: time
        at: "18:00:00"
    condition:
      - condition: template
        value_template: "{{ states('sensor.magister_mark_gollov_huiswerk')|int > 0 }}"
    action:
      - service: notify.mobile_app_jouw_telefoon
        data:
          title: "📚 Huiswerk herinnering"
          message: "Je hebt nog {{ states('sensor.magister_mark_golov_huiswerk') }} huiswerk items!"

Notificatie voor roosterwijzigingen:

```automation:
  - alias: "Notificatie roosterwijziging Mark"
    trigger:
      - platform: state
        entity_id: sensor.magister_mark_gollov_wijzigingen
    condition:
      - condition: template
        value_template: "{{ trigger.to_state.attributes.wijzigingen|length > 0 }}"
    action:
      - service: notify.mobile_app_jouw_telefoon
        data:
          title: "⚠️ Roosterwijziging!"
          message: "Er zijn wijzigingen in je rooster"

Let op: Vervang notify.mobile_app_jouw_telefoon door de naam van je eigen Home Assistant Companion App notificatie service. Je kunt deze vinden in Developer Tools → Services → zoek naar “notify”.

Lukt het hiermee? Laat maar weten als je nog vragen hebt! :blush: