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.
Adopt your PlantSense device
- Get PlantSense onto your Wi-Fi (via the PlantSense app onboarding, or ESPHome Wi-Fi provisioning).
- In Home Assistant, open Settings → Devices & Services. A newly-joined PlantSense appears under Discovered as an ESPHome device — click Configure and confirm.
- 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. - 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
| Reading | Entity | Unit | Notes |
|---|---|---|---|
| Soil moisture | sensor.plantsense_xxxxxx_soil_moisture | % | Capacitive, per-device calibrated. |
| Temperature | sensor.plantsense_xxxxxx_temperature | °C | Ambient/air (AHT20), not soil temperature. |
| Humidity | sensor.plantsense_xxxxxx_humidity | % | Relative humidity (AHT20). |
| Light | sensor.plantsense_xxxxxx_light | lux | Illuminance (estimated lux, not true PAR). |
| Battery | sensor.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)
- In HACS → ⋮ → Custom repositories, add the PlantSense Card repository with category Dashboard.
- Download PlantSense Card, then hard-refresh your browser.
Manual install
- Copy
plantsense-card.jstoconfig/www/plantsense-card.js. - Settings → Dashboards → ⋮ → Resources → Add resource: URL
/local/plantsense-card.js, type JavaScript Module. - 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.