OPS on-demand: This skill should be used when the user asks to "homey", "smart home", or…

MITAuto-check: notes

Install Ops Home

skills CLI
$ npx skills add Lifecycle-Innovations-Limited/claude-ops --skill ops-home -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install Lifecycle-Innovations-Limited/claude-ops ops-home --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/Lifecycle-Innovations-Limited/claude-ops.git skills-src && mkdir -p .claude/skills && cp -r skills-src/claude-ops/skills/ops-home .claude/skills/ops-home && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
ops-home
GitHub stars
542
Token cost
~7.9k tokens
SKILL.md length
1,784 words
Files
2 (incl. references)
Skills in repo
67
Repo updated
First seen
Licence
MIT

At a glance

OPS on-demand: This skill should be used when the user asks to "homey", "smart home", or…

  • Works in 4 steps: Resolve credentials → Route by $ARGUMENTS → Cross-channel integration → …
  • SKILL.md covers Runtime Context, Agent Teams support, Phase 1 — Resolve credentials and Phase 2 — Route by $ARGUMENTS, plus 14 more sections
  • Calls jq, curl and node; reaches developer.athom.com and api.athom.com; needs HOMEY_LOCAL_TOKEN and HOMEY_CLOUD_TOKEN

What it does

Ops Home is an agent skill from Lifecycle-Innovations-Limited/claude-ops. OPS on-demand: This skill should be used when the user asks to "homey", "smart home", or…

Its SKILL.md is about 7.9k tokens, which your agent loads only when the skill is triggered. The skill folder holds 2 other files, including reference files (for example `references/cli.md`).

The repository describes itself as: Business operating system for Claude Code — 57 skills, 21 agents, smart daemon. Unified inbox (WhatsApp/Email/Slack/Telegram), autonomous PR merge, full-AWS monitoring, revenue… The licence is MIT.

Example prompts

  • “smart home”
  • “/ops-home”

Requirements

  • A credential in HOMEY_LOCAL_TOKEN
  • A credential in HOMEY_CLOUD_TOKEN
  • Pre-approved tools (allowed-tools): Bash, Read, Write, Grep, Glob, Agent, TeamCreate, SendMessage, AskUserQuestion, WebFetch, WebSearch

Workflow steps

4 steps, taken from the step headings in SKILL.md.

  1. Resolve credentials
  2. Route by $ARGUMENTS
  3. Cross-channel integration
  4. Error handling

What it can do on your machine

Read from SKILL.md and the folder at commit ee9c784. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves these tools, so the agent can use them without asking each time:

    • Bash
    • Read
    • Write
    • Grep
    • Glob
    • Agent
    • TeamCreate
    • SendMessage
    • AskUserQuestion
    • WebFetch

    …and 1 more on the same allowed-tools line.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • jq
    • curl
    • node
    • uv
    • brew

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • developer.athom.com
    • api.athom.com

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • HOMEY_LOCAL_TOKEN
    • HOMEY_CLOUD_TOKEN
    • HOMEY_ACCESS_TOKEN
    • PROVIDED_TOKEN

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Ops Home loads about 7.9k tokens when it runs, and up to ~8.6k if it reads all its reference files. Until then it costs about 25 tokens; SKILL.md has 1,784 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~25
When it runs · the whole SKILL.md, loaded when a task matches
~7.9k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~8.6k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check: notes

The automated check noted patterns worth knowing about, such as sudo or a known installer.

  • NotePre-approves every shell command (allowed-tools: Bash)SKILL.md
    allowed-tools: Bash, Read, Write, Grep, Glob, Agent, TeamCreate, SendMessage, AskUserQuestion, WebFetch, WebSearch

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from Lifecycle-Innovations-Limited/claude-ops at commit ee9c784, republished under its MIT licence (© Lifecycle-Innovations-Limited). 1,784 words, ~7,901 tokens.

