Skip to content
 
 

Latest commit

 

History

212 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Adaptive Plant

A fully local, event-driven Home Assistant custom integration for tracking and managing your plants — with intelligent adaptive watering logic that learns your plants' needs over time. Includes a highly customizable companion Lovelace card with a full visual editor and a task reminder blueprint for Companion App notifications.

Adaptive Plant Card

hacs_badge HA Version License


Contents


Features

🚿 Adaptive Watering

  • Track watering intervals per plant
  • Adaptive & customizable interval reduction — if you consistently water early, the interval automatically shortens
  • Adaptive & customizable interval extension — if you consistently snooze watering, the interval automatically lengthens
  • Snooze watering by one day without resetting the period
  • Sensors show human-readable status: Today, In 3 Days, 2 Days Overdue
  • Changing an interval reschedules immediately — editing a watering or fertilization interval (via the number entity or Configure) recomputes the next due date on the spot (last done + new interval). Moisture-sensor plants keep their watering date sensor-managed; fertilization reschedules for every plant.

🌿 Plant Health

  • Health select entity: Excellent, Good, Poor, Sick
  • Configurable reminder notifications if health hasn't been checked recently
  • Confirm Health button — press to confirm you've checked on your plant without needing to change the health value. Resets the check-in clock.

🧪 Fertilization (optional)

  • Track fertilization on a separate interval
  • Same sensor pattern as watering
  • Snoozing watering also snoozes fertilization if it is due the same day
  • Sync to watering day (optional) — set a sync window of 16 days and marking a plant watered will snap an upcoming fertilization that falls within that window onto the same day, so you water and fertilize in one go. Off by default (0, fully independent intervals). It never delays a fertilization that's already due or overdue, and is skipped for plants with moisture-sensors enabled. Set it under Fertilization settings (at setup or via Configure) — keep it below your watering interval.
  • Can be enabled on any plant after setup via Configure — you'll be prompted for the last fertilized date when first enabled
  • When enabling fertilization on an existing plant via Configure, reload the entry/plant afterwards (Settings → Devices & Services → Adaptive Plant →⋮ → Reload) to create the fertilization entities. Once reloaded, open Configure again to set your desired interval — the Fertilization interval field appears once fertilization is active. Changing the interval takes effect immediately: the next fertilization is rescheduled from the last fertilized date you entered when enabling.

💧 Moisture Sensor Integration (optional)

  • Link any existing sensor entity
  • Automatically reschedule watering if soil is dry
  • Automatically mark as watered if soil is saturated
  • Adaptive watering logic is disabled for moisture sensor plants — the sensor drives watering decisions, the schedule acts as a fallback only
  • Moisture sensor, dry threshold, and wet threshold can all be added, changed, or removed after setup via Configure. Use the Enable moisture sensor toggle to remove a sensor — toggling off clears the sensor and both thresholds.
  • The live moisture % can be shown as a chip on any card tab — Overview, Today, and Upcoming — instead of the watering-days countdown (see show_moisture_in_overview / show_moisture_in_today / show_moisture_in_upcoming in the card config below).

Tip: To remove a moisture sensor after setup, open Configure, toggle Enable moisture sensor off, and save. (The moisture sensor uses Home Assistant's entity picker, which can't be cleared by deleting the value — the toggle is the supported way to remove it.)

🪴 Repotting (optional)

  • Track when a plant was last repotted via the Last repotted date sensor
  • Mark repotted button stamps today's date as the last repotting event
  • Repotted on text field — enter a date in YYYY-MM-DD format (e.g. 2026-04-01) before pressing Mark repotted to record a past date instead of today. The field clears automatically after the button is pressed.
  • Can be enabled on any plant after setup via Configure — you'll be prompted for the last repotted date when first enabled

Note: The Repotted on field accepts dates in YYYY-MM-DD format only (e.g. 2026-04-01). Invalid entries are ignored and Mark repotted will fall back to today's date.

🖼️ Plant Image (optional)

