Skip to main content

Integration Development

An integration is the unit of functionality in ApexOS. Each integration owns a domain — a short, unique, lowercase identifier made of characters and underscores — and packages everything needed to connect a device, service, or helper to the platform: setup code, a manifest, config flows, entity platforms, and translations.

Where integrations live

Built-in integrations are Python packages inside the core repository, under:

apexos/components/<domain>/

The domain must match the directory name; the manifest validator rejects any mismatch. A typical integration directory looks like this (the sun integration is a good minimal reference):

apexos/components/sun/
├── __init__.py # setup / unload entry points
├── manifest.json # metadata (see the manifest reference)
├── config_flow.py # UI-driven configuration
├── const.py # DOMAIN and other constants
├── entity.py # shared entity base for the integration
├── sensor.py # a platform (one file per entity platform)
├── binary_sensor.py
├── strings.json # translatable texts (source of truth)
├── icons.json
└── translations/ # per-language files: en.json, de.json, ...

Integrations installed by users outside the core tree are custom integrations and live in a custom_components/ directory instead — see Custom integrations.

The core object every integration works with is apex, an instance of ApexOS (apexos.core.ApexOS) — see The apex object.

Scaffolding a new integration

The core repository ships a scaffold tool. Run it from the repository root (it checks for requirements_all.txt and exits otherwise):

python3 -m script.scaffold integration

The first positional argument is a template name. Available templates:

TemplatePurpose
integrationA new integration skeleton (also generates a config flow)
config_flowConfig flow for a manually configured integration
config_flow_discoveryConfig flow for a discoverable integration
config_flow_helperConfig flow for a helper integration
config_flow_oauth2Config flow using OAuth2
backupBackup platform
device_action / device_condition / device_triggerDevice automation platforms
reproduce_stateReproduce-state support
significant_changeSignificant-change support

Options:

  • --integration <domain> — target an existing integration instead of prompting.
  • --develop — fill in all answers automatically (domain develop) and run the integration's tests at the end.

What the tool asks

For a new integration the scaffolder prompts for:

  • domain — must be unique, cannot be changed, must match the directory name, and must contain no spaces or special characters.
  • name — the human-readable integration name.
  • GitHub handle — becomes the entry in codeowners (an @ is prepended if you omit it).
  • PyPI requirement — optional; versions must be pinned with ==.
  • iot_class — one of assumed_state, calculated, cloud_polling, cloud_push, local_polling, local_push.
  • Whether the user must authenticate, whether the device is discoverable on the local network, the integration type, and whether OAuth2 applies. These answers pick the config-flow template that is generated alongside the integration (helper → config_flow_helper, OAuth2 → config_flow_oauth2, authentication or not discoverable → config_flow, otherwise → config_flow_discovery).

What it generates

The integration template produces __init__.py, const.py, a quality_scale.yaml (all rules set to todo), and this manifest:

{
"domain": "NEW_DOMAIN",
"name": "NEW_NAME",
"codeowners": [],
"config_flow": false,
"dependencies": [],
"documentation": "https://www.apexinfosys.in/integrations/NEW_DOMAIN",
"homekit": {},
"iot_class": "IOT_CLASS",
"quality_scale": "bronze",
"requirements": [],
"ssdp": [],
"zeroconf": []
}

Note the documentation URL convention for built-in integrations: https://www.apexinfosys.in/integrations/<domain> — this exact prefix is enforced by the manifest validator.

What runs afterwards

After generating files the scaffolder automatically runs:

  1. python -m script.apexfest --integration-path <dir> --skip-plugins quality_scale — the manifest/integration validator (quality scale is skipped because a fresh skeleton cannot pass it yet).
  2. python -m script.gen_requirements_all — regenerates the aggregated requirement files.
  3. python -m script.translations develop --integration <domain> — generates translation files from strings.json.

With --develop it additionally runs pytest against tests/components/<domain>.

Section contents