Download SKILL.mdSave it as .claude/skills/ops-home/SKILL.md (or your agent's skills folder). This skill also uses 1 other file; get the full folder from GitHub.
name
ops-home
description
OPS on-demand: This skill should be used when the user asks to "homey", "smart home", or…
allowed-tools
Bash, Read, Write, Grep, Glob, Agent, TeamCreate, SendMessage, AskUserQuestion, WebFetch, WebSearch
argument-hint
[status|devices|flow|scene|energy|climate|presence|alarm|setup]
effort
medium
maxTurns
30
context
fork

OPS ► HOME — Smart Home Command Center (Homey Pro)

Load ops-rules before acting. Public repo (no personal data). Outbound: one draft → one approval → one send. If AskUserQuestion / Workflow are missing, follow Rule 10 in ops-rules (Hermes: numbered options / two-turn Telegram card; delegate_task).

Runtime Context

Before executing, load available context:

  1. Preferences: Read ${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json

    • timezone — display all timestamps in user's timezone
    • home_automation.homey_local_url — e.g. http://192.168.1.100 (preferred path, faster, no cloud dependency)
    • home_automation.homey_local_token — Personal Access Token for local API
    • home_automation.homey_cloud_token — Athom OAuth token for cloud fallback
    • home_automation.homey_id — Homey ID (cloud resolution)
  2. Daemon health: Read ${CLAUDE_PLUGIN_DATA_DIR}/daemon-health.json

    • If action_needed is not null → surface it before running any Homey operations
    • On any auth/connectivity failure in this skill, write action_needed back to daemon-health.json
  3. Secrets: Resolve Homey credentials via userConfig → env vars → Doppler → keychain (see Phase 1 below)

Agent Teams support

If CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set, use Agent Teams for parallel hub probing:

TeamCreate("home-team")
Agent(team_name="home-team", name="devices-scanner", prompt="List all Homey devices, group by zone, return online/offline state and current capabilities")
Agent(team_name="home-team", name="flows-scanner", prompt="List all flows and their last-fired timestamps")
Agent(team_name="home-team", name="energy-scanner", prompt="Pull live power draw + today's kWh + top consumers, flag anomalies vs 7-day baseline")
Agent(team_name="home-team", name="presence-scanner", prompt="Return presence state and active alarms")

If the flag is NOT set, dispatch ops:home-agent as standard fire-and-forget subagents per scope (devices, flows, energy, presence, alarms).

Phase 1 — Resolve credentials

Resolve Homey credentials in this order. Local path is preferred (faster, works offline, lower latency):

bash
PREFS_PATH="${CLAUDE_PLUGIN_DATA_DIR:-$HOME/.claude/plugins/data/ops-ops-marketplace}/preferences.json"

# 1. Plugin userConfig (preferences.json)
HOMEY_LOCAL_URL=$(jq -r '.home_automation.homey_local_url // empty' "$PREFS_PATH" 2>/dev/null)
HOMEY_LOCAL_TOKEN=$(jq -r '.home_automation.homey_local_token // empty' "$PREFS_PATH" 2>/dev/null)
HOMEY_CLOUD_TOKEN=$(jq -r '.home_automation.homey_cloud_token // empty' "$PREFS_PATH" 2>/dev/null)
HOMEY_ID=$(jq -r '.home_automation.homey_id // empty' "$PREFS_PATH" 2>/dev/null)

# 2. Environment variables (override userConfig if set)
[ -n "$HOMEY_LOCAL_URL" ] || HOMEY_LOCAL_URL="${HOMEY_LOCAL_URL:-}"
[ -n "$HOMEY_LOCAL_TOKEN" ] || HOMEY_LOCAL_TOKEN="${HOMEY_LOCAL_TOKEN:-}"
[ -n "$HOMEY_CLOUD_TOKEN" ] || HOMEY_CLOUD_TOKEN="${HOMEY_CLOUD_TOKEN:-${HOMEY_ACCESS_TOKEN:-}}"
[ -n "$HOMEY_ID" ] || HOMEY_ID="${HOMEY_ID:-}"

# 3. Doppler fallback (project: homey-pro)
if [ -z "$HOMEY_LOCAL_TOKEN" ] && command -v doppler &>/dev/null; then
  HOMEY_LOCAL_TOKEN=$(doppler secrets get HOMEY_LOCAL_TOKEN --project homey-pro --plain 2>/dev/null)
fi
if [ -z "$HOMEY_CLOUD_TOKEN" ] && command -v doppler &>/dev/null; then
  HOMEY_CLOUD_TOKEN=$(doppler secrets get HOMEY_ACCESS_TOKEN --project homey-pro --plain 2>/dev/null)
fi
if [ -z "$HOMEY_LOCAL_URL" ] && command -v doppler &>/dev/null; then
  HOMEY_LOCAL_URL=$(doppler secrets get HOMEY_LOCAL_URL --project homey-pro --plain 2>/dev/null)
fi
if [ -z "$HOMEY_ID" ] && command -v doppler &>/dev/null; then
  HOMEY_ID=$(doppler secrets get HOMEY_ID --project homey-pro --plain 2>/dev/null)
fi

# 4. Keychain fallback
[ -z "$HOMEY_LOCAL_TOKEN" ] && HOMEY_LOCAL_TOKEN=$(security find-generic-password -s "homey-local-token" -w 2>/dev/null)
[ -z "$HOMEY_CLOUD_TOKEN" ] && HOMEY_CLOUD_TOKEN=$(security find-generic-password -s "homey-cloud-token" -w 2>/dev/null)

If neither a (HOMEY_LOCAL_URL + HOMEY_LOCAL_TOKEN) pair nor (HOMEY_CLOUD_TOKEN + HOMEY_ID) is resolvable, tell the user and exit gracefully:

No Homey credentials configured. Run /ops:setup --section home to configure your Homey Pro hub.

Write action_needed: "configure_homey" to daemon-health.json and exit.

Set helpers used by all phases below:

bash
HOMEY_BASE_LOCAL="${HOMEY_LOCAL_URL}/api/manager"
HOMEY_BASE_CLOUD="https://api.athom.com/v2/homey/${HOMEY_ID}"
HOMEY_AUTH_LOCAL="Authorization: Bearer ${HOMEY_LOCAL_TOKEN}"
HOMEY_AUTH_CLOUD="Authorization: Bearer ${HOMEY_CLOUD_TOKEN}"

# homey_call <path> [method] [body] — tries local first, falls back to cloud on failure
homey_call() {
  local path="$1" method="${2:-GET}" body="${3:-}"
  local resp http_code
  if [ -n "$HOMEY_LOCAL_URL" ] && [ -n "$HOMEY_LOCAL_TOKEN" ]; then
    resp=$(curl -s -o /tmp/homey_resp -w "%{http_code}" -X "$method" \
      -H "$HOMEY_AUTH_LOCAL" -H "Content-Type: application/json" \
      ${body:+--data "$body"} \
      "${HOMEY_BASE_LOCAL}${path}" 2>/dev/null)
    if [ "$resp" -ge 200 ] && [ "$resp" -lt 300 ]; then
      cat /tmp/homey_resp; return 0
    fi
  fi
  # Fallback to cloud
  if [ -n "$HOMEY_CLOUD_TOKEN" ] && [ -n "$HOMEY_ID" ]; then
    # Map manager-style local paths to cloud equivalents where possible
    local cloud_path="${path/\/devices\/device/\/devices}"
    cloud_path="${cloud_path/\/flow\/flow/\/flows}"
    cloud_path="${cloud_path/\/zones\/zone/\/zones}"
    curl -s -X "$method" \
      -H "$HOMEY_AUTH_CLOUD" -H "Content-Type: application/json" \
      ${body:+--data "$body"} \
      "${HOMEY_BASE_CLOUD}${cloud_path}"
    return $?
  fi
  echo '{"error":"no homey transport available"}'
  return 1
}

Phase 2 — Route by $ARGUMENTS

InputAction
(empty)Home status dashboard
status, dashboardHome status dashboard
devices, device, lights, locks, sensorsDevices manager
flow, flowsTrigger / list flows
scene, scenesTrigger scene (alias)
energy, power, kwhEnergy dashboard
climate, temp, thermostat, heatingClimate manager
presence, who, homePresence
alarm, alarms, arm, disarm, securityAlarms / security
health, diagnose, outageHealth / outage scan
sonos, speaker, music, play, volume, groupSonos audio control
setup, configure, init, tokenSetup flow

STATUS (default — empty $ARGUMENTS)

One-screen home dashboard. Run devices/flows/energy/presence/alarms calls in parallel (separate Bash calls or Agent Team), then render.

bash
# Devices online state
homey_call "/devices/device" | jq '{
  total: (. | length),
  online: ([.[] | select(.available == true)] | length),
  offline: ([.[] | select(.available == false)] | length)
}'

# Flows
homey_call "/flow/flow" | jq '{
  total: (. | length),
  enabled: ([.[] | select(.enabled == true)] | length),
  last_fired: ([.[] | select(.lastExecuted != null)] | sort_by(.lastExecuted) | reverse | .[0] | {name, lastExecuted})
}'