Give a plant a photo to display on dashboard cards. There are two ways to do it — pick whichever you prefer, in the setup wizard or later via Configure:

  • Upload a photo (recommended) — choose a PNG or JPEG file directly in the wizard or options flow. The image is processed for you automatically (orientation corrected, downscaled to a max of 1024px, saved as JPEG) and written to config/www/adaptive_plant/. Uploaded images are managed by the integration: the old file is cleaned up automatically when you replace the photo, disable the image option, or remove the plant.
  • Enter a /local/ path — point at an image you've placed yourself. I recommend creating a folder titled 'adaptive_plant' in your /www/ folder and putting your plant images there.

Example image pathway (w/ folder created) for card config: /local/adaptive_plant/monstera.png

Example image pathway (without folder, uploaded directly into /www/) for card config: /local/monstera.png

If you supply both an upload and a path at the same time, the upload wins.

  • Image size (px) and shape (circle / square, softly rounded) are configurable on the companion card via the visual editor or YAML. Set image_size: 0 to hide plant photos entirely for clean text-only rows.

📱 Uploading from an iPhone? Photos you've taken are HEIC/HEIF, but iOS transcodes them to JPEG when you pick one through the file selector — so iPhone uploads work. A raw .heic file (e.g. dragged from a desktop) isn't supported and is rejected with an "invalid image" error.

🏷️ A note on file names: Uploaded images get auto-generated names — a 32-character hex string ending in .jpg — and those are the only files the integration ever deletes on its own. Hand-placed images are left completely untouched, unless you happen to give one a 32-character hex name ending in .jpg inside /local/adaptive_plant/, which would look like a managed file. Any normal name (monstera.png, my_fern.jpg) is perfectly safe.

🔬 Latin Name (optional)

  • Store the scientific name for each plant
  • Enabled or disabled per plant during setup or via Configure at any time
  • Displayed on the companion card below the plant name (if enabled)

📝 Notes (optional)

  • Free-form text field stored per plant - directly editable via the companion card.
  • Can be enabled or disabled at any time via Configure — no restart required

📖 Care Instructions (optional)

  • Free-form care notes per plant — light, soil, humidity, feeding quirks, whatever you want to remember
  • Displayed read-only on the companion card, in the expanded detail on the Overview tab
  • Basic formatting supported: wrap text in **double asterisks** for bold, and line breaks are preserved
  • Up to 2000 characters
  • Enabled per plant via Configure at any time. After enabling, save and reopen Configure to type your notes (the text box appears once the feature is active). Your text is preserved if you toggle the feature off and back on.

Note: Care instructions are read-only on the card by design — they're a reference you set in Configure, not an editable field on the dashboard. Clearing the text while the feature stays enabled simply hides the Care section.

🏠 Area & Label Support

  • Assign each plant to a Home Assistant area during setup
  • The area can be changed — or cleared — at any time after setup from the plant's edit device page (pencil icon on integration page).
  • Optionally add a label (e.g. Left shelf, Window sill) to group plants within an area
  • Labels can be added, changed, or removed at any time via the integration's settings
  • Unlabelled plants always appear first within their area on the companion card.

🌱 Duplicate a Plant

Do you also propagate your plants? When you already have at least one plant already set up, adding a new one opens a small menu: create a plant from scratch, or duplicate an existing plant.

  • Duplicating copies the plant's care recipe: watering interval (the current, adapted value), adaptive thresholds, enabled features, fertilization settings, latin name, care instructions, area, and label
  • The lived history starts fresh: health resets to Good with a new check-in clock, adaptive counters at zero, notes empty
  • In each "last watered / fertilized / repotted" date step you can pick Mirror parent plant to carry the parent's dates over verbatim instead of entering your own
  • A moisture sensor and its thresholds are never copied — two plants shouldn't share one probe. Link a sensor on the duplicate afterwards via Configure.
  • An uploaded photo isn't shared between plants — the duplicate keeps the image feature enabled so you can upload its own. A hand-placed /local/ path is copied as-is; shared files are safe and never touched by cleanup.
  • Duplicates land in the parent's current area (as shown on its device page).

