Metadata-Version: 2.4
Name: peha-phc-stmv3
Version: 0.1.0
Summary: A Python library to interact with PEHA PHC stmv3 controllers.
Author: Philipp Harms
License-Expression: MIT
Project-URL: Homepage, https://git.supercookie.de/philipp/peha-phc-stmv3
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Requires-Python: >=3.7
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: requests
Dynamic: license-file

# PEHA PHC STMv3 Python Library

A Python library for controlling and monitoring PEHA PHC System (STMv3) smart home devices.

## Features

- **Device Discovery:** automatically downloads and parses the project file (`project.ppfx`) from the STM controller to identify all connected modules (Inputs, Outputs, Dimmers, Shutters, Analog).
- **Control:** Switch Output, dimmers, and simulate inputs.
- **Monitoring:** Read output status, and read/write "Merker" (flag) values.
- **Input Simulation:** Simulate physical button presses (`simInputEvent`) to trigger internal logic or scenes.
- **Robust Catalog:** uses a reverse-engineered device catalog (`modules.xml`) to correctly map physical addresses for 50+ module types.

> **Note on live input/sensor state:** the STM's RPC surface has no way to read a physical input
> or sensor's live state directly, and no push/event mechanism either (see Limitations below). The
> supported pattern is: in the PHC Systemsoftware, wire the input/sensor to a "Merker" via basic
> programming (one-time setup per sensor), then poll that Merker with this library.

## Installation

```bash
pip install .
```

## Usage

### Connecting and Discovery

```python
from peha.client import PehaPHC

# Connect to the STM controller
client = PehaPHC("192.168.1.10")

# Get device info
info = client.who_are_you()
print(f"Connected to STM at address {info.get('STM-Address', 'Unknown')}")

# Discover modules
modules = client.get_modules()
for mod in modules:
    print(f"{mod['name']} - Addr: {mod['module_addr']} - {mod['description']}")
```

### Controlling a Light (Output)

```python
# Switch ON channel 0 of module at address 65
# (Note: Address 65 usually corresponds to the first output module)
client.switch_channel(stm_address=2, module_address=65, channel_index=0, state=True)
```

### Simulating a Button Press (Input)

Useful for triggering scenes or logic that depends on a physical switch.

```python
from peha.client import VirtualInputEvent

# Simulate a short press ON event on Input Module 0, Channel 0
client.sim_input_event(
    stm_addr=2, 
    module_addr=0, 
    channel=0, 
    event=VirtualInputEvent.ON_SHORT
)
```

### Reading/Writing a Merker (Flag)

Merker are project-wide boolean flags created in the PHC Systemsoftware. Since the STM has no way
to report a physical input's or sensor's live state directly (see Limitations), the supported
pattern for monitoring something like a motion sensor is: create a Merker, wire the sensor to it
via "basic programming" in the desktop software (once, per sensor), then poll the Merker here.

```python
from peha.client import MerkerType

# Read a user-created Merker (e.g. wired to a motion sensor's basic programming)
is_on = client.get_marker(stm_addr=2, marker_id=0)  # marker_type defaults to ANWENDERMERKER

# Write one (e.g. a flag your own logic reads elsewhere in the project)
client.set_marker(stm_addr=2, marker_id=0, state=True)
```

## Limitations

- **No live input/sensor monitoring via the STM's RPC surface.** There is no RPC call that
  returns a physical input's or sensor's current state, and no push/event mechanism for input
  changes either — confirmed by testing (a physical button press produced no change anywhere in
  the RPC surface) and by the fact that RPC methods that look like an event log
  (`checkInputs`/`checkOutputs`/`getEventBuffer`/`getEventCounter`) exist in the vendor client's
  code but are unused there and fault with "Feature not supported by device!" on real hardware.
  Use the Merker pattern above instead.
- **Output state on radio (EnOcean/Funk) actuators is optimistic, not verified.** `get_output_state()`
  reflects the last command *this library* sent, not a real hardware readback — these actuators
  only push a status telegram on an actual switching event, with no way to actively query current
  state. If the device is switched by other means (its own remote, a power cycle), the reported
  state silently goes stale. Wired (non-radio) output modules are expected to behave better, but
  this hasn't been hardware-verified either way yet.

## Advanced

### Address Logic
The library automatically calculates the correct physical address for modules based on their type:
- **Input Modules:** Offset `0` (e.g., Index 0 -> Addr 0)
- **Output Modules:** Offset `64` (e.g., Index 0 -> Addr 64)
- **Analog/RF Modules:** Offset `96` (e.g., Index 0 -> Addr 96)

### Device Catalog
The library includes a generated catalog (`peha/catalog_data.py`) derived from the official PEHA System Software `modules.xml`, ensuring accurate support for all module variants (e.g., `MFM_FUNK2`, `MCC_2`).