# Live energy
homey_call "/energy/live" | jq '{watts: .totalPower // 0}'

# Presence
homey_call "/presence" | jq '[.[] | select(.present == true) | .name]'

# Alarms (active)
homey_call "/alarms/alarm" | jq '[.[] | select(.active == true)]'

# Zones
homey_call "/zones/zone" | jq '[.[] | .name]'

Desktop render:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME — [hub-name] — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HUB          [name]  ([firmware version])
TRANSPORT    local | cloud  ([latency-ms]ms)

DEVICES      [N online] / [N total]   [N offline]
FLOWS        [N enabled] / [N total]
LAST FLOW    [name] fired [N min] ago

POWER        [W] now    [kWh] today
ZONES        [N rooms]
PRESENCE     [name1], [name2]   — home

ALARMS       [N active]
  [type] in [zone] — [device]    (if active)

──────────────────────────────────────────────────────
 [d] devices   [f] flows   [e] energy
 [c] climate   [p] presence   [a] alarms
 /ops:ops-home setup — configure credentials
──────────────────────────────────────────────────────

Mobile mode ($SSH_CONNECTION set or $OPS_MOBILE=1): plain text only, 5–8 lines max, no banners.

home: [N]/[N] devices · [W]W now · [kWh] today.
flows: [N] enabled · last "[name]" [N]m ago.
presence: [names] home.
alarms: [N] active.
next: /ops-home devices | flows | energy

If [N] alarms active is non-zero AND any are critical (smoke/leak/security), surface immediately at top of output and suggest piping to /ops:ops-comms to broadcast.

Use AskUserQuestion for next-action selection (max 4 options per Rule 1).


DEVICES

List devices, group by zone. Support filter and bulk-toggle.

bash
# All devices with zone + capabilities
homey_call "/devices/device" | jq '[.[] | {
  id: .id,
  name: .name,
  zone: .zoneName,
  driverId: .driverId,
  class: .class,
  available: .available,
  capabilities: .capabilities,
  capabilityValues: (.capabilitiesObj // {} | to_entries | map({key: .key, value: .value.value}))
}]'

# Zones for grouping
homey_call "/zones/zone" | jq '[.[] | {id: .id, name: .name}]'

Apply filter from $ARGUMENTS:

  • devices lights → filter class == "light" or capability includes dim/light_hue
  • devices locks → filter class == "lock" or capability includes locked
  • devices climate → filter capability includes target_temperature or measure_temperature
  • devices sensors → filter capability starts with measure_ or alarm_
  • devices --off → set onoff=false on filtered set (REQUIRES AskUserQuestion confirmation — destructive)
  • devices --on → set onoff=true on filtered set (REQUIRES AskUserQuestion confirmation)

