šŸŽ“ 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 %}

Looks cool!!!

1 Like

Very nice !
I will have a look into it.

1 Like