Installation

Via HACS (recommended)

  1. In HACS, go to Integrations → Custom Repositories
  2. Add https://github.com/Big-Xan/adaptive_plant as an Integration
  3. Search for Adaptive Plant and install
  4. Restart Home Assistant
  5. After restarting, the companion card and task reminder blueprint are registered automatically — no further steps needed.

Manual

  1. Copy the custom_components/adaptive_plant/ folder into your HA config/custom_components/ directory
  2. Restart Home Assistant

Setup

  1. Go to Settings → Devices & Services → Add Integration
  2. Search for Adaptive Plant
  3. If you already have plants set up, a menu appears first: Add a plant (full wizard) or Duplicate an existing plant (see Duplicate a Plant)
  4. Follow the setup wizard:
    • Plant name, area, optional label, watering interval, adaptive thresholds
    • Optional features (fertilization, notes, latin name, image, repotting, moisture sensor)
    • Last watered date (Today / Yesterday / Custom / Haven't yet — plus Mirror parent plant when duplicating)
    • Last fertilized date (same options) (if fertilization enabled)
    • Last repotted date (same options) (if repotting enabled)
    • Latin name (if latin name enabled)
    • Image — upload a photo or enter a /local/ path (if image enabled)
    • Moisture thresholds (if a sensor was selected)

To edit any setting after setup, go to Settings → Devices & Services → Adaptive Plant → Configure.

Tip: To remove a label, latin name, or image after setup, open Configure, clear the field (or, for an uploaded image, disable the image option), and save.


Entities

Each plant creates a device with the following entities:

Entity Type Description
Last watered Sensor Date of last watering
Next watering Sensor Scheduled next watering date
Days until watering Sensor Human-readable countdown
Early watering count Sensor Diagnostic — consecutive periods watered early
Consecutive periods snoozed Sensor Diagnostic — consecutive periods snoozed before watering
Health Select Excellent / Good / Poor / Sick
Watering interval Number Editable interval in days
Mark watered Button Records watering, applies adaptive logic
Snooze today's tasks Button Delays watering (and fertilization if also due) by 1 day
Confirm health Button Resets the health check-in clock without changing the health value
Last fertilized Sensor (if fertilization enabled)
Next fertilization Sensor (if fertilization enabled)
Days until fertilization Sensor (if fertilization enabled)
Fertilization interval Number (if fertilization enabled)
Mark fertilized Button (if fertilization enabled)
Last repotted Sensor (if repotting enabled)
Mark repotted Button (if repotting enabled) Stamps today's date, or the date in the Repotted on field if set
Repotted on Text (if repotting enabled) Enter a past date in YYYY-MM-DD format before pressing Mark repotted
Notes Text (if notes enabled)
Latin name Text (if latin name enabled)
Soil moisture Sensor Diagnostic — live reading from linked moisture sensor (if moisture sensor configured)

Adaptive Logic

Watering interval reduction

If you press Mark Watered before the scheduled date, an early watering counter increments. Once it reaches the configured threshold, the watering interval is reduced by 1 day (minimum 1). The counter resets if you water on time.

Example: If you notice a plant that has a 7 day watering interval is dry prior to its set watering date (7th day since last watering) -> you water it early repeatedly (marking the watering each time) -> once it hits the threshold you entered on set-up the watering period is decreased by a day.

Watering interval extension

If you press Snooze today's tasks when a watering is due, a snooze streak counter increments and the task is pushed to tomorrow. Once it the snooze count reaches the configured threshold across consecutive periods, the watering interval increases by 1 day (maximum 365). The streak resets if you water without snoozing.

Example: If you notice a plant that has a 7 day watering interval is not in need of watering on its due date -> you snooze the task until the soil is adequately dry -> if this pattern repeats across enough consecutive watering periods to hit the configured threshold, the watering interval is extended by a day to better match the plant's actual needs.

Note: Snoozing and then watering the same plant on the same day will count that period as both early and snoozed. This is a known edge case and may be addressed in a future release. In the meantime.... don't do that? Why would you do that?


🃏 Companion Lovelace Card

This repo includes a companion Lovelace card (adaptive-plant-card.js) with a full visual editor, designed specifically for use with this integration.

Card Installation

The card is bundled with the integration and registered automatically as a Lovelace resource when the integration loads — no manual installation required. The integration registers a single HTTP endpoint to serve the card file, which is what enables this automatic registration.

Hard refresh your browser (Ctrl+Shift+R / Cmd+Shift+R) after installing or updating.

Upgrading from v1.1.0 or earlier? Previous versions required manually copying www/adaptive-plant-card.js to your HA config/www/ directory and adding it as a resource under Settings → Dashboards → Resources. Remove that old resource entry to avoid the card loading twice.

Card Features

  • Today tab — plants due or overdue, grouped by area and label. Mark watered, mark fertilized, or snooze directly from the card. Hold the button at the bottom to complete all tasks at once. The snooze button remains visible until all of a plant's tasks for the day are resolved.
  • Upcoming tab — future waterings and fertilizations with a configurable day cutoff. Plants with both tasks due on the same day appear as a single combined row. Mark tasks early directly from the card.
  • Overview tab — all plants grouped by area and label, with a configurable sort order (alphabetical, health, or days until watering). Expand any plant to see next watering/fertilization dates, edit health, add notes, confirm health check-in, and mark tasks complete.
  • Labels — plants with a label assigned are grouped under a sublabel header within their area, across all tabs
  • Health ring — colored ring around each plant avatar indicating health status, configurable per tab
  • Confirm Health button — always visible in the Overview expanded detail. Shows a heart icon and reads "Update Due" when a health check-in is overdue. Color configurable.
  • Repotting — Mark Repotted button and date input in the expanded detail view on the overview tab, with customizable button color and icon. The button and input can be hidden via the visual editor or show_repotting — the last repotted date always remains visible.
  • Latin / scientific name — displays in italics below the plant name across all three tabs when enabled on a plant. Font size, color, and vertical padding all configurable.
  • Care instructions — free-form, read-only care notes shown in the Overview expanded detail when enabled on a plant. Supports **bold** and line breaks; appears automatically when a plant has care text (no card config needed).
  • Transparent background — option to hide the card background, compatible with frosted glass themes
  • Pin hold button — optionally fix the "Hold to complete all" button to the bottom of the card
  • Full visual editor — configure everything without writing YAML

Card Configuration & Visual Editor

The card is fully configurable via the visual editor — no YAML required. The card can be modified via YAML if that is your preference (scroll down).

Default configuration - no options set (all 3 tabs shown for visual reference. They are displayed one at a time by the card.): BIG(21)

type: custom:adaptive-plant-card

Custom palette — deep blue-gray background, muted sage tabs, warm amber area headers and copper label sub-headers. Max height set, latin name enabled, centered labels, pinned hold button:

BIG(22)
type: custom:adaptive-plant-card
height: 750
pin_hold_button: true

# Card appearance
show_background: true
card_background_color: '#1f2933'        # deep blue-gray
tab_active_color: '#8fb88a'             # muted sage — softer than the default green

# Area & label headers
area_header_size: 13
area_header_color: '#e8b86a'            # warm amber — clearly distinct from health greens
label_align: center
label_color: '#c89968'                  # softer copper — visually nested below the area header
label_header_size: 11

# Latin name
show_latin_name: true
latin_name_size: 11
latin_name_color: '#9ba8b4'             # cool gray-blue, low-contrast on purpose
latin_name_padding: 2

Visual editor as of v19.2 — every option is configurable without touching YAML. Customization is virtually endless: BIG(28)

Visual editor appears as a vertical scroll - edited together because there are so many config options the vertical image was comically long. Customize away! :)

