Metadata-Version: 2.4
Name: inepro-metering
Version: 0.1.0a1
Summary: Protocol and model library for Inepro Metering devices
Author: Inepro Metering
License-Expression: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: bleak-retry-connector<5,>=4.6
Requires-Dist: bleak<3,>=2.1
Requires-Dist: pymodbus==3.11.2
Requires-Dist: pyserial<4,>=3.5
Provides-Extra: test
Requires-Dist: pytest-homeassistant-custom-component<0.14,>=0.13.108; extra == 'test'
Requires-Dist: pytest-socket<1,>=0.7; extra == 'test'
Requires-Dist: zeroconf<1,>=0.147; extra == 'test'
Description-Content-Type: text/markdown

# Inepro Metering Home Assistant Integration

Custom Home Assistant integration for Inepro Metering devices.

This repository intentionally has two layers:

- `src/inepro_metering`: the reusable Python library that owns transport handling, register maps, decoding, runtime models, discovery helpers, and writable-setting definitions
- `custom_components/inepro_metering`: the Home Assistant integration that consumes that shared library

The current architecture direction is to keep Home Assistant as a thin consumer of the shared core rather than the place where protocol and business logic live.

## Status

Current repo focus:

- stabilize the shared-library architecture
- keep the custom integration working for real hardware bench testing
- prepare the project for cleaner upstream-quality Home Assistant work

Current family support:

- `GROW`
- `PRO`

Current live bench result:

- shared RTU bus is working on real hardware
- Ethernet meter polling is working on real hardware
- GROW mDNS/Zeroconf discovery is implemented and validated against the live Ethernet meter advertisement
- mixed-family shared-bus polling is working on real hardware
- the previously configured TCP gateway address was stale and has been removed from the bench Home Assistant instance pending a replacement IP from support

Detailed validation history and environment notes live in [docs/testing-log.md](docs/testing-log.md). Gateway and GROW mDNS discovery behavior is documented in [docs/gateway-discovery.md](docs/gateway-discovery.md), with the live mDNS capture recorded in [docs/grow_mdns_discovery_findings.md](docs/grow_mdns_discovery_findings.md).

## Repository Layout

- `README.md`: high-level project overview and setup guide
- `src/inepro_metering`: shared protocol, model, runtime, discovery, settings, and command code
- `custom_components/inepro_metering`: Home Assistant integration wrapper
- `tests/library`: tests for the reusable library
- `tests/components/inepro_metering`: Home Assistant integration tests
- `scripts`: Windows and bench-development helper utilities
- `dashboards`: optional Lovelace examples
- `docs/testing-log.md`: detailed validation log and environment notes
- `docs/inepro-repo-strategy.md`: Eastron landscape review and recommended Inepro repo strategy
- `docs/architecture-audit.md`: current shared-library versus Home Assistant adapter boundary audit

## Supported Models And Transports

| Family | Models | Supported transports |
| --- | --- | --- |
| `GROW` | `GROW 3P4U`, `GROW 3P4S` | `Wired Modbus RTU`, `Modbus TCP via Gateway`, `Modbus over Bluetooth`, `Modbus TCP over Wi-Fi`, `Modbus TCP over Ethernet` |
| `GROW` | `GROW 1P2U` | `Wired Modbus RTU`, `Modbus TCP via Gateway`, `Modbus over Bluetooth`, `Modbus TCP over Wi-Fi` |
| `GROW` | `GROW 1P1U` | `Wired Modbus RTU`, `Modbus TCP via Gateway` |
| `PRO` | `PRO1`, `PRO2`, `PRO380`, `PRO380CT` | `Wired Modbus RTU`, `Modbus TCP via Gateway` |

## Current Capabilities

- Config-flow based setup
- Manual setup for a single meter
- Home Assistant Zeroconf discovery for GROW Ethernet/Wi-Fi meters advertising `_modbus._tcp.local.`
- Shared-bus discovery for `GROW` meters on:
  - direct Modbus RTU buses
  - Modbus TCP gateways that expose downstream RS485 meters