Render grouped by zone:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► DEVICES — [filter] — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[ZONE: Living Room]
  [Living Room Lamp]      light    on    dim:0.65    online
  [Sofa Outlet]           socket   off                online
  [Thermostat]            climate  22.5°C → 21.0°C   online

[ZONE: Kitchen]
  [Kitchen Ceiling]       light    on    dim:1.0     online
  ...

OFFLINE
  [Garage Sensor]         sensor                     offline 2h

──────────────────────────────────────────────────────
 Actions:
 a) Toggle a specific device
 b) Turn all [filter] off
 c) Filter by zone
 d) View device capabilities
──────────────────────────────────────────────────────

For toggle / set capability:

bash
# Set onoff
homey_call "/devices/device/${DEVICE_ID}/capability/onoff" PUT '{"value": false}'

# Set dim (0.0 - 1.0)
homey_call "/devices/device/${DEVICE_ID}/capability/dim" PUT '{"value": 0.5}'

# Set target temperature
homey_call "/devices/device/${DEVICE_ID}/capability/target_temperature" PUT '{"value": 21.0}'

Bulk operations REQUIRE AskUserQuestion confirmation (Rule 5 — destructive-like behavior). Show device count + sample before executing.


FLOWS (and SCENES — alias)

Homey calls scenes "flows". Both flow and scene arguments route here.

bash
# List flows
homey_call "/flow/flow" | jq '[.[] | {
  id: .id,
  name: .name,
  enabled: .enabled,
  lastExecuted: .lastExecuted,
  triggerable: .triggerable
}]'

If $ARGUMENTS includes a flow name (e.g. flow movie-time, scene good-night), fuzzy-match by name (case-insensitive substring), then trigger:

bash
FLOW_ID="[matched id]"
homey_call "/flow/flow/${FLOW_ID}/trigger" POST '{}'

If multiple flows match, present top 4 via AskUserQuestion (Rule 1) and let user pick.

If flow list or no flow name provided, render the list with last-fired age.

Common scene names users may try: movie-time, good-night, leaving-home, coming-home, wake-up, dinner, away. Fuzzy match handles variations (goodnight, good night, night).

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► FLOWS — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

ENABLED FLOWS ([N])
  [name]                 fired [N min] ago
  [name]                 never
  ...

DISABLED ([N])
  [name]
  ...

──────────────────────────────────────────────────────
 Actions:
 a) Trigger a flow
 b) Enable / disable a flow
 c) View flow definition
──────────────────────────────────────────────────────

Trigger results: confirm {"success": true} or surface the error.


ENERGY

Live power draw + today's kWh + top consumers + anomaly detection.

bash
# Live power
homey_call "/energy/live" | jq '{
  totalWatts: .totalPower // 0,
  byDevice: [.devices // {} | to_entries[] | {id: .key, watts: .value.power}] | sort_by(-.watts) | .[:10]
}'

# Today's energy report
TODAY=$(date -u +"%Y-%m-%d")
homey_call "/energy/report?period=today" | jq '{
  todayKwh: .totalEnergy // 0,
  byZone: .zones // {}
}'

# 7-day baseline for anomaly detection
homey_call "/energy/report?period=last7days" | jq '.dailyAverage // 0'

Compute anomaly: if todayKwh > 1.5 * dailyAverage, flag as anomaly.

Render:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► ENERGY — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

LIVE         [W] right now
TODAY        [kWh]    (baseline: [kWh]/day  → [+/-N%])

TOP CONSUMERS (live)
  1. [device]  [W]
  2. [device]  [W]
  ...

ANOMALY      [yes/no]  [reason if yes]

──────────────────────────────────────────────────────
 Actions:
 a) View 30-day energy trend
 b) Estimate monthly cost
 c) Set energy alert threshold
──────────────────────────────────────────────────────

If anomaly detected AND cost projection > threshold, route to /ops:ops-fires (see Phase 3).

Mobile mode: 3 lines only — now [W]W · today [kWh] (baseline [kWh]) · top: [device] [W]W.


CLIMATE

Per-zone temperature, humidity, target temp, heating mode. Allow setting.

bash
# Climate devices
homey_call "/devices/device" | jq '[.[] | select(
  (.capabilities | index("target_temperature")) or
  (.capabilities | index("measure_temperature")) or
  (.capabilities | index("measure_humidity"))
) | {
  name: .name,
  zone: .zoneName,
  measure_temperature: (.capabilitiesObj.measure_temperature.value // null),
  target_temperature: (.capabilitiesObj.target_temperature.value // null),
  measure_humidity: (.capabilitiesObj.measure_humidity.value // null),
  mode: (.capabilitiesObj.thermostat_mode.value // null)
}] | group_by(.zone)'

If $ARGUMENTS is climate <zone> <temp> (e.g. climate bedroom 19), find the thermostat in that zone and set target temp via AskUserQuestion confirmation:

bash
homey_call "/devices/device/${THERMO_ID}/capability/target_temperature" PUT '{"value": 19.0}'

Render:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► CLIMATE — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[ZONE: Living Room]
  Temperature   21.5°C   target 21.0°C   mode: heat
  Humidity      45%

[ZONE: Bedroom]
  Temperature   19.0°C   target 19.0°C   mode: heat
  Humidity      52%

──────────────────────────────────────────────────────
 Actions:
 a) Set temperature for a zone
 b) Switch mode (heat/cool/off/auto)
 c) View 24h history
