# lex-campbell/centsys_remote architecture

> Architecture diagram of the GitHub repository lex-campbell/centsys_remote, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-09). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/lex-campbell/centsys_remote
- Repository: https://github.com/lex-campbell/centsys_remote

## Overview

#### Purpose and Runtime
This is a Home Assistant custom integration for controlling and monitoring Centurion/CenSys gate operators through Centurion’s cloud API. It runs inside Home Assistant (2024.1+), is installed through HACS or copied under `custom_components`, and exposes each linked operator as an HA device with cover, button, switch, sensor, and binary-sensor entities.

Core integration package: `custom_components/centsys_remote/`  
HA integration metadata/dependencies: `custom_components/centsys_remote/manifest.json`

#### Home Assistant Entry and Lifecycle
Home Assistant loads the integration through `custom_components/centsys_remote/__init__.py`. That module owns config-entry setup/unload and wires shared runtime objects into the entry before forwarding platforms.

User onboarding is implemented as a HA config flow in `custom_components/centsys_remote/config_flow.py`: country/local phone input, WhatsApp/SMS OTP request, OTP verification, and persisted login data. Country dialing rules are defined in `custom_components/centsys_remote/countries.py`.

#### Cloud API and Authentication Boundary
The API layer encapsulates the unofficial Centurion cloud protocol and shields HA entity code from HTTP/MQTT details.

- `custom_components/centsys_remote/api/client.py` is the authenticated cloud client and likely performs OTP/session/device operations.
- `custom_components/centsys_remote/api/models.py` carries typed operator, telemetry, and remote/output data between transport and HA layers.
- `custom_components/centsys_remote/api/packets.py` and `custom_components/centsys_remote/api/enums.py` define protocol representations/status vocabulary.
- `custom_components/centsys_remote/api/certs/centsys_ca.pem` supplies a bundled CA certificate for secure service communication.

External dependencies are Centurion’s OTP delivery and cloud service, plus its real-time MQTT-style remote channel.

#### Device Discovery, Refresh, and Live State
`custom_components/centsys_remote/coordinator.py` is the central synchronization stage. It fetches linked operators, maintains current operator state, schedules normal versus slower deep-telemetry updates, and distributes changes to entities.

Real-time control/status delivery is isolated in `custom_components/centsys_remote/api/mqtt_remote.py`. This supports live opening/closing transitions while the coordinator supplies periodic steady-state and diagnostic refreshes. The system must tolerate no linked gates initially, offline operators, delayed telemetry, and different SMART Wi-Fi versus GSM/ULTRA capabilities.

#### Domain Abstraction and Entity Mapping
`custom_components/centsys_remote/entity.py` provides the common HA entity base and coordinator integration. `custom_components/centsys_remote/const.py` centralizes integration/domain constants.

Platform modules project capability-aware operator models into HA domains:

- Gate control and state semantics: `custom_components/centsys_remote/cover.py`
- SMART pedestrian and GSM momentary auxiliary controls: `custom_components/centsys_remote/button.py`
- GSM latching outputs: `custom_components/centsys_remote/switch.py`
- Diagnostics and operator status: `custom_components/centsys_remote/sensor.py`
- Online/fault flags and GSM feedback inputs: `custom_components/centsys_remote/binary_sensor.py`

Controls call the API boundary; incoming coordinator/MQTT state updates drive HA entity state rather than entities polling independently.

#### Device-Type Behavior
The architecture supports two operational families through shared models plus conditional entity creation. SMART Wi-Fi operators expose live cover movement, pedestrian action, and broad telemetry. GSM/ULTRA devices use pulse-style commands, optional feedback inputs, and configurable auxiliary outputs; absent feedback produces assumed cover state. Protocol-specific errors are normalized through `custom_components/centsys_remote/api/exceptions.py`.

#### User-Facing Contract
HA labels, config-flow copy, and localization are maintained in `custom_components/centsys_remote/strings.json` and `custom_components/centsys_remote/translations/en.json`. This integration deliberately stores credentials in HA config entries and communicates only outbound to Centurion infrastructure.