- Guided Ambition Gateway setup with user-triggered Modbus TCP discovery, manual IP fallback, and gateway-only entries when no downstream meters are detected
- Shared-bus entries that can contain multiple meters on one RTU bus or one TCP gateway endpoint
- Mixed `GROW` + `PRO` support on the same shared bus entry
- Per-meter route storage with one active route per configured meter
- Route switching and route editing through the options flow
- Canonical decoded runtime model in the shared library
- Shared writable-setting model in the shared library
- Measurement, diagnostic, identity, version, and status entities
- Writable `switch`, `select`, and `number` entities backed by shared-library definitions
- Optional OCMF session diagnostics for supported `GROW` models
- `inepro_metering.set_wifi_credentials` service for supported `GROW` meters
- Optional dashboard examples in `dashboards/`

## Architecture

The repo is structured around three layers:

1. Raw transport and register layer
   - Modbus serial, TCP, Bluetooth, and Bluetooth-proxy communication
   - register reads and writes
   - device-identification reads
2. Shared decoded library layer
   - family/model definitions
   - sensor metadata
   - writable-setting metadata and write semantics
   - runtime models for identity, firmware, route, availability, readings, and writable settings
3. Home Assistant presentation layer
   - config flows
   - coordinator orchestration
   - entity creation and device metadata
   - Home Assistant services

Important consequence:

- `number.py`, `select.py`, and `switch.py` are intended to stay thin wrappers over shared-library definitions
- protocol-specific write rules belong in `src/inepro_metering`, not in Home Assistant entity modules

## Sensor Strategy

The current entity selection follows a conservative pattern:

- core electrical values are enabled by default
- transport, identity, version, and status information is exposed as diagnostic data
- more specialized diagnostics stay out of the default entity surface unless they are broadly useful

For `GROW`, the register modeling still follows this practical split:

- `0x5000` to `0x5099`: instantaneous values
- `0x6000` and above: accumulated counters and totals

That keeps instantaneous electrical values aligned with measurement-style entities while counters can be modeled separately.

## OCMF

The codebase still includes dedicated OCMF handling for `GROW` meters where that feature exists.

Current OCMF status:

- OCMF-related register definitions are captured in [src/inepro_metering/ocmf.py](src/inepro_metering/ocmf.py)
- lightweight OCMF session diagnostics are modeled for supported `GROW` variants
- those diagnostics are intended to stay optional rather than cluttering the default entity surface

Current design choice:

- large opaque OCMF payloads are intentionally not exposed as ordinary Home Assistant sensor entities
- command-style and billing-style workflows should stay explicit and carefully modeled rather than becoming generic writable entities

Confirmed register points already tracked in the shared library include:

- `0x1101`: billing command
- `0x1102`: billing command status

## Real Hardware Validation

The integration has been exercised on a live bench setup with Home Assistant running in WSL and Windows providing local helper bridges where needed.

Current confirmed live meters:

| Serial | Family / model | Active route | Result |
| --- | --- | --- | --- |
| `085125250008` | `GROW 1P1U` | Shared RTU bus on Windows `COM5` bridged to `socket://172.28.224.1:15025` | `online` |
| `080125260007` | `GROW 1P2U` | Shared RTU bus on Windows `COM5` bridged to `socket://172.28.224.1:15025` | `online` |
| `025723541870` | `PRO380` | Shared RTU bus on Windows `COM5` bridged to `socket://172.28.224.1:15025` | `online` |
| `075625480002` | `GROW 3P4S` | `Modbus TCP over Ethernet` | `online` |

Additional confirmed bench findings:

- one shared RTU bus entry can host multiple meters with different slave IDs
- one shared RTU bus entry can mix `GROW` and `PRO`
- Windows `COM5` works reliably for the current bench setup when exposed to WSL/Home Assistant through a local serial-to-TCP bridge
- `075625480002` advertises `_modbus._tcp.local.` with TXT `serial`, `model`, and `vendor`; Home Assistant discovery uses TXT `serial` as the stable identity and the advertised service port as the TCP port
- Ethernet-capable GROW meters are intentionally filtered out of Ambition Gateway discovery results until Ethernet-meter-as-master support is actually available
- the BLE-capable `075625480002` meter is currently healthy in Home Assistant, but its active bench route is TCP Ethernet rather than Bluetooth
- the previously configured TCP gateway address `10.5.2.14:502` was unreachable from both Windows and WSL and has been removed from the bench Home Assistant instance pending a new address from support

For the detailed timeline, historical BLE notes, and earlier validation experiments, see [docs/testing-log.md](docs/testing-log.md).

## Installation

### Important Install Note

This repo is currently validated as a developer or bench-test checkout.
This section documents the current custom-repository layout, not the eventual
Home Assistant Core install story if the integration is upstreamed later.

