This custom component integrates InfoMentor school communication platform with Home Assistant, providing real-time access to school schedules, news, and timeline entries for your children.
- Multiple Children Support: Manage multiple pupils/children from one or more schools
- Real-time Schedule Data: Access current and upcoming school schedules
- News & Timeline: Get school news and timeline entries
- Child Type Detection: Automatically distinguish between school and preschool children
- Robust Authentication: Secure login with session management
- Push Notifications: Alternative to the broken InfoMentor Android push β sends new notices to your phone via HA
For each pupil, the integration creates several sensors:
- Dashboard: Overview of all children's schedules for today and tomorrow
- Today Schedule: Current day's schedule status (school/preschool_fritids/no_activities)
- Tomorrow Schedule: Next day's schedule status and details
- Schedule: Complete upcoming schedule (7 days) with detailed breakdown
- Needs Preparation Today: Binary sensor indicating if child needs preparation (school OR preschool/fritids)
- Has School Tomorrow: Binary sensor indicating if child needs preparation tomorrow
- Has Preschool Today: Binary sensor for preschool/fritids activities today (kept for compatibility)
- Child Type: Determines if child is "school" or "preschool" based on timetable data
- News: Count and details of unread school news
- Timeline: Count and details of timeline entries
- Notifications: Unread notification count; attributes include the latest 20 notifications with title, date, type, pupil, URL, and state
- Pupil Count: Total number of children in the account
- Data Freshness: Now only marks data as fresh after every pupil receives a fully refreshed schedule and exposes which pupils are still missing or using cached schedules
The integration uses different properties to accurately represent activities:
has_school: Any scheduled activity (timetable entries OR time registrations)has_timetable_entries: Only actual school lessons from the timetablehas_preschool_or_fritids: Time registrations for preschool/after-school care
The integration correctly distinguishes between school and preschool children:
- Primary: Children with timetable entries β School child
- Fallback: Children with "fritids" time registrations β School child
- Fallback: Children with "fΓΆrskola" time registrations β Preschool child
- Default: No clear indicators β Preschool child
This ensures accurate classification even when timetable data is temporarily unavailable.
- Install HACS if you haven't already
- Add this repository as a custom repository in HACS
- Install "InfoMentor" from HACS
- Restart Home Assistant
- Download the latest release
- Copy the
custom_components/infomentorfolder to your Home Assistantcustom_componentsdirectory - Restart Home Assistant
- Go to Settings β Devices & Services
- Click Add Integration
- Search for "InfoMentor"
- Enter your InfoMentor credentials
- The integration will discover all your children automatically
- Credentials: Use the same username/password you use for the InfoMentor website
- Multiple Children: All children associated with your account are automatically added
- Updates: Schedule data updates every 30 minutes by default
- Authentication: Sessions are managed automatically with re-authentication as needed
- Restart Resilience: Integration uses cached data on Home Assistant restarts (up to 72 hours) and verifies credentials in the background, preventing authentication errors from disrupting service
- You can update your InfoMentor username/password via the integration's Options.
- The options form validates the credentials against InfoMentor before saving.
- On success, the integration reloads immediately with the new credentials.
When the integration is stuck on hourly retries, notifications stay at 0 / 0, or you see HTTP 500 / timetable HTML errors, use the device buttons or the service for an immediate attempt:
- InfoMentor run diagnostics (button): full re-login with your stored credentials, clears auth/notification backoff timers, then runs a normal coordinator refresh. Check the log for lines starting with
Diagnostics poke:. - InfoMentor full refresh (clears schedule cache) (button): same as above, plus clears the in-memory today/tomorrow schedule cache before refreshing (your logs will show
clear_cache=True). - Service (automations, Developer tools):
infomentor.diagnostic_pokewith optionalclear_cache: true(defaults tofalse). Target your InfoMentor device or passconfig_entry_id.
If Home Assistant runs in a VM and you don't want to tail home-assistant.log, you have three UIβonly options:
- InfoMentor Diagnostic Log sensor β appears under the InfoMentor device. Its state shows the most recent event; open it in Developer Tools β States and you'll see the last ~50 events (
Session refresh OK,Hub warmup ok=true,Notification probe items=24, etc.) as theeventsattribute. - Download diagnostics β on Settings β Devices & services β InfoMentor, click the threeβdot menu on the device and choose "Download diagnostics". You get a JSON bundle with pupil IDs, cookie counts per domain, the diagnostic event ring buffer, and the current notification buffer (credentials are redacted).
- Settings β System β Logs β filter for
custom_components.infomentorto seeWARNINGβlevel lines includingDiagnostics poke: β¦.
The InfoMentor Android app has a known issue where it fails to register push notifications. This integration provides a reliable alternative using Home Assistant's notification system.
- Go to Settings β Devices & Services β InfoMentor β Configure
- In the "Notification services" field, enter comma-separated HA notify service names:
mobile_app_andrews_phone, mobile_app_partner_phone - Save β the integration will now push new InfoMentor notices directly to those phones.
Each push notification includes:
- Title: The notification title from InfoMentor (e.g. "Nytt inlΓ€gg i lΓ€rloggen")
- Message: Notification type and date
- Tap action: Opens the relevant InfoMentor page URL
LearnLog entries, CalendarV2 events (new + upcoming), News items, and all other types from the NotificationApp endpoint.
Every new notification also fires an infomentor_new_notification event, which you can use in automations:
automation:
- alias: "InfoMentor β custom push"
trigger:
- platform: event
event_type: infomentor_new_notification
action:
- service: notify.mobile_app_my_phone
data:
title: "{{ trigger.event.data.title }}"
message: "{{ trigger.event.data.pupil_name }} β {{ trigger.event.data.date_sent }}"
data:
url: "{{ trigger.event.data.url }}"
clickAction: "{{ trigger.event.data.url }}"- When authentication fails, the integration logs a short, truncated snippet of the server response for visibility.
- For deeper inspection, full HTML responses are written to debug files without blocking Home Assistant:
- /tmp/infomentor_debug_initial.html
- /tmp/infomentor_debug_oauth.html
- /tmp/infomentor_debug_dashboard.html
- These can help detect changes in InfoMentor's login process.
- Login form submission now parses and submits the exact form fields (including selects, checkboxes, and submit buttons) and refreshes the login page when fields are missing, improving resilience to portal changes.
- If the live form includes the embedded school list or encoded viewstate, those hidden fields are now merged into the payload and the login postback target is set explicitly.
- The integration stores both the URL and name of the successful school/IdP choice, reusing it automatically on future logins.
- We also mirror the browser cookie (
Im1_Ck_LastUsedIdp) that InfoMentor uses, so new sessions immediately jump to the correct municipality instead of falling back to the first entry in the list. - When no cached choice exists, it scores every option, prioritising InfoMentor-operated endpoints, entries containing "elever", and options matching the domain of your username or e-mail address.
- Options that do not match any clues are penalised, preventing the workflow from choosing the first municipality in the list (e.g. Avesta) by mistake.
- These heuristics eliminate the previous behaviour where the integration consistently picked the first entry instead of the correct school.
When InfoMentor servers are unreliable and authentication fails, you can manually retry:
Service: infomentor.retry_authentication
- clear_cache (optional): Set to
trueto clear cached data and force fresh authentication - Example: Call this service when you see authentication failures in the logs
This service resets authentication failure tracking and attempts immediate re-authentication, useful when InfoMentor servers are temporarily unstable.
- Cookie reuse: The integration now persists the InfoMentor session cookies to Home Assistant storage. On restart (or after temporary network hiccups) we attempt to restore the previous session before running the full OAuth dance, so successful logins stay alive much longer.
- Stale data handling: When the last successful data pull is older than 24 hours we automatically move into an hourly retry cadence with a randomly offset start time (between +3 and +17 minutes past the hour). This avoids colliding with InfoMentorβs on-the-hour maintenance jobs and keeps trying until fresh data arrives.
All InfoMentor services now expose a target selector, so you can choose the specific InfoMentor device (account) when running an action from the Developer Tools UI or automations. When no target is provided the action runs for every configured account.
| Action | What it does | Notes |
|---|---|---|
infomentor.refresh_data |
Runs the standard coordinator refresh or a single-pupil refresh when pupil_id is provided. |
Respects retry/backoff logic and logs a clear success/failure message. |
infomentor.force_refresh |
Forces an immediate update, optionally clearing cached data first. | Useful when HA cached data has gone stale. |
infomentor.switch_pupil |
Calls the InfoMentor API to switch context to a specific pupil. | Requires an active session; action warns if the client is not initialised yet. |
infomentor.debug_authentication |
Runs the extended OAuth/pupil extraction diagnostics and logs the resulting payload. | Results are logged at INFO level for quick copy/paste in bug reports. |
infomentor.cleanup_duplicate_entities |
Removes duplicate entities, with optional dry_run and aggressive_cleanup flags. |
Dry-run mode now reports exactly which entities would be removed. |
infomentor.retry_authentication |
Clears auth backoff counters and re-establishes the client (optionally clearing cached data). | Handy after password changes or school-side fixes. |
Advanced automations can also pass config_entry_id in the service data to scope an action programmatically (for example, when you store the entry id in an input text). This mirrors the device selector but keeps YAML automations tidy.
# Notify when child needs preparation today
- alias: "School Day Notification"
trigger:
- platform: state
entity_id: binary_sensor.felix_needs_preparation_today
to: "on"
action:
- service: notify.mobile_app
data:
message: "Felix needs preparation today!"
# Different actions for school vs preschool
- alias: "Morning Routine"
trigger:
- platform: time
at: "07:00:00"
condition:
- condition: state
entity_id: binary_sensor.felix_needs_preparation_today
state: "on"
action:
- choose:
- conditions:
- condition: state
entity_id: sensor.felix_child_type
state: "school"
sequence:
- service: tts.speak
data:
message: "Time to get ready for school!"
- conditions:
- condition: state
entity_id: sensor.felix_child_type
state: "preschool"
sequence:
- service: tts.speak
data:
message: "Time to get ready for preschool!"
# Dashboard-based automation for all kids
- alias: "Any Child Needs Preparation Tomorrow"
trigger:
- platform: template
value_template: >
{% set kids = state_attr('sensor.infomentor_dashboard', 'kids') %}
{% if kids %}
{{ kids | selectattr('tomorrow.needs_preparation', 'equalto', true) | list | length > 0 }}
{% else %}
false
{% endif %}
action:
- service: notify.mobile_app
data:
title: "Tomorrow's School Schedule"
message: >
{% set kids = state_attr('sensor.infomentor_dashboard', 'kids') %}
{% set tomorrow_kids = kids | selectattr('tomorrow.needs_preparation', 'equalto', true) | list %}
{% for kid in tomorrow_kids %}
{{ kid.name }}: {{ kid.tomorrow.summary }}
{% endfor %}# New unified dashboard - shows all kids at once
type: custom:mushroom-template-card
primary: "{{ states('sensor.infomentor_dashboard') }}"
secondary: |
{% for kid in state_attr('sensor.infomentor_dashboard', 'kids') %}
{{ kid.name }}: {{ kid.today.summary }}
{% if kid.tomorrow.needs_preparation %}π Tomorrow: {{ kid.tomorrow.summary }}{% endif %}
{% endfor %}
icon: mdi:view-dashboard
badge_icon: |
{% set needs_prep_today = state_attr('sensor.infomentor_dashboard', 'kids') | selectattr('today.needs_preparation', 'equalto', true) | list | length %}
{% if needs_prep_today > 0 %}mdi:school{% endif %}
# Traditional individual sensors
type: entities
title: Today's Schedule
entities:
- sensor.felix_today_schedule
- sensor.isolde_today_schedule
- binary_sensor.felix_needs_preparation_today
- binary_sensor.isolde_needs_preparation_today
# Tomorrow preparation check
type: entities
title: Tomorrow's Schedule
entities:
- sensor.felix_tomorrow_schedule
- sensor.isolde_tomorrow_schedule
- binary_sensor.felix_has_school_tomorrow
- binary_sensor.isolde_has_school_tomorrow- Complete-schedule requirement: Data freshness now updates only when every pupil returns a fresh schedule payload in the same cycle.
- Per-pupil diagnostics: Sensors expose which pupils are missing data and which ones rely on cached schedules, making troubleshooting easier.
- Storage compatibility: The integration stores a dedicated
last_complete_schedule_updatetimestamp, falling back to the legacy field for existing installations. - Smarter retries: The coordinator keeps retrying quickly until the schedule is complete, preventing false "<1 day" freshness claims when the upstream API stalls mid-fetch.
- Unified Dashboard: New dashboard sensor showing all children's schedules for today and tomorrow
- Tomorrow Schedule Support: Added sensors for tomorrow's schedule and preparation needs
- Merged Preparation Logic: "Needs Preparation Today" sensor now includes both school and preschool/fritids
- Comprehensive Attributes: Dashboard provides detailed schedule summaries with times and activity types
- Enhanced Automation Support: New dashboard-based automations can monitor all children at once
- Fixed Logic: Corrected child type detection to properly distinguish school vs preschool children
- Timetable Focus: Now primarily uses actual timetable entries for school child detection
- Better Properties: Added
has_timetable_entriesproperty for clearer logic - Improved Fallback: Enhanced fallback logic using time registration types
- Better Data Source: Switched from calendar endpoint to dedicated timetable endpoint
- More Accurate: School timetables now retrieved from proper
/timetable/timetable/gettimetablelistendpoint - Reliable Classification: Improved accuracy in distinguishing educational content from general calendar events
- Issue: School child shows as preschool or vice versa
- Solution: Check the
sensor.child_name_child_typeattributes for detailed reasoning - Data: The
descriptionattribute explains the classification logic used
- Check Authentication: Verify credentials in the integration configuration
- Check Pupils: Ensure pupil IDs are correctly retrieved
- Check Logs: Look for authentication or API errors in Home Assistant logs
- School System: Some schools may not publish timetables through the API
- Timing: Timetables might not be available far in advance
- Fallback: The system uses time registration data as fallback for classification
Enable debug logging to troubleshoot issues:
logger:
default: warning
logs:
custom_components.infomentor: debugContributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Add/update tests as needed
- Submit a pull request
This project is licensed under the MIT License - see the LICENSE file for details.
This is an unofficial integration. InfoMentor is a trademark of its respective owners. This integration is not affiliated with or endorsed by InfoMentor.
Problem: Felix was correctly identified as a school child, but his timetable entries were not appearing in his schedule attributes - only fritids time registrations were visible.
Root Cause: The sensor code was trying to access entry.classroom but the TimetableEntry model uses entry.room. This caused an AttributeError that silently prevented timetable entries from being included in the schedule display.
Final Fix Applied:
- Corrected Field Name: Changed
entry.classroomtoentry.roomin both schedule sensors - Added Null Safety: Added null checks for
start_timeandend_timein display logic - Fixed Time Comparison: Fixed
earliest_startandlatest_endproperties to filter outNonevalues
Verification: Testing confirms that timetable entries now properly appear in schedule attributes alongside time registrations.
Problem: School children were appearing as preschool children because the classification logic was flawed.
Root Cause: The has_school property included both timetable entries and time registrations, making preschool children appear as school children.
Final Fix Applied:
- New Property: Added
has_timetable_entriesproperty for precise school lesson detection - Improved Logic: Child type sensor now uses
has_timetable_entriesfor primary classification - Better Properties: Clarified semantics of
has_schoolvshas_timetable_entriesvshas_preschool_or_fritids - Enhanced Fallback: Added fallback logic using time registration types
Verification: Testing confirms accurate school vs preschool distinction.
Problem: Both pupils were showing identical schedule data because the pupil switching mechanism wasn't working correctly.
Root Cause: The pupil switching was incorrectly treating the server's 302 Found redirect response as a failure, when it's actually the correct response for a successful pupil switch.
Final Fix Applied:
- Correct HTTP Status Handling: Modified
switch_pupil()to accept both200 OKand302 Foundas successful responses - Proper Redirect Handling: Added
allow_redirects=Trueto handle server-side redirects correctly - Increased Switch Delay: Extended delay to 2.0 seconds to ensure server-side session changes take effect
- Endpoint Prioritisation: Prioritised the hub endpoint (
hub.infomentor.se) as the primary switching endpoint
Verification: Testing confirms that Felix and Isolde now return different data:
- Felix: 12:00-16:00 time registration, 35 timetable entries across various date ranges
- Isolde: 08:00-16:00 time registration, different schedule pattern
This issue has been fixed in the latest version. If you still experience it:
- Check the logs for switch ID mapping (should show different switch IDs for each pupil)
- Ensure the integration has been restarted after the update
- Look for debug messages showing successful pupil switching
- Verify your credentials are correct
- Check if you can log in to InfoMentor directly
- Look for OAuth-related errors in the logs
To enable debug logging, add this to your configuration.yaml:
logger:
default: info
logs:
custom_components.infomentor: debugFor issues and feature requests, please check the logs first and include relevant debug information when reporting problems.