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.

Adopt your PlantSense device

  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. If your firmware sets an API encryption key, paste it when prompted.
  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.

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 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 → ⋮ → Custom repositories, add the PlantSense Card repository with category Dashboard.
  2. Download PlantSense Card, then hard-refresh your browser.

Manual install

  1. Copy plantsense-card.js 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.