Skip to content
PlantSense
PlantSenseKnow Your Plants

Documentation

PlantSense works with Home Assistant

PlantSense runs ESPHome firmware, so it drops into Home Assistant as a native, local device — no PlantSense cloud account, no bridge, no third-party integration. Your soil, light, temperature, and humidity readings stay on your own network.

Auto-discovered
Join your Wi-Fi and Home Assistant offers to adopt it.
Local control
Readings and OTA firmware updates run over your LAN.
No cloud, no lock-in
Data never leaves your house unless you send it.

Two ways to connect

PlantSense is a battery sensor that deep-sleeps 90 minutes to 3 hours between short wake cycles. Pick the path that fits how you run Home Assistant:

Recommended · zero setup

Cloud integration

A HACS integration that reads your readings from your PlantSense account — so Home Assistant always has the latest values, even while the sensor sleeps. No broker, no LAN setup, no key.

Advanced · fully local

ESPHome / MQTT

PlantSense runs ESPHome, so it can be adopted natively — no cloud. Great for a mains-powered unit; a battery unit is only reachable during its brief wake, so pair it with MQTT (retained) for reliable data.

Install the cloud integration

  1. In HACS → ⋮ (top-right) → Custom repositories, add https://github.com/mattshax/plantsense-ha-integration with category Integration.
  2. Search PlantSense in HACS → Download → restart Home Assistant.
  3. Settings → Devices & Services → Add Integration → PlantSense, then sign in with your PlantSense account email and password.
  4. Each of your sensors appears as a Home Assistant device with moisture, temperature, humidity, light, battery, and Wi-Fi signal entities, refreshed about every 20 minutes.

Cloud-polling: readings come from your PlantSense account (the same data the app shows), so the sensor never needs to be awake or on the same network as Home Assistant.

Or adopt it locally over ESPHome

Prefer no cloud? Adopt the device natively. Note a battery unit is only reachable during its ~30s wake — keep it awake (mains power, or the app's calibration screen) to adopt, or use the MQTT path below for reliable data between sleeps.

  1. Get PlantSense onto your Wi-Fi (via the PlantSense app onboarding, or ESPHome Wi-Fi provisioning).
  2. In Home Assistant, open Settings → Devices & Services. A newly-joined PlantSense appears under Discovered as an ESPHome device — click Configure and confirm.
  3. If it isn't auto-discovered, add it manually: Add Integration → ESPHome → the device's IP or plantsense-xxxxxx.local.
  4. The device and its sensors now show under that ESPHome integration.

The xxxxxx in the name is a per-device suffix from the module's MAC address, so each unit gets a unique, stable entity prefix.

No encryption key needed. PlantSense's native API is unencrypted on your local network, so Home Assistant adopts it without prompting for a key. If an older unit ever asks for one, re-flash the latest firmware to clear it.

Entities PlantSense exposes

ReadingEntityUnitNotes
Soil moisturesensor.plantsense_xxxxxx_soil_moisture%Capacitive, per-device calibrated.
Temperaturesensor.plantsense_xxxxxx_temperature°CAmbient/air (AHT20), not soil temperature.
Humiditysensor.plantsense_xxxxxx_humidity%Relative humidity (AHT20).
Lightsensor.plantsense_xxxxxx_lightluxIlluminance (estimated lux, not true PAR).
Batterysensor.plantsense_xxxxxx_battery%From the LiPo discharge curve.

Diagnostic entities are also exposed and hidden by default: battery voltage (..._battery_voltage), raw moisture voltage (..._raw_moisture), and Wi-Fi signal (..._wifi_signal).

A quick word on battery life

A battery PlantSense deep-sleeps 90 minutes to 3 hours between short (~30s) wake cycles — that's how it lasts on a small LiPo. It affects how Home Assistant sees it:

  • Always-on (mains-powered) unit: the native ESPHome API stays connected — live updates, nothing extra to configure.
  • Battery unit: while it sleeps, a persistent connection would read unavailable. Use the opt-in MQTT path so Home Assistant retains the last published value and your dashboard always shows the latest reading.

Everything below works the same on either path — same entity ids, same card.

Install the PlantSense dashboard card

The PlantSense Card is a custom Lovelace card that mirrors the app: a plant name, a status pill, and four dial gauges.

Via HACS (recommended)

  1. In HACS, open the ⋮ menu (top-right) → Custom repositories.
  2. Repository: https://github.com/mattshax/plantsense-ha-card, category Dashboard, then Add.
  3. Search HACS for PlantSense Card, hit Download, then hard-refresh your browser.

Manual install

  1. Grab plantsense-card.js from the latest release at github.com/mattshax/plantsense-ha-card and copy it to config/www/plantsense-card.js.
  2. Settings → Dashboards → ⋮ → Resources → Add resource: URL /local/plantsense-card.js, type JavaScript Module.
  3. Hard-refresh your browser.

Add the card

type: custom:plantsense-card
name: Monstera
location: Living room
moisture: sensor.plantsense_a1b2c3_soil_moisture
temperature: sensor.plantsense_a1b2c3_temperature
humidity: sensor.plantsense_a1b2c3_humidity
illuminance: sensor.plantsense_a1b2c3_light
battery: sensor.plantsense_a1b2c3_battery
# optional — tune the healthy soil-moisture band per plant (defaults 15 / 60)
moisture_min: 15
moisture_max: 60

The moisture band drives the Healthy / Needs water / Too wet pill and the moisture-ring colour. Succulents want a much lower band; tropicals higher.

Example: water when the soil gets dry

The readings are ordinary Home Assistant sensors, so you can trigger anything. This notifies your phone and pulses a pump on a smart plug for 20 seconds when soil moisture drops below 25%.

alias: PlantSense — water Basil when dry
mode: single
trigger:
  - platform: numeric_state
    entity_id: sensor.plantsense_a1b2c3_soil_moisture
    below: 25
    for:
      minutes: 10   # ignore a single noisy reading
condition:
  - condition: time
    after: "07:00:00"
    before: "21:00:00"
action:
  - service: notify.mobile_app_your_phone
    data:
      title: "Basil needs water"
      message: >-
        Soil moisture dropped to
        {{ states('sensor.plantsense_a1b2c3_soil_moisture') | round(0) }}%.
  - service: switch.turn_on
    target: { entity_id: switch.basil_pump }
  - delay: { seconds: 20 }
  - service: switch.turn_off
    target: { entity_id: switch.basil_pump }

Other ideas: a low-battery reminder (..._battery below 15%), a “too dark for too long” alert, or a weekly template digest of every plant's status.

Everything here is local and source-agnostic — the card and automations read the same entity ids whether the data arrives over the native ESPHome API or MQTT. Questions? Reach us on the support page.