# har1x/ha-franklinwh-modbus architecture

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

- Interactive diagram: https://gitdiagram.com/har1x/ha-franklinwh-modbus
- Repository: https://github.com/har1x/ha-franklinwh-modbus

## Overview

FranklinWH Modbus is a Home Assistant integration for monitoring and controlling an aGate over local Modbus TCP, with optional cloud writes for operating mode and reserve settings. Users configure and validate a local connection, then the integration polls status into a coordinator that feeds Home Assistant entities. Control entities issue local commands or optional cloud operations; battery commands also use a persisted safety deadline. The README documents the sensor and control capabilities; sampled code shows the coordinator/entity path and optional cloud behavior, but not all platform implementations or the local client library.

Main entry points: [`custom_components/ha_franklinwh_modbus/coordinator.py`](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/coordinator.py) (Status coordinator), [`custom_components/ha_franklinwh_modbus/__init__.py`](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/__init__.py) (Integration setup), [`custom_components/ha_franklinwh_modbus/select.py`](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/select.py) (Mode selector), [`custom_components/ha_franklinwh_modbus/switch.py`](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/switch.py) (Charge/discharge switches)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_setup["Setup and options"]
  node_config_flow["Setup flow<br/>[config_flow.py]"]
  node_configuration["Integration setup<br/>[__init__.py]"]
  node_constants["Options and defaults<br/>[const.py]"]
end

subgraph group_runtime["Polling and state"]
  node_local_client["Local Modbus client"]
  node_coordinator["Status coordinator<br/>[coordinator.py]"]
  node_deadline[("Command deadline<br/>[coordinator.py]")]
end

subgraph group_entities["Home Assistant entities"]
  node_base_entity["Shared entity base<br/>[entity.py]"]
  node_sensors["Status sensors<br/>[sensor.py]"]
  node_alarms["Alarm sensors<br/>[binary_sensor.py]"]
end

subgraph group_control["Control paths"]
  node_cloud_client["Cloud API client<br/>[cloud.py]"]
  node_mode_select["Mode selector<br/>[select.py]"]
  node_reserve["Reserve controls<br/>[number.py]"]
  node_battery_power["Battery power controls<br/>[number.py]"]
  node_battery_duration["Command duration<br/>[number.py]"]
  node_battery_switch["Charge/discharge switches<br/>[switch.py]"]
end

node_ha_user(("Home Assistant user"))
node_agate["FranklinWH aGate"]
node_cloud_service["FranklinWH cloud"]
node_ha_platforms(("Home Assistant"))

node_ha_user -->|"configures"| node_config_flow
node_config_flow -->|"validates connection"| node_local_client
node_configuration -->|"connects and reads"| node_local_client
node_configuration -->|"creates"| node_coordinator
node_configuration -->|"optionally creates"| node_cloud_client
node_configuration -->|"registers entities"| node_ha_platforms
node_config_flow -->|"uses defaults"| node_constants
node_local_client -->|"Modbus TCP"| node_agate
node_coordinator -->|"polls status"| node_local_client
node_coordinator -->|"persists deadlines"| node_deadline
node_base_entity -->|"observes state"| node_coordinator
node_sensors -->|"extends"| node_base_entity
node_alarms -->|"extends"| node_base_entity
node_mode_select -->|"reads and writes"| node_coordinator
node_mode_select -->|"sets mode locally"| node_local_client
node_mode_select -.->|"optionally sets mode"| node_cloud_client
node_reserve -->|"reads state"| node_coordinator
node_reserve -->|"optionally updates reserve"| node_cloud_client
node_cloud_client -->|"sends API requests"| node_cloud_service
node_battery_switch -->|"gets power and deadline"| node_coordinator
node_battery_switch -->|"starts commands"| node_local_client
node_battery_switch -->|"reads setpoint"| node_battery_power
node_battery_power -->|"uses limits"| node_coordinator
node_battery_duration -.->|"configures timeout"| node_coordinator
node_ha_platforms -->|"displays measurements"| node_sensors
node_ha_platforms -->|"displays alarms"| node_alarms
node_ha_platforms -->|"selects mode"| node_mode_select
node_ha_platforms -->|"sets reserve"| node_reserve
node_ha_platforms -->|"controls battery"| node_battery_switch

click node_config_flow "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/config_flow.py"
click node_configuration "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/__init__.py"
click node_constants "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/const.py"
click node_coordinator "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/coordinator.py"
click node_deadline "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/coordinator.py"
click node_cloud_client "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/cloud.py"
click node_base_entity "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/entity.py"
click node_sensors "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/sensor.py"
click node_alarms "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/binary_sensor.py"
click node_mode_select "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/select.py"
click node_reserve "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py"
click node_battery_power "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py"
click node_battery_duration "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py"
click node_battery_switch "https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/switch.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_config_flow,node_configuration,node_constants,node_ha_user toneBlue
class node_local_client,node_coordinator,node_deadline toneAmber
class node_base_entity,node_sensors,node_alarms toneMint
class node_cloud_client,node_mode_select,node_reserve,node_battery_power,node_battery_duration,node_battery_switch toneRose
class node_agate,node_cloud_service,node_ha_platforms toneIndigo
```

## Components

### Setup and options

- [Setup flow](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/config_flow.py): `custom_components/ha_franklinwh_modbus/config_flow.py`
- [Integration setup](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/__init__.py): `custom_components/ha_franklinwh_modbus/__init__.py`
- [Options and defaults](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/const.py): `custom_components/ha_franklinwh_modbus/const.py`

### Polling and state

- **Local Modbus client**
- [Status coordinator](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/coordinator.py): `custom_components/ha_franklinwh_modbus/coordinator.py`
- [Command deadline](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/coordinator.py): `custom_components/ha_franklinwh_modbus/coordinator.py`

### Home Assistant entities

- [Shared entity base](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/entity.py): `custom_components/ha_franklinwh_modbus/entity.py`
- [Status sensors](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/sensor.py): `custom_components/ha_franklinwh_modbus/sensor.py`
- [Alarm sensors](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/binary_sensor.py): `custom_components/ha_franklinwh_modbus/binary_sensor.py`

### Control paths

- [Cloud API client](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/cloud.py): `custom_components/ha_franklinwh_modbus/cloud.py`
- [Mode selector](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/select.py): `custom_components/ha_franklinwh_modbus/select.py`
- [Reserve controls](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py): `custom_components/ha_franklinwh_modbus/number.py`
- [Battery power controls](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py): `custom_components/ha_franklinwh_modbus/number.py`
- [Command duration](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/number.py): `custom_components/ha_franklinwh_modbus/number.py`
- [Charge/discharge switches](https://github.com/har1x/ha-franklinwh-modbus/blob/main/custom_components/ha_franklinwh_modbus/switch.py): `custom_components/ha_franklinwh_modbus/switch.py`

### Other components

- **Home Assistant user**
- **FranklinWH aGate**
- **FranklinWH cloud**
- **Home Assistant**

## Connections

- Home Assistant user → Setup flow: configures (evidence: `README.md`)
- Setup flow → Local Modbus client: validates connection (evidence: `custom_components/ha_franklinwh_modbus/config_flow.py`)
- Integration setup → Local Modbus client: connects and reads (evidence: `custom_components/ha_franklinwh_modbus/__init__.py`)
- Integration setup → Status coordinator: creates (evidence: `custom_components/ha_franklinwh_modbus/__init__.py`)
- Integration setup → Cloud API client: optionally creates (evidence: `custom_components/ha_franklinwh_modbus/__init__.py`)
- Integration setup → Home Assistant: registers entities (evidence: `custom_components/ha_franklinwh_modbus/__init__.py`)
- Setup flow → Options and defaults: uses defaults (evidence: `custom_components/ha_franklinwh_modbus/config_flow.py`)
- Local Modbus client → FranklinWH aGate: Modbus TCP (evidence: `README.md`)
- Status coordinator → Local Modbus client: polls status (evidence: `custom_components/ha_franklinwh_modbus/coordinator.py`)
- Status coordinator → Command deadline: persists deadlines (evidence: `custom_components/ha_franklinwh_modbus/coordinator.py`)
- Shared entity base → Status coordinator: observes state (evidence: `custom_components/ha_franklinwh_modbus/entity.py`)
- Status sensors → Shared entity base: extends (evidence: `custom_components/ha_franklinwh_modbus/sensor.py`)
- Alarm sensors → Shared entity base: extends (evidence: `custom_components/ha_franklinwh_modbus/binary_sensor.py`)
- Mode selector → Status coordinator: reads and writes (evidence: `custom_components/ha_franklinwh_modbus/select.py`)
- Mode selector → Local Modbus client: sets mode locally (evidence: `custom_components/ha_franklinwh_modbus/select.py`)
- Mode selector → Cloud API client: optionally sets mode (evidence: `custom_components/ha_franklinwh_modbus/select.py`)
- Reserve controls → Status coordinator: reads state (evidence: `custom_components/ha_franklinwh_modbus/number.py`)
- Reserve controls → Cloud API client: optionally updates reserve (evidence: `custom_components/ha_franklinwh_modbus/number.py`)
- Cloud API client → FranklinWH cloud: sends API requests (evidence: `custom_components/ha_franklinwh_modbus/cloud.py`)
- Charge/discharge switches → Status coordinator: gets power and deadline (evidence: `custom_components/ha_franklinwh_modbus/switch.py`)
- Charge/discharge switches → Local Modbus client: starts commands (evidence: `custom_components/ha_franklinwh_modbus/switch.py`)
- Charge/discharge switches → Battery power controls: reads setpoint (evidence: `custom_components/ha_franklinwh_modbus/switch.py`)
- Battery power controls → Status coordinator: uses limits (evidence: `custom_components/ha_franklinwh_modbus/number.py`)
- Command duration → Status coordinator: configures timeout (evidence: `custom_components/ha_franklinwh_modbus/number.py`)
- Home Assistant → Status sensors: displays measurements (evidence: `README.md`)
- Home Assistant → Alarm sensors: displays alarms (evidence: `README.md`)
- Home Assistant → Mode selector: selects mode (evidence: `README.md`)
- Home Assistant → Reserve controls: sets reserve (evidence: `README.md`)
- Home Assistant → Charge/discharge switches: controls battery (evidence: `README.md`)
