Skip to content

Updating from 3.17 or earlier? Read the upgrade guide first.

Crop Steering
Browse the documents

System status

Applies to release 3.18.1 · View source at the tag · Markdown

On this page

Bottom line: Settings › System status shows, on one page, every device your rooms' setups map, whether each one is online, when it last reported and how much of the last 7 days it was online, plus each room's controller heartbeat and the software versions in use. The same numbers come from the crop_steering.system_status_get service and the site-wide sensor.crop_steering_system_health sensor. Nothing on this page, in the service or in the sensor changes irrigation. Only the Acknowledge button on an alert writes anything, and that write is read back.

Getting there

  • In the dashboard menu: Settings › System status (route #/settings/system).
  • The page polls system_status_get every 30 s. The time of the last good read is shown as Checked HH:MM. If a later poll fails, the page says so and keeps showing the last good read, with a Read again button.
  • Capabilities › at the top right opens the read-only features inventory (#/settings/features).

What the page shows

Settings › System status: health line, Upgrade report, software, heartbeat and every mapped device

Health line

A ring with the site's percent online and one sentence, for example:

System health 94%: 34 of 35 devices online, controller running, 3 open alerts, each shown below where it happens.

If the site's controller is running but one room's controller is not, the sentence says "controller not reporting in 1 of 2 rooms". Open alerts that do not belong to a single device are listed under their room's name here.

Software

RowWhat it shows
Controller app (f2_control)Its version, and Running, Not reporting or No heartbeat.
Integration (crop_steering)Its version, and whether it matches the controller's version. A mismatch reads "The controller runs X".
Dashboard cardsThe ?v= of the registered Lovelace resource whose URL contains crop_steering, or "Card version not reported".
Home AssistantThe running Home Assistant version.
AI assistantThe model, and calls today against the daily budget (from sensor.crop_steering_<prefix>jev).

Controller and AI-service alerts (CS-602, CS-609, CS-610, CS-706, CS-708, CS-709) are shown on this card.

Heartbeat

One strip per room for the last hour of the controller's heartbeat (sensor.crop_steering_<prefix>ai_heartbeat). The controller is expected to beat every 60 s. Missed beats show as gaps, and the note under the strip reads, for example, "Every 60 s · 2 missed in the last hour". The integration also reads a readback_ms attribute from each beat, and the note would add the read-back time, but the controller does not write that attribute, so in practice it is not shown.

The heartbeat record is kept in memory, the last 120 beats per room. After a Home Assistant restart the strip covers only the minutes since then ("the last 14 min"), or says "no beats recorded since Home Assistant started".

Every mapped device

Devices are grouped as Moisture and EC probes, Valves, Pumps (pump and flow meters) and Tank and feed sensors. Each group header says "N of M online" and, when the recorder has data, the group's mean 7-day uptime. Each row shows:

  • a dot: green when online; orange for a zone or feed probe (probe_vwc, probe_ec, probe_temp, feed_probe) that is online but last reported over 2 min ago, or whose last report time is unknown; red when the device is not online. A red zone or feed probe reads "silent"; every other red row, including the tank's EC, pH, temperature and distance sensors, reads "not available". Red rows sort first.
  • the room and device name, and its entity ID.
  • last seen: "4 s ago" for probes, sensors and flow meters; "open now", "running" or "switched 13:58" for valves, the pump and the main line.
  • a bar and percent for 7-day uptime. The bar is marked when uptime is below 95 %. "—" means the recorder has nothing for that entity.

Open alerts are placed on the device they concern: a moisture or EC code (CS-1xx) on that zone's probe, the silent one first; a valve, pump or main-line code (CS-3xx) on that device; zone codes CS-701, CS-702 and CS-710 on the zone's valve and CS-703 to CS-705 on its probe; tank, stock and dosing codes (CS-8xx, CS-9xx, CS-608) on the Tank and feed sensors card, except CS-810 and CS-811 (lights dimmed), which go in the room's header. A tank-card alert also goes in the room's header when the room has no Tank and feed sensors group. An alert that names its own entity sits on that entity's row.

Acknowledging an alert

Each alert card has What to do → (opens Help for that code) and, when the alert is in the room's journal, Acknowledge. Acknowledge calls crop_steering.alert_ack. Any signed-in Home Assistant user can acknowledge; an administrator is not needed. The alert leaves the room's open alerts (sensor.crop_steering_<prefix>alerts_open) and is journaled as alert.acknowledged with who did it. When the write is read back, the page says "CS-xxx acknowledged. Written and read back HH:MM." Acknowledging does not fix the cause, and a threshold rule's own sensor stays on until its value is back in range.

Which devices are listed

For each loaded room, everything its setup maps, each entity once:

Kind (kind)Source in the room setupHeld to the silent-probe rule
probe_vwceach zone's vwc_sensors (or vwc_front / vwc_back)yes
probe_eceach zone's ec_sensors (or ec_front / ec_back)yes
probe_tempeach zone's substrate_temperature_sensoryes
valveeach zone's zone_switchno
pumppump_switchno
main_linemain_line_switchno
feed_probefeed_ec_sensor, feed_ph_sensoryes
tanktank_distance_sensor, tank_temperature_sensor, tank_ec_sensor, tank_ph_sensoryes
tankwater_level_sensor, tank_low_floatno
flow_meterthe zone meters set in the site supply (zone_meters)no

Dosing pumps are not listed.

Online, offline and silent

  • Offline (not available): the entity is missing, unknown or unavailable. This applies to every kind.
  • Silent: a probe (see the table) that is available but has not reported within its own limit, max(180 s, 3 × the median of its last 12 report intervals). A probe that reports every 5 min is allowed 15 min; a probe that reports every 30 s is allowed 180 s. A probe repeating the same value still counts as reporting: the integration listens for both state-changed and state-reported events and uses last_reported where Home Assistant provides it.
  • Until two reports of a probe are known, its limit is 900 s. Report times are kept in memory, so this applies again for a short while after every Home Assistant restart.
  • Valves, the pump, the main line, the tank level sensor, the low float and flow meters only change when something happens, so they are online while available, however old their last change.

7-day uptime

uptime_7d_pct is the share of the last 7 days the entity spent neither unknown nor unavailable, read from Home Assistant's recorder. For an entity first recorded less than 7 days ago, it is the share of the time since its first record, so a new install shows its real uptime rather than a low number. Each entity is read at most once an hour. Without the recorder, or with nothing recorded, the value is null (shown as "—"), and the integration logs once at info level that 7-day uptime is not known. Uptime measures availability only: a probe can be silent now and still show high uptime.

Controller: running, stale, absent

Per room, from sensor.crop_steering_<prefix>ai_heartbeat:

  • running: the heartbeat entity exists, its state is not unavailable, unknown, none or empty, and it was updated less than 10 min ago. This is the same rule as the engine_offline Repairs check.
  • stale (shown as "not reporting"): the entity exists but is dead or older than 10 min.
  • absent (shown as "no heartbeat"): the entity does not exist.

The site's controller state is the best of its rooms', and the controller version shown comes from that room's heartbeat (controller_version attribute). Use the per-room Heartbeat strips to find a room whose controller has stopped.

sensor.crop_steering_system_health

One sensor for the whole site.

FieldMeaning
StatePercent of mapped devices online, unrounded; unknown when no devices are mapped. Unit %.
pct_onlineThe same number.
silentSorted entity IDs of every device not online (offline or silent).
controllerrunning, stale or absent.
addon_versionThe controller version from the best room's heartbeat.

Only the room that loaded first (the owner) publishes it: immediately when a room loads, again 60 s after a room's load and on each 5-min health check, and whenever a room loads or unloads. If that room unloads, the next one takes over. When the last room unloads, the sensor and the service are removed.

Example automation trigger:

trigger:
  - platform: numeric_state
    entity_id: sensor.crop_steering_system_health
    below: 90
    for: "00:10:00"

crop_steering.system_status_get

Read-only and response-only, with no administrator check. It takes no fields of its own; the common API fields api, client and proposal_token are accepted (see the API v2 envelope). It refreshes the uptime cache before answering. Answer shape without api: 2 (values are examples):

{
  "controller": "running",
  "addon_version": "3.17.0",
  "pct_online": 97.1,
  "ha_version": "2026.10.1",
  "card_version": "3170",
  "ai": {"calls_today": 12, "daily_budget": 48, "pct_used": 25.0, "model": "example-model"},
  "rooms": [
    {
      "room_id": "room:f2_",
      "pct_online": 96.0,
      "alerts_open": 1,
      "controller": "running",
      "entities": [
        {
          "entity_id": "sensor.f2_z1_vwc_front",
          "kind": "probe_vwc",
          "name": "Room A Z1 VWC front",
          "zone": 1,
          "last_seen": "2026-10-23T02:14:05+00:00",
          "last_change": "2026-10-23T02:14:05+00:00",
          "ok": true,
          "uptime_7d_pct": 99.8
        }
      ],
      "groups": [{"kind": "probe_vwc", "entities": []}],
      "heartbeat": {
        "last_beat": "2026-10-23T02:14:30+00:00",
        "age_s": 12.4,
        "controller": "running",
        "interval_s": 60,
        "beats": [
          {"at": "2026-10-23T02:05:00+00:00", "missed": true, "readback_ms": null, "gap_s": 190.0},
          {"at": "2026-10-23T02:13:30+00:00", "missed": false, "readback_ms": null}
        ]
      }
    }
  ]
}
  • groups holds the same entity rows as entities, grouped by kind in the order of the table above (shortened here).
  • ai is site-wide: it comes from the first loaded room that has a sensor.crop_steering_<prefix>jev, and is null only when no room has one.
  • card_version is null when the Lovelace resources cannot be read, when no resource URL contains crop_steering, or when the first such resource has no ?v= (later matches are not checked).
  • alerts_open is the state of the room's alerts_open sensor, or null.
  • A missed beat is added when the gap between two beats exceeds 2 × 60 s. It sits one interval after the last beat and carries the whole gap in gap_s.
  • The MCP server exposes this as the read-only tool get_system_status.

Older integrations

When the system_status_get service is not there (the call comes back as missing), the page builds the same view from entity states: zone probes and valves, the pump and the main line only, with a probe online while it reported in the last 15 min. The page does not check version numbers; it falls back only on the missing service. In this mode the 7-day uptime and Heartbeat panels say they need the newer integration. The Software card stays, with Home Assistant shown as "—" and Dashboard cards as "Card version not reported"; the AI assistant row is still filled from the jev sensor. Acknowledge then reports that the integration cannot acknowledge alerts yet.

Troubleshooting with this page

  1. Red probe, "silent". The probe is available but stopped reporting at its usual rhythm. Check its device (power, Wi-Fi, ESPHome log) before treating the probe as faulty. The zone's own CS-1xx alert, if any, sits on the same row.
  2. Red valve, pump or main line, "not available". Home Assistant cannot reach the switch, and a shot needs it. Check the relay board or the integration that provides the switch.
  3. Heartbeat "not reporting" or "no heartbeat". The controller app is stopped, restarting or cannot post to Home Assistant. Check the app's log in Home Assistant. The engine_offline Repairs card is raised on the same 10-min rule.
  4. Integration and controller versions differ. Update the one that is behind: the integration first, then the controller (see UPGRADING.md).
  5. Low 7-day uptime but online now. The device dropped out recently. Look at its history in Home Assistant for the gaps.
  6. "—" for uptime everywhere. The recorder is not running, or excludes these entities.

Related: ERROR_CODES.md for each CS code, NOTIFICATIONS.md for who is told about alerts, troubleshooting.md for fixes by symptom.