──────────────────────────────────────────────────────

PRESENCE

Who is home, based on Homey presence detection.

bash
homey_call "/presence" | jq '[.[] | {
  id: .id,
  name: .name,
  present: .present,
  lastSeen: .lastSeen
}]'

Render:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► PRESENCE — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HOME ([N])
  [name]    home since [HH:MM]
  ...

AWAY ([N])
  [name]    left [HH:MM]   away [N]h
  ...

──────────────────────────────────────────────────────
 Actions:
 a) Trigger 'leaving-home' flow
 b) Trigger 'coming-home' flow
 c) Check presence-linked automations
──────────────────────────────────────────────────────

If house has been empty for > 1 hour, surface "empty since HH:MM" for cross-reference with /ops:ops-go briefing.


ALARMS / SECURITY

Active alarms (smoke, water, motion in armed zone, contact). Allow arm/disarm.

bash
# Active alarms
homey_call "/alarms/alarm" | jq '[.[] | select(.active == true) | {
  type: .type,
  zone: .zoneName,
  device: .deviceName,
  triggeredAt: .triggeredAt,
  severity: .severity
}]'

# Security mode (fw 13.2.0+: /api/manager/system — NOT /system/info, that returns the Web App HTML)
homey_call "/system" | jq '.securityMode // "unknown"'

If $ARGUMENTS is alarm arm or alarm disarm, set security mode (use a flow if Homey exposes it as such — typical Homey setups use a "Security Armed" flow):

bash
# Find the arm/disarm flow by name
FLOW_ID=$(homey_call "/flow/flow" | jq -r '.[] | select(.name | test("arm|security"; "i")) | .id' | head -1)
homey_call "/flow/flow/${FLOW_ID}/trigger" POST '{}'

Arm/disarm REQUIRES AskUserQuestion confirmation (Rule 5 — security-impacting action).

Render:

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► ALARMS — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

SECURITY MODE     [armed | disarmed | partial]

ACTIVE ALARMS ([N])
  CRITICAL  [smoke]  [zone]  [device]  triggered [time]
  HIGH      [water]  [zone]  [device]  triggered [time]
  MEDIUM    [motion] [zone]  [device]  triggered [time]

NO ACTIVE ALARMS  (if N == 0)

RECENT (last 24h)
  [time]  [type]  [zone]  [device]  — cleared

──────────────────────────────────────────────────────
 Actions:
 a) Arm security
 b) Disarm security
 c) Clear all active alarms
 d) Broadcast critical alarm to /ops:ops-comms
──────────────────────────────────────────────────────

Critical alarm protocol: If a smoke / water / unauthorized-entry alarm fires, IMMEDIATELY suggest piping a message to /ops:ops-comms (WhatsApp + Telegram). Stage the draft and follow Rule 6 (per-message approval). Never auto-send.

Example draft (stage for approval):

Channel: WhatsApp + Telegram
To: [user's emergency contacts from preferences.json → emergency_contacts]
Body:
  [HOMEY ALERT] Smoke alarm triggered in [zone] at [time].
  Device: [device name].
  Check the home immediately. Hub: [hub name].

Then AskUserQuestion with [Send] / [Edit] / [Skip].


HEALTH (health, diagnose, outage)

Plejd-style mass-outage detector. Groups offline devices by driverUri (the source app/integration), then flags any driver where > 30% of its devices are offline as a probable single-driver outage — usually an app crash, expired credentials, or hub-side disconnect inside that integration.

bash
# Pull devices once, then group/aggregate locally
DEVICES_JSON=$(homey_call "/devices/device")

echo "$DEVICES_JSON" | jq '{
  total: (. | length),
  online: ([.[] | select(.available == true)] | length),
  offline: ([.[] | select(.available == false)] | length),
  drivers: (
    [.[] | {driverUri: (.driverUri // "unknown"), available: .available}]
    | group_by(.driverUri)
    | map({
        driverUri: .[0].driverUri,
        total: length,
        offline: ([.[] | select(.available == false)] | length),
        offline_pct: (([.[] | select(.available == false)] | length) * 100 / length)
      })
    | sort_by(-.offline_pct)
  )
}'

Driver short-name: strip homey:app: prefix and dotted namespace (e.g. homey:app:com.plejd → com.plejd → plejd). Display logic:

  • Total banner: total devices: N (X online, Y offline).
  • For each driver where offline_pct > 30 AND total >= 2, surface a MASS OUTAGE line with the count, percentage, and a likely-cause hint based on the driver namespace.
  • For drivers where total == 1 AND offline, label as likely powered off (single device — not a mass outage).
  • For drivers where offline_pct <= 30, list under a partial outage section only if offline >= 2.

Likely-cause hints (keyed by driver namespace substring):

  • plejd, hue, tradfri, lifx, tuya, smartthings, homekit → app credentials expired or app crashed. Fix: open Homey app → Apps → [app name] → reconfigure.
  • chromecast, sonos, airplay → media device dropped off network. Fix: power-cycle device + check Wi-Fi.
  • zwave, zigbee, 433 → radio congestion or hub-mesh issue. Fix: check Homey → Settings → Z-Wave/Zigbee mesh.
  • whisker, litter, vacuum, generic single-device → likely powered off.
  • Unknown → unknown integration — check the app's status in Homey app → Apps.

Render (desktop):

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
 OPS ► HOME ► HEALTH — [timestamp]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

HOMEY ► HEALTH
  total devices: 181 (82 online, 99 offline)

  ⚠ MASS OUTAGE: com.plejd — 96 / 96 offline (100%)
    likely: app credentials expired or app crashed.
    Fix: open Homey app → Apps → Plejd → reconfigure.

  whisker: 1 / 1 offline (100%) — likely powered off
  chromecast: 2 / 4 offline (50%) — media device dropped off network.

──────────────────────────────────────────────────────
 Actions:
 a) Reconfigure flagged app (deep-link to Homey app)
 b) Power-cycle Homey hub
 c) Re-run health scan after fix
 d) Broadcast outage to /ops:ops-comms