Main entry points: [`custom_components/centsys_remote/api/client.py`](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/client.py) (Authenticated Cloud Client), [`custom_components/centsys_remote/entity.py`](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/entity.py) (Coordinator Entity Base), [`custom_components/centsys_remote/__init__.py`](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/__init__.py) (Integration Lifecycle), [`custom_components/centsys_remote/coordinator.py`](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/coordinator.py) (State Coordinator)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ha["Home Assistant"]
  node_ha_core{{"Home Assistant Core<br/>host runtime"}}
  node_config_entry[("Config Entry Storage<br/>credential store")]
end

subgraph group_integration["Integration runtime"]
  node_init["Integration Lifecycle<br/>entry setup<br/>[__init__.py]"]
  node_manifest["Integration Manifest<br/>HA metadata<br/>[manifest.json]"]
  node_config_flow["OTP Config Flow<br/>onboarding<br/>[config_flow.py]"]
  node_countries["Country Rules<br/>dialing data<br/>[countries.py]"]
  node_coordinator["State Coordinator<br/>synchronization<br/>[coordinator.py]"]
  node_entity_base["Coordinator Entity Base<br/>HA abstraction<br/>[entity.py]"]
  node_cover["Gate Covers<br/>HA platform<br/>[cover.py]"]
  node_controls["Buttons and Switches<br/>HA platforms<br/>[button.py]"]
  node_diagnostics["Sensors and Binary Sensors<br/>HA platforms<br/>[sensor.py]"]
  node_const["Domain Constants<br/>shared definitions<br/>[const.py]"]
end

subgraph group_api["Centurion API boundary"]
  node_client["Authenticated Cloud Client<br/>API client<br/>[client.py]"]
  node_mqtt["Real-time Remote Channel<br/>MQTT transport<br/>[mqtt_remote.py]"]
  node_models["Operator Models<br/>typed domain models<br/>[models.py]"]
  node_protocol["Protocol Definitions<br/>packets and enums<br/>[packets.py]"]
end

subgraph group_external["External services"]
  node_cloud{{"Centurion Cloud Service<br/>external API"}}
  node_otp{{"OTP Delivery<br/>external messaging"}}
  node_operators{{"Gate Operators<br/>physical devices"}}
end

node_ha_core -->|"discovers"| node_manifest
node_ha_core -->|"sets up entry"| node_init
node_config_flow -->|"stores login data"| node_config_entry
node_countries -->|"formats phone input"| node_config_flow
node_config_flow -->|"requests and verifies OTP"| node_client
node_client -->|"uses"| node_otp
node_init -->|"creates"| node_client
node_init -->|"creates"| node_coordinator
node_init -->|"forwards platforms"| node_entity_base
node_coordinator -->|"periodic discovery and refresh"| node_client
node_coordinator -->|"maintains live channel"| node_mqtt
node_client -->|"authenticated API calls"| node_cloud
node_mqtt -->|"real-time channel"| node_cloud
node_cloud -->|"controls and reports state"| node_operators
node_client -->|"maps responses"| node_models
node_protocol -->|"defines protocol"| node_client
node_coordinator -->|"publishes state updates"| node_entity_base
node_entity_base -->|"shared entity behavior"| node_cover
node_entity_base -->|"shared entity behavior"| node_controls
node_entity_base -->|"shared entity behavior"| node_diagnostics
node_cover -->|"gate commands"| node_client
node_controls -->|"auxiliary commands"| node_client