Because the shared library lives in `src/inepro_metering`, copying only `custom_components/inepro_metering` is not enough. The Home Assistant Python environment must also be able to import `inepro_metering`.

The manifest now declares the shared package as `inepro-metering==0.1.0a1`.
This is a pre-release development validation package so Home Assistant OS
package resolution can be tested before final `0.1.0` is frozen. Once the
pinned pre-release package is published, Home Assistant can satisfy the wrapper
import path from the manifest requirements. Until publication is complete,
bench installs still need an editable install or local wheel in the Home
Assistant Python environment.

Validated install path today:

1. clone this repository
2. install the shared library into the Home Assistant Python environment as an editable package or local wheel
3. copy or symlink `custom_components/inepro_metering` into the Home Assistant configuration directory
4. restart Home Assistant

### Local Development Install

Create a local development environment for the repo itself:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
python -m pip install -e .[test]
```

### Local Home Assistant Install

For a pre-publication bench install, install the shared library into the Home Assistant Python environment:

```powershell
python -m pip install -e .
```

Then make the Home Assistant custom component available from your Home Assistant config directory by copying or symlinking:

- [custom_components/inepro_metering](custom_components/inepro_metering)

After that, restart Home Assistant and add `Inepro Metering` from `Settings -> Devices & Services`.

### Current Packaging Reality

Runtime dependency versions are intentionally aligned between:

- [pyproject.toml](pyproject.toml)
- [manifest.json](custom_components/inepro_metering/manifest.json)

Current aligned runtime dependencies:

- `inepro-metering==0.1.0a1`
- `bleak>=2.1,<3`
- `bleak-retry-connector>=4.6,<5`
- `pymodbus==3.11.2`
- `pyserial>=3.5,<4`

Current shared-library and manifest version:

- `0.1.0a1`

## Configuration Flows

Current setup paths include:

- configure one meter manually
- accept an automatically discovered GROW Ethernet/Wi-Fi meter from mDNS/Zeroconf
- scan `GROW` meters on a shared wired RTU bus
- scan `GROW` meters behind a Modbus TCP gateway
- update connection details through the options flow
- add and switch per-meter routes through the options flow

The integration treats these as distinct route types:

- `Wired Modbus RTU`
- `Modbus TCP via Gateway`
- `Modbus TCP over Wi-Fi`
- `Modbus TCP over Ethernet`
- `Modbus over Bluetooth`

## Shared-Bus Behavior

For `Wired Modbus RTU` and `Modbus TCP via Gateway`, one Home Assistant config entry represents one shared Modbus bus endpoint.

That means:

- one config entry can contain multiple Inepro meters
- each meter keeps its own slave ID
- each meter can also keep its own known routes
- repeated scans on the same bus endpoint extend the existing entry instead of creating duplicates
- mixed `GROW` and `PRO` buses are supported

Important caveat:

- this does not make a physical serial line safely shareable between unrelated Home Assistant integrations at the same time
- one Modbus master still owns the endpoint

## Writable Settings

Writable behavior is now defined centrally in the shared library rather than per-entity in Home Assistant.

Current writable areas include:

- Wi-Fi support enablement for supported `GROW` models
- display and LCD related settings where the target profile exposes those writable registers
  - backlight mode
  - backlight level
  - LCD orientation
  - tariff display mode
  - LCD cycle times

Home Assistant exposes these through `switch`, `select`, and `number` platforms, but the register addresses, validation, option maps, and write semantics live in the shared library.

## Wi-Fi Credential Service

Supported `GROW` meters expose the `inepro_metering.set_wifi_credentials` service.

Use it only when:

- the target model supports Wi-Fi
- the meter is already reachable through a safe control route such as RTU, Ethernet, or another known-good route

Parameters:

- `serial_number`: required immutable serial number of the configured target meter
- `ssid`: required Wi-Fi network name to write
- `password`: required Wi-Fi password to write
- `apply`: optional, defaults to `true`, and sends the meter's Wi-Fi apply command after the credentials are written

If the serial number is unknown or the matching config entry is currently not
loaded, Home Assistant raises a validation error instead of silently ignoring
the action.

Example:

```yaml
action: inepro_metering.set_wifi_credentials
data:
  serial_number: "080125260007"
  ssid: "your_wifi_name"
  password: "your_wifi_password"
  apply: true
```

Service metadata lives in [services.yaml](custom_components/inepro_metering/services.yaml).

## Windows And WSL Helper Scripts

These scripts are development and bench-test helpers. They are not required for normal production Home Assistant deployments.

### mDNS/Zeroconf Inspection

Use [discover_mdns_services.py](scripts/discover_mdns_services.py) to inspect local mDNS advertisements before extending GROW discovery matchers:

```powershell
python .\scripts\discover_mdns_services.py --duration 30 --type _modbus._tcp.local.
```

The script listens to Zeroconf only. It does not scan IP ranges or probe Modbus ports.

### Windows Serial To TCP Bridge

Use [windows_serial_tcp_bridge.py](scripts/windows_serial_tcp_bridge.py) when Home Assistant runs in WSL but the serial adapter works more reliably from native Windows.

Example:

```powershell
python .\scripts\windows_serial_tcp_bridge.py --port COM5 --tcp-port 15025
```

That makes the serial bus available to WSL/Home Assistant as a pyserial socket URL such as:

- `socket://172.28.224.1:15025`

### Windows BLE Proxy

Use [windows_ble_proxy.py](scripts/windows_ble_proxy.py) when Windows handles the BLE connection and Home Assistant in WSL should talk to it through a small proxy.

Example:

```powershell
python .\scripts\windows_ble_proxy.py serve --host localhost --port 15026
```

### Windows BLE PIN Validation Helper

Use [windows_ble_pin_pair_test.py](scripts/windows_ble_pin_pair_test.py) for Windows-side pairing and safe read validation against BLE-capable meters.

## Optional Dashboards

Optional Lovelace examples live in `dashboards/`.

Current example:

- [inepro_multi_meter_overview.yaml](dashboards/inepro_multi_meter_overview.yaml)

## Tests

The repo includes:

- `tests/library`: pure shared-library tests
- `tests/components/inepro_metering`: Home Assistant integration tests

Run the full suite with:

```powershell
pytest
```

Clean-checkout workflow:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -U pip
python -m pip install -e .[test]
pytest
```

## Current Limitations

- the current bench Home Assistant instance is waiting for a replacement IP address for the removed TCP gateway
- GROW mDNS discovery currently allowlists the observed WAGO/GROW model `879-3120`; add more model values only after capturing real mDNS payloads
- direct WSL access to Windows serial adapters can still be unreliable depending on the laptop and adapter combination; the Windows serial bridge is the proven local workaround
- the shared `inepro-metering==0.1.0a1` pre-release package must be published before the next HA OS package-resolution validation can proceed; final `0.1.0` remains reserved until the package is ready to freeze

## To-do

- re-validate the TCP gateway path when support provides the replacement gateway address
- capture mDNS payloads for additional GROW firmware/model combinations and extend `KNOWN_GROW_MDNS_MODELS` only from observed data
- validate Home Assistant's discovered-device UX on a fresh instance after a clean restart, including duplicate serial handling and renamed hostnames
- revisit Ethernet-meter-as-master support only when the firmware/product roadmap exposes that role; until then, keep Ethernet GROW meters out of gateway discovery results
- publish the pinned `inepro-metering==0.1.0a1` pre-release package and run the clean-instance validation checklist against that package install path
- continue direct Home Assistant BLE runtime validation and keep the Windows BLE proxy path as a documented fallback for WSL bench setups
- expand live validation across more `PRO` and `GROW` meters, especially gateway-backed routes and writable settings
- keep refining route management so route testing, route health, and route switching are easier to understand from the options flow
- move more of the route model into the shared runtime so fewer top-level config-entry connection fields need to be mirrored for backward compatibility
- complete shared-bus route reparenting so a meter can leave one RTU-style bus grouping when its active route changes, then cleanly rejoin the correct bus later
- add clearer route descriptions, explicit route health, and last-successful route test status in the options flow
- improve shared-bus discovery so one bus scan can classify and discover both `GROW` and `PRO` meters across direct RTU and gateway-backed endpoints
- complete a fuller GROW register-map audit against the official source data for address, type, scale, and register count
- add stronger audit coverage for multi-register values such as serial fragments, firmware CRCs, floats, 32-bit counters, Wi-Fi credential blocks, and OCMF fields
- add tests that fail when modeled register counts drift away from the source map
- keep expanding `PRO` follow-up work, especially model-specific writable settings, stronger identity capture, and broader live hardware validation
- keep higher-risk workflows such as OCMF, billing-style commands, and other sensitive writes modeled as explicit workflows rather than broad generic entities until their behavior is fully validated
