HA Menstruation Cycle is a Home Assistant custom integration for tracking cycle history, showing cycle phases, and powering Lovelace dashboards with interactive menstrual-cycle cards.
It combines a Home Assistant integration, per-profile sensors, local data storage, and a frontend card set so households can keep the setup inside Home Assistant instead of spreading data across separate tools. The project supports multiple profiles, visual dashboards, product usage tracking, symptom logging, and export workflows.
- HACS-ready Home Assistant integration with UI-based setup
- Multiple profiles for shared households
- Interactive cards for cycle entry, calendar views, history, heatmaps, timers, and statistics
- Services for history management, symptom logging, exports, inventory workflows, and automations
- Automatic frontend resource registration when installed through the integration
- Local-first storage inside Home Assistant
Each profile creates these entities (<name> is the slugified profile name):
| Entity | Purpose |
|---|---|
sensor.menstruation_<name> |
Main cycle status (period, fertile, PMS, neutral, pregnant, ...) with all cycle data as attributes. Shows a state-based icon unless you set your own icon. |
sensor.menstruation_<name>_next_ovulation |
Date of the next predicted ovulation. |
sensor.menstruation_<name>_cycle_length |
Length of the last completed cycle in days, with Home Assistant long-term statistics so you can chart it over months. |
sensor.menstruation_<name>_products_today |
Period products used today (usage statistics). |
sensor.menstruation_<name>_basal_temp |
Basal body temperature, when a temperature sensor is linked. |
calendar.menstruation_<name>_cycle |
Predicted period, fertile window and ovulation (plus the routine check-up) as a native calendar. Can be switched off per profile in the options. Five more options (off by default) add the pregnancy due date, contraception dates (renewal due, end of the pill pack, next patch/ring steps), your logged periods of the last 12 months, the period date from your own luteal phase (as long as it lies ahead) and the ovulation day your own logs show for each cycle of the last 12 months (temperature rise, otherwise the day after the first positive LH test); these also go into the calendar feed (ICS) and show only at visibility "Full" in the calendar. |
image.menstruation_<name>_cycle_phase |
Illustration of the current phase, for picture cards and wall tablets. |
todo.menstruation_<name>_hospital_bag |
Editable hospital-bag checklist, only available during a pregnancy. Pre-filled in the Home Assistant language (German, English, Spanish, French, Swedish; English otherwise). |
Entities follow the profile's visibility level: at "Private" nothing is shown, at "Status only" only period events remain in the calendar. Cycle events (state change, period start, pill intake, product usage) also appear as readable entries in the Home Assistant logbook, and repair issues point out things like an old calendar feed (ICS) token an unreachable notify target, or pregnancy mode still being on 14 days after the due date.
- Open HACS and add the custom repository
git: /wallenium/HA-menstrual-cycle. - Install Menstruation Cycle, then add the integration under Settings → Devices & Services.
- Create a profile with a friendly name, restart Home Assistant, and add
custom:menstruation-gauge-cardto a dashboard. - Optional but recommended: import or recreate the daily refresh automation from
/examples/daily_recalculate_days_until_next_start.yaml.
For manual installation, extra cards, service examples, and troubleshooting, use the wiki pages below.
custom:menstruation-cycle-card has been removed. Update existing Lovelace YAML dashboards to use custom:menstruation-gauge-card instead.
Start here: Documentation Hub
Detailed guides:
The integration can notify you itself (Configure → Notifications), no automation needed. Switch on Enable notifications and pick a notify target such as mobile_app_myphone; with no target, a persistent notification in the HA UI is used. All settings are per profile.
| Notification | Sent when | Option | Default |
|---|---|---|---|
| Period reminder | a set number of days before the predicted start | Notify before period starts (+ days ahead) | on, 1 day |
| Fertile window | a set number of days before the window starts | Notify when fertile window starts (+ days ahead) | on, same day |
| Ovulation | a set number of days before the estimated ovulation | Notify when ovulation is estimated (+ days ahead) | off |
| Cycle recap | a new cycle start was logged (length and period duration of the finished cycle, compared with the average, plus pain days) | Recap after each cycle | off |
| Period overdue | the period is 7 days past its predicted start and not logged (only with reliable predictions) | Notify when the period is overdue | off |
| Checkup | 14 days before the next checkup is due, or once if already overdue | Notify before a checkup is due (+ checkup interval, 0 = off) | off, 12 months |
| Log reminder | nothing was logged for today yet | Evening reminder to log (+ time) | off, 20:00 |
| Pill reminder | today's pill is not logged yet, plus an optional follow-up after 1-12 hours | Pill reminder (+ time, follow-up) | off, 09:00 |
| Pill hint | 2 or more days in a row without a logged pill (neutral hint to check the leaflet) | Hint when pill intakes are missing | off |
| Patch / ring | on each step of the usual 28-day rhythm (patch: change on days 7 and 14, remove on day 21, new patch on day 28; ring: remove on day 21, new ring on day 28), sent with the pill reminder time | Pill reminder (also covers patch and ring) | off |
| Pregnancy week | pregnancy mode is on: one short, neutral message per week on the weekday of the pregnancy start (current week and calculated due date), with a trimester note when the 2nd or 3rd trimester begins (no medical advice) | Weekly pregnancy message | off |
| Unusual cycle length | with a new period start: the last three cycles were all shorter than 21 or all longer than 38 days, or the last cycle was 10+ days off your average; one neutral hint to mention it at the next check-up (no diagnosis; a streak is announced once) | Hint for an unusual cycle length | off |
| Pregnancy test timing | 14 days after an ovulation confirmed by your temperature and mucus/cervix logs (for people trying to conceive): one neutral message that a test is meaningful from about now; a rule of thumb, no medical advice; skipped while the fertility notifications are muted for hormonal contraception | Pregnancy test timing hint | off |
| Ovulation test start | 7 days before the expected ovulation (window of 3 days), once per cycle: one neutral message that now is a good time to start ovulation (LH) tests; not sent once a positive LH test or a confirmed ovulation moved the estimate; skipped while the fertility notifications are muted for hormonal contraception | Hint to start ovulation tests | off |
| Basal temperature | At the notification time from the start of the fertile window until 3 days after the expected ovulation, as long as no temperature rise is confirmed: reminds you to measure and log your temperature; only if you logged it on at least 3 of the last 7 days and not yet today | Basal temperature reminder | off |
| Period from luteal phase | Switches the "Period reminder" to the date from your own luteal phase length (needs a confirmed ovulation in the running cycle and learned luteal phases); otherwise the calendar date stays; the overdue hint and repair notice use the same date | Period reminder from the luteal phase | off |
| Unprotected intercourse | unprotected intercourse was logged for today or one of the last 5 days: one neutral hint to ask a pharmacy or doctor about emergency contraception (no dosing or medical advice; not during pregnancy or menopause) | Hint after unprotected intercourse | off |
| Badges | a new progress badge was unlocked | part of the date reminders | with notifications |
Date reminders, the recap, overdue and checkup notifications are sent at Notification time (default 08:00).
- Pill pack break: set Pill break (days per pack) (for example 7 for a 21+7 pack) so no reminder is sent during the break. It also lets the integration add "order a new pill pack" to the shopping list a few days before the pack ends.
- Buttons (mobile app targets only): Period started, Pill taken, Started today (on the patch and ring reminders that start a new pack) and Remind me in 1 hour. A snooze survives a Home Assistant restart.
- Bleeding without a period:
menstruation_cycle.repair_storagereports logged bleeding that never became a period;menstruation_cycle.create_periods_from_bleedingadds those days (bleeding within 14 days after a period day counts as bleeding outside the period and is not turned into a period). The doctor report lists such bleeding in its own neutral section. - Contraception renewal: the renewal reminder for an IUD, implant or injection counts from the first day the method was logged. After a renewal (or a new patch/ring pack) call
menstruation_cycle.confirm_contraception_renewalor use the button in the dashboard; the period or the patch/ring rhythm then counts from that day. - Hormonal methods: No fertility notifications on hormonal contraception skips the fertile-window and ovulation messages while the current method is hormonal. The sensor state and the dashboard stay unchanged.
- Partner target: an optional second notify target that only receives the date reminders (period; fertile window and ovulation only at visibility level "Full"), never health details. Nothing is sent for private profiles.
- Check your setup: call the service
menstruation_cycle.send_test_notification(Developer tools → Actions). If the target does not exist or fails, a repair issue appears under Settings → Repairs and disappears again after the next successful delivery.
Ready-made automations for the common cases. Click Import to add one to Home Assistant (or paste the file URL under Settings → Automations & Scenes → Blueprints → Import Blueprint).
| Blueprint | What it does | |
|---|---|---|
| Basal temperature reminder | Daily reminder at a fixed time to log the basal body temperature. | Import |
| Contraception renewal in calendar | Calendar event ahead of an IUD, implant or injection renewal. | Import |
| Light during the fertile window | Sets lights to a colour while the fertile window is active. | Import |
| Scene on heavy bleeding | Activates a scene when heavy or very heavy bleeding is logged. | Import |
| Weekly household digest | One combined weekly overview across all profiles. | Import |
| Irregularity alert | Notifies when the cycle regularity drops below a threshold. | Import |
| Action on positive ovulation test | Runs your own action when the first positive LH test of a cycle is logged. | Import |
| Action on confirmed temperature rise | Runs your own action when the temperature rise of a cycle is newly confirmed. | Import |
| Notify on period start | Notification the moment a period is confirmed. | Import |
| Ovulation confirmed | Notification once the NFP analysis confirms a temperature rise. | Import |
| Period as calendar block | Multi-day calendar event from the actual start to the predicted end. | Import |
| Pill not taken escalation | Runs your own actions when today's pill is still not logged at a chosen time. | Import |
| Light during PMS | Sets lights to a colour while the PMS phase is active. | Import |
| Action on cycle state | Runs any action when a profile enters a chosen state (period, fertile, ...). | Import |
For your own automations the integration also fires the events menstruation_cycle_cycle_start_logged, menstruation_cycle_pill_taken and menstruation_cycle_lh_positive (the first positive ovulation test of a cycle), menstruation_cycle_ovulation_confirmed (the temperature rise is newly confirmed; date = day of the rise; not repeated after a restart) (all three with the data entry_id, profile, friendly_name, date; not fired for private profiles), menstruation_cycle_product_consumed and menstruation_cycle_state_changed.
This project is a convenience and visualization tool. It is not a medical device and must not be used as a reliable standalone method for contraception, conception planning, diagnosis, or safety-critical decisions.
Before using it in a shared household or for sensitive automations:
- treat predictions as approximations
- use automations only with explicit agreement from the affected people
- keep health, privacy, and backup considerations in mind
Read the full disclaimer in Disclaimer.
The integration now supports stage-aware onboarding and forecast confidence gating:
- pre_menarche – educational mode before the first period. Deterministic period/ovulation predictions are suppressed.
- early_menarche – learning phase after the first period when history is sparse/irregular. Forecasts are shown as broader possible windows with low confidence by default.
- established_cycle – standard cycle forecasting. If data quality is still too low, read-only display logic can temporarily downgrade to learning-phase behavior.
- Pre-menarche: no precise cycle-day claims; emphasis is on neutral tracking/supportive messaging.
- Early menarche: low-data users get uncertainty-aware windows (for example “possible period window”) and ovulation-day precision is withheld until data quality thresholds are met.
- Established cycle: prior behavior is retained unless confidence gates detect insufficient quality (too few valid cycles, high variability, or too few recent logs).
High-precision outputs are only shown when all required checks pass:
- minimum valid cycle count
- acceptable cycle variability bounds
- sufficient recent log activity
Otherwise the integration degrades to low-confidence window output and suppresses precise ovulation claims.
You can change the onboarding stage at any time in Settings → Devices & Services → Menstruation Cycle → Configure (onboarding_stage option).
The custom:menstruation-support-card provides age-appropriate, practical education and low-anxiety support for pre-/early-menarche users. It has no effect on forecast logic — it is a UI-only card.
| Module | Description |
|---|---|
| 🗓️ School-day helper reminders | Configurable, discreet reminder presets: kit check, drink water, comfort check-in, rest cue |
| 📖 Glossary | Plain-language definitions for cycle, ovulation, and spotting, with optional "learn more" expansion |
| 🔵 Cycle phases graphic | Abstract SVG donut chart of period / follicular / ovulation / luteal phases with legend and ARIA description |
| 🧼 Hygiene how-to cards | Step-by-step guides for washing period underwear and using a period cup (basics) |
| 💛 Reassurance cards | Short "Is this normal?" cards covering irregular timing, flow variation, and spotting, each with a gentle escalation prompt |
- Shown by default in
pre_menarcheandearly_menarchemodes. - Hidden by default in
established_cyclemode; set the internal_showInEstablishedflag or use a conditional card to display it when desired.
Reminders are rendered as a settings panel inside the card. Each preset can be toggled on/off and assigned a preferred time. School-day-only reminders are labelled accordingly. Quiet hours can be enabled to suppress reminders between configurable start and end times.
Note: The card renders reminder previews only. To send actual notifications, connect the reminder state to a Home Assistant automation using the notification service of your choice.
All content is for educational purposes only and must not be used as medical advice. Each content module includes a visible disclaimer. Users are encouraged to follow the instructions provided with their hygiene products and to consult a clinician for medical questions.
All user-facing strings in the Young Girls Support card use i18n keys (ygs_*). Translations are provided for English (🇬🇧), German (🇩🇪), Swedish (🇸🇪), French (🇫🇷), and Spanish (🇪🇸). To add or improve a translation, edit the corresponding file in custom_components/menstruation_cycle/www/translations/.
- The cycle phases SVG includes
role="img",aria-label, and a hidden<desc>element for screen readers. - Non-colour-only meaning: every phase has a text label in the legend alongside its colour dot.
- Toggle controls use visible focus styles.
- Reduced-motion: any future animations must respect
prefers-reduced-motion; the current SVG graphic is static.
The integration now includes an optional Cycle Dashboard sidebar page for a fast daily workflow.
- Open Settings → Devices & Services → Menstruation Cycle → Configure.
- Enable Show Cycle Dashboard in sidebar.
- (Optional) Set Prefer Cycle Dashboard as start page as a preference flag for setups that support default-page behavior.
If the sidebar toggle is disabled, existing cards and views continue to work unchanged.
- Use Edit dashboard to:
- show/hide cards
- reorder cards (up/down)
- toggle discreet mode
- optionally set display name/pronouns for the My Info mini-card
- Preferences are stored per user and profile.
- Young mode (
pre_menarche/early_menarche): simpler default layout with discreet mode enabled. - General mode (
established_cycle): richer default layout with more insight cards. - Users can reset back to mode defaults at any time from Edit mode.
- Discreet mode uses more neutral wording in overview content.
- Sensitive cards can be hidden individually.
- My Info card is optional and can stay hidden.
| Language | Status |
|---|---|
| 🇬🇧 English | ✅ 100% |
| 🇩🇪 German | ✅ 100% |
| 🇸🇪 Swedish | ✅ Complete – native review welcome |
| 🇫🇷 French | ✅ Complete – native review welcome |
| 🇪🇸 Spanish | ✅ Complete – native review welcome |
Swedish, French and Spanish are fully translated but not yet reviewed by native speakers, so corrections are very welcome. See Translation Section for instructions on how to contribute a translation.
Feedback, ideas, bug reports, edge cases, and pull requests are welcome. If you want to improve documentation, add cards, refine services, or help with testing, please open an issue or PR.
AI was used to help draft parts of the code and English wording, while the project idea and implementation direction remain human-authored.