──────────────────────────────────────────────────────

Mobile mode:

home health: 82/181 online.
⚠ plejd: 96/96 offline (app down — reconfigure in Homey app).
whisker: 1/1 offline (powered off).
next: /ops-home devices | reconfigure plejd

If any MASS OUTAGE is flagged, surface it at the top of the default STATUS dashboard as well (after the DEVICES line), so the user sees it without needing to run /ops-home health explicitly.

Cross-channel: if MASS OUTAGE count > 50 devices OR a security-related integration is down (alarm panel, locks, cameras), suggest piping to /ops:ops-comms (Rule 6 — stage draft, never auto-send).


SONOS (sonos, speaker, music, play, volume, group)

Sonos multi-room audio is controlled independently of Homey, directly over the LAN via UPnP/SOAP + SSDP discovery. A full reusable toolchain is installed on this machine (set up 2026-06-28). Pick the layer that fits the task — they are redundant control paths over the same speakers, so any one works.

Show full SKILL.md (719 more words)Show less
Installed tooling (all local, all reusable)

CLIs (use for quick one-shot control from Bash; each has a distinct name to avoid the sonos collision):

CommandToolLanguageBest for
socosoco-cli (avantrec)PythonScriptable control, macros, loops, HTTP server
sonos-svrooij@svrooij/sonos-cliNodeModern TS lib wrapper, queue/sleep-timer/EQ
sonos-steipetesteipete/sonoscli (sonos on PATH)GoFast discovery/status, Spotify + SMAPI search
bash
sonos-steipete discover                       # list speakers on the LAN
soco "Kitchen" volume 30                       # set Kitchen to volume 30
soco "Living Room" play                         # resume playback
sonos-svrooij --help                            # queue / sleep-timer / EQ commands
soco-discover                                   # cache the speaker topology

HTTP API bridge — jishi/node-sonos-http-api at ~/Projects/sonos-tools/node-sonos-http-api (default port 5005). Start with node server.js (background it). Gives a simple REST surface for automations:

bash
curl http://localhost:5005/zones                       # all zones + state
curl http://localhost:5005/Kitchen/play
curl http://localhost:5005/Living%20Room/volume/25
curl http://localhost:5005/Bedroom/sleep/600           # 10-min sleep timer

soco-cli ships its own equivalent server too: sonos-http-api-server.

MCP servers (use these for agent/LLM-driven control — they expose Sonos as callable tools; preferred for this skill):

  • sonos-ts-mcp (Tommertom, TypeScript) — registered + live. Served through the local mcp-proxy at http://127.0.0.1:8090/servers/sonos-ts-mcp/mcp (entry in ~/.claude.json + ~/.claude/mcp-proxy/servers.json). Tools: device discovery, playback, volume, EQ, alarms, grouping, library browse. All tools take a deviceId (room name, UUID, or IP). After a Claude restart the mcp__sonos-ts-mcp__* tools are available directly.
  • sonos-mcp-server (WinstonFassett, Python/uv) at ~/Projects/sonos-tools/sonos-mcp-server — run with uv run mcp run server.py. Secondary/redundant; register the same proxy way if needed.
Routing sub-actions
InputAction
sonos / sonos statussonos-steipete discover then per-zone status → render table
sonos play [room]soco "<room>" play (default to first zone if none given)
sonos pause [room]soco "<room>" pause
sonos volume <room> <0-100>soco "<room>" volume <n> — confirm if >60 (loud)
sonos group <room> <room>join second room to first's group (soco group commands)
sonos play <uri/playlist>use MCP tool or sonos-svrooij to enqueue + play

If sonos-steipete discover returns 0 speakers, there are no Sonos devices reachable on the current LAN (or the Mac is on a different VLAN/Wi-Fi than the speakers). Report that plainly — it is not a tooling failure. Both the CLI and the MCP confirmed 0 devices at install time, which is expected off-network.

Loud-volume (>60) and group-teardown are mildly disruptive — confirm via AskUserQuestion before applying (Rule 5 spirit).


SETUP FLOW (setup, configure, init, token)

Delegate to the central setup wizard with the home section:

/ops:setup --section home

If for any reason the wizard is not available, run the inline credential discovery (background per Rule 4):

