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.
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
- In HACS → ⋮ (top-right) → Custom repositories, add
https://github.com/mattshax/plantsense-ha-integrationwith category Integration. - Search PlantSense in HACS → Download → restart Home Assistant.
- Settings → Devices & Services → Add Integration → PlantSense, then sign in with your PlantSense account email and password.
- 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.
- 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. - 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
| 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 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)
- In HACS, open the ⋮ menu (top-right) → Custom repositories.
- Repository:
https://github.com/mattshax/plantsense-ha-card, category Dashboard, then Add. - Search HACS for PlantSense Card, hit Download, then hard-refresh your browser.
Manual install
- Grab
plantsense-card.jsfrom the latest release at github.com/mattshax/plantsense-ha-card and copy it toconfig/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.