For full YAML configuration reference:

type: custom:adaptive-plant-card
# Layout
height: 500               # optional — enables internal scroll
width: 400                # optional
# Tabs
show_today: true
show_upcoming: true
show_overview: true
# Schedule
upcoming_days: 14         # how many days ahead to show (default: 30)
overdue_color: '#e05c5c'  # color for overdue chips and indicators
# Card appearance
show_background: true     # set false for transparent/frosted glass themes
card_background_color: #1c1c1e # optional — hex value shown represents the default
tab_active_color: #7cb97e # optional — hex value shown represents the default
pin_hold_button: false    # set true to fix hold bar to bottom of card
image_size: 44            # plant photo / avatar size in px (0–100, default 44; 0 hides the image)
image_shape: circle       # circle | square — square uses softly rounded corners; health ring follows
# Moisture sensor options
exclude_moisture_from_upcoming: false  # hide moisture-tracked plants from Upcoming tab
show_moisture_in_overview: false       # show live moisture % instead of watering days in Overview
show_moisture_in_today: false          # show live moisture % chip on the Today tab
show_moisture_in_upcoming: false       # show live moisture % chip on the Upcoming tab
                                       # (exclude_moisture_from_upcoming still wins on Upcoming)
# Repotting
show_repotting: true      # set false to hide button & date input (date still shown)
# Latin / scientific name
show_latin_name: false    # show italic latin name below plant name in all tabs
latin_name_size: 11       # optional — font size in px
latin_name_color: '#888888'  # optional — defaults to --secondary-text-color
latin_name_padding: 1     # optional — vertical padding in px
# Overview sort order
overview_sort: alphabetical   # alphabetical | health | watering
# Label appearance
label_align: left         # left | center | right
label_padding: 20         # px offset from the chosen edge
label_color: '#666666'    # optional — defaults to --secondary-text-color
# Area & label header sizing
area_header_size: 12      # optional — font size in px for area name headers
area_header_color: '#888888'  # optional — color for area name headers
label_header_size: 11     # optional — font size in px for label sub-headers
                          # label_header color is set via label_color above
# Health ring & text
health:
  ring: true              # show health ring globally (default: true)
  text: false             # show health text globally (default: false, overview only)
  ring_width: 3           # ring thickness in px
  ring_today: true        # per-tab override (true / false, omit for global default)
  ring_upcoming: true
  ring_overview: true
  text_today: false       # per-tab override (true / false, omit for global default)
  text_upcoming: false
  text_overview: true     # text shown on overview by default
  colors:
    excellent: '#7cb97e'
    good: '#a8cc8a'
    poor: '#e6a817'
    sick: '#e05c5c'
# Icons — use any emoji or MDI icon (e.g. mdi:water)
icons:
  water: mdi:water
  water_color: '#64b4ff'
  fertilize: mdi:flower
  fertilize_color: '#7cb97e'
  snooze: mdi:bell-sleep
  snooze_color: '#aaaaaa'
  fertilize_done: mdi:check
  fertilize_done_color: '#7cb97e'
  water_done: mdi:check
  water_done_color: '#64b4ff'
  health_confirm: 'mdi:cards-heart'       # icon for Confirm Health button
  health_confirm_color: '#aaaaaa'         # color when check-in is not overdue
  health_confirm_overdue_color: '#e05c5c' # color when check-in is overdue
  repotted_button_icon: 'mdi:pot'         # optional — emoji or MDI; omit for text-only button
  repotted_button_color: '#c8975a'        # optional — button and input focus ring color

All options are... they're optional — omit any to use defaults.


📋 Task Reminder Blueprint

A companion blueprint for daily plant task reminders is bundled with the integration and copied automatically into your HA blueprints directory when the integration loads — find it under Settings → Automations & Scenes → Blueprints without any manual import needed.