click node_init "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/__init__.py"
click node_manifest "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/manifest.json"
click node_config_flow "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/config_flow.py"
click node_countries "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/countries.py"
click node_coordinator "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/coordinator.py"
click node_entity_base "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/entity.py"
click node_cover "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/cover.py"
click node_controls "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/button.py"
click node_diagnostics "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/sensor.py"
click node_const "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/const.py"
click node_client "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/client.py"
click node_mqtt "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/mqtt_remote.py"
click node_models "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/models.py"
click node_protocol "https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/packets.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_ha_core,node_config_entry toneBlue
class node_init,node_manifest,node_config_flow,node_countries,node_coordinator,node_entity_base,node_cover,node_controls,node_diagnostics,node_const toneAmber
class node_client,node_mqtt,node_models,node_protocol toneMint
class node_cloud,node_otp,node_operators toneRose
```

## Components

### Home Assistant

- **Home Assistant Core**: host runtime · Loads config entries and entity platforms.
- **Config Entry Storage**: credential store · Persists verified login data.

### Integration runtime

- [Integration Lifecycle](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/__init__.py): entry setup · Creates shared runtime objects and forwards platforms. · `custom_components/centsys_remote/__init__.py`
- [Integration Manifest](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/manifest.json): HA metadata · `custom_components/centsys_remote/manifest.json`
- [OTP Config Flow](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/config_flow.py): onboarding · Collects phone details and verifies OTP login. · `custom_components/centsys_remote/config_flow.py`
- [Country Rules](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/countries.py): dialing data · `custom_components/centsys_remote/countries.py`
- [State Coordinator](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/coordinator.py): synchronization · Discovers operators and schedules normal and deep telemetry refreshes. · `custom_components/centsys_remote/coordinator.py`
- [Coordinator Entity Base](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/entity.py): HA abstraction · Connects platform entities to shared updates. · `custom_components/centsys_remote/entity.py`
- [Gate Covers](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/cover.py): HA platform · Maps gate control and movement state. · `custom_components/centsys_remote/cover.py`
- [Buttons and Switches](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/button.py): HA platforms · Maps pedestrian, pulse, and latching auxiliary controls. · `custom_components/centsys_remote/button.py`
- [Sensors and Binary Sensors](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/sensor.py): HA platforms · Maps telemetry, online, fault, and feedback state. · `custom_components/centsys_remote/sensor.py`
- [Domain Constants](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/const.py): shared definitions · `custom_components/centsys_remote/const.py`

### Centurion API boundary

- [Authenticated Cloud Client](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/client.py): API client · Handles OTP, sessions, operator operations, and refresh requests. · `custom_components/centsys_remote/api/client.py`
- [Real-time Remote Channel](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/mqtt_remote.py): MQTT transport · Delivers live control and operator status transitions. · `custom_components/centsys_remote/api/mqtt_remote.py`
- [Operator Models](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/models.py): typed domain models · Carries operator, telemetry, remote, and output state. · `custom_components/centsys_remote/api/models.py`
- [Protocol Definitions](https://github.com/lex-campbell/centsys_remote/blob/main/custom_components/centsys_remote/api/packets.py): packets and enums · Defines cloud packet representations and status vocabulary. · `custom_components/centsys_remote/api/packets.py`

### External services

- **Centurion Cloud Service**: external API
- **OTP Delivery**: external messaging · WhatsApp or SMS verification delivery.
- **Gate Operators**: physical devices · SMART Wi-Fi and GSM/ULTRA operators.

## Connections

- Home Assistant Core → Integration Manifest: discovers
- Home Assistant Core → Integration Lifecycle: sets up entry
- OTP Config Flow → Config Entry Storage: stores login data
- Country Rules → OTP Config Flow: formats phone input
- OTP Config Flow → Authenticated Cloud Client: requests and verifies OTP
- Authenticated Cloud Client → OTP Delivery: uses
- Integration Lifecycle → Authenticated Cloud Client: creates
- Integration Lifecycle → State Coordinator: creates
- Integration Lifecycle → Coordinator Entity Base: forwards platforms
- State Coordinator → Authenticated Cloud Client: periodic discovery and refresh
- State Coordinator → Real-time Remote Channel: maintains live channel
- Authenticated Cloud Client → Centurion Cloud Service: authenticated API calls
- Real-time Remote Channel → Centurion Cloud Service: real-time channel
- Centurion Cloud Service → Gate Operators: controls and reports state
- Authenticated Cloud Client → Operator Models: maps responses
- Protocol Definitions → Authenticated Cloud Client: defines protocol
- State Coordinator → Coordinator Entity Base: publishes state updates
- Coordinator Entity Base → Gate Covers: shared entity behavior
- Coordinator Entity Base → Buttons and Switches: shared entity behavior
- Coordinator Entity Base → Sensors and Binary Sensors: shared entity behavior
- Gate Covers → Authenticated Cloud Client: gate commands
- Buttons and Switches → Authenticated Cloud Client: auxiliary commands