bash
# 1. Env vars
printenv HOMEY_LOCAL_URL HOMEY_LOCAL_TOKEN HOMEY_ACCESS_TOKEN HOMEY_CLOUD_TOKEN HOMEY_ID 2>/dev/null

# 2. Shell profiles
grep -hE 'HOMEY_' ~/.zshrc ~/.bashrc ~/.zprofile ~/.envrc 2>/dev/null | grep -v '^#'

# 3. Doppler — homey-pro project
doppler secrets --project homey-pro --config prd --json 2>/dev/null | \
  jq -r 'to_entries[] | select(.key | test("HOMEY"; "i")) | "\(.key)=(present)"'

# 4. Keychain
security find-generic-password -s "homey-local-token" 2>/dev/null
security find-generic-password -s "homey-cloud-token" 2>/dev/null

# 5. Local network scan for Homey Pro (mDNS)
dns-sd -B _homey._tcp 2>/dev/null & sleep 2; kill $! 2>/dev/null

# 6. Existing prefs
jq -r '.home_automation // empty' "$PREFS_PATH" 2>/dev/null

If local IP discovered but no token, instruct (Rule 3 — never silently skip):

  1. Try https://developer.athom.com/tools/api Web API playground to generate a Personal Access Token with scopes homey, homey.device, homey.flow, homey.zone.
  2. If browser automation is available (Kapture), navigate https://my.homey.app/account and automate token creation.
  3. Manual fallback: ask user to paste the token via AskUserQuestion.

Verify connectivity after acquisition:

bash
curl -s -H "Authorization: Bearer ${PROVIDED_TOKEN}" \
  "${PROVIDED_LOCAL_URL}/api/manager/system" | jq '{name, firmware: .firmwareVersion}'

If 200 — confirm success and write to preferences.json under home_automation.*. If 401/403 — token invalid, re-prompt via AskUserQuestion ([Paste new token], [Deep hunt — spawn agent], [Skip]).


Phase 3 — Cross-channel integration

After producing the main output, evaluate cross-channel triggers:

  1. Critical alarm → comms — If smoke / water leak / unauthorized-entry alarm is active, suggest piping to /ops:ops-comms (WhatsApp/Telegram). Stage the draft; follow Rule 6 (per-message approval, never auto-send).

  2. Energy anomaly → fires — If todayKwh > 1.5 * 7d_average AND projected monthly cost spike > $50 / €50, surface as a fire item:

    • Write the anomaly to daemon-health.json under action_needed
    • Suggest running /ops:ops-fires
  3. Presence → morning briefing — If house has been empty > 1 hour during typical wake hours (06:00–10:00 in user's timezone), suggest cross-referencing /ops:ops-go:

    • "Home empty since [HH:MM] — confirm intended for /ops:ops-go briefing?"
  4. Hub offline → status — If local API fails AND cloud API fails, write action_needed: "homey_unreachable" to daemon-health and exit with an action banner.

These integrations are SUGGESTIONS shown in the action footer — never auto-execute Rule-5 / Rule-6 protected actions.


Phase 4 — Error handling

FailureBehavior
Local 401Token expired. Tell user to run /ops:setup --section home.
Local connection refused / timeoutFall back to cloud API. Log "transport=cloud (local unreachable)".
Cloud 401Cloud token expired. Tell user to refresh via Athom OAuth.
Both local + cloud failReport which channel failed; write action_needed: "homey_unreachable" to daemon-health; exit with banner.
jq missingPrint raw JSON, suggest brew install jq.
No credentials at allExit gracefully with /ops:setup --section home instruction.

Audit log every state-changing call (PUT capability, POST flow trigger, arm/disarm) to ${CLAUDE_PLUGIN_DATA_DIR}/ops-home-audit.log with timestamp, action, device/flow id, result.


Output style

  • Terse-direct. Plain text in mobile mode (Rule 7). Tables only on desktop.
  • Always show a hotkey footer ([d] devices [f] flows [e] energy [c] climate [p] presence [a] alarms) on desktop.
  • Use AskUserQuestion (max 4 options per Rule 1) for any state-changing action.
  • Never auto-send messages — always stage drafts per Rule 6.

Additional resources

CLI detail: references/cli.md.

© Lifecycle-Innovations-Limited, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 1 other file (references) in claude-ops/skills/ops-home of Lifecycle-Innovations-Limited/claude-ops.

  • SKILL.md
  • references/cli.md

Open the folder on GitHubat commit ee9c784

Compare with similar skills

Ops Home next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Ops Home compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Ops Home this skillLifecycle-Innovations-Limited/claude-ops542—~7.9kAutomated safety check: NotesMIT
Knowledge Opsaffaan-m/ECC276k2 repos~1.7kAutomated safety check: PassMIT
Research Opsaffaan-m/ECC276k2 repos~902Automated safety check: PassMIT
Terminal Opsaffaan-m/ECC276k2 repos~750Automated safety check: PassMIT
Messages Opsaffaan-m/ECC276k1 repos~724Automated safety check: PassMIT
Email Opsaffaan-m/ECC276k1 repos~1.1kAutomated safety check: PassMIT

Similar skills

  • Knowledge Ops

    affaan-m/ECC

    Knowledge base management, ingestion, sync, and retrieval across multiple storage layers (local files, MCP memory, vector stores, Git repos).

    276k GitHub starsUsed in 2 repos~1.7k tokens
    Knowledge ManagementAuto-check passed
  • Research Ops

    affaan-m/ECC

    Evidence-first current-state research workflow for ECC. An agent skill from affaan-m/ECC.

    276k GitHub starsUsed in 2 repos~902 tokens
    Research & ScienceAuto-check passed
  • Terminal Ops

    affaan-m/ECC

    Evidence-first repo execution workflow for ECC. An agent skill from affaan-m/ECC.

    276k GitHub starsUsed in 2 repos~750 tokens
    Testing & QAAuto-check passed
  • Messages Ops

    affaan-m/ECC

    Evidence-first live messaging workflow for ECC. An agent skill from affaan-m/ECC.

    276k GitHub starsUsed in 1 repo~724 tokens
    Productivity & AutomationAuto-check passed
  • Email Ops

    affaan-m/ECC

    Evidence-first mailbox triage, drafting, send verification, and sent-mail-safe follow-up workflow for ECC.

    276k GitHub starsUsed in 1 repo~1.1k tokens
    Writing & ContentAuto-check passed
  • GitHub Ops

    affaan-m/ECC

    GitHub repository operations, automation, and management. An agent skill from affaan-m/ECC.

    276k GitHub starsUsed in 2 repos~1.5k tokens
    DevelopmentAuto-check: warnings

More from Lifecycle-Innovations-Limited/claude-ops

All 67 skills in this repo
  • Ops Dash

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "ops dashboard", "pixel HQ", or…

    542 GitHub stars~4.7k tokensUpdated today
    Auto-check: notes
  • Ops Gtm

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "go to market", "GTM plan", or…

    542 GitHub stars~3.7k tokensUpdated today
    Auto-check: notes
  • Ops Marketing

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "klaviyo", "ads spend", or…

    542 GitHub stars~3.5k tokensUpdated today
    Auto-check: notes
  • Ops Socials

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "tweet", "post to linkedin", or…

    542 GitHub stars~3.6k tokensUpdated today
    Auto-check: notes
  • Ops Yolo

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "yolo mode", "run the business today"…

    542 GitHub stars~4k tokensUpdated today
    Auto-check: notes
  • Ops Monitor

    Lifecycle-Innovations-Limited/claude-ops

    OPS on-demand: This skill should be used when the user asks to "datadog", "APM alerts", or…

    542 GitHub starsUsed in 1 repo~1.5k tokens
    Auto-check: notes

Questions about Ops Home

What does Ops Home do?

OPS on-demand: This skill should be used when the user asks to "homey", "smart home", or…. Ops Home is an agent skill from Lifecycle-Innovations-Limited/claude-ops.

How do I install Ops Home in Claude Code?

Run `npx skills add Lifecycle-Innovations-Limited/claude-ops --skill ops-home -a claude-code`. Or copy the skill folder (claude-ops/skills/ops-home in Lifecycle-Innovations-Limited/claude-ops) into .claude/skills/ops-home in your project. Claude Code loads it when a task matches its description.

How do I install Ops Home in Codex?

Run `npx skills add Lifecycle-Innovations-Limited/claude-ops --skill ops-home -a codex`. Or copy the skill folder (claude-ops/skills/ops-home in Lifecycle-Innovations-Limited/claude-ops) into .agents/skills/ops-home in your project. Codex loads it when a task matches its description.

Can I use Ops Home in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add Lifecycle-Innovations-Limited/claude-ops --skill ops-home -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ops-home, .gemini/skills/ops-home, .github/skills/ops-home and .opencode/skills/ops-home in your project.

What does Ops Home need to run?

Going by SKILL.md and its folder, Ops Home needs the command-line tools its instructions call (jq, curl, node, uv and brew) and credentials named HOMEY_LOCAL_TOKEN, HOMEY_CLOUD_TOKEN, HOMEY_ACCESS_TOKEN and PROVIDED_TOKEN. Our summary lists: A credential in HOMEY_LOCAL_TOKEN; A credential in HOMEY_CLOUD_TOKEN. Its frontmatter pre-approves these tools: Bash, Read, Write, Grep, Glob, Agent, TeamCreate, SendMessage, AskUserQuestion, WebFetch, WebSearch.

Does Ops Home access the network?

SKILL.md names 2 domains. In commands or code: developer.athom.com and api.athom.com; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is Ops Home safe to install?

Our automated static check of SKILL.md found notes only (pre-approves every shell command (allowed-tools: bash)), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.

What licence does Ops Home use?

Ops Home is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Ops Home use?

About 7.9k tokens (SKILL.md is roughly 32k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 699 tokens, read only when the agent opens those files.

What are the alternatives to Ops Home?

Skills that share tags, products or a category with Ops Home: Knowledge Ops (affaan-m/ECC, 276k stars), Research Ops (affaan-m/ECC, 276k stars), Terminal Ops (affaan-m/ECC, 276k stars) and Messages Ops (affaan-m/ECC, 276k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Ops Home?

Lifecycle-Innovations-Limited (a GitHub organization) maintains it in Lifecycle-Innovations-Limited/claude-ops, which has 542 GitHub stars. The repository holds 67 skills in this directory. The repository was last updated on October 10, 2026.

Source: Lifecycle-Innovations-Limited/claude-ops on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.