Sends a single combined notification when any of your plants have watering or fertilization tasks due or overdue — automatically discovering all plants without any manual configuration. Supports up to three daily reminder times, customizable notification text, an optional task count summary (e.g. "4 Waterings and 2 Fertilizations"), and a tap action to open your plant dashboard directly. Optionally restrict notifications to only fire when a person is in a specific zone. Plants can be individually excluded from watering or fertilization reminders. Compatible with the Home Assistant Companion App (iOS and Android).

Upgrading from v1.1.0 or earlier? The blueprint was previously available at blueprints/automation/adaptive_plant/plant_task_reminders.yaml in the repo root and required manual import. It can still be imported manually from that path on those versions. From v1.2.0 onwards it is bundled and copied automatically.

Import Blueprint

Or manually import via Settings → Automations & Scenes → Blueprints → Import Blueprint and paste:

https://raw.githubusercontent.com/Big-Xan/adaptive_plant/main/custom_components/adaptive_plant/blueprints/automation/plant_task_reminders.yaml

Task Reminder Blueprint


❓ FAQ

Does Adaptive Plant tell me how to take care of my plants?

No — and that's by design. Adaptive Plant tracks and adapts to your care routine rather than prescribing one. It learns your plant's actual needs over time based on how you interact with it ("oh the soil is still wet I need to snooze it again."), but it won't tell you that a Monstera wants indirect light or that succulents need to dry out completely between waterings.

A plant's watering needs are influenced by a wide range of factors — potting mix, pot size, pot type (terracotta vs. plastic vs. ceramic), distance from the window, window direction, season, humidity, and more. For species-specific guidance, the best starting points are:

  • Houseplant subreddits (r/houseplants, r/plantclinic, and many species-specific communities)
  • A targeted Google search for your plant's latin name
  • AI assistants — just be sure to include context like potting mix, pot size and type, distance from window, and window direction for the most accurate advice

Once you have a rough watering cadence, set it as your starting interval and let Adaptive Plant tune it from there.


How do I get the tablet layout shown in the screenshot?

Three separate cards placed side by side, each showing only one tab (Today, Upcoming, and Overview respectively), sized to fit the tablet screen exactly. To replicate it:

  • Add three Adaptive Plant cards to a horizontal stack or grid layout
  • On each card, disable the two tabs you don't want:
  # Card 1 — Today only
  type: custom:adaptive-plant-card
  show_upcoming: false
  show_overview: false

  # Card 2 — Upcoming only
  type: custom:adaptive-plant-card
  show_today: false
  show_overview: false

  # Card 3 — Overview only
  type: custom:adaptive-plant-card
  show_today: false
  show_upcoming: false
  • Set a height on each card to fill your screen and adjust widths to taste

Can I use this without the companion card?

Yes — the card is entirely optional. Every entity the integration creates is a standard HA entity and works with any dashboard setup. You can use generic HA cards like entity, button, or history-graph — whatever fits your existing dashboard. The companion card just gives you a purpose-built view with all your plants in one place, adaptive logic visualized, and one-tap actions. The integration has no dependency on the card.


What happens if I delete a plant and re-add it?

All state is stored in the config entry — last watered date, next watering, fertilization dates, repotting history, notes, health, and the adapted watering interval. Deleting the entry permanently deletes all of that. Re-adding the plant starts completely fresh.

If you need to change a setting, always use Configure rather than deleting and re-adding — almost everything is editable after setup without losing any data.


Privacy & Security

  • Fully local — no external API calls, no telemetry, no analytics
  • All state stored in config entries only
  • One HTTP endpoint registered to serve the bundled Lovelace card (/adaptive_plant/adaptive-plant-card.js) — no other endpoints exposed

Note: Versions v1.1.0 and earlier registered no HTTP endpoints and required manual card and blueprint installation.

  • No shell commands executed

Requirements

  • Home Assistant 2024.6 or newer
  • No additional Python packages required

License

MIT License — see LICENSE for details.

About

A Home Assistant custom integration for intelligent plant care tracking with adaptive watering intervals.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages