Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Standalone Mode (No Home Assistant)

LocalSky is a complete, native irrigation + weather product. Home Assistant is one of several integration paths, not a dependency. This document is for users who:

  • Don’t run Home Assistant and don’t want to
  • Run HA but want LocalSky to own irrigation end-to-end
  • Need to understand exactly what works without HA

What “standalone” gets you (the short answer)

Everything. The full LocalSky feature set runs without HA:

  • Live weather dashboard (Tempest UDP / Open-Meteo / Ecowitt / NWS / etc.)
  • FAO-56 reference ET₀ with Hargreaves fallback
  • Per-zone water balance + MAD-driven scheduling
  • 17-rule skip ladder
  • 7-day forward verdict strip
  • Cycle-and-soak runtime splitting
  • Direct controller dispatch (OpenSprinkler HTTP API, ESPHome native protocol, Rachio cloud)
  • Sensor ingestion via MQTT subscribe + direct LAN adapters
  • LLM advisor (Ollama, llama.cpp, or any OpenAI-compatible)
  • Web Push notifications (browser, per device)
  • PWA install on iOS + Android
  • Settings UI + first-run wizard

What you don’t get without HA:

  • HA’s broader home-automation ecosystem (lights, locks, scenes)
  • HA’s dashboard widgets and other integrations

That’s a fair trade if you don’t already run HA.

Sensor ingestion without Home Assistant

This is the question that surfaces most often: “I have soil moisture sensors. How do they get into LocalSky without HA?” Three paths, none requiring HA.

Path 1: MQTT broker (the universal path)

Most modern sensors publish to MQTT. LocalSky’s mqtt source subscribes to topics directly. The architecture:

[Sensor: Tasmota / ESPHome / Zigbee2MQTT / etc.]
              |
              v (publishes to topic)
        [MQTT broker: Mosquitto]
              |
              v (LocalSky subscribes)
        [LocalSky source: kind = "mqtt"]

The broker can be Mosquitto (open-source, free, runs in a 5 MB Docker container), EMQX, HiveMQ, or anything that speaks MQTT 3.1.1 or 5.0. HA’s broker works too if you already have one; the point is the broker is the standard, not HA.

Set up Mosquitto

mkdir -p /opt/mosquitto/{config,data,log}
cat > /opt/mosquitto/config/mosquitto.conf <<'EOF'
listener 1883
allow_anonymous true
persistence true
persistence_location /mosquitto/data/
log_dest file /mosquitto/log/mosquitto.log
EOF

docker run -d \
  --name mosquitto \
  --restart unless-stopped \
  -p 1883:1883 \
  -v /opt/mosquitto/config:/mosquitto/config \
  -v /opt/mosquitto/data:/mosquitto/data \
  -v /opt/mosquitto/log:/mosquitto/log \
  eclipse-mosquitto:latest

Lock this down with username/password before exposing to anything but localhost.

Configure LocalSky to subscribe

In /data/localsky.toml (or via /settings/sources once the editor lands):

[[sources]]
id = "mqtt_sensors"
priority = 80
enabled = true
kind = "mqtt"
[sources.config]
broker_host = "192.0.2.5"     # the mosquitto host
broker_port = 1883
username = "${MQTT_USER}"
password = "${MQTT_PASSWORD}"

[[sources.config.subscriptions]]
topic = "tasmota/soil/back_yard/SENSOR"
field = "soil_moisture_pct"   # planned WeatherField variant for per-zone soil
json_path = "ANALOG.A0"
zone_slug = "back_yard"
scale = 0.0976                # adjust for sensor calibration
offset = 0.0

[[sources.config.subscriptions]]
topic = "esphome/lawn/temperature/state"
field = "air_temp_f"
# no json_path means parse whole payload as a number
# (ESPHome native API publishes raw values to /state topics)

The adapter handles:

  • MQTT 3.1.1 + 5.0
  • Wildcards: + for one segment, # for trailing segments. Example: tasmota/+/SENSOR matches every Tasmota device’s SENSOR topic
  • Plain numeric payloads (Tasmota / ESPHome /state topics)
  • JSON payloads with arbitrary nesting and arrays via json_path. Examples:
    • "soil.moisture" reads obj["soil"]["moisture"]
    • "sensors.0.value" reads obj["sensors"][0]["value"]
  • Tasmota-style number-as-string payloads
  • Linear transforms: published_value * scale + offset for unit conversion or sensor calibration

Hardware that works this way

DeviceHow it gets to MQTTLocalSky path
ESPHome-flashed ESP32 + sensorNative MQTT publish (or via HA’s MQTT integration)Subscribe to esphome/<device>/<sensor>/state
Tasmota-flashed deviceNative MQTT publishSubscribe to tasmota/<device>/SENSOR
Zigbee sensors (Aqara, Sonoff)Via Zigbee2MQTT (no HA needed)Subscribe to zigbee2mqtt/<friendly_name>
Ecowitt gateway (WH51, WH52)Via ecowitt2mqtt sidecarSubscribe to ecowitt/<device_id>
Shelly devicesNative MQTT (firmware setting)Subscribe to shellies/<device>/<field>
Arbitrary Arduino / Pi projectPubSubClient / paho-mqttSubscribe to whatever topic you publish

Zigbee2MQTT is a particularly good fit. It’s a single Docker container that talks to a USB Zigbee coordinator (Conbee II, Sonoff dongle, etc.) and publishes every Zigbee device’s state to MQTT. No HA required.

Path 2: Direct LAN adapters

For sensors that speak a documented LAN protocol, LocalSky can talk to them directly without MQTT in the middle.

SensorAdapterStatus
Tempest hub (UDP broadcast 50222)tempest_udpTested
Ecowitt GW1100 / GW2000 (HTTP POST)ecowitt_localPlanned
Ambient Weather (socket.io)ambient_weatherPlanned
ESPHome native API (protobuf over TCP)esphome_native (sensor mode)Planned

Direct adapters bypass MQTT entirely; the device talks to LocalSky’s listener directly. Less infra, no broker. Use when the device supports a documented protocol that LocalSky has an adapter for.

Path 3: HTTP webhook receiver (planned)

For sensors with arbitrary HTTP push capability (some commercial weather stations, custom scripts), a generic webhook receiver source is planned:

[[sources]]
id = "webhook_sensors"
kind = "http_webhook"
[sources.config]
path = "/ingest/<token>"
# Sensor POSTs JSON to http://localsky:8090/ingest/<token>

Status: planned. Until then, run a small Python or Node bridge that converts your HTTP source to MQTT publishes.

Controller dispatch without Home Assistant

You have three direct paths:

Direct HTTP API on the LAN. See docs/controllers.md. $130-180 hardware; the engine talks to it without anything else in the middle.

ESPHome sprinkler (DIY)

For people who want full open hardware: an ESP32 + relay board + ESPHome’s sprinkler component. ~$15-40 in parts. LocalSky’s esphome_native controller (planned) speaks the protobuf protocol directly. Until that adapter lands, run the ESPHome device under ESPHome’s standalone web interface (no HA needed) and use MQTT for state, with manual valve control from LocalSky still pending the native adapter.

Rachio (planned)

Cloud API, no HA required. LocalSky speaks Rachio v1 directly.

Existing setups: what if I already have HA driving Rachio / Hunter / B-hyve?

Use the ha_service_call controller. LocalSky dispatches through your existing HA setup. This is the “legacy continuity” mode; you keep HA in the loop because the integration to your hardware already lives there.

Reaching LocalSky remotely without HA

HA is sometimes used as a remote-access shim. If you’re not running HA, options:

  • Tailscale – recommended; works on any platform
  • Reverse proxy + TLS – Caddy / nginx / Traefik with Let’s Encrypt
  • Cloudflare Tunnel – no port forwarding, no public IP needed

See getting-started.md#remote-reachability.

Notifications without HA

LocalSky has four notification channels, none requiring HA:

  • Web Push – per-device, via VAPID. Works in any modern browser
  • ntfy.sh – free public service or self-host
  • Slack – incoming webhook
  • Email (SMTP) – planned

Configure under /settings/notifications. None of these touch HA.

Smart Irrigation? Irrigation Unlimited? Are those needed?

No. LocalSky’s engine is a complete, native replacement for both:

The clean-room rewrite was deliberate: both projects are excellent and were the prior art that proved this design space works. LocalSky absorbs their lessons + adds:

  • Multi-source weather merge with provenance
  • Native ET₀ from station readings (not just forecast model output)
  • Cycle-and-soak runoff prevention
  • A real first-run wizard
  • Settings UI
  • Multi-controller HAL
  • An LLM advisor

For an existing HA user already running SI + IU: see Mode 3 in getting-started.md. LocalSky’s ha_service_call controller can still dispatch through SI + IU if you’d rather keep your existing setup and use LocalSky for the dashboard + skip-rule engine only.

The “I’m against HA” reality check

Some objections to HA we hear and how LocalSky stands up:

ObjectionLocalSky position
“HA is too heavy for one feature”Agreed. LocalSky is one Docker container, ~30 MB resident.
“HA pulls in Python deps I don’t trust”Agreed. LocalSky is a single Rust binary; no plugin system, no eval’d YAML, no Python at all.
“I don’t want a YAML automation layer”Agreed. LocalSky’s logic is in compiled Rust + a typed TOML config; no automation YAML.
“I want a focused single-purpose tool”Agreed. LocalSky does irrigation + weather. That’s it.
“I’m worried HA’s roadmap will diverge from mine”Agreed. LocalSky is governed by its repo + its license; the project’s scope is irrigation forever.
“HA’s UX isn’t great for irrigation”Agreed. LocalSky’s UI was built for irrigation first, dashboard second.

LocalSky is for the user who wants the irrigation engine without buying into the broader home automation philosophy. If you’re an HA user already, LocalSky still plays well (Mode 2 / Mode 3); if you’re not, you’re not missing anything.

Future: LocalSky as an HACS integration

There’s a path the other direction: a Python-side HACS integration that polls LocalSky’s REST API and creates HA entities natively, without going through MQTT. This lets HA users get LocalSky as a “first-class HA integration” experience:

  • One-click install via HACS
  • Configuration through HA’s UI
  • LocalSky entities appear under “LocalSky” in HA’s device list
  • LocalSky’s verdicts + zone state become available to HA automations and Lovelace dashboards without YAML

Status: roadmap. Once the LocalSky API stabilizes at v1.0, the HACS integration is a separate ~300-line Python project that wraps the REST endpoints documented in docs/api.md. If you’re a Python developer interested in building this, see the CONTRIBUTING.md on cross-project contribution.

Summary table

CapabilityStandaloneHA + LocalSky (Mode 2: outbound)HA + LocalSky (Mode 3: HA-driven)
Weather dashboard
Engine (ET, bucket, skip rules)
Controller dispatch✅ direct✅ direct✅ through HA
Sensor ingestion✅ MQTT subscribe + direct adapters✅ same + HA passthrough✅ HA passthrough
Sensor entities visible in HA✅ via MQTT discovery✅ HA owns them
HA automations on LocalSky verdicts✅ via MQTT entities✅ direct in HA
Web Push notifications
LLM advisor
Mobile PWA
Configuration surfaceLocalSky /settingsLocalSky /settingsLocalSky /settings
LocalSky depends on HANoNoYes (for dispatch only)

Pick the row that matches your current setup